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 40using namespace lldb_private; 41 42namespace { 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. 46class StoringDiagnosticConsumer : public clang::DiagnosticConsumer { 47public: 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 57private: 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. 66class ClangModulesDeclVendorImpl : public ClangModulesDeclVendor { 67public: 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; 87private: 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 ClangASTContext, so we also store 112 // a custom ClangASTContext for our internal ASTContext. 113 std::unique_ptr<ClangASTContext> m_ast_context; 114}; 115} // anonymous namespace 116 117StoringDiagnosticConsumer::StoringDiagnosticConsumer() { 118 m_log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); 119} 120 121void 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 132void StoringDiagnosticConsumer::ClearDiagnostics() { m_diagnostics.clear(); } 133 134void 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 147ClangModulesDeclVendor::ClangModulesDeclVendor() 148 : ClangDeclVendor(eClangModuleDeclVendor) {} 149 150ClangModulesDeclVendor::~ClangModulesDeclVendor() {} 151 152ClangModulesDeclVendorImpl::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 ClangASTContext. 163 m_ast_context.reset(new ClangASTContext(m_compiler_instance->getASTContext())); 164} 165 166void ClangModulesDeclVendorImpl::ReportModuleExportsHelper( 167 std::set<ClangModulesDeclVendor::ModuleID> &exports, 168 clang::Module *module) { 169 if (exports.count(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module))) 170 return; 171 172 exports.insert(reinterpret_cast<ClangModulesDeclVendor::ModuleID>(module)); 173 174 llvm::SmallVector<clang::Module *, 2> sub_exports; 175 176 module->getExportedModules(sub_exports); 177 178 for (clang::Module *module : sub_exports) { 179 ReportModuleExportsHelper(exports, module); 180 } 181} 182 183void ClangModulesDeclVendorImpl::ReportModuleExports( 184 ClangModulesDeclVendor::ModuleVector &exports, clang::Module *module) { 185 std::set<ClangModulesDeclVendor::ModuleID> exports_set; 186 187 ReportModuleExportsHelper(exports_set, module); 188 189 for (ModuleID module : exports_set) { 190 exports.push_back(module); 191 } 192} 193 194bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module, 195 ModuleVector *exported_modules, 196 Stream &error_stream) { 197 // Fail early. 198 199 if (m_compiler_instance->hadModuleLoaderFatalFailure()) { 200 error_stream.PutCString("error: Couldn't load a module because the module " 201 "loader is in a fatal state.\n"); 202 return false; 203 } 204 205 // Check if we've already imported this module. 206 207 std::vector<ConstString> imported_module; 208 209 for (ConstString path_component : module.path) { 210 imported_module.push_back(path_component); 211 } 212 213 { 214 ImportedModuleMap::iterator mi = m_imported_modules.find(imported_module); 215 216 if (mi != m_imported_modules.end()) { 217 if (exported_modules) { 218 ReportModuleExports(*exported_modules, mi->second); 219 } 220 return true; 221 } 222 } 223 224 clang::HeaderSearch &HS = 225 m_compiler_instance->getPreprocessor().getHeaderSearchInfo(); 226 227 if (module.search_path) { 228 auto path_begin = llvm::sys::path::begin(module.search_path.GetStringRef()); 229 auto path_end = llvm::sys::path::end(module.search_path.GetStringRef()); 230 auto sysroot_begin = llvm::sys::path::begin(module.sysroot.GetStringRef()); 231 auto sysroot_end = llvm::sys::path::end(module.sysroot.GetStringRef()); 232 // FIXME: Use C++14 std::equal(it, it, it, it) variant once it's available. 233 bool is_system_module = (std::distance(path_begin, path_end) >= 234 std::distance(sysroot_begin, sysroot_end)) && 235 std::equal(sysroot_begin, sysroot_end, path_begin); 236 // No need to inject search paths to modules in the sysroot. 237 if (!is_system_module) { 238 auto error = [&]() { 239 error_stream.Printf("error: No module map file in %s\n", 240 module.search_path.AsCString()); 241 return false; 242 }; 243 244 bool is_system = true; 245 bool is_framework = false; 246 auto dir = 247 HS.getFileMgr().getDirectory(module.search_path.GetStringRef()); 248 if (!dir) 249 return error(); 250 auto *file = HS.lookupModuleMapFile(*dir, is_framework); 251 if (!file) 252 return error(); 253 if (!HS.loadModuleMapFile(file, is_system)) 254 return error(); 255 } 256 } 257 if (!HS.lookupModule(module.path.front().GetStringRef())) { 258 error_stream.Printf("error: Header search couldn't locate module %s\n", 259 module.path.front().AsCString()); 260 return false; 261 } 262 263 llvm::SmallVector<std::pair<clang::IdentifierInfo *, clang::SourceLocation>, 264 4> 265 clang_path; 266 267 { 268 clang::SourceManager &source_manager = 269 m_compiler_instance->getASTContext().getSourceManager(); 270 271 for (ConstString path_component : module.path) { 272 clang_path.push_back(std::make_pair( 273 &m_compiler_instance->getASTContext().Idents.get( 274 path_component.GetStringRef()), 275 source_manager.getLocForStartOfFile(source_manager.getMainFileID()) 276 .getLocWithOffset(m_source_location_index++))); 277 } 278 } 279 280 StoringDiagnosticConsumer *diagnostic_consumer = 281 static_cast<StoringDiagnosticConsumer *>( 282 m_compiler_instance->getDiagnostics().getClient()); 283 284 diagnostic_consumer->ClearDiagnostics(); 285 286 clang::Module *top_level_module = DoGetModule(clang_path.front(), false); 287 288 if (!top_level_module) { 289 diagnostic_consumer->DumpDiagnostics(error_stream); 290 error_stream.Printf("error: Couldn't load top-level module %s\n", 291 module.path.front().AsCString()); 292 return false; 293 } 294 295 clang::Module *submodule = top_level_module; 296 297 for (auto &component : llvm::ArrayRef<ConstString>(module.path).drop_front()) { 298 submodule = submodule->findSubmodule(component.GetStringRef()); 299 if (!submodule) { 300 diagnostic_consumer->DumpDiagnostics(error_stream); 301 error_stream.Printf("error: Couldn't load submodule %s\n", 302 component.GetCString()); 303 return false; 304 } 305 } 306 307 clang::Module *requested_module = DoGetModule(clang_path, true); 308 309 if (requested_module != nullptr) { 310 if (exported_modules) { 311 ReportModuleExports(*exported_modules, requested_module); 312 } 313 314 m_imported_modules[imported_module] = requested_module; 315 316 m_enabled = true; 317 318 return true; 319 } 320 321 return false; 322} 323 324bool ClangModulesDeclVendor::LanguageSupportsClangModules( 325 lldb::LanguageType language) { 326 switch (language) { 327 default: 328 return false; 329 case lldb::LanguageType::eLanguageTypeC: 330 case lldb::LanguageType::eLanguageTypeC11: 331 case lldb::LanguageType::eLanguageTypeC89: 332 case lldb::LanguageType::eLanguageTypeC99: 333 case lldb::LanguageType::eLanguageTypeC_plus_plus: 334 case lldb::LanguageType::eLanguageTypeC_plus_plus_03: 335 case lldb::LanguageType::eLanguageTypeC_plus_plus_11: 336 case lldb::LanguageType::eLanguageTypeC_plus_plus_14: 337 case lldb::LanguageType::eLanguageTypeObjC: 338 case lldb::LanguageType::eLanguageTypeObjC_plus_plus: 339 return true; 340 } 341} 342 343bool ClangModulesDeclVendorImpl::AddModulesForCompileUnit( 344 CompileUnit &cu, ClangModulesDeclVendor::ModuleVector &exported_modules, 345 Stream &error_stream) { 346 if (LanguageSupportsClangModules(cu.GetLanguage())) { 347 for (auto &imported_module : cu.GetImportedModules()) 348 if (!AddModule(imported_module, &exported_modules, error_stream)) 349 return false; 350 } 351 return true; 352} 353 354// ClangImporter::lookupValue 355 356uint32_t 357ClangModulesDeclVendorImpl::FindDecls(ConstString name, bool append, 358 uint32_t max_matches, 359 std::vector<CompilerDecl> &decls) { 360 if (!m_enabled) { 361 return 0; 362 } 363 364 if (!append) 365 decls.clear(); 366 367 clang::IdentifierInfo &ident = 368 m_compiler_instance->getASTContext().Idents.get(name.GetStringRef()); 369 370 clang::LookupResult lookup_result( 371 m_compiler_instance->getSema(), clang::DeclarationName(&ident), 372 clang::SourceLocation(), clang::Sema::LookupOrdinaryName); 373 374 m_compiler_instance->getSema().LookupName( 375 lookup_result, 376 m_compiler_instance->getSema().getScopeForContext( 377 m_compiler_instance->getASTContext().getTranslationUnitDecl())); 378 379 uint32_t num_matches = 0; 380 381 for (clang::NamedDecl *named_decl : lookup_result) { 382 if (num_matches >= max_matches) 383 return num_matches; 384 385 decls.push_back(CompilerDecl(m_ast_context.get(), named_decl)); 386 ++num_matches; 387 } 388 389 return num_matches; 390} 391 392void ClangModulesDeclVendorImpl::ForEachMacro( 393 const ClangModulesDeclVendor::ModuleVector &modules, 394 std::function<bool(const std::string &)> handler) { 395 if (!m_enabled) { 396 return; 397 } 398 399 typedef std::map<ModuleID, ssize_t> ModulePriorityMap; 400 ModulePriorityMap module_priorities; 401 402 ssize_t priority = 0; 403 404 for (ModuleID module : modules) { 405 module_priorities[module] = priority++; 406 } 407 408 if (m_compiler_instance->getPreprocessor().getExternalSource()) { 409 m_compiler_instance->getPreprocessor() 410 .getExternalSource() 411 ->ReadDefinedMacros(); 412 } 413 414 for (clang::Preprocessor::macro_iterator 415 mi = m_compiler_instance->getPreprocessor().macro_begin(), 416 me = m_compiler_instance->getPreprocessor().macro_end(); 417 mi != me; ++mi) { 418 const clang::IdentifierInfo *ii = nullptr; 419 420 { 421 if (clang::IdentifierInfoLookup *lookup = 422 m_compiler_instance->getPreprocessor() 423 .getIdentifierTable() 424 .getExternalIdentifierLookup()) { 425 lookup->get(mi->first->getName()); 426 } 427 if (!ii) { 428 ii = mi->first; 429 } 430 } 431 432 ssize_t found_priority = -1; 433 clang::MacroInfo *macro_info = nullptr; 434 435 for (clang::ModuleMacro *module_macro : 436 m_compiler_instance->getPreprocessor().getLeafModuleMacros(ii)) { 437 clang::Module *module = module_macro->getOwningModule(); 438 439 { 440 ModulePriorityMap::iterator pi = 441 module_priorities.find(reinterpret_cast<ModuleID>(module)); 442 443 if (pi != module_priorities.end() && pi->second > found_priority) { 444 macro_info = module_macro->getMacroInfo(); 445 found_priority = pi->second; 446 } 447 } 448 449 clang::Module *top_level_module = module->getTopLevelModule(); 450 451 if (top_level_module != module) { 452 ModulePriorityMap::iterator pi = module_priorities.find( 453 reinterpret_cast<ModuleID>(top_level_module)); 454 455 if ((pi != module_priorities.end()) && pi->second > found_priority) { 456 macro_info = module_macro->getMacroInfo(); 457 found_priority = pi->second; 458 } 459 } 460 } 461 462 if (macro_info) { 463 std::string macro_expansion = "#define "; 464 macro_expansion.append(mi->first->getName().str()); 465 466 { 467 if (macro_info->isFunctionLike()) { 468 macro_expansion.append("("); 469 470 bool first_arg = true; 471 472 for (auto pi = macro_info->param_begin(), 473 pe = macro_info->param_end(); 474 pi != pe; ++pi) { 475 if (!first_arg) { 476 macro_expansion.append(", "); 477 } else { 478 first_arg = false; 479 } 480 481 macro_expansion.append((*pi)->getName().str()); 482 } 483 484 if (macro_info->isC99Varargs()) { 485 if (first_arg) { 486 macro_expansion.append("..."); 487 } else { 488 macro_expansion.append(", ..."); 489 } 490 } else if (macro_info->isGNUVarargs()) { 491 macro_expansion.append("..."); 492 } 493 494 macro_expansion.append(")"); 495 } 496 497 macro_expansion.append(" "); 498 499 bool first_token = true; 500 501 for (clang::MacroInfo::tokens_iterator ti = macro_info->tokens_begin(), 502 te = macro_info->tokens_end(); 503 ti != te; ++ti) { 504 if (!first_token) { 505 macro_expansion.append(" "); 506 } else { 507 first_token = false; 508 } 509 510 if (ti->isLiteral()) { 511 if (const char *literal_data = ti->getLiteralData()) { 512 std::string token_str(literal_data, ti->getLength()); 513 macro_expansion.append(token_str); 514 } else { 515 bool invalid = false; 516 const char *literal_source = 517 m_compiler_instance->getSourceManager().getCharacterData( 518 ti->getLocation(), &invalid); 519 520 if (invalid) { 521 lldbassert(0 && "Unhandled token kind"); 522 macro_expansion.append("<unknown literal value>"); 523 } else { 524 macro_expansion.append( 525 std::string(literal_source, ti->getLength())); 526 } 527 } 528 } else if (const char *punctuator_spelling = 529 clang::tok::getPunctuatorSpelling(ti->getKind())) { 530 macro_expansion.append(punctuator_spelling); 531 } else if (const char *keyword_spelling = 532 clang::tok::getKeywordSpelling(ti->getKind())) { 533 macro_expansion.append(keyword_spelling); 534 } else { 535 switch (ti->getKind()) { 536 case clang::tok::TokenKind::identifier: 537 macro_expansion.append(ti->getIdentifierInfo()->getName().str()); 538 break; 539 case clang::tok::TokenKind::raw_identifier: 540 macro_expansion.append(ti->getRawIdentifier().str()); 541 break; 542 default: 543 macro_expansion.append(ti->getName()); 544 break; 545 } 546 } 547 } 548 549 if (handler(macro_expansion)) { 550 return; 551 } 552 } 553 } 554 } 555} 556 557clang::ModuleLoadResult 558ClangModulesDeclVendorImpl::DoGetModule(clang::ModuleIdPath path, 559 bool make_visible) { 560 clang::Module::NameVisibilityKind visibility = 561 make_visible ? clang::Module::AllVisible : clang::Module::Hidden; 562 563 const bool is_inclusion_directive = false; 564 565 return m_compiler_instance->loadModule(path.front().second, path, visibility, 566 is_inclusion_directive); 567} 568 569static const char *ModuleImportBufferName = "LLDBModulesMemoryBuffer"; 570 571lldb_private::ClangModulesDeclVendor * 572ClangModulesDeclVendor::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->createASTReader(); 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