Path: blob/main/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
39648 views
//===-- ClangModulesDeclVendor.cpp ----------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "clang/Basic/Diagnostic.h"9#include "clang/Basic/DiagnosticFrontend.h"10#include "clang/Basic/TargetInfo.h"11#include "clang/Frontend/CompilerInstance.h"12#include "clang/Frontend/FrontendActions.h"13#include "clang/Frontend/TextDiagnosticPrinter.h"14#include "clang/Lex/Preprocessor.h"15#include "clang/Lex/PreprocessorOptions.h"16#include "clang/Parse/Parser.h"17#include "clang/Sema/Lookup.h"18#include "clang/Serialization/ASTReader.h"19#include "llvm/ADT/StringRef.h"20#include "llvm/Support/Path.h"21#include "llvm/Support/Threading.h"2223#include "ClangHost.h"24#include "ClangModulesDeclVendor.h"2526#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"27#include "lldb/Core/ModuleList.h"28#include "lldb/Core/Progress.h"29#include "lldb/Symbol/CompileUnit.h"30#include "lldb/Symbol/SourceModule.h"31#include "lldb/Target/Target.h"32#include "lldb/Utility/FileSpec.h"33#include "lldb/Utility/LLDBAssert.h"34#include "lldb/Utility/LLDBLog.h"35#include "lldb/Utility/Log.h"3637#include <memory>3839using namespace lldb_private;4041namespace {42/// Any Clang compiler requires a consumer for diagnostics. This one stores43/// them as strings so we can provide them to the user in case a module failed44/// to load.45class StoringDiagnosticConsumer : public clang::DiagnosticConsumer {46public:47StoringDiagnosticConsumer();4849void HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel,50const clang::Diagnostic &info) override;5152void ClearDiagnostics();5354void DumpDiagnostics(Stream &error_stream);5556void BeginSourceFile(const clang::LangOptions &LangOpts,57const clang::Preprocessor *PP = nullptr) override;58void EndSourceFile() override;5960private:61bool HandleModuleRemark(const clang::Diagnostic &info);62void SetCurrentModuleProgress(std::string module_name);6364typedef std::pair<clang::DiagnosticsEngine::Level, std::string>65IDAndDiagnostic;66std::vector<IDAndDiagnostic> m_diagnostics;67/// The DiagnosticPrinter used for creating the full diagnostic messages68/// that are stored in m_diagnostics.69std::unique_ptr<clang::TextDiagnosticPrinter> m_diag_printer;70/// Output stream of m_diag_printer.71std::unique_ptr<llvm::raw_string_ostream> m_os;72/// Output string filled by m_os. Will be reused for different diagnostics.73std::string m_output;74/// A Progress with explicitly managed lifetime.75std::unique_ptr<Progress> m_current_progress_up;76std::vector<std::string> m_module_build_stack;77};7879/// The private implementation of our ClangModulesDeclVendor. Contains all the80/// Clang state required to load modules.81class ClangModulesDeclVendorImpl : public ClangModulesDeclVendor {82public:83ClangModulesDeclVendorImpl(84llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine,85std::shared_ptr<clang::CompilerInvocation> compiler_invocation,86std::unique_ptr<clang::CompilerInstance> compiler_instance,87std::unique_ptr<clang::Parser> parser);8889~ClangModulesDeclVendorImpl() override = default;9091bool AddModule(const SourceModule &module, ModuleVector *exported_modules,92Stream &error_stream) override;9394bool AddModulesForCompileUnit(CompileUnit &cu, ModuleVector &exported_modules,95Stream &error_stream) override;9697uint32_t FindDecls(ConstString name, bool append, uint32_t max_matches,98std::vector<CompilerDecl> &decls) override;99100void ForEachMacro(101const ModuleVector &modules,102std::function<bool(llvm::StringRef, llvm::StringRef)> handler) override;103104private:105typedef llvm::DenseSet<ModuleID> ExportedModuleSet;106void ReportModuleExportsHelper(ExportedModuleSet &exports,107clang::Module *module);108109void ReportModuleExports(ModuleVector &exports, clang::Module *module);110111clang::ModuleLoadResult DoGetModule(clang::ModuleIdPath path,112bool make_visible);113114bool m_enabled = false;115116llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> m_diagnostics_engine;117std::shared_ptr<clang::CompilerInvocation> m_compiler_invocation;118std::unique_ptr<clang::CompilerInstance> m_compiler_instance;119std::unique_ptr<clang::Parser> m_parser;120size_t m_source_location_index =1210; // used to give name components fake SourceLocations122123typedef std::vector<ConstString> ImportedModule;124typedef std::map<ImportedModule, clang::Module *> ImportedModuleMap;125typedef llvm::DenseSet<ModuleID> ImportedModuleSet;126ImportedModuleMap m_imported_modules;127ImportedModuleSet m_user_imported_modules;128// We assume that every ASTContext has an TypeSystemClang, so we also store129// a custom TypeSystemClang for our internal ASTContext.130std::shared_ptr<TypeSystemClang> m_ast_context;131};132} // anonymous namespace133134StoringDiagnosticConsumer::StoringDiagnosticConsumer() {135auto *options = new clang::DiagnosticOptions();136m_os = std::make_unique<llvm::raw_string_ostream>(m_output);137m_diag_printer =138std::make_unique<clang::TextDiagnosticPrinter>(*m_os, options);139}140141void StoringDiagnosticConsumer::HandleDiagnostic(142clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &info) {143if (HandleModuleRemark(info))144return;145146// Print the diagnostic to m_output.147m_output.clear();148m_diag_printer->HandleDiagnostic(DiagLevel, info);149m_os->flush();150151// Store the diagnostic for later.152m_diagnostics.push_back(IDAndDiagnostic(DiagLevel, m_output));153}154155void StoringDiagnosticConsumer::ClearDiagnostics() { m_diagnostics.clear(); }156157void StoringDiagnosticConsumer::DumpDiagnostics(Stream &error_stream) {158for (IDAndDiagnostic &diag : m_diagnostics) {159switch (diag.first) {160default:161error_stream.PutCString(diag.second);162error_stream.PutChar('\n');163break;164case clang::DiagnosticsEngine::Level::Ignored:165break;166}167}168}169170void StoringDiagnosticConsumer::BeginSourceFile(171const clang::LangOptions &LangOpts, const clang::Preprocessor *PP) {172m_diag_printer->BeginSourceFile(LangOpts, PP);173}174175void StoringDiagnosticConsumer::EndSourceFile() {176m_current_progress_up = nullptr;177m_diag_printer->EndSourceFile();178}179180bool StoringDiagnosticConsumer::HandleModuleRemark(181const clang::Diagnostic &info) {182Log *log = GetLog(LLDBLog::Types | LLDBLog::Expressions);183switch (info.getID()) {184case clang::diag::remark_module_build: {185const auto &module_name = info.getArgStdStr(0);186SetCurrentModuleProgress(module_name);187m_module_build_stack.push_back(module_name);188189const auto &module_path = info.getArgStdStr(1);190LLDB_LOG(log, "Building Clang module {0} as {1}", module_name, module_path);191return true;192}193case clang::diag::remark_module_build_done: {194// The current module is done.195m_module_build_stack.pop_back();196if (m_module_build_stack.empty()) {197m_current_progress_up = nullptr;198} else {199// When the just completed module began building, a module that depends on200// it ("module A") was effectively paused. Update the progress to re-show201// "module A" as continuing to be built.202const auto &resumed_module_name = m_module_build_stack.back();203SetCurrentModuleProgress(resumed_module_name);204}205206const auto &module_name = info.getArgStdStr(0);207LLDB_LOG(log, "Finished building Clang module {0}", module_name);208return true;209}210default:211return false;212}213}214215void StoringDiagnosticConsumer::SetCurrentModuleProgress(216std::string module_name) {217if (!m_current_progress_up)218m_current_progress_up =219std::make_unique<Progress>("Building Clang modules");220221m_current_progress_up->Increment(1, std::move(module_name));222}223224ClangModulesDeclVendor::ClangModulesDeclVendor()225: ClangDeclVendor(eClangModuleDeclVendor) {}226227ClangModulesDeclVendor::~ClangModulesDeclVendor() = default;228229ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl(230llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine,231std::shared_ptr<clang::CompilerInvocation> compiler_invocation,232std::unique_ptr<clang::CompilerInstance> compiler_instance,233std::unique_ptr<clang::Parser> parser)234: m_diagnostics_engine(std::move(diagnostics_engine)),235m_compiler_invocation(std::move(compiler_invocation)),236m_compiler_instance(std::move(compiler_instance)),237m_parser(std::move(parser)) {238239// Initialize our TypeSystemClang.240m_ast_context =241std::make_shared<TypeSystemClang>("ClangModulesDeclVendor ASTContext",242m_compiler_instance->getASTContext());243}244245void ClangModulesDeclVendorImpl::ReportModuleExportsHelper(246ExportedModuleSet &exports, clang::Module *module) {247if (exports.count(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module)))248return;249250exports.insert(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module));251252llvm::SmallVector<clang::Module *, 2> sub_exports;253254module->getExportedModules(sub_exports);255256for (clang::Module *module : sub_exports)257ReportModuleExportsHelper(exports, module);258}259260void ClangModulesDeclVendorImpl::ReportModuleExports(261ClangModulesDeclVendor::ModuleVector &exports, clang::Module *module) {262ExportedModuleSet exports_set;263264ReportModuleExportsHelper(exports_set, module);265266for (ModuleID module : exports_set)267exports.push_back(module);268}269270bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module,271ModuleVector *exported_modules,272Stream &error_stream) {273// Fail early.274275if (m_compiler_instance->hadModuleLoaderFatalFailure()) {276error_stream.PutCString("error: Couldn't load a module because the module "277"loader is in a fatal state.\n");278return false;279}280281// Check if we've already imported this module.282283std::vector<ConstString> imported_module;284285for (ConstString path_component : module.path)286imported_module.push_back(path_component);287288{289ImportedModuleMap::iterator mi = m_imported_modules.find(imported_module);290291if (mi != m_imported_modules.end()) {292if (exported_modules)293ReportModuleExports(*exported_modules, mi->second);294return true;295}296}297298clang::HeaderSearch &HS =299m_compiler_instance->getPreprocessor().getHeaderSearchInfo();300301if (module.search_path) {302auto path_begin = llvm::sys::path::begin(module.search_path.GetStringRef());303auto path_end = llvm::sys::path::end(module.search_path.GetStringRef());304auto sysroot_begin = llvm::sys::path::begin(module.sysroot.GetStringRef());305auto sysroot_end = llvm::sys::path::end(module.sysroot.GetStringRef());306// FIXME: Use C++14 std::equal(it, it, it, it) variant once it's available.307bool is_system_module = (std::distance(path_begin, path_end) >=308std::distance(sysroot_begin, sysroot_end)) &&309std::equal(sysroot_begin, sysroot_end, path_begin);310// No need to inject search paths to modules in the sysroot.311if (!is_system_module) {312auto error = [&]() {313error_stream.Printf("error: No module map file in %s\n",314module.search_path.AsCString());315return false;316};317318bool is_system = true;319bool is_framework = false;320auto dir = HS.getFileMgr().getOptionalDirectoryRef(321module.search_path.GetStringRef());322if (!dir)323return error();324auto file = HS.lookupModuleMapFile(*dir, is_framework);325if (!file)326return error();327if (!HS.loadModuleMapFile(*file, is_system))328return error();329}330}331if (!HS.lookupModule(module.path.front().GetStringRef())) {332error_stream.Printf("error: Header search couldn't locate module %s\n",333module.path.front().AsCString());334return false;335}336337llvm::SmallVector<std::pair<clang::IdentifierInfo *, clang::SourceLocation>,3384>339clang_path;340341{342clang::SourceManager &source_manager =343m_compiler_instance->getASTContext().getSourceManager();344345for (ConstString path_component : module.path) {346clang_path.push_back(std::make_pair(347&m_compiler_instance->getASTContext().Idents.get(348path_component.GetStringRef()),349source_manager.getLocForStartOfFile(source_manager.getMainFileID())350.getLocWithOffset(m_source_location_index++)));351}352}353354StoringDiagnosticConsumer *diagnostic_consumer =355static_cast<StoringDiagnosticConsumer *>(356m_compiler_instance->getDiagnostics().getClient());357358diagnostic_consumer->ClearDiagnostics();359360clang::Module *top_level_module = DoGetModule(clang_path.front(), false);361362if (!top_level_module) {363diagnostic_consumer->DumpDiagnostics(error_stream);364error_stream.Printf("error: Couldn't load top-level module %s\n",365module.path.front().AsCString());366return false;367}368369clang::Module *submodule = top_level_module;370371for (auto &component : llvm::ArrayRef<ConstString>(module.path).drop_front()) {372submodule = submodule->findSubmodule(component.GetStringRef());373if (!submodule) {374diagnostic_consumer->DumpDiagnostics(error_stream);375error_stream.Printf("error: Couldn't load submodule %s\n",376component.GetCString());377return false;378}379}380381clang::Module *requested_module = DoGetModule(clang_path, true);382383if (requested_module != nullptr) {384if (exported_modules)385ReportModuleExports(*exported_modules, requested_module);386387m_imported_modules[imported_module] = requested_module;388389m_enabled = true;390391return true;392}393394return false;395}396397bool ClangModulesDeclVendor::LanguageSupportsClangModules(398lldb::LanguageType language) {399switch (language) {400default:401return false;402case lldb::LanguageType::eLanguageTypeC:403case lldb::LanguageType::eLanguageTypeC11:404case lldb::LanguageType::eLanguageTypeC89:405case lldb::LanguageType::eLanguageTypeC99:406case lldb::LanguageType::eLanguageTypeC_plus_plus:407case lldb::LanguageType::eLanguageTypeC_plus_plus_03:408case lldb::LanguageType::eLanguageTypeC_plus_plus_11:409case lldb::LanguageType::eLanguageTypeC_plus_plus_14:410case lldb::LanguageType::eLanguageTypeObjC:411case lldb::LanguageType::eLanguageTypeObjC_plus_plus:412return true;413}414}415416bool ClangModulesDeclVendorImpl::AddModulesForCompileUnit(417CompileUnit &cu, ClangModulesDeclVendor::ModuleVector &exported_modules,418Stream &error_stream) {419if (LanguageSupportsClangModules(cu.GetLanguage())) {420for (auto &imported_module : cu.GetImportedModules())421if (!AddModule(imported_module, &exported_modules, error_stream))422return false;423}424return true;425}426427// ClangImporter::lookupValue428429uint32_t430ClangModulesDeclVendorImpl::FindDecls(ConstString name, bool append,431uint32_t max_matches,432std::vector<CompilerDecl> &decls) {433if (!m_enabled)434return 0;435436if (!append)437decls.clear();438439clang::IdentifierInfo &ident =440m_compiler_instance->getASTContext().Idents.get(name.GetStringRef());441442clang::LookupResult lookup_result(443m_compiler_instance->getSema(), clang::DeclarationName(&ident),444clang::SourceLocation(), clang::Sema::LookupOrdinaryName);445446m_compiler_instance->getSema().LookupName(447lookup_result,448m_compiler_instance->getSema().getScopeForContext(449m_compiler_instance->getASTContext().getTranslationUnitDecl()));450451uint32_t num_matches = 0;452453for (clang::NamedDecl *named_decl : lookup_result) {454if (num_matches >= max_matches)455return num_matches;456457decls.push_back(m_ast_context->GetCompilerDecl(named_decl));458++num_matches;459}460461return num_matches;462}463464void ClangModulesDeclVendorImpl::ForEachMacro(465const ClangModulesDeclVendor::ModuleVector &modules,466std::function<bool(llvm::StringRef, llvm::StringRef)> handler) {467if (!m_enabled)468return;469470typedef std::map<ModuleID, ssize_t> ModulePriorityMap;471ModulePriorityMap module_priorities;472473ssize_t priority = 0;474475for (ModuleID module : modules)476module_priorities[module] = priority++;477478if (m_compiler_instance->getPreprocessor().getExternalSource()) {479m_compiler_instance->getPreprocessor()480.getExternalSource()481->ReadDefinedMacros();482}483484for (clang::Preprocessor::macro_iterator485mi = m_compiler_instance->getPreprocessor().macro_begin(),486me = m_compiler_instance->getPreprocessor().macro_end();487mi != me; ++mi) {488const clang::IdentifierInfo *ii = nullptr;489490{491if (clang::IdentifierInfoLookup *lookup =492m_compiler_instance->getPreprocessor()493.getIdentifierTable()494.getExternalIdentifierLookup()) {495lookup->get(mi->first->getName());496}497if (!ii)498ii = mi->first;499}500501ssize_t found_priority = -1;502clang::MacroInfo *macro_info = nullptr;503504for (clang::ModuleMacro *module_macro :505m_compiler_instance->getPreprocessor().getLeafModuleMacros(ii)) {506clang::Module *module = module_macro->getOwningModule();507508{509ModulePriorityMap::iterator pi =510module_priorities.find(reinterpret_cast<ModuleID>(module));511512if (pi != module_priorities.end() && pi->second > found_priority) {513macro_info = module_macro->getMacroInfo();514found_priority = pi->second;515}516}517518clang::Module *top_level_module = module->getTopLevelModule();519520if (top_level_module != module) {521ModulePriorityMap::iterator pi = module_priorities.find(522reinterpret_cast<ModuleID>(top_level_module));523524if ((pi != module_priorities.end()) && pi->second > found_priority) {525macro_info = module_macro->getMacroInfo();526found_priority = pi->second;527}528}529}530531if (macro_info) {532std::string macro_expansion = "#define ";533llvm::StringRef macro_identifier = mi->first->getName();534macro_expansion.append(macro_identifier.str());535536{537if (macro_info->isFunctionLike()) {538macro_expansion.append("(");539540bool first_arg = true;541542for (auto pi = macro_info->param_begin(),543pe = macro_info->param_end();544pi != pe; ++pi) {545if (!first_arg)546macro_expansion.append(", ");547else548first_arg = false;549550macro_expansion.append((*pi)->getName().str());551}552553if (macro_info->isC99Varargs()) {554if (first_arg)555macro_expansion.append("...");556else557macro_expansion.append(", ...");558} else if (macro_info->isGNUVarargs())559macro_expansion.append("...");560561macro_expansion.append(")");562}563564macro_expansion.append(" ");565566bool first_token = true;567568for (clang::MacroInfo::const_tokens_iterator569ti = macro_info->tokens_begin(),570te = macro_info->tokens_end();571ti != te; ++ti) {572if (!first_token)573macro_expansion.append(" ");574else575first_token = false;576577if (ti->isLiteral()) {578if (const char *literal_data = ti->getLiteralData()) {579std::string token_str(literal_data, ti->getLength());580macro_expansion.append(token_str);581} else {582bool invalid = false;583const char *literal_source =584m_compiler_instance->getSourceManager().getCharacterData(585ti->getLocation(), &invalid);586587if (invalid) {588lldbassert(0 && "Unhandled token kind");589macro_expansion.append("<unknown literal value>");590} else {591macro_expansion.append(592std::string(literal_source, ti->getLength()));593}594}595} else if (const char *punctuator_spelling =596clang::tok::getPunctuatorSpelling(ti->getKind())) {597macro_expansion.append(punctuator_spelling);598} else if (const char *keyword_spelling =599clang::tok::getKeywordSpelling(ti->getKind())) {600macro_expansion.append(keyword_spelling);601} else {602switch (ti->getKind()) {603case clang::tok::TokenKind::identifier:604macro_expansion.append(ti->getIdentifierInfo()->getName().str());605break;606case clang::tok::TokenKind::raw_identifier:607macro_expansion.append(ti->getRawIdentifier().str());608break;609default:610macro_expansion.append(ti->getName());611break;612}613}614}615616if (handler(macro_identifier, macro_expansion)) {617return;618}619}620}621}622}623624clang::ModuleLoadResult625ClangModulesDeclVendorImpl::DoGetModule(clang::ModuleIdPath path,626bool make_visible) {627clang::Module::NameVisibilityKind visibility =628make_visible ? clang::Module::AllVisible : clang::Module::Hidden;629630const bool is_inclusion_directive = false;631632return m_compiler_instance->loadModule(path.front().second, path, visibility,633is_inclusion_directive);634}635636static const char *ModuleImportBufferName = "LLDBModulesMemoryBuffer";637638lldb_private::ClangModulesDeclVendor *639ClangModulesDeclVendor::Create(Target &target) {640// FIXME we should insure programmatically that the expression parser's641// compiler and the modules runtime's642// compiler are both initialized in the same way – preferably by the same643// code.644645if (!target.GetPlatform()->SupportsModules())646return nullptr;647648const ArchSpec &arch = target.GetArchitecture();649650std::vector<std::string> compiler_invocation_arguments = {651"clang",652"-fmodules",653"-fimplicit-module-maps",654"-fcxx-modules",655"-fsyntax-only",656"-femit-all-decls",657"-target",658arch.GetTriple().str(),659"-fmodules-validate-system-headers",660"-Werror=non-modular-include-in-framework-module",661"-Xclang=-fincremental-extensions",662"-Rmodule-build"};663664target.GetPlatform()->AddClangModuleCompilationOptions(665&target, compiler_invocation_arguments);666667compiler_invocation_arguments.push_back(ModuleImportBufferName);668669// Add additional search paths with { "-I", path } or { "-F", path } here.670671{672llvm::SmallString<128> path;673const auto &props = ModuleList::GetGlobalModuleListProperties();674props.GetClangModulesCachePath().GetPath(path);675std::string module_cache_argument("-fmodules-cache-path=");676module_cache_argument.append(std::string(path.str()));677compiler_invocation_arguments.push_back(module_cache_argument);678}679680FileSpecList module_search_paths = target.GetClangModuleSearchPaths();681682for (size_t spi = 0, spe = module_search_paths.GetSize(); spi < spe; ++spi) {683const FileSpec &search_path = module_search_paths.GetFileSpecAtIndex(spi);684685std::string search_path_argument = "-I";686search_path_argument.append(search_path.GetPath());687688compiler_invocation_arguments.push_back(search_path_argument);689}690691{692FileSpec clang_resource_dir = GetClangResourceDir();693694if (FileSystem::Instance().IsDirectory(clang_resource_dir.GetPath())) {695compiler_invocation_arguments.push_back("-resource-dir");696compiler_invocation_arguments.push_back(clang_resource_dir.GetPath());697}698}699700std::vector<const char *> compiler_invocation_argument_cstrs;701compiler_invocation_argument_cstrs.reserve(702compiler_invocation_arguments.size());703for (const std::string &arg : compiler_invocation_arguments)704compiler_invocation_argument_cstrs.push_back(arg.c_str());705706auto diag_options_up =707clang::CreateAndPopulateDiagOpts(compiler_invocation_argument_cstrs);708llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine =709clang::CompilerInstance::createDiagnostics(diag_options_up.release(),710new StoringDiagnosticConsumer);711712Log *log = GetLog(LLDBLog::Expressions);713LLDB_LOG(log, "ClangModulesDeclVendor's compiler flags {0:$[ ]}",714llvm::make_range(compiler_invocation_arguments.begin(),715compiler_invocation_arguments.end()));716717clang::CreateInvocationOptions CIOpts;718CIOpts.Diags = diagnostics_engine;719std::shared_ptr<clang::CompilerInvocation> invocation =720clang::createInvocation(compiler_invocation_argument_cstrs,721std::move(CIOpts));722723if (!invocation)724return nullptr;725726std::unique_ptr<llvm::MemoryBuffer> source_buffer =727llvm::MemoryBuffer::getMemBuffer(728"extern int __lldb __attribute__((unavailable));",729ModuleImportBufferName);730731invocation->getPreprocessorOpts().addRemappedFile(ModuleImportBufferName,732source_buffer.release());733734std::unique_ptr<clang::CompilerInstance> instance(735new clang::CompilerInstance);736737// Make sure clang uses the same VFS as LLDB.738instance->createFileManager(FileSystem::Instance().GetVirtualFileSystem());739instance->setDiagnostics(diagnostics_engine.get());740instance->setInvocation(invocation);741742std::unique_ptr<clang::FrontendAction> action(new clang::SyntaxOnlyAction);743744instance->setTarget(clang::TargetInfo::CreateTargetInfo(745*diagnostics_engine, instance->getInvocation().TargetOpts));746747if (!instance->hasTarget())748return nullptr;749750instance->getTarget().adjust(*diagnostics_engine, instance->getLangOpts());751752if (!action->BeginSourceFile(*instance,753instance->getFrontendOpts().Inputs[0]))754return nullptr;755756instance->createASTReader();757758instance->createSema(action->getTranslationUnitKind(), nullptr);759760const bool skipFunctionBodies = false;761std::unique_ptr<clang::Parser> parser(new clang::Parser(762instance->getPreprocessor(), instance->getSema(), skipFunctionBodies));763764instance->getPreprocessor().EnterMainSourceFile();765parser->Initialize();766767clang::Parser::DeclGroupPtrTy parsed;768auto ImportState = clang::Sema::ModuleImportState::NotACXX20Module;769while (!parser->ParseTopLevelDecl(parsed, ImportState))770;771772return new ClangModulesDeclVendorImpl(std::move(diagnostics_engine),773std::move(invocation),774std::move(instance), std::move(parser));775}776777778