summaryrefslogtreecommitdiff
path: root/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-20 20:51:52 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-20 20:51:52 +0000
commit5f29bb8a675e8f96452b632e7129113f7dec850e (patch)
tree3d3f2a0d3ad10872a4dcaba8ec8d1d20c87ab147 /source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
parent88c643b6fec27eec436c8d138fee6346e92337d6 (diff)
Notes
Diffstat (limited to 'source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp')
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp115
1 files changed, 79 insertions, 36 deletions
diff --git a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
index ced21dfe0dda2..4a220790e50dc 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -1,9 +1,8 @@
//===-- ClangModulesDeclVendor.cpp ------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -23,15 +22,18 @@
#include "ClangHost.h"
#include "ClangModulesDeclVendor.h"
+#include "ModuleDependencyCollector.h"
#include "lldb/Core/ModuleList.h"
#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"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/StreamString.h"
using namespace lldb_private;
@@ -70,13 +72,13 @@ public:
~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,
Stream &error_stream) override;
- uint32_t FindDecls(const ConstString &name, bool append, uint32_t max_matches,
+ uint32_t FindDecls(ConstString name, bool append, uint32_t max_matches,
std::vector<clang::NamedDecl *> &decls) override;
void ForEachMacro(const ModuleVector &modules,
@@ -183,7 +185,7 @@ void ClangModulesDeclVendorImpl::ReportModuleExports(
}
}
-bool ClangModulesDeclVendorImpl::AddModule(ModulePath &path,
+bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module,
ModuleVector *exported_modules,
Stream &error_stream) {
// Fail early.
@@ -198,7 +200,7 @@ bool ClangModulesDeclVendorImpl::AddModule(ModulePath &path,
std::vector<ConstString> imported_module;
- for (ConstString path_component : path) {
+ for (ConstString path_component : module.path) {
imported_module.push_back(path_component);
}
@@ -213,11 +215,42 @@ bool ClangModulesDeclVendorImpl::AddModule(ModulePath &path,
}
}
- 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) {
+ auto error = [&]() {
+ error_stream.Printf("error: No module map file in %s\n",
+ module.search_path.AsCString());
+ return false;
+ };
+
+ bool is_system = true;
+ bool is_framework = false;
+ auto *dir =
+ HS.getFileMgr().getDirectory(module.search_path.GetStringRef());
+ if (!dir)
+ return error();
+ auto *file = HS.lookupModuleMapFile(dir, is_framework);
+ if (!file)
+ return error();
+ if (!HS.loadModuleMapFile(file, is_system))
+ return error();
+ }
+ }
+ 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;
}
@@ -229,7 +262,7 @@ bool ClangModulesDeclVendorImpl::AddModule(ModulePath &path,
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()),
@@ -249,19 +282,18 @@ bool ClangModulesDeclVendorImpl::AddModule(ModulePath &path,
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;
}
}
@@ -288,12 +320,16 @@ bool ClangModulesDeclVendor::LanguageSupportsClangModules(
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;
}
}
@@ -302,28 +338,17 @@ bool ClangModulesDeclVendorImpl::AddModulesForCompileUnit(
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;
}
// ClangImporter::lookupValue
uint32_t
-ClangModulesDeclVendorImpl::FindDecls(const ConstString &name, bool append,
+ClangModulesDeclVendorImpl::FindDecls(ConstString name, bool append,
uint32_t max_matches,
std::vector<clang::NamedDecl *> &decls) {
if (!m_enabled) {
@@ -583,7 +608,7 @@ ClangModulesDeclVendor::Create(Target &target) {
compiler_invocation_arguments.push_back(module_cache_argument);
}
- FileSpecList &module_search_paths = target.GetClangModuleSearchPaths();
+ FileSpecList module_search_paths = target.GetClangModuleSearchPaths();
for (size_t spi = 0, spe = module_search_paths.GetSize(); spi < spe; ++spi) {
const FileSpec &search_path = module_search_paths.GetFileSpecAtIndex(spi);
@@ -610,9 +635,13 @@ ClangModulesDeclVendor::Create(Target &target) {
std::vector<const char *> compiler_invocation_argument_cstrs;
compiler_invocation_argument_cstrs.reserve(
compiler_invocation_arguments.size());
- for (const std::string &arg : compiler_invocation_arguments) {
+ for (const std::string &arg : compiler_invocation_arguments)
compiler_invocation_argument_cstrs.push_back(arg.c_str());
- }
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+ LLDB_LOG(log, "ClangModulesDeclVendor's compiler flags {0:$[ ]}",
+ llvm::make_range(compiler_invocation_arguments.begin(),
+ compiler_invocation_arguments.end()));
std::shared_ptr<clang::CompilerInvocation> invocation =
clang::createInvocationFromCommandLine(compiler_invocation_argument_cstrs,
@@ -632,6 +661,20 @@ ClangModulesDeclVendor::Create(Target &target) {
std::unique_ptr<clang::CompilerInstance> instance(
new clang::CompilerInstance);
+ // When capturing a reproducer, hook up the file collector with clang to
+ // collector modules and headers.
+ if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) {
+ repro::FileProvider &fp = g->GetOrCreate<repro::FileProvider>();
+ instance->setModuleDepCollector(
+ std::make_shared<ModuleDependencyCollectorAdaptor>(
+ fp.GetFileCollector()));
+ clang::DependencyOutputOptions &opts = instance->getDependencyOutputOpts();
+ opts.IncludeSystemHeaders = true;
+ opts.IncludeModuleFiles = true;
+ }
+
+ // Make sure clang uses the same VFS as LLDB.
+ instance->createFileManager(FileSystem::Instance().GetVirtualFileSystem());
instance->setDiagnostics(diagnostics_engine.get());
instance->setInvocation(invocation);