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

Michael Buch via lldb-commits lldb-commits at lists.llvm.org
Tue Aug 6 03:47:04 PDT 2024


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

>From 3d7c2b87ec73a48de30e1c5387a7f0d8d817b0f4 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 2 Aug 2024 23:38:18 +0100
Subject: [PATCH 1/6] [lldb][ClangExpressionParser] Set
 BuiltinHeadersInSystemModules depending on SDK version

This patch addresses an issue that will arise with future
SDKs. The ClangExpressionParser currently unconditionally
sets `-fbuiltin-headers-in-system-modules` when evaluating
expressions with the `target.import-std-module` setting.
This flag should, however, be set depending on the SDK
version (which is what the Clang Darwin toolchain does).

Unfortunately, the compiler instance that we create with
`ClangExpressionParser` never consults the Clang driver,
and thus doesn't correctly infer `BuiltinHeadersInSystemModules`.
Note, this isn't an issue with the `CompilerInstance` that the
`ClangModulesDeclVendor` creates because it uses the `createInovcation`
API, which calls into `Darwin::addClangTargetOptions`.

This patch mimicks how `sdkSupportsBuiltinModules` is used in
`Darwin::addClangTargetOptions`.

This ensures that the `import-std-module` API tests run cleanly
regardless of SDK version.

The plan is to make the `CompilerInstance` construction in
`ClangExpressionParser` go through the driver, so we can avoid
duplicating the logic in LLDB.
---
 .../Clang/ClangExpressionParser.cpp           | 69 ++++++++++++++++++-
 1 file changed, 66 insertions(+), 3 deletions(-)

diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 2a8bdf29314e4..c6217e2f13394 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"
@@ -561,7 +562,62 @@ static void SetupLangOpts(CompilerInstance &compiler,
   lang_opts.NoBuiltin = true;
 }
 
-static void SetupImportStdModuleLangOpts(CompilerInstance &compiler) {
+// NOTE: should be kept in sync with sdkSupportsBuiltinModules in
+// Toolchains/Darwin.cpp
+static bool
+sdkSupportsBuiltinModulesImpl(const llvm::Triple &triple,
+                              const std::optional<DarwinSDKInfo> &SDKInfo) {
+  if (!SDKInfo)
+    return false;
+
+  VersionTuple SDKVersion = SDKInfo->getVersion();
+  switch (triple.getOS()) {
+  case Triple::OSType::MacOSX:
+    return SDKVersion >= VersionTuple(15U);
+  case Triple::OSType::IOS:
+    return SDKVersion >= VersionTuple(18U);
+  case Triple::OSType::TvOS:
+    return SDKVersion >= VersionTuple(18U);
+  case Triple::OSType::WatchOS:
+    return SDKVersion >= VersionTuple(11U);
+  case Triple::OSType::XROS:
+    return SDKVersion >= VersionTuple(2U);
+  default:
+    // New SDKs support builtin modules from the start.
+    return true;
+  }
+}
+
+static bool
+sdkSupportsBuiltinModules(llvm::Triple const &triple,
+                          std::vector<std::string> const &include_dirs) {
+  static constexpr std::string_view s_sdk_suffix = ".sdk";
+  auto it = llvm::find_if(include_dirs, [](std::string const &path) {
+    return path.find(s_sdk_suffix) != std::string::npos;
+  });
+  if (it == include_dirs.end())
+    return false;
+
+  size_t suffix = it->find(s_sdk_suffix);
+  if (suffix == std::string::npos)
+    return false;
+
+  auto VFS = FileSystem::Instance().GetVirtualFileSystem();
+  if (!VFS)
+    return false;
+
+  std::string sdk_path = it->substr(0, suffix + s_sdk_suffix.size());
+  auto parsed = clang::parseDarwinSDKInfo(*VFS, sdk_path);
+  if (!parsed)
+    return false;
+
+  return sdkSupportsBuiltinModulesImpl(triple, *parsed);
+}
+
+static void
+SetupImportStdModuleLangOpts(CompilerInstance &compiler,
+                             llvm::Triple const &triple,
+                             std::vector<std::string> const &include_dirs) {
   LangOptions &lang_opts = compiler.getLangOpts();
   lang_opts.Modules = true;
   // We want to implicitly build modules.
@@ -578,7 +634,12 @@ static void SetupImportStdModuleLangOpts(CompilerInstance &compiler) {
   lang_opts.GNUMode = true;
   lang_opts.GNUKeywords = true;
   lang_opts.CPlusPlus11 = true;
-  lang_opts.BuiltinHeadersInSystemModules = true;
+
+  // FIXME: We should use the driver to derive this for use.
+  // ClangModulesDeclVendor already parses the SDKSettings for the purposes of
+  // this check.
+  lang_opts.BuiltinHeadersInSystemModules =
+      !sdkSupportsBuiltinModules(triple, include_dirs);
 
   // The Darwin libc expects this macro to be set.
   lang_opts.GNUCVersion = 40201;
@@ -663,7 +724,9 @@ 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->GetArchitecture().GetTriple(),
+                                 m_include_directories);
     SetupModuleHeaderPaths(m_compiler.get(), m_include_directories, target_sp);
   }
 

>From 664059ce3118296c8b575d84df2fff40104a8eda Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Sat, 3 Aug 2024 01:12:27 +0100
Subject: [PATCH 2/6] fixup! fix comment

---
 .../Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index c6217e2f13394..5deb6a782481c 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -635,7 +635,7 @@ SetupImportStdModuleLangOpts(CompilerInstance &compiler,
   lang_opts.GNUKeywords = true;
   lang_opts.CPlusPlus11 = true;
 
-  // FIXME: We should use the driver to derive this for use.
+  // FIXME: We should use the driver to derive this for us.
   // ClangModulesDeclVendor already parses the SDKSettings for the purposes of
   // this check.
   lang_opts.BuiltinHeadersInSystemModules =

>From eb2f21333ff6d7bd6881e14fdb275ebb9572eef2 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Sat, 3 Aug 2024 17:44:41 +0100
Subject: [PATCH 3/6] fixup!

---
 .../Clang/ClangExpressionParser.cpp           | 27 +++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 5deb6a782481c..69c23e43c7fad 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -588,9 +588,23 @@ sdkSupportsBuiltinModulesImpl(const llvm::Triple &triple,
   }
 }
 
+/// 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.
+///
+/// This function assumes one of the directories in \ref include_dirs
+/// is an SDK path that exists on the host. The SDK version is
+/// read from the SDKSettings.json in that directory.
+///
+/// \param[in] triple The target triple.
+/// \param[in] include_dirs The include directories the compiler will use
+///                         during header search.
+///
 static bool
 sdkSupportsBuiltinModules(llvm::Triple const &triple,
                           std::vector<std::string> const &include_dirs) {
+  // Find an SDK directory.
   static constexpr std::string_view s_sdk_suffix = ".sdk";
   auto it = llvm::find_if(include_dirs, [](std::string const &path) {
     return path.find(s_sdk_suffix) != std::string::npos;
@@ -599,14 +613,16 @@ sdkSupportsBuiltinModules(llvm::Triple const &triple,
     return false;
 
   size_t suffix = it->find(s_sdk_suffix);
-  if (suffix == std::string::npos)
-    return false;
+  assert (suffix == std::string::npos);
 
   auto VFS = FileSystem::Instance().GetVirtualFileSystem();
   if (!VFS)
     return false;
 
+  // Extract: /path/to/some.sdk
   std::string sdk_path = it->substr(0, suffix + s_sdk_suffix.size());
+
+  // Extract SDK version from the /path/to/some.sdk/SDKSettings.json
   auto parsed = clang::parseDarwinSDKInfo(*VFS, sdk_path);
   if (!parsed)
     return false;
@@ -614,6 +630,13 @@ sdkSupportsBuiltinModules(llvm::Triple const &triple,
   return sdkSupportsBuiltinModulesImpl(triple, *parsed);
 }
 
+/// Sets the LangOptions to prepare for running with `import-std-module` enabled.
+///
+/// \param[out] compiler CompilerInstance on which to set the LangOptions.
+/// \param[in] triple The target triple.
+/// \param[in] include_dirs The include directories the compiler will use
+///                         during header search.
+///
 static void
 SetupImportStdModuleLangOpts(CompilerInstance &compiler,
                              llvm::Triple const &triple,

>From 3070e78a175db5a1cc994cd544910170b72f6d2c Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Sat, 3 Aug 2024 17:44:53 +0100
Subject: [PATCH 4/6] fixup! add comments

---
 .../Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 69c23e43c7fad..fbe1953dba5b8 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -613,7 +613,7 @@ sdkSupportsBuiltinModules(llvm::Triple const &triple,
     return false;
 
   size_t suffix = it->find(s_sdk_suffix);
-  assert (suffix == std::string::npos);
+  assert(suffix == std::string::npos);
 
   auto VFS = FileSystem::Instance().GetVirtualFileSystem();
   if (!VFS)
@@ -630,7 +630,8 @@ sdkSupportsBuiltinModules(llvm::Triple const &triple,
   return sdkSupportsBuiltinModulesImpl(triple, *parsed);
 }
 
-/// Sets the LangOptions to prepare for running with `import-std-module` enabled.
+/// Sets the LangOptions to prepare for running with `import-std-module`
+/// enabled.
 ///
 /// \param[out] compiler CompilerInstance on which to set the LangOptions.
 /// \param[in] triple The target triple.

>From b4b79b9a96d0b0461d94e4810a37a4aa767f8db1 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Sat, 3 Aug 2024 17:46:12 +0100
Subject: [PATCH 5/6] fixup! move assert

---
 .../Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index fbe1953dba5b8..e05cd649bb044 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -612,14 +612,13 @@ sdkSupportsBuiltinModules(llvm::Triple const &triple,
   if (it == include_dirs.end())
     return false;
 
-  size_t suffix = it->find(s_sdk_suffix);
-  assert(suffix == std::string::npos);
-
   auto VFS = FileSystem::Instance().GetVirtualFileSystem();
   if (!VFS)
     return false;
 
   // Extract: /path/to/some.sdk
+  size_t suffix = it->find(s_sdk_suffix);
+  assert(suffix != std::string::npos);
   std::string sdk_path = it->substr(0, suffix + s_sdk_suffix.size());
 
   // Extract SDK version from the /path/to/some.sdk/SDKSettings.json

>From ff7333fd9a072b2c31d1aa1b0f33d70b70b1504f Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Tue, 6 Aug 2024 11:45:36 +0100
Subject: [PATCH 6/6] fixup! add another FIXME

---
 .../Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp    | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index e05cd649bb044..9531104d81b1c 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -661,6 +661,8 @@ SetupImportStdModuleLangOpts(CompilerInstance &compiler,
   // FIXME: We should use the driver to derive this for us.
   // ClangModulesDeclVendor already parses the SDKSettings for the purposes of
   // this check.
+  // FIXME: Instead of using include_dirs here, we should use DW_AT_LLVM_sdk
+  // and look up a matching local SDK using HostInfo.
   lang_opts.BuiltinHeadersInSystemModules =
       !sdkSupportsBuiltinModules(triple, include_dirs);
 



More information about the lldb-commits mailing list