diff --git a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp index de89a80c91119..58be6cebf629c 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp @@ -2812,7 +2812,7 @@ SwiftASTContext::CreateInstance(const SymbolContext &sc, return {}; } - bool handled_sdk_path = false; + bool sdk_path_override = false; ModuleList module_module; if (!target_sp) module_module.Append(module_sp); @@ -2826,10 +2826,11 @@ SwiftASTContext::CreateInstance(const SymbolContext &sc, swift_ast_sp->SetPlatformSDKPath(target_sdk_spec.GetPath()); LOG_PRINTF(GetLog(LLDBLog::Types), "Using target SDK override: %s", target_sdk_spec.GetPath().c_str()); - handled_sdk_path = true; + sdk_path_override = true; } // Get the precise SDK from the symbol context. + std::optional sdk; if (cu) if (auto platform_sp = Platform::GetHostPlatform()) { auto sdk_or_err = platform_sp->GetSDKPathFromDebugInfo(*cu); @@ -2837,32 +2838,13 @@ SwiftASTContext::CreateInstance(const SymbolContext &sc, Debugger::ReportError("Error while parsing SDK path from debug info: " + toString(sdk_or_err.takeError())); else { - std::string sdk_path = GetSDKPath(m_description, *sdk_or_err); - if (!sdk_path.empty()) { - swift_ast_sp->SetPlatformSDKPath(sdk_path); - handled_sdk_path = true; - LOG_PRINTF(GetLog(LLDBLog::Types), "Using precise SDK: %s", - sdk_path.c_str()); - } + sdk = *sdk_or_err; + LOG_PRINTF(GetLog(LLDBLog::Types), "Using precise SDK: %s", + sdk->GetString().str().c_str()); } } - if (!handled_sdk_path) { - for (size_t mi = 0; mi != num_images; ++mi) { - ModuleSP module_sp = modules.GetModuleAtIndex(mi); - if (!HasSwiftModules(*module_sp)) - continue; - - std::string sdk_path = GetSDKPathFromDebugInfo(m_description, *module_sp); - - if (sdk_path.empty()) - continue; - - swift_ast_sp->SetPlatformSDKPath(sdk_path); - handled_sdk_path = true; - break; - } - } + // Derive the triple next. // First, prime the compiler with the options from the main executable: bool got_serialized_options = false; @@ -2907,13 +2889,30 @@ SwiftASTContext::CreateInstance(const SymbolContext &sc, ArchSpec preferred_arch; llvm::Triple preferred_triple; if (is_repl) { + LOG_PRINTF(GetLog(LLDBLog::Types), "REPL: prefer target triple."); + preferred_arch = target_arch; + preferred_triple = target_triple; + } else if (!sdk_path_override && !sdk && target_arch) { + LOG_PRINTF(GetLog(LLDBLog::Types), + "No Swift debug info: prefer target triple."); + if (!target_arch.IsCompatibleMatch(module_arch)) + HEALTH_LOG_PRINTF( + "SwiftASTContext requested for a non-Swift translation unit. Using " + "target triple \"%s\", which is not compatible with this " + "translation unit's triple \"%s\". Expressions may behave " + "unexpectedly because of this.", + target_triple.str().c_str(), module_triple.str().c_str()); preferred_arch = target_arch; preferred_triple = target_triple; } else if (module_arch && (!target_arch || module_arch.IsFullySpecifiedTriple())) { + LOG_PRINTF(GetLog(LLDBLog::Types), + "Prefer module triple."); preferred_arch = module_arch; preferred_triple = module_triple; } else { + LOG_PRINTF(GetLog(LLDBLog::Types), + "No viable alternatives: Prefer target triple."); // When no viable module triple, fallback to the target triple. preferred_arch = target_arch; preferred_triple = target_triple; @@ -2993,6 +2992,27 @@ SwiftASTContext::CreateInstance(const SymbolContext &sc, } llvm::Triple triple = swift_ast_sp->GetTriple(); + + // Triple has been derived, find a matching SDK. + if (!sdk_path_override) { + XcodeSDK::Type sdk_type_for_triple = XcodeSDK::GetSDKTypeForTriple(triple); + if (sdk && sdk->GetType() != sdk_type_for_triple) { + HEALTH_LOG_PRINTF("Precise SDK is not compatible with triple. Ignoring."); + XcodeSDK::Info info{sdk_type_for_triple, {}, sdk->IsAppleInternalSDK()}; + sdk = XcodeSDK(info); + } + if (!sdk) { + XcodeSDK::Info info{sdk_type_for_triple, {}, false}; + sdk = XcodeSDK(info); + } + + std::string sdk_path = GetSDKPath(m_description, *sdk); + if (!sdk_path.empty()) { + swift_ast_sp->SetPlatformSDKPath(sdk_path); + LOG_PRINTF(GetLog(LLDBLog::Types), "Using SDK: %s", sdk_path.c_str()); + } + } + std::string resource_dir = HostInfo::GetSwiftResourceDir( triple, swift_ast_sp->GetPlatformSDKPath()); ConfigureResourceDirs(swift_ast_sp->GetCompilerInvocation(), resource_dir, diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index bfcd6649a6eb1..5101fa6ef1f35 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -1775,8 +1775,11 @@ const char *TypeSystemSwiftTypeRef::DeriveKeyFor(const SymbolContext &sc) { if (ConstString name = GetSwiftModuleFor(sc)) return name.GetCString(); - if (sc.module_sp) - return sc.module_sp->GetFileSpec().GetFilename().GetCString(); + if (sc.module_sp) { + if (sc.module_sp->GetFileSpec()) + return sc.module_sp->GetFileSpec().GetFilename().GetCString(); + return sc.module_sp->GetObjectName().GetCString(); + } return nullptr; } diff --git a/lldb/test/API/lang/swift/expression/no_debuginfo/Makefile b/lldb/test/API/lang/swift/expression/no_debuginfo/Makefile new file mode 100644 index 0000000000000..eb79578210051 --- /dev/null +++ b/lldb/test/API/lang/swift/expression/no_debuginfo/Makefile @@ -0,0 +1,20 @@ +SWIFT_SOURCES = main.swift +SWIFTFLAGS_EXTRAS = -I. +SWIFT_BRIDGING_HEADER = bridging-header.h +LD_EXTRAS = -L. -lDylib + +all: dylib $(EXE) + +include Makefile.rules + +.PHONY: dylib +dylib: + $(MAKE) MAKE_DSYM=$(MAKE_DSYM) CC=$(CC) SWIFTC=$(SWIFTC) \ + ARCH=$(ARCH) DSYMUTIL=$(DSYMUTIL) \ + VPATH=$(SRCDIR) -I $(SRCDIR) \ + -f $(THIS_FILE_DIR)/Makefile.rules \ + DYLIB_C_SOURCES=dylib.c \ + DYLIB_NAME=Dylib \ + DYLIB_ONLY=YES \ + DEBUG_INFO_FLAG= \ + all diff --git a/lldb/test/API/lang/swift/expression/no_debuginfo/TestSwiftExpressionNoDebugInfo.py b/lldb/test/API/lang/swift/expression/no_debuginfo/TestSwiftExpressionNoDebugInfo.py new file mode 100644 index 0000000000000..16d8360cb4a12 --- /dev/null +++ b/lldb/test/API/lang/swift/expression/no_debuginfo/TestSwiftExpressionNoDebugInfo.py @@ -0,0 +1,22 @@ +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +import lldbsuite.test.lldbutil as lldbutil + +class TestSwiftExpressionNoDebugInfo(TestBase): + NO_DEBUG_INFO_TESTCASE = True + + @swiftTest + @skipUnlessDarwin + def test_missing_var(self): + """Test running a Swift expression in a non-Swift context""" + self.build() + target, process, thread, bkpt = lldbutil.run_to_name_breakpoint( + self, 'foo') + + types_log = self.getBuildArtifact("types.log") + self.expect("log enable lldb types -f " + types_log) + self.expect('expr -l Swift -- 1') + self.filecheck('platform shell cat "%s"' % types_log, __file__) + # CHECK: No Swift debug info: prefer target triple. + # CHECK: Using SDK: {{.*}}MacOSX diff --git a/lldb/test/API/lang/swift/expression/no_debuginfo/bridging-header.h b/lldb/test/API/lang/swift/expression/no_debuginfo/bridging-header.h new file mode 100644 index 0000000000000..c8620b64b2cee --- /dev/null +++ b/lldb/test/API/lang/swift/expression/no_debuginfo/bridging-header.h @@ -0,0 +1 @@ +void foo(); diff --git a/lldb/test/API/lang/swift/expression/no_debuginfo/dylib.c b/lldb/test/API/lang/swift/expression/no_debuginfo/dylib.c new file mode 100644 index 0000000000000..85e6cd8c3909a --- /dev/null +++ b/lldb/test/API/lang/swift/expression/no_debuginfo/dylib.c @@ -0,0 +1 @@ +void foo() {} diff --git a/lldb/test/API/lang/swift/expression/no_debuginfo/main.swift b/lldb/test/API/lang/swift/expression/no_debuginfo/main.swift new file mode 100644 index 0000000000000..eb28ef4401b2e --- /dev/null +++ b/lldb/test/API/lang/swift/expression/no_debuginfo/main.swift @@ -0,0 +1 @@ +foo()