aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp')
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp44
1 files changed, 38 insertions, 6 deletions
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
index f1272c67d20f..ffab16b1682b 100644
--- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp
@@ -38,9 +38,11 @@ bool CppModuleConfiguration::analyzeFile(const FileSpec &f) {
// Check for /c++/vX/ that is used by libc++.
static llvm::Regex libcpp_regex(R"regex(/c[+][+]/v[0-9]/)regex");
- if (libcpp_regex.match(f.GetPath())) {
- // Strip away libc++'s /experimental directory if there is one.
- posix_dir.consume_back("/experimental");
+ // If the path is in the libc++ include directory use it as the found libc++
+ // path. Ignore subdirectories such as /c++/v1/experimental as those don't
+ // need to be specified in the header search.
+ if (libcpp_regex.match(f.GetPath()) &&
+ parent_path(posix_dir, Style::posix).endswith("c++")) {
return m_std_inc.TrySet(posix_dir);
}
@@ -55,9 +57,38 @@ bool CppModuleConfiguration::analyzeFile(const FileSpec &f) {
return true;
}
+/// Utility function for just appending two paths.
+static std::string MakePath(llvm::StringRef lhs, llvm::StringRef rhs) {
+ llvm::SmallString<256> result(lhs);
+ llvm::sys::path::append(result, rhs);
+ return std::string(result);
+}
+
bool CppModuleConfiguration::hasValidConfig() {
- // We all these include directories to have a valid usable configuration.
- return m_c_inc.Valid() && m_std_inc.Valid();
+ // We need to have a C and C++ include dir for a valid configuration.
+ if (!m_c_inc.Valid() || !m_std_inc.Valid())
+ return false;
+
+ // Do some basic sanity checks on the directories that we don't activate
+ // the module when it's clear that it's not usable.
+ const std::vector<std::string> files_to_check = {
+ // * Check that the C library contains at least one random C standard
+ // library header.
+ MakePath(m_c_inc.Get(), "stdio.h"),
+ // * Without a libc++ modulemap file we can't have a 'std' module that
+ // could be imported.
+ MakePath(m_std_inc.Get(), "module.modulemap"),
+ // * Check for a random libc++ header (vector in this case) that has to
+ // exist in a working libc++ setup.
+ MakePath(m_std_inc.Get(), "vector"),
+ };
+
+ for (llvm::StringRef file_to_check : files_to_check) {
+ if (!FileSystem::Instance().Exists(file_to_check))
+ return false;
+ }
+
+ return true;
}
CppModuleConfiguration::CppModuleConfiguration(
@@ -76,7 +107,8 @@ CppModuleConfiguration::CppModuleConfiguration(
m_resource_inc = std::string(resource_dir.str());
// This order matches the way Clang orders these directories.
- m_include_dirs = {m_std_inc.Get(), m_resource_inc, m_c_inc.Get()};
+ m_include_dirs = {m_std_inc.Get().str(), m_resource_inc,
+ m_c_inc.Get().str()};
m_imported_modules = {"std"};
}
}