[Lldb-commits] [lldb] [lldb][ClangExpressionParser] Set BuiltinHeadersInSystemModules depending on SDK version (PR #102309)

Michael Buch via lldb-commits lldb-commits at lists.llvm.org
Wed Aug 7 09:05:29 PDT 2024


https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/102309

>From 3dfbfc759f61827f010f4a65241c8464c5815484 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Wed, 7 Aug 2024 12:46:24 +0100
Subject: [PATCH 1/2] [lldb][ClangExpressionParser] Set
 BuiltinHeadersInSystemModules depending on SDK version

---
 lldb/include/lldb/Utility/XcodeSDK.h          | 14 +++++
 .../Clang/ClangExpressionParser.cpp           | 53 +++++++++++++++++--
 lldb/source/Utility/XcodeSDK.cpp              | 21 ++++++++
 3 files changed, 85 insertions(+), 3 deletions(-)

diff --git a/lldb/include/lldb/Utility/XcodeSDK.h b/lldb/include/lldb/Utility/XcodeSDK.h
index 673ea578ffce8..69c7e23d3d0f6 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 &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 f41323d32ac86..4a4063996fe18 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,48 @@ 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.
+///
+/// \param[in] target The target triple.
+///
+static llvm::Expected<bool>
+sdkSupportsBuiltinModules(lldb_private::Target &target) {
+  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 sdk_or_err = PlatformDarwin::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());
+}
+
 static void SetupModuleHeaderPaths(CompilerInstance *compiler,
                                    std::vector<std::string> include_directories,
                                    lldb::TargetSP target_sp) {
@@ -561,7 +607,8 @@ static void SetupLangOpts(CompilerInstance &compiler,
   lang_opts.NoBuiltin = true;
 }
 
-static void SetupImportStdModuleLangOpts(CompilerInstance &compiler) {
+static void SetupImportStdModuleLangOpts(CompilerInstance &compiler,
+                                         lldb_private::Target &target) {
   LangOptions &lang_opts = compiler.getLangOpts();
   lang_opts.Modules = true;
   // We want to implicitly build modules.
@@ -578,7 +625,7 @@ static void SetupImportStdModuleLangOpts(CompilerInstance &compiler) {
   lang_opts.GNUMode = true;
   lang_opts.GNUKeywords = true;
   lang_opts.CPlusPlus11 = true;
-  lang_opts.BuiltinHeadersInSystemModules = true;
+  lang_opts.BuiltinHeadersInSystemModules = !sdkSupportsBuiltinModules(target);
 
   // The Darwin libc expects this macro to be set.
   lang_opts.GNUCVersion = 40201;
@@ -659,7 +706,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 712d611db28f8..64e0672a963ca 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 &triple,
+                                         llvm::VersionTuple sdk_version) {
+  using namespace llvm;
+
+  switch (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 090f2c437769ac59c6bbb4b6ef25ae936d11e94e Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Wed, 7 Aug 2024 17:04:53 +0100
Subject: [PATCH 2/2] fixup! check Expected return properly; add platform ifdef

---
 .../Clang/ClangExpressionParser.cpp                | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 4a4063996fe18..1b580aabf891f 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -292,6 +292,9 @@ class ClangDiagnosticManagerAdapter : public clang::DiagnosticConsumer {
 ///
 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();
@@ -323,6 +326,7 @@ 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,
@@ -609,6 +613,7 @@ static void SetupLangOpts(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.
@@ -625,7 +630,14 @@ static void SetupImportStdModuleLangOpts(CompilerInstance &compiler,
   lang_opts.GNUMode = true;
   lang_opts.GNUKeywords = true;
   lang_opts.CPlusPlus11 = true;
-  lang_opts.BuiltinHeadersInSystemModules = !sdkSupportsBuiltinModules(target);
+
+  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;



More information about the lldb-commits mailing list