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