https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/102497
>From d2f0b68afe6ebfffe5a2ef3ce14a77a5e1025c90 Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Thu, 8 Aug 2024 16:07:21 +0100 Subject: [PATCH 1/3] [lldb][Platform] Move the GetSDKPathFromDebugInfo helpers from PlatformDarwin into Platform This will soon be needed for https://github.com/llvm/llvm-project/pull/102309, where we plan on calling these APIs from generic ExpressionParser code. --- lldb/include/lldb/Target/Platform.h | 34 +++++++++++++++++++ .../Plugins/Platform/MacOSX/PlatformDarwin.h | 31 +++-------------- .../SymbolFile/DWARF/XcodeSDKModuleTests.cpp | 12 +++++-- 3 files changed, 48 insertions(+), 29 deletions(-) diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h index 5ed2fc33356d9d..8cf52a486e2c87 100644 --- a/lldb/include/lldb/Target/Platform.h +++ b/lldb/include/lldb/Target/Platform.h @@ -27,6 +27,7 @@ #include "lldb/Utility/StructuredData.h" #include "lldb/Utility/Timeout.h" #include "lldb/Utility/UserIDResolver.h" +#include "lldb/Utility/XcodeSDK.h" #include "lldb/lldb-private-forward.h" #include "lldb/lldb-public.h" @@ -436,6 +437,39 @@ class Platform : public PluginInterface { return lldb_private::ConstString(); } + /// Search each CU associated with the specified 'module' for + /// the SDK paths the CUs were compiled against. In the presence + /// of different SDKs, we try to pick the most appropriate one + /// using \ref XcodeSDK::Merge. + /// + /// \param[in] module Module whose debug-info CUs to parse for + /// which SDK they were compiled against. + /// + /// \returns If successful, returns a pair of a parsed XcodeSDK + /// object and a boolean that is 'true' if we encountered + /// a conflicting combination of SDKs when parsing the CUs + /// (e.g., a public and internal SDK). + virtual llvm::Expected<std::pair<XcodeSDK, bool>> + GetSDKPathFromDebugInfo(Module &module) { + return llvm::createStringError(llvm::formatv( + "{0} not implemented for '{1}' platform.", __func__, GetName())); + } + + /// Returns the full path of the most appropriate SDK for the + /// specified 'module'. This function gets this path by parsing + /// debug-info (see \ref `GetSDKPathFromDebugInfo`). + /// + /// \param[in] module Module whose debug-info to parse for + /// which SDK it was compiled against. + /// + /// \returns If successful, returns the full path to an + /// Xcode SDK. + virtual llvm::Expected<std::string> + ResolveSDKPathFromDebugInfo(Module &module) { + return llvm::createStringError(llvm::formatv( + "{0} not implemented for '{1}' platform.", __func__, GetName())); + } + const std::string &GetRemoteURL() const { return m_remote_url; } bool IsHost() const { diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h index ff7087da6825d9..66a26d2f496776 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h @@ -124,32 +124,11 @@ class PlatformDarwin : public PlatformPOSIX { /// located in. static FileSpec GetCurrentCommandLineToolsDirectory(); - /// Search each CU associated with the specified 'module' for - /// the SDK paths the CUs were compiled against. In the presence - /// of different SDKs, we try to pick the most appropriate one - /// using \ref XcodeSDK::Merge. - /// - /// \param[in] module Module whose debug-info CUs to parse for - /// which SDK they were compiled against. - /// - /// \returns If successful, returns a pair of a parsed XcodeSDK - /// object and a boolean that is 'true' if we encountered - /// a conflicting combination of SDKs when parsing the CUs - /// (e.g., a public and internal SDK). - static llvm::Expected<std::pair<XcodeSDK, bool>> - GetSDKPathFromDebugInfo(Module &module); - - /// Returns the full path of the most appropriate SDK for the - /// specified 'module'. This function gets this path by parsing - /// debug-info (see \ref `GetSDKPathFromDebugInfo`). - /// - /// \param[in] module Module whose debug-info to parse for - /// which SDK it was compiled against. - /// - /// \returns If successful, returns the full path to an - /// Xcode SDK. - static llvm::Expected<std::string> - ResolveSDKPathFromDebugInfo(Module &module); + llvm::Expected<std::pair<XcodeSDK, bool>> + GetSDKPathFromDebugInfo(Module &module) override; + + llvm::Expected<std::string> + ResolveSDKPathFromDebugInfo(Module &module) override; protected: static const char *GetCompatibleArch(ArchSpec::Core core, size_t idx); diff --git a/lldb/unittests/SymbolFile/DWARF/XcodeSDKModuleTests.cpp b/lldb/unittests/SymbolFile/DWARF/XcodeSDKModuleTests.cpp index c37da89ff79ce7..dc5680522e1836 100644 --- a/lldb/unittests/SymbolFile/DWARF/XcodeSDKModuleTests.cpp +++ b/lldb/unittests/SymbolFile/DWARF/XcodeSDKModuleTests.cpp @@ -162,7 +162,9 @@ TEST_F(XcodeSDKModuleTests, TestSDKPathFromDebugInfo_InvalidSDKPath) { ModuleSP module = t.GetModule(); ASSERT_NE(module, nullptr); - auto path_or_err = PlatformDarwin::ResolveSDKPathFromDebugInfo(*module); + auto platform_sp = Platform::GetHostPlatform(); + ASSERT_TRUE(platform_sp); + auto path_or_err = platform_sp->ResolveSDKPathFromDebugInfo(*module); EXPECT_FALSE(static_cast<bool>(path_or_err)); llvm::consumeError(path_or_err.takeError()); } @@ -206,7 +208,9 @@ TEST_F(XcodeSDKModuleTests, TestSDKPathFromDebugInfo_No_DW_AT_APPLE_sdk) { ModuleSP module = t.GetModule(); ASSERT_NE(module, nullptr); - auto path_or_err = PlatformDarwin::ResolveSDKPathFromDebugInfo(*module); + auto platform_sp = Platform::GetHostPlatform(); + ASSERT_TRUE(platform_sp); + auto path_or_err = platform_sp->ResolveSDKPathFromDebugInfo(*module); EXPECT_FALSE(static_cast<bool>(path_or_err)); llvm::consumeError(path_or_err.takeError()); } @@ -254,7 +258,9 @@ TEST_P(SDKPathParsingMultiparamTests, TestSDKPathFromDebugInfo) { ModuleSP module = t.GetModule(); ASSERT_NE(module, nullptr); - auto sdk_or_err = PlatformDarwin::GetSDKPathFromDebugInfo(*module); + auto platform_sp = Platform::GetHostPlatform(); + ASSERT_TRUE(platform_sp); + auto sdk_or_err = platform_sp->GetSDKPathFromDebugInfo(*module); ASSERT_TRUE(static_cast<bool>(sdk_or_err)); auto [sdk, found_mismatch] = *sdk_or_err; >From 4b73f06eb085435cdcdfbee0179fb08581d939ab Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Thu, 8 Aug 2024 15:14:46 +0100 Subject: [PATCH 2/3] Reland "[lldb][ClangExpressionParser] Set BuiltinHeadersInSystemModules depending on SDK version (#102309)" Depends on https://github.com/llvm/llvm-project/pull/102488 This reverts commit cf56e265e4b74799aee72a04b634fcc261078084. The original change was reverted because it was causing linker failures in the unit-tests: ``` Undefined symbols for architecture arm64: "lldb_private::PlatformDarwin::GetSDKPathFromDebugInfo(lldb_private::Module&)", referenced from: lldb_private::ClangExpressionParser::ClangExpressionParser(lldb_private::ExecutionContextScope*, lldb_private::Expression&, bool, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>>>, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>) in liblldbPluginExpressionParserClang.a[11](ClangExpressionParser.cpp.o) ld: symbol(s) not found for architecture arm64 c++: error: linker command failed with exit code 1 (use -v to see invocation) ``` The relanded version differs only in the fact that we now use the generic `Platform` abstraction to get to `GetSDKPathFromDebugInfo`. --- lldb/include/lldb/Utility/XcodeSDK.h | 14 ++++ .../Clang/ClangExpressionParser.cpp | 66 ++++++++++++++++++- lldb/source/Utility/XcodeSDK.cpp | 21 ++++++ 3 files changed, 98 insertions(+), 3 deletions(-) diff --git a/lldb/include/lldb/Utility/XcodeSDK.h b/lldb/include/lldb/Utility/XcodeSDK.h index 673ea578ffce85..2720d0d8a44a11 100644 --- a/lldb/include/lldb/Utility/XcodeSDK.h +++ b/lldb/include/lldb/Utility/XcodeSDK.h @@ -85,6 +85,20 @@ class XcodeSDK { /// Whether LLDB feels confident importing Clang modules from this SDK. static bool SDKSupportsModules(Type type, llvm::VersionTuple version); static bool SDKSupportsModules(Type desired_type, const FileSpec &sdk_path); + + /// Returns true if the SDK for the specified triple supports + /// builtin modules in system headers. + /// + /// NOTE: should be kept in sync with sdkSupportsBuiltinModules in + /// Toolchains/Darwin.cpp + /// + /// FIXME: this function will be removed once LLDB's ClangExpressionParser + /// constructs the compiler instance through the driver/toolchain. See \ref + /// SetupImportStdModuleLangOpts + /// + static bool SDKSupportsBuiltinModules(const llvm::Triple &target_triple, + llvm::VersionTuple sdk_version); + /// Return the canonical SDK name, such as "macosx" for the macOS SDK. static std::string GetCanonicalName(Info info); /// Return the best-matching SDK type for a specific triple. diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index f41323d32ac863..aa57179f0e79cd 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -11,6 +11,7 @@ #include "clang/AST/ExternalASTSource.h" #include "clang/AST/PrettyPrinter.h" #include "clang/Basic/Builtins.h" +#include "clang/Basic/DarwinSDKInfo.h" #include "clang/Basic/DiagnosticIDs.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/TargetInfo.h" @@ -39,6 +40,7 @@ #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/Support/CrashRecoveryContext.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/TargetSelect.h" @@ -91,6 +93,8 @@ #include "lldb/Utility/StringList.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" +#include "Plugins/Platform/MacOSX/PlatformDarwin.h" +#include "lldb/Utility/XcodeSDK.h" #include <cctype> #include <memory> @@ -279,6 +283,53 @@ class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer { std::string m_output; }; +/// Returns true if the SDK for the specified triple supports +/// builtin modules in system headers. This is used to decide +/// whether to pass -fbuiltin-headers-in-system-modules to +/// the compiler instance when compiling the `std` module. +static llvm::Expected<bool> +sdkSupportsBuiltinModules(lldb_private::Target &target) { +#ifndef __APPLE__ + return false; +#else + auto arch_spec = target.GetArchitecture(); + auto const &triple = arch_spec.GetTriple(); + auto module_sp = target.GetExecutableModule(); + if (!module_sp) + return llvm::createStringError("Executable module not found."); + + // Get SDK path that the target was compiled against. + auto platform_sp = target.GetPlatform(); + if (!platform_sp) + return llvm::createStringError("No Platform plugin found on target."); + + auto sdk_or_err = platform_sp->GetSDKPathFromDebugInfo(*module_sp); + if (!sdk_or_err) + return sdk_or_err.takeError(); + + // Use the SDK path from debug-info to find a local matching SDK directory. + auto sdk_path_or_err = + HostInfo::GetSDKRoot(HostInfo::SDKOptions{std::move(sdk_or_err->first)}); + if (!sdk_path_or_err) + return sdk_path_or_err.takeError(); + + auto VFS = FileSystem::Instance().GetVirtualFileSystem(); + if (!VFS) + return llvm::createStringError("No virtual filesystem available."); + + // Extract SDK version from the /path/to/some.sdk/SDKSettings.json + auto parsed_or_err = clang::parseDarwinSDKInfo(*VFS, *sdk_path_or_err); + if (!parsed_or_err) + return parsed_or_err.takeError(); + + auto maybe_sdk = *parsed_or_err; + if (!maybe_sdk) + return llvm::createStringError("Couldn't find Darwin SDK info."); + + return XcodeSDK::SDKSupportsBuiltinModules(triple, maybe_sdk->getVersion()); +#endif +} + static void SetupModuleHeaderPaths(CompilerInstance *compiler, std::vector<std::string> include_directories, lldb::TargetSP target_sp) { @@ -561,7 +612,9 @@ static void SetupLangOpts(CompilerInstance &compiler, lang_opts.NoBuiltin = true; } -static void SetupImportStdModuleLangOpts(CompilerInstance &compiler) { +static void SetupImportStdModuleLangOpts(CompilerInstance &compiler, + lldb_private::Target &target) { + Log *log = GetLog(LLDBLog::Expressions); LangOptions &lang_opts = compiler.getLangOpts(); lang_opts.Modules = true; // We want to implicitly build modules. @@ -578,7 +631,14 @@ static void SetupImportStdModuleLangOpts(CompilerInstance &compiler) { lang_opts.GNUMode = true; lang_opts.GNUKeywords = true; lang_opts.CPlusPlus11 = true; - lang_opts.BuiltinHeadersInSystemModules = true; + + auto supported_or_err = sdkSupportsBuiltinModules(target); + if (supported_or_err) + lang_opts.BuiltinHeadersInSystemModules = !*supported_or_err; + else + LLDB_LOG_ERROR(log, supported_or_err.takeError(), + "Failed to determine BuiltinHeadersInSystemModules when " + "setting up import-std-module: {0}"); // The Darwin libc expects this macro to be set. lang_opts.GNUCVersion = 40201; @@ -659,7 +719,7 @@ ClangExpressionParser::ClangExpressionParser( if (auto *clang_expr = dyn_cast<ClangUserExpression>(&m_expr); clang_expr && clang_expr->DidImportCxxModules()) { LLDB_LOG(log, "Adding lang options for importing C++ modules"); - SetupImportStdModuleLangOpts(*m_compiler); + SetupImportStdModuleLangOpts(*m_compiler, *target_sp); SetupModuleHeaderPaths(m_compiler.get(), m_include_directories, target_sp); } diff --git a/lldb/source/Utility/XcodeSDK.cpp b/lldb/source/Utility/XcodeSDK.cpp index 712d611db28f83..b7d51f7e0827ac 100644 --- a/lldb/source/Utility/XcodeSDK.cpp +++ b/lldb/source/Utility/XcodeSDK.cpp @@ -259,6 +259,27 @@ bool XcodeSDK::SupportsSwift() const { } } +bool XcodeSDK::SDKSupportsBuiltinModules(const llvm::Triple &target_triple, + llvm::VersionTuple sdk_version) { + using namespace llvm; + + switch (target_triple.getOS()) { + case Triple::OSType::MacOSX: + return sdk_version >= VersionTuple(15U); + case Triple::OSType::IOS: + return sdk_version >= VersionTuple(18U); + case Triple::OSType::TvOS: + return sdk_version >= VersionTuple(18U); + case Triple::OSType::WatchOS: + return sdk_version >= VersionTuple(11U); + case Triple::OSType::XROS: + return sdk_version >= VersionTuple(2U); + default: + // New SDKs support builtin modules from the start. + return true; + } +} + bool XcodeSDK::SDKSupportsModules(XcodeSDK::Type desired_type, const FileSpec &sdk_path) { ConstString last_path_component = sdk_path.GetFilename(); >From 2e5556e3a18b2e884e7aef2ea7430b1f0c147b79 Mon Sep 17 00:00:00 2001 From: Michael Buch <michaelbuc...@gmail.com> Date: Thu, 8 Aug 2024 17:09:16 +0100 Subject: [PATCH 3/3] fixup! remove ifdef --- .../Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index aa57179f0e79cd..375d3d877a8537 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -289,9 +289,6 @@ class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer { /// the compiler instance when compiling the `std` module. static llvm::Expected<bool> sdkSupportsBuiltinModules(lldb_private::Target &target) { -#ifndef __APPLE__ - return false; -#else auto arch_spec = target.GetArchitecture(); auto const &triple = arch_spec.GetTriple(); auto module_sp = target.GetExecutableModule(); @@ -327,7 +324,6 @@ sdkSupportsBuiltinModules(lldb_private::Target &target) { return llvm::createStringError("Couldn't find Darwin SDK info."); return XcodeSDK::SDKSupportsBuiltinModules(triple, maybe_sdk->getVersion()); -#endif } static void SetupModuleHeaderPaths(CompilerInstance *compiler, _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits