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