Deserialize Clang module search path from DWARF
This patch properly extracts the full submodule path as well as its
search paths from DWARF import decls and passes it on to the
ClangModulesDeclVendor.
rdar://problem/47970144
Differential Revision: https://reviews.llvm.org/D58090
llvm-svn: 353961
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 266b1e2..acb08a6 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -113,24 +113,19 @@
void moduleImport(SourceLocation import_location, clang::ModuleIdPath path,
const clang::Module * /*null*/) override {
- std::vector<ConstString> string_path;
+ SourceModule module;
- for (const std::pair<IdentifierInfo *, SourceLocation> &component : path) {
- string_path.push_back(ConstString(component.first->getName()));
- }
+ for (const std::pair<IdentifierInfo *, SourceLocation> &component : path)
+ module.path.push_back(ConstString(component.first->getName()));
StreamString error_stream;
ClangModulesDeclVendor::ModuleVector exported_modules;
-
- if (!m_decl_vendor.AddModule(string_path, &exported_modules,
- m_error_stream)) {
+ if (!m_decl_vendor.AddModule(module, &exported_modules, m_error_stream))
m_has_errors = true;
- }
- for (ClangModulesDeclVendor::ModuleID module : exported_modules) {
+ for (ClangModulesDeclVendor::ModuleID module : exported_modules)
m_persistent_vars.AddHandLoadedClangModule(module);
- }
}
bool hasErrors() { return m_has_errors; }
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
index de5c809..b08c454 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -28,6 +28,7 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/SourceModule.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/LLDBAssert.h"
@@ -71,7 +72,7 @@
~ClangModulesDeclVendorImpl() override = default;
- bool AddModule(ModulePath &path, ModuleVector *exported_modules,
+ bool AddModule(const SourceModule &module, ModuleVector *exported_modules,
Stream &error_stream) override;
bool AddModulesForCompileUnit(CompileUnit &cu, ModuleVector &exported_modules,
@@ -184,7 +185,7 @@
}
}
-bool ClangModulesDeclVendorImpl::AddModule(ModulePath &path,
+bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module,
ModuleVector *exported_modules,
Stream &error_stream) {
// Fail early.
@@ -199,7 +200,7 @@
std::vector<ConstString> imported_module;
- for (ConstString path_component : path) {
+ for (ConstString path_component : module.path) {
imported_module.push_back(path_component);
}
@@ -214,11 +215,34 @@
}
}
- if (!m_compiler_instance->getPreprocessor()
- .getHeaderSearchInfo()
- .lookupModule(path[0].GetStringRef())) {
+ clang::HeaderSearch &HS =
+ m_compiler_instance->getPreprocessor().getHeaderSearchInfo();
+
+ if (module.search_path) {
+ auto path_begin = llvm::sys::path::begin(module.search_path.GetStringRef());
+ auto path_end = llvm::sys::path::end(module.search_path.GetStringRef());
+ auto sysroot_begin = llvm::sys::path::begin(module.sysroot.GetStringRef());
+ auto sysroot_end = llvm::sys::path::end(module.sysroot.GetStringRef());
+ // FIXME: Use C++14 std::equal(it, it, it, it) variant once it's available.
+ bool is_system_module = (std::distance(path_begin, path_end) >=
+ std::distance(sysroot_begin, sysroot_end)) &&
+ std::equal(sysroot_begin, sysroot_end, path_begin);
+ // No need to inject search paths to modules in the sysroot.
+ if (!is_system_module) {
+ bool is_system = true;
+ bool is_framework = false;
+ auto *dir =
+ HS.getFileMgr().getDirectory(module.search_path.GetStringRef());
+ auto *file = HS.lookupModuleMapFile(dir, is_framework);
+ if (!HS.loadModuleMapFile(file, is_system))
+ error_stream.Printf("error: No module map file in %s\n",
+ module.search_path.AsCString());
+ return false;
+ }
+ }
+ if (!HS.lookupModule(module.path.front().GetStringRef())) {
error_stream.Printf("error: Header search couldn't locate module %s\n",
- path[0].AsCString());
+ module.path.front().AsCString());
return false;
}
@@ -230,7 +254,7 @@
clang::SourceManager &source_manager =
m_compiler_instance->getASTContext().getSourceManager();
- for (ConstString path_component : path) {
+ for (ConstString path_component : module.path) {
clang_path.push_back(std::make_pair(
&m_compiler_instance->getASTContext().Idents.get(
path_component.GetStringRef()),
@@ -250,19 +274,18 @@
if (!top_level_module) {
diagnostic_consumer->DumpDiagnostics(error_stream);
error_stream.Printf("error: Couldn't load top-level module %s\n",
- path[0].AsCString());
+ module.path.front().AsCString());
return false;
}
clang::Module *submodule = top_level_module;
- for (size_t ci = 1; ci < path.size(); ++ci) {
- llvm::StringRef component = path[ci].GetStringRef();
- submodule = submodule->findSubmodule(component.str());
+ for (auto &component : llvm::ArrayRef<ConstString>(module.path).drop_front()) {
+ submodule = submodule->findSubmodule(component.GetStringRef());
if (!submodule) {
diagnostic_consumer->DumpDiagnostics(error_stream);
error_stream.Printf("error: Couldn't load submodule %s\n",
- component.str().c_str());
+ component.GetCString());
return false;
}
}
@@ -289,12 +312,16 @@
switch (language) {
default:
return false;
- // C++ and friends to be added
case lldb::LanguageType::eLanguageTypeC:
case lldb::LanguageType::eLanguageTypeC11:
case lldb::LanguageType::eLanguageTypeC89:
case lldb::LanguageType::eLanguageTypeC99:
+ case lldb::LanguageType::eLanguageTypeC_plus_plus:
+ case lldb::LanguageType::eLanguageTypeC_plus_plus_03:
+ case lldb::LanguageType::eLanguageTypeC_plus_plus_11:
+ case lldb::LanguageType::eLanguageTypeC_plus_plus_14:
case lldb::LanguageType::eLanguageTypeObjC:
+ case lldb::LanguageType::eLanguageTypeObjC_plus_plus:
return true;
}
}
@@ -303,21 +330,10 @@
CompileUnit &cu, ClangModulesDeclVendor::ModuleVector &exported_modules,
Stream &error_stream) {
if (LanguageSupportsClangModules(cu.GetLanguage())) {
- std::vector<ConstString> imported_modules = cu.GetImportedModules();
-
- for (ConstString imported_module : imported_modules) {
- std::vector<ConstString> path;
-
- path.push_back(imported_module);
-
- if (!AddModule(path, &exported_modules, error_stream)) {
+ for (auto &imported_module : cu.GetImportedModules())
+ if (!AddModule(imported_module, &exported_modules, error_stream))
return false;
- }
- }
-
- return true;
}
-
return true;
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
index bcb233a..c5b5a88 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h
@@ -36,7 +36,7 @@
//------------------------------------------------------------------
/// Add a module to the list of modules to search.
///
- /// @param[in] path
+ /// @param[in] module
/// The path to the exact module to be loaded. E.g., if the desired
/// module is std.io, then this should be { "std", "io" }.
///
@@ -53,7 +53,8 @@
/// compiler encountered a fatal error during a previous module
/// load, then this will always return false for this ModuleImporter.
//------------------------------------------------------------------
- virtual bool AddModule(ModulePath &path, ModuleVector *exported_modules,
+ virtual bool AddModule(const SourceModule &module,
+ ModuleVector *exported_modules,
Stream &error_stream) = 0;
//------------------------------------------------------------------