From bf30120dd00dfa061006dfeed67571f332f51c3d Mon Sep 17 00:00:00 2001 From: Augusto Noronha Date: Thu, 21 Mar 2024 17:26:49 -0700 Subject: [PATCH 1/3] [lldb] Add a setting to allow Swift AST context instantiations For testing purposes, it's useful to have a setting to disable the instantiation of SwiftASTContext, to ensure that TypeSystemSwiftTypeRef, which by default falls back to it on failure, is working independently. This setting might also be useful for end users, as when debugging a program that was built with a different compiler version versus what is embedded in LLDB instantiation of Swift AST contexts would be moot. --- lldb/include/lldb/Core/ModuleList.h | 1 + lldb/source/Core/CoreProperties.td | 4 ++++ lldb/source/Core/ModuleList.cpp | 6 ++++++ .../Plugins/TypeSystem/Swift/SwiftASTContext.cpp | 16 ++++++++++++++++ 4 files changed, 27 insertions(+) diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h index a94544f1e86cb..1a70431a1f262 100644 --- a/lldb/include/lldb/Core/ModuleList.h +++ b/lldb/include/lldb/Core/ModuleList.h @@ -95,6 +95,7 @@ class ModuleListProperties : public Properties { AutoBool GetSwiftEnableCxxInterop() const; AutoBool GetSwiftEnableFullDwarfDebugging() const; + bool GetSwiftEnableASTContext() const; // END SWIFT FileSpec GetClangModulesCachePath() const; diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td index 65d02dabbb807..c5fb921139dc8 100644 --- a/lldb/source/Core/CoreProperties.td +++ b/lldb/source/Core/CoreProperties.td @@ -64,6 +64,10 @@ let Definition = "modulelist" in { DefaultEnumValue<"llvm::to_underlying(AutoBool::Auto)">, EnumValues<"OptionEnumValues(g_enable_full_dwarf_debugging)">, Desc<"Read full debug information from DWARF for Swift debugging. By default LLDB will use DWARF debug information if it cannot use reflection metadata.">; + def SwiftEnableASTContext: Property<"swift-enable-ast-context", "Boolean">, + Global, + DefaultTrue, + Desc<"Enable instantiating Swift AST contexts.">; // END SWIFT def SymLinkPaths: Property<"debug-info-symlink-paths", "FileSpecList">, Global, diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index 85fdcf5f32511..26682eacb976b 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -274,6 +274,12 @@ AutoBool ModuleListProperties::GetSwiftEnableFullDwarfDebugging() const { idx, static_cast( g_modulelist_properties[idx].default_uint_value)); } + +bool ModuleListProperties::GetSwiftEnableASTContext() const { + const uint32_t idx = ePropertySwiftEnableASTContext; + return GetPropertyAtIndexAs( + idx, g_modulelist_properties[idx].default_uint_value != 0); +} // END SWIFT FileSpec ModuleListProperties::GetLLDBIndexCachePath() const { diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index e5ba27fd75e5b..0ec85c971e6e6 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -976,6 +976,10 @@ SwiftASTContext::SwiftASTContext(std::string description, : TypeSystemSwift(), m_typeref_typesystem(&typeref_typesystem), m_compiler_invocation_ap(new swift::CompilerInvocation()), m_diagnostic_consumer_ap(new StoringDiagnosticConsumer(*this)) { + assert( + ModuleList::GetGlobalModuleListProperties().GetSwiftEnableASTContext() && + "Swift AST context instantiation is disabled!"); + m_description = description; // Set the clang modules cache path. @@ -1884,6 +1888,10 @@ SwiftASTContext::CreateInstance(lldb::LanguageType language, Module &module, if (!SwiftASTContextSupportsLanguage(language)) return lldb::TypeSystemSP(); + if (!ModuleList::GetGlobalModuleListProperties() + .GetSwiftEnableASTContext()) + return lldb::TypeSystemSP(); + std::string m_description; { llvm::raw_string_ostream ss(m_description); @@ -2359,6 +2367,10 @@ lldb::TypeSystemSP SwiftASTContext::CreateInstance( if (!SwiftASTContextSupportsLanguage(language)) return lldb::TypeSystemSP(); + if (!ModuleList::GetGlobalModuleListProperties() + .GetSwiftEnableASTContext()) + return lldb::TypeSystemSP(); + LLDB_SCOPED_TIMER(); std::string m_description = "SwiftASTContextForExpressions"; std::vector plugin_search_options; @@ -2650,6 +2662,10 @@ lldb::TypeSystemSP SwiftASTContext::CreateInstance( TypeSystemSwiftTypeRefForExpressions &typeref_typesystem) { LLDB_SCOPED_TIMER(); + if (!ModuleList::GetGlobalModuleListProperties() + .GetSwiftEnableASTContext()) + return lldb::TypeSystemSP(); + CompileUnit *cu = sc.comp_unit; StringRef swift_module_name = TypeSystemSwiftTypeRef::GetSwiftModuleFor(&sc); std::string m_description; From f9a7e9b20bc06b293a855280b10cee4215a6771f Mon Sep 17 00:00:00 2001 From: Augusto Noronha Date: Fri, 22 Mar 2024 12:53:11 -0700 Subject: [PATCH 2/3] [lldb] Change default alignment to be the same as the size --- .../SymbolFile/DWARF/DWARFASTParserSwiftDescriptorFinder.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserSwiftDescriptorFinder.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserSwiftDescriptorFinder.cpp index 0e5333ae33793..d36e5531ab52f 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserSwiftDescriptorFinder.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserSwiftDescriptorFinder.cpp @@ -357,7 +357,8 @@ DWARFASTParserSwift::getBuiltinTypeDescriptor( if (byte_size == LLDB_INVALID_ADDRESS) return {}; - auto alignment = die.GetAttributeValueAsUnsigned(DW_AT_alignment, 8); + auto alignment = die.GetAttributeValueAsUnsigned(DW_AT_alignment, + byte_size ? byte_size : 8); // TODO: this seems simple to calculate but maybe we should encode the stride // in DWARF? That's what reflection metadata does. From 0f5f917091f0ad68557b2bc3930c9c24a116ca3c Mon Sep 17 00:00:00 2001 From: Augusto Noronha Date: Fri, 22 Mar 2024 12:53:52 -0700 Subject: [PATCH 3/3] [lldb] Split TestSwiftEmbeddedFrameVariable into two tests Split TestSwiftEmbeddedFrameVariable into one test that runs with instantiation of SwiftASTContext enabled, and one that runs with it disabled. The first one is useful because of the validation code that compares TypeSystemSwiftTypeRef results with SwiftASTContext's. The second one is useful to validate that the test is passing without TypeSystemSwiftTypeRef falling back to SwiftASTContext. --- .../TestSwiftEmbeddedFrameVariable.py | 112 ++++++++++-------- 1 file changed, 61 insertions(+), 51 deletions(-) diff --git a/lldb/test/API/lang/swift/embedded/frame_variable/TestSwiftEmbeddedFrameVariable.py b/lldb/test/API/lang/swift/embedded/frame_variable/TestSwiftEmbeddedFrameVariable.py index 9199675093356..f529b5109b58e 100644 --- a/lldb/test/API/lang/swift/embedded/frame_variable/TestSwiftEmbeddedFrameVariable.py +++ b/lldb/test/API/lang/swift/embedded/frame_variable/TestSwiftEmbeddedFrameVariable.py @@ -10,6 +10,18 @@ class TestSwiftEmbeddedFrameVariable(TestBase): @swiftTest def test(self): self.build() + self.implementation() + + @skipUnlessDarwin + @swiftTest + def test_without_ast(self): + """Run the test turning off instantion of Swift AST contexts in order to ensure that all type information comes from DWARF""" + self.build() + self.runCmd("setting set symbols.swift-enable-ast-context false") + self.implementation() + + def implementation(self): + self.runCmd("setting set symbols.swift-enable-full-dwarf-debugging true") target, process, thread, _ = lldbutil.run_to_source_breakpoint( self, "break here", lldb.SBFileSpec("main.swift") @@ -19,144 +31,142 @@ def test(self): varB = frame.FindVariable("varB") field = varB.GetChildMemberWithName("a").GetChildMemberWithName("field") - lldbutil.check_variable(self, field, False, value='4.5') + lldbutil.check_variable(self, field, False, value="4.5") b = varB.GetChildMemberWithName("b") - lldbutil.check_variable(self, b, False, value='123456') + lldbutil.check_variable(self, b, False, value="123456") tuple = frame.FindVariable("tuple") first = tuple.GetChildAtIndex(0) field = first.GetChildMemberWithName("field") - lldbutil.check_variable(self, field, False, value='4.5') + lldbutil.check_variable(self, field, False, value="4.5") second = tuple.GetChildAtIndex(1) a = second.GetChildMemberWithName("a") field = a.GetChildMemberWithName("field") - lldbutil.check_variable(self, field, False, value='4.5') + lldbutil.check_variable(self, field, False, value="4.5") b = second.GetChildMemberWithName("b") - lldbutil.check_variable(self, b, False, value='123456') + lldbutil.check_variable(self, b, False, value="123456") nonPayload1 = frame.FindVariable("nonPayload1") - lldbutil.check_variable(self, nonPayload1, False, value='one') + lldbutil.check_variable(self, nonPayload1, False, value="one") nonPayload2 = frame.FindVariable("nonPayload2") - lldbutil.check_variable(self, nonPayload2, False, value='two') + lldbutil.check_variable(self, nonPayload2, False, value="two") singlePayload = frame.FindVariable("singlePayload") - payload = singlePayload.GetChildMemberWithName('payload') - field = payload.GetChildMemberWithName('a').GetChildMemberWithName('field') - lldbutil.check_variable(self, field, False, value='4.5') - b = payload.GetChildMemberWithName('b') - lldbutil.check_variable(self, b, False, value='123456') + payload = singlePayload.GetChildMemberWithName("payload") + field = payload.GetChildMemberWithName("a").GetChildMemberWithName("field") + lldbutil.check_variable(self, field, False, value="4.5") + b = payload.GetChildMemberWithName("b") + lldbutil.check_variable(self, b, False, value="123456") emptySinglePayload = frame.FindVariable("emptySinglePayload") - lldbutil.check_variable(self, emptySinglePayload, False, value='nonPayloadTwo') + lldbutil.check_variable(self, emptySinglePayload, False, value="nonPayloadTwo") smallMultipayloadEnum1 = frame.FindVariable("smallMultipayloadEnum1") one = smallMultipayloadEnum1.GetChildMemberWithName("one") - lldbutil.check_variable(self, one, False, value='two') + lldbutil.check_variable(self, one, False, value="two") smallMultipayloadEnum2 = frame.FindVariable("smallMultipayloadEnum2") two = smallMultipayloadEnum2.GetChildMemberWithName("two") - lldbutil.check_variable(self, two, False, value='one') - + lldbutil.check_variable(self, two, False, value="one") bigMultipayloadEnum1 = frame.FindVariable("bigMultipayloadEnum1") one = bigMultipayloadEnum1.GetChildMemberWithName("one") first = one.GetChildAtIndex(0).GetChildMemberWithName("supField") second = one.GetChildAtIndex(1).GetChildMemberWithName("supField") third = one.GetChildAtIndex(2).GetChildMemberWithName("supField") - lldbutil.check_variable(self, first, False, value='42') - lldbutil.check_variable(self, second, False, value='43') - lldbutil.check_variable(self, third, False, value='44') - + lldbutil.check_variable(self, first, False, value="42") + lldbutil.check_variable(self, second, False, value="43") + lldbutil.check_variable(self, third, False, value="44") fullMultipayloadEnum1 = frame.FindVariable("fullMultipayloadEnum1") one = fullMultipayloadEnum1.GetChildMemberWithName("one") - lldbutil.check_variable(self, one, False, value='120') + lldbutil.check_variable(self, one, False, value="120") fullMultipayloadEnum2 = frame.FindVariable("fullMultipayloadEnum2") two = fullMultipayloadEnum2.GetChildMemberWithName("two") - lldbutil.check_variable(self, two, False, value='9.5') + lldbutil.check_variable(self, two, False, value="9.5") bigFullMultipayloadEnum1 = frame.FindVariable("bigFullMultipayloadEnum1") one = bigFullMultipayloadEnum1.GetChildMemberWithName("one") first = one.GetChildAtIndex(0) second = one.GetChildAtIndex(1) - lldbutil.check_variable(self, first, False, value='209') - lldbutil.check_variable(self, second, False, value='315') + lldbutil.check_variable(self, first, False, value="209") + lldbutil.check_variable(self, second, False, value="315") bigFullMultipayloadEnum2 = frame.FindVariable("bigFullMultipayloadEnum2") two = bigFullMultipayloadEnum2.GetChildMemberWithName("two") first = two.GetChildAtIndex(0) second = two.GetChildAtIndex(1) - lldbutil.check_variable(self, first, False, value='452.5') - lldbutil.check_variable(self, second, False, value='753.5') - + lldbutil.check_variable(self, first, False, value="452.5") + lldbutil.check_variable(self, second, False, value="753.5") sup = frame.FindVariable("sup") supField = sup.GetChildMemberWithName("supField") - lldbutil.check_variable(self, supField, False, value='42') + lldbutil.check_variable(self, supField, False, value="42") sub = frame.FindVariable("sub") supField = sub.GetChildMemberWithName("supField") - lldbutil.check_variable(self, supField, False, value='42') + lldbutil.check_variable(self, supField, False, value="42") subField = sub.GetChildMemberWithName("subField") a = subField.GetChildMemberWithName("a") field = a.GetChildMemberWithName("field") - lldbutil.check_variable(self, field, False, value='4.5') + lldbutil.check_variable(self, field, False, value="4.5") b = subField.GetChildMemberWithName("b") - lldbutil.check_variable(self, b, False, value='123456') + lldbutil.check_variable(self, b, False, value="123456") subSub = frame.FindVariable("subSub") supField = subSub.GetChildMemberWithName("supField") - lldbutil.check_variable(self, supField, False, value='42') + lldbutil.check_variable(self, supField, False, value="42") subField = subSub.GetChildMemberWithName("subField") a = subField.GetChildMemberWithName("a") field = a.GetChildMemberWithName("field") - lldbutil.check_variable(self, field, False, value='4.5') + lldbutil.check_variable(self, field, False, value="4.5") b = subField.GetChildMemberWithName("b") - lldbutil.check_variable(self, b, False, value='123456') + lldbutil.check_variable(self, b, False, value="123456") - subSubField = subSub.GetChildMemberWithName("subSubField").GetChildMemberWithName("field") - lldbutil.check_variable(self, subSubField, False, value='4.5') + subSubField = subSub.GetChildMemberWithName( + "subSubField" + ).GetChildMemberWithName("field") + lldbutil.check_variable(self, subSubField, False, value="4.5") gsp = frame.FindVariable("gsp") t = gsp.GetChildMemberWithName("t") - lldbutil.check_variable(self, t, False, value='42') + lldbutil.check_variable(self, t, False, value="42") u = gsp.GetChildMemberWithName("u") - lldbutil.check_variable(self, u, False, value='94.5') + lldbutil.check_variable(self, u, False, value="94.5") gsp2 = frame.FindVariable("gsp2") t = gsp2.GetChildMemberWithName("t") supField = t.GetChildMemberWithName("supField") - lldbutil.check_variable(self, supField, False, value='42') + lldbutil.check_variable(self, supField, False, value="42") u = gsp2.GetChildMemberWithName("u") a = u.GetChildMemberWithName("a") field = a.GetChildMemberWithName("field") - lldbutil.check_variable(self, field, False, value='4.5') + lldbutil.check_variable(self, field, False, value="4.5") b = u.GetChildMemberWithName("b") - lldbutil.check_variable(self, b, False, value='123456') + lldbutil.check_variable(self, b, False, value="123456") gsp3 = frame.FindVariable("gsp3") t = gsp3.GetChildMemberWithName("t") one = t.GetChildMemberWithName("one") first = one.GetChildAtIndex(0) second = one.GetChildAtIndex(1) - lldbutil.check_variable(self, first, False, value='209') - lldbutil.check_variable(self, second, False, value='315') + lldbutil.check_variable(self, first, False, value="209") + lldbutil.check_variable(self, second, False, value="315") u = gsp3.GetChildMemberWithName("u") two = u.GetChildMemberWithName("two") - lldbutil.check_variable(self, two, False, value='one') + lldbutil.check_variable(self, two, False, value="one") gcp = frame.FindVariable("gcp") t = gcp.GetChildMemberWithName("t") - lldbutil.check_variable(self, t, False, value='55.5') + lldbutil.check_variable(self, t, False, value="55.5") u = gcp.GetChildMemberWithName("u") - lldbutil.check_variable(self, u, False, value='9348') - + lldbutil.check_variable(self, u, False, value="9348") either = frame.FindVariable("either") left = either.GetChildMemberWithName("left") - lldbutil.check_variable(self, left, False, value='1234') + lldbutil.check_variable(self, left, False, value="1234") either2 = frame.FindVariable("either2") right = either2.GetChildMemberWithName("right") @@ -164,8 +174,8 @@ def test(self): one = t.GetChildMemberWithName("one") first = one.GetChildAtIndex(0) second = one.GetChildAtIndex(1) - lldbutil.check_variable(self, first, False, value='209') - lldbutil.check_variable(self, second, False, value='315') + lldbutil.check_variable(self, first, False, value="209") + lldbutil.check_variable(self, second, False, value="315") u = right.GetChildMemberWithName("u") two = u.GetChildMemberWithName("two") - lldbutil.check_variable(self, two, False, value='one') + lldbutil.check_variable(self, two, False, value="one")