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