diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:51:52 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:51:52 +0000 |
commit | 5f29bb8a675e8f96452b632e7129113f7dec850e (patch) | |
tree | 3d3f2a0d3ad10872a4dcaba8ec8d1d20c87ab147 /source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp | |
parent | 88c643b6fec27eec436c8d138fee6346e92337d6 (diff) |
Notes
Diffstat (limited to 'source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp')
-rw-r--r-- | source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp | 115 |
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); |