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