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