1 //===-- ClangModulesDeclVendor.cpp ----------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include <mutex> 10 11 #include "clang/Basic/TargetInfo.h" 12 #include "clang/Frontend/CompilerInstance.h" 13 #include "clang/Frontend/FrontendActions.h" 14 #include "clang/Frontend/TextDiagnosticPrinter.h" 15 #include "clang/Lex/Preprocessor.h" 16 #include "clang/Lex/PreprocessorOptions.h" 17 #include "clang/Parse/Parser.h" 18 #include "clang/Sema/Lookup.h" 19 #include "clang/Serialization/ASTReader.h" 20 #include "llvm/Support/FileSystem.h" 21 #include "llvm/Support/Path.h" 22 #include "llvm/Support/Threading.h" 23 24 #include "ClangHost.h" 25 #include "ClangModulesDeclVendor.h" 26 #include "ModuleDependencyCollector.h" 27 28 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" 29 #include "lldb/Core/ModuleList.h" 30 #include "lldb/Host/Host.h" 31 #include "lldb/Host/HostInfo.h" 32 #include "lldb/Symbol/CompileUnit.h" 33 #include "lldb/Symbol/SourceModule.h" 34 #include "lldb/Target/Target.h" 35 #include "lldb/Utility/FileSpec.h" 36 #include "lldb/Utility/LLDBAssert.h" 37 #include "lldb/Utility/Log.h" 38 #include "lldb/Utility/Reproducer.h" 39 #include "lldb/Utility/StreamString.h" 40 41 using namespace lldb_private; 42 43 namespace { 44 // Any Clang compiler requires a consumer for diagnostics. This one stores 45 // them as strings so we can provide them to the user in case a module failed 46 // to load. 47 class StoringDiagnosticConsumer : public clang::DiagnosticConsumer { 48 public: 49 StoringDiagnosticConsumer(); 50 51 void HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel, 52 const clang::Diagnostic &info) override; 53 54 void ClearDiagnostics(); 55 56 void DumpDiagnostics(Stream &error_stream); 57 58 void BeginSourceFile(const clang::LangOptions &LangOpts, 59 const clang::Preprocessor *PP = nullptr) override; 60 void EndSourceFile() override; 61 62 private: 63 typedef std::pair<clang::DiagnosticsEngine::Level, std::string> 64 IDAndDiagnostic; 65 std::vector<IDAndDiagnostic> m_diagnostics; 66 /// The DiagnosticPrinter used for creating the full diagnostic messages 67 /// that are stored in m_diagnostics. 68 std::shared_ptr<clang::TextDiagnosticPrinter> m_diag_printer; 69 /// Output stream of m_diag_printer. 70 std::shared_ptr<llvm::raw_string_ostream> m_os; 71 /// Output string filled by m_os. Will be reused for different diagnostics. 72 std::string m_output; 73 Log *m_log; 74 }; 75 76 // The private implementation of our ClangModulesDeclVendor. Contains all the 77 // Clang state required to load modules. 78 class ClangModulesDeclVendorImpl : public ClangModulesDeclVendor { 79 public: 80 ClangModulesDeclVendorImpl( 81 llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine, 82 std::shared_ptr<clang::CompilerInvocation> compiler_invocation, 83 std::unique_ptr<clang::CompilerInstance> compiler_instance, 84 std::unique_ptr<clang::Parser> parser); 85 86 ~ClangModulesDeclVendorImpl() override = default; 87 88 bool AddModule(const SourceModule &module, ModuleVector *exported_modules, 89 Stream &error_stream) override; 90 91 bool AddModulesForCompileUnit(CompileUnit &cu, ModuleVector &exported_modules, 92 Stream &error_stream) override; 93 94 uint32_t FindDecls(ConstString name, bool append, uint32_t max_matches, 95 std::vector<CompilerDecl> &decls) override; 96 97 void ForEachMacro(const ModuleVector &modules, 98 std::function<bool(const std::string &)> handler) override; 99 private: 100 void 101 ReportModuleExportsHelper(std::set<ClangModulesDeclVendor::ModuleID> &exports, 102 clang::Module *module); 103 104 void ReportModuleExports(ModuleVector &exports, clang::Module *module); 105 106 clang::ModuleLoadResult DoGetModule(clang::ModuleIdPath path, 107 bool make_visible); 108 109 bool m_enabled = false; 110 111 llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> m_diagnostics_engine; 112 std::shared_ptr<clang::CompilerInvocation> m_compiler_invocation; 113 std::unique_ptr<clang::CompilerInstance> m_compiler_instance; 114 std::unique_ptr<clang::Parser> m_parser; 115 size_t m_source_location_index = 116 0; // used to give name components fake SourceLocations 117 118 typedef std::vector<ConstString> ImportedModule; 119 typedef std::map<ImportedModule, clang::Module *> ImportedModuleMap; 120 typedef std::set<ModuleID> ImportedModuleSet; 121 ImportedModuleMap m_imported_modules; 122 ImportedModuleSet m_user_imported_modules; 123 // We assume that every ASTContext has an TypeSystemClang, so we also store 124 // a custom TypeSystemClang for our internal ASTContext. 125 std::unique_ptr<TypeSystemClang> m_ast_context; 126 }; 127 } // anonymous namespace 128 129 StoringDiagnosticConsumer::StoringDiagnosticConsumer() { 130 m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); 131 132 clang::DiagnosticOptions *m_options = new clang::DiagnosticOptions(); 133 m_os.reset(new llvm::raw_string_ostream(m_output)); 134 m_diag_printer.reset(new clang::TextDiagnosticPrinter(*m_os, m_options)); 135 } 136 137 void StoringDiagnosticConsumer::HandleDiagnostic( 138 clang::DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &info) { 139 // Print the diagnostic to m_output. 140 m_output.clear(); 141 m_diag_printer->HandleDiagnostic(DiagLevel, info); 142 m_os->flush(); 143 144 // Store the diagnostic for later. 145 m_diagnostics.push_back(IDAndDiagnostic(DiagLevel, m_output)); 146 } 147 148 void StoringDiagnosticConsumer::ClearDiagnostics() { m_diagnostics.clear(); } 149 150 void StoringDiagnosticConsumer::DumpDiagnostics(Stream &error_stream) { 151 for (IDAndDiagnostic &diag : m_diagnostics) { 152 switch (diag.first) { 153 default: 154 error_stream.PutCString(diag.second); 155 error_stream.PutChar('\n'); 156 break; 157 case clang::DiagnosticsEngine::Level::Ignored: 158 break; 159 } 160 } 161 } 162 163 void StoringDiagnosticConsumer::BeginSourceFile( 164 const clang::LangOptions &LangOpts, const clang::Preprocessor *PP) { 165 m_diag_printer->BeginSourceFile(LangOpts, PP); 166 } 167 168 void StoringDiagnosticConsumer::EndSourceFile() { 169 m_diag_printer->EndSourceFile(); 170 } 171 172 ClangModulesDeclVendor::ClangModulesDeclVendor() 173 : ClangDeclVendor(eClangModuleDeclVendor) {} 174 175 ClangModulesDeclVendor::~ClangModulesDeclVendor() {} 176 177 ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl( 178 llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine, 179 std::shared_ptr<clang::CompilerInvocation> compiler_invocation, 180 std::unique_ptr<clang::CompilerInstance> compiler_instance, 181 std::unique_ptr<clang::Parser> parser) 182 : m_diagnostics_engine(std::move(diagnostics_engine)), 183 m_compiler_invocation(std::move(compiler_invocation)), 184 m_compiler_instance(std::move(compiler_instance)), 185 m_parser(std::move(parser)) { 186 187 // Initialize our TypeSystemClang. 188 m_ast_context.reset( 189 new TypeSystemClang("ClangModulesDeclVendor ASTContext", 190 m_compiler_instance->getASTContext())); 191 } 192 193 void ClangModulesDeclVendorImpl::ReportModuleExportsHelper( 194 std::set<ClangModulesDeclVendor::ModuleID> &exports, 195 clang::Module *module) { 196 if (exports.count(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module))) 197 return; 198 199 exports.insert(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module)); 200 201 llvm::SmallVector<clang::Module *, 2> sub_exports; 202 203 module->getExportedModules(sub_exports); 204 205 for (clang::Module *module : sub_exports) { 206 ReportModuleExportsHelper(exports, module); 207 } 208 } 209 210 void ClangModulesDeclVendorImpl::ReportModuleExports( 211 ClangModulesDeclVendor::ModuleVector &exports, clang::Module *module) { 212 std::set<ClangModulesDeclVendor::ModuleID> exports_set; 213 214 ReportModuleExportsHelper(exports_set, module); 215 216 for (ModuleID module : exports_set) { 217 exports.push_back(module); 218 } 219 } 220 221 bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module, 222 ModuleVector *exported_modules, 223 Stream &error_stream) { 224 // Fail early. 225 226 if (m_compiler_instance->hadModuleLoaderFatalFailure()) { 227 error_stream.PutCString("error: Couldn't load a module because the module " 228 "loader is in a fatal state.\n"); 229 return false; 230 } 231 232 // Check if we've already imported this module. 233 234 std::vector<ConstString> imported_module; 235 236 for (ConstString path_component : module.path) { 237 imported_module.push_back(path_component); 238 } 239 240 { 241 ImportedModuleMap::iterator mi = m_imported_modules.find(imported_module); 242 243 if (mi != m_imported_modules.end()) { 244 if (exported_modules) { 245 ReportModuleExports(*exported_modules, mi->second); 246 } 247 return true; 248 } 249 } 250 251 clang::HeaderSearch &HS = 252 m_compiler_instance->getPreprocessor().getHeaderSearchInfo(); 253 254 if (module.search_path) { 255 auto path_begin = llvm::sys::path::begin(module.search_path.GetStringRef()); 256 auto path_end = llvm::sys::path::end(module.search_path.GetStringRef()); 257 auto sysroot_begin = llvm::sys::path::begin(module.sysroot.GetStringRef()); 258 auto sysroot_end = llvm::sys::path::end(module.sysroot.GetStringRef()); 259 // FIXME: Use C++14 std::equal(it, it, it, it) variant once it's available. 260 bool is_system_module = (std::distance(path_begin, path_end) >= 261 std::distance(sysroot_begin, sysroot_end)) && 262 std::equal(sysroot_begin, sysroot_end, path_begin); 263 // No need to inject search paths to modules in the sysroot. 264 if (!is_system_module) { 265 auto error = [&]() { 266 error_stream.Printf("error: No module map file in %s\n", 267 module.search_path.AsCString()); 268 return false; 269 }; 270 271 bool is_system = true; 272 bool is_framework = false; 273 auto dir = 274 HS.getFileMgr().getDirectory(module.search_path.GetStringRef()); 275 if (!dir) 276 return error(); 277 auto *file = HS.lookupModuleMapFile(*dir, is_framework); 278 if (!file) 279 return error(); 280 if (!HS.loadModuleMapFile(file, is_system)) 281 return error(); 282 } 283 } 284 if (!HS.lookupModule(module.path.front().GetStringRef())) { 285 error_stream.Printf("error: Header search couldn't locate module %s\n", 286 module.path.front().AsCString()); 287 return false; 288 } 289 290 llvm::SmallVector<std::pair<clang::IdentifierInfo *, clang::SourceLocation>, 291 4> 292 clang_path; 293 294 { 295 clang::SourceManager &source_manager = 296 m_compiler_instance->getASTContext().getSourceManager(); 297 298 for (ConstString path_component : module.path) { 299 clang_path.push_back(std::make_pair( 300 &m_compiler_instance->getASTContext().Idents.get( 301 path_component.GetStringRef()), 302 source_manager.getLocForStartOfFile(source_manager.getMainFileID()) 303 .getLocWithOffset(m_source_location_index++))); 304 } 305 } 306 307 StoringDiagnosticConsumer *diagnostic_consumer = 308 static_cast<StoringDiagnosticConsumer *>( 309 m_compiler_instance->getDiagnostics().getClient()); 310 311 diagnostic_consumer->ClearDiagnostics(); 312 313 clang::Module *top_level_module = DoGetModule(clang_path.front(), false); 314 315 if (!top_level_module) { 316 diagnostic_consumer->DumpDiagnostics(error_stream); 317 error_stream.Printf("error: Couldn't load top-level module %s\n", 318 module.path.front().AsCString()); 319 return false; 320 } 321 322 clang::Module *submodule = top_level_module; 323 324 for (auto &component : llvm::ArrayRef<ConstString>(module.path).drop_front()) { 325 submodule = submodule->findSubmodule(component.GetStringRef()); 326 if (!submodule) { 327 diagnostic_consumer->DumpDiagnostics(error_stream); 328 error_stream.Printf("error: Couldn't load submodule %s\n", 329 component.GetCString()); 330 return false; 331 } 332 } 333 334 clang::Module *requested_module = DoGetModule(clang_path, true); 335 336 if (requested_module != nullptr) { 337 if (exported_modules) { 338 ReportModuleExports(*exported_modules, requested_module); 339 } 340 341 m_imported_modules[imported_module] = requested_module; 342 343 m_enabled = true; 344 345 return true; 346 } 347 348 return false; 349 } 350 351 bool ClangModulesDeclVendor::LanguageSupportsClangModules( 352 lldb::LanguageType language) { 353 switch (language) { 354 default: 355 return false; 356 case lldb::LanguageType::eLanguageTypeC: 357 case lldb::LanguageType::eLanguageTypeC11: 358 case lldb::LanguageType::eLanguageTypeC89: 359 case lldb::LanguageType::eLanguageTypeC99: 360 case lldb::LanguageType::eLanguageTypeC_plus_plus: 361 case lldb::LanguageType::eLanguageTypeC_plus_plus_03: 362 case lldb::LanguageType::eLanguageTypeC_plus_plus_11: 363 case lldb::LanguageType::eLanguageTypeC_plus_plus_14: 364 case lldb::LanguageType::eLanguageTypeObjC: 365 case lldb::LanguageType::eLanguageTypeObjC_plus_plus: 366 return true; 367 } 368 } 369 370 bool ClangModulesDeclVendorImpl::AddModulesForCompileUnit( 371 CompileUnit &cu, ClangModulesDeclVendor::ModuleVector &exported_modules, 372 Stream &error_stream) { 373 if (LanguageSupportsClangModules(cu.GetLanguage())) { 374 for (auto &imported_module : cu.GetImportedModules()) 375 if (!AddModule(imported_module, &exported_modules, error_stream)) 376 return false; 377 } 378 return true; 379 } 380 381 // ClangImporter::lookupValue 382 383 uint32_t 384 ClangModulesDeclVendorImpl::FindDecls(ConstString name, bool append, 385 uint32_t max_matches, 386 std::vector<CompilerDecl> &decls) { 387 if (!m_enabled) { 388 return 0; 389 } 390 391 if (!append) 392 decls.clear(); 393 394 clang::IdentifierInfo &ident = 395 m_compiler_instance->getASTContext().Idents.get(name.GetStringRef()); 396 397 clang::LookupResult lookup_result( 398 m_compiler_instance->getSema(), clang::DeclarationName(&ident), 399 clang::SourceLocation(), clang::Sema::LookupOrdinaryName); 400 401 m_compiler_instance->getSema().LookupName( 402 lookup_result, 403 m_compiler_instance->getSema().getScopeForContext( 404 m_compiler_instance->getASTContext().getTranslationUnitDecl())); 405 406 uint32_t num_matches = 0; 407 408 for (clang::NamedDecl *named_decl : lookup_result) { 409 if (num_matches >= max_matches) 410 return num_matches; 411 412 decls.push_back(m_ast_context->GetCompilerDecl(named_decl)); 413 ++num_matches; 414 } 415 416 return num_matches; 417 } 418 419 void ClangModulesDeclVendorImpl::ForEachMacro( 420 const ClangModulesDeclVendor::ModuleVector &modules, 421 std::function<bool(const std::string &)> handler) { 422 if (!m_enabled) { 423 return; 424 } 425 426 typedef std::map<ModuleID, ssize_t> ModulePriorityMap; 427 ModulePriorityMap module_priorities; 428 429 ssize_t priority = 0; 430 431 for (ModuleID module : modules) { 432 module_priorities[module] = priority++; 433 } 434 435 if (m_compiler_instance->getPreprocessor().getExternalSource()) { 436 m_compiler_instance->getPreprocessor() 437 .getExternalSource() 438 ->ReadDefinedMacros(); 439 } 440 441 for (clang::Preprocessor::macro_iterator 442 mi = m_compiler_instance->getPreprocessor().macro_begin(), 443 me = m_compiler_instance->getPreprocessor().macro_end(); 444 mi != me; ++mi) { 445 const clang::IdentifierInfo *ii = nullptr; 446 447 { 448 if (clang::IdentifierInfoLookup *lookup = 449 m_compiler_instance->getPreprocessor() 450 .getIdentifierTable() 451 .getExternalIdentifierLookup()) { 452 lookup->get(mi->first->getName()); 453 } 454 if (!ii) { 455 ii = mi->first; 456 } 457 } 458 459 ssize_t found_priority = -1; 460 clang::MacroInfo *macro_info = nullptr; 461 462 for (clang::ModuleMacro *module_macro : 463 m_compiler_instance->getPreprocessor().getLeafModuleMacros(ii)) { 464 clang::Module *module = module_macro->getOwningModule(); 465 466 { 467 ModulePriorityMap::iterator pi = 468 module_priorities.find(reinterpret_cast<ModuleID>(module)); 469 470 if (pi != module_priorities.end() && pi->second > found_priority) { 471 macro_info = module_macro->getMacroInfo(); 472 found_priority = pi->second; 473 } 474 } 475 476 clang::Module *top_level_module = module->getTopLevelModule(); 477 478 if (top_level_module != module) { 479 ModulePriorityMap::iterator pi = module_priorities.find( 480 reinterpret_cast<ModuleID>(top_level_module)); 481 482 if ((pi != module_priorities.end()) && pi->second > found_priority) { 483 macro_info = module_macro->getMacroInfo(); 484 found_priority = pi->second; 485 } 486 } 487 } 488 489 if (macro_info) { 490 std::string macro_expansion = "#define "; 491 macro_expansion.append(mi->first->getName().str()); 492 493 { 494 if (macro_info->isFunctionLike()) { 495 macro_expansion.append("("); 496 497 bool first_arg = true; 498 499 for (auto pi = macro_info->param_begin(), 500 pe = macro_info->param_end(); 501 pi != pe; ++pi) { 502 if (!first_arg) { 503 macro_expansion.append(", "); 504 } else { 505 first_arg = false; 506 } 507 508 macro_expansion.append((*pi)->getName().str()); 509 } 510 511 if (macro_info->isC99Varargs()) { 512 if (first_arg) { 513 macro_expansion.append("..."); 514 } else { 515 macro_expansion.append(", ..."); 516 } 517 } else if (macro_info->isGNUVarargs()) { 518 macro_expansion.append("..."); 519 } 520 521 macro_expansion.append(")"); 522 } 523 524 macro_expansion.append(" "); 525 526 bool first_token = true; 527 528 for (clang::MacroInfo::tokens_iterator ti = macro_info->tokens_begin(), 529 te = macro_info->tokens_end(); 530 ti != te; ++ti) { 531 if (!first_token) { 532 macro_expansion.append(" "); 533 } else { 534 first_token = false; 535 } 536 537 if (ti->isLiteral()) { 538 if (const char *literal_data = ti->getLiteralData()) { 539 std::string token_str(literal_data, ti->getLength()); 540 macro_expansion.append(token_str); 541 } else { 542 bool invalid = false; 543 const char *literal_source = 544 m_compiler_instance->getSourceManager().getCharacterData( 545 ti->getLocation(), &invalid); 546 547 if (invalid) { 548 lldbassert(0 && "Unhandled token kind"); 549 macro_expansion.append("<unknown literal value>"); 550 } else { 551 macro_expansion.append( 552 std::string(literal_source, ti->getLength())); 553 } 554 } 555 } else if (const char *punctuator_spelling = 556 clang::tok::getPunctuatorSpelling(ti->getKind())) { 557 macro_expansion.append(punctuator_spelling); 558 } else if (const char *keyword_spelling = 559 clang::tok::getKeywordSpelling(ti->getKind())) { 560 macro_expansion.append(keyword_spelling); 561 } else { 562 switch (ti->getKind()) { 563 case clang::tok::TokenKind::identifier: 564 macro_expansion.append(ti->getIdentifierInfo()->getName().str()); 565 break; 566 case clang::tok::TokenKind::raw_identifier: 567 macro_expansion.append(ti->getRawIdentifier().str()); 568 break; 569 default: 570 macro_expansion.append(ti->getName()); 571 break; 572 } 573 } 574 } 575 576 if (handler(macro_expansion)) { 577 return; 578 } 579 } 580 } 581 } 582 } 583 584 clang::ModuleLoadResult 585 ClangModulesDeclVendorImpl::DoGetModule(clang::ModuleIdPath path, 586 bool make_visible) { 587 clang::Module::NameVisibilityKind visibility = 588 make_visible ? clang::Module::AllVisible : clang::Module::Hidden; 589 590 const bool is_inclusion_directive = false; 591 592 return m_compiler_instance->loadModule(path.front().second, path, visibility, 593 is_inclusion_directive); 594 } 595 596 static const char *ModuleImportBufferName = "LLDBModulesMemoryBuffer"; 597 598 lldb_private::ClangModulesDeclVendor * 599 ClangModulesDeclVendor::Create(Target &target) { 600 // FIXME we should insure programmatically that the expression parser's 601 // compiler and the modules runtime's 602 // compiler are both initialized in the same way – preferably by the same 603 // code. 604 605 if (!target.GetPlatform()->SupportsModules()) 606 return nullptr; 607 608 const ArchSpec &arch = target.GetArchitecture(); 609 610 std::vector<std::string> compiler_invocation_arguments = { 611 "clang", 612 "-fmodules", 613 "-fimplicit-module-maps", 614 "-fcxx-modules", 615 "-fsyntax-only", 616 "-femit-all-decls", 617 "-target", 618 arch.GetTriple().str(), 619 "-fmodules-validate-system-headers", 620 "-Werror=non-modular-include-in-framework-module"}; 621 622 target.GetPlatform()->AddClangModuleCompilationOptions( 623 &target, compiler_invocation_arguments); 624 625 compiler_invocation_arguments.push_back(ModuleImportBufferName); 626 627 // Add additional search paths with { "-I", path } or { "-F", path } here. 628 629 { 630 llvm::SmallString<128> path; 631 const auto &props = ModuleList::GetGlobalModuleListProperties(); 632 props.GetClangModulesCachePath().GetPath(path); 633 std::string module_cache_argument("-fmodules-cache-path="); 634 module_cache_argument.append(std::string(path.str())); 635 compiler_invocation_arguments.push_back(module_cache_argument); 636 } 637 638 FileSpecList module_search_paths = target.GetClangModuleSearchPaths(); 639 640 for (size_t spi = 0, spe = module_search_paths.GetSize(); spi < spe; ++spi) { 641 const FileSpec &search_path = module_search_paths.GetFileSpecAtIndex(spi); 642 643 std::string search_path_argument = "-I"; 644 search_path_argument.append(search_path.GetPath()); 645 646 compiler_invocation_arguments.push_back(search_path_argument); 647 } 648 649 { 650 FileSpec clang_resource_dir = GetClangResourceDir(); 651 652 if (FileSystem::Instance().IsDirectory(clang_resource_dir.GetPath())) { 653 compiler_invocation_arguments.push_back("-resource-dir"); 654 compiler_invocation_arguments.push_back(clang_resource_dir.GetPath()); 655 } 656 } 657 658 llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> diagnostics_engine = 659 clang::CompilerInstance::createDiagnostics(new clang::DiagnosticOptions, 660 new StoringDiagnosticConsumer); 661 662 std::vector<const char *> compiler_invocation_argument_cstrs; 663 compiler_invocation_argument_cstrs.reserve( 664 compiler_invocation_arguments.size()); 665 for (const std::string &arg : compiler_invocation_arguments) 666 compiler_invocation_argument_cstrs.push_back(arg.c_str()); 667 668 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 669 LLDB_LOG(log, "ClangModulesDeclVendor's compiler flags {0:$[ ]}", 670 llvm::make_range(compiler_invocation_arguments.begin(), 671 compiler_invocation_arguments.end())); 672 673 std::shared_ptr<clang::CompilerInvocation> invocation = 674 clang::createInvocationFromCommandLine(compiler_invocation_argument_cstrs, 675 diagnostics_engine); 676 677 if (!invocation) 678 return nullptr; 679 680 std::unique_ptr<llvm::MemoryBuffer> source_buffer = 681 llvm::MemoryBuffer::getMemBuffer( 682 "extern int __lldb __attribute__((unavailable));", 683 ModuleImportBufferName); 684 685 invocation->getPreprocessorOpts().addRemappedFile(ModuleImportBufferName, 686 source_buffer.release()); 687 688 std::unique_ptr<clang::CompilerInstance> instance( 689 new clang::CompilerInstance); 690 691 // When capturing a reproducer, hook up the file collector with clang to 692 // collector modules and headers. 693 if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) { 694 repro::FileProvider &fp = g->GetOrCreate<repro::FileProvider>(); 695 instance->setModuleDepCollector( 696 std::make_shared<ModuleDependencyCollectorAdaptor>( 697 fp.GetFileCollector())); 698 clang::DependencyOutputOptions &opts = instance->getDependencyOutputOpts(); 699 opts.IncludeSystemHeaders = true; 700 opts.IncludeModuleFiles = true; 701 } 702 703 // Make sure clang uses the same VFS as LLDB. 704 instance->createFileManager(FileSystem::Instance().GetVirtualFileSystem()); 705 instance->setDiagnostics(diagnostics_engine.get()); 706 instance->setInvocation(invocation); 707 708 std::unique_ptr<clang::FrontendAction> action(new clang::SyntaxOnlyAction); 709 710 instance->setTarget(clang::TargetInfo::CreateTargetInfo( 711 *diagnostics_engine, instance->getInvocation().TargetOpts)); 712 713 if (!instance->hasTarget()) 714 return nullptr; 715 716 instance->getTarget().adjust(instance->getLangOpts()); 717 718 if (!action->BeginSourceFile(*instance, 719 instance->getFrontendOpts().Inputs[0])) 720 return nullptr; 721 722 instance->getPreprocessor().enableIncrementalProcessing(); 723 724 instance->createASTReader(); 725 726 instance->createSema(action->getTranslationUnitKind(), nullptr); 727 728 const bool skipFunctionBodies = false; 729 std::unique_ptr<clang::Parser> parser(new clang::Parser( 730 instance->getPreprocessor(), instance->getSema(), skipFunctionBodies)); 731 732 instance->getPreprocessor().EnterMainSourceFile(); 733 parser->Initialize(); 734 735 clang::Parser::DeclGroupPtrTy parsed; 736 737 while (!parser->ParseTopLevelDecl(parsed)) 738 ; 739 740 return new ClangModulesDeclVendorImpl(std::move(diagnostics_engine), 741 std::move(invocation), 742 std::move(instance), std::move(parser)); 743 } 744