1 //===-- CompilerInstance.h - Clang Compiler Instance ------------*- 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 #ifndef LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_ 10 #define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_ 11 12 #include "clang/AST/ASTConsumer.h" 13 #include "clang/Basic/Diagnostic.h" 14 #include "clang/Basic/SourceManager.h" 15 #include "clang/Basic/TargetInfo.h" 16 #include "clang/Frontend/CompilerInvocation.h" 17 #include "clang/Frontend/PCHContainerOperations.h" 18 #include "clang/Frontend/Utils.h" 19 #include "clang/Lex/DependencyDirectivesScanner.h" 20 #include "clang/Lex/HeaderSearchOptions.h" 21 #include "clang/Lex/ModuleLoader.h" 22 #include "llvm/ADT/ArrayRef.h" 23 #include "llvm/ADT/DenseMap.h" 24 #include "llvm/ADT/IntrusiveRefCntPtr.h" 25 #include "llvm/ADT/StringRef.h" 26 #include "llvm/Support/BuryPointer.h" 27 #include "llvm/Support/FileSystem.h" 28 #include "llvm/Support/VirtualFileSystem.h" 29 #include <cassert> 30 #include <list> 31 #include <memory> 32 #include <optional> 33 #include <string> 34 #include <utility> 35 36 namespace llvm { 37 class raw_fd_ostream; 38 class Timer; 39 class TimerGroup; 40 } 41 42 namespace clang { 43 class ASTContext; 44 class ASTReader; 45 46 namespace serialization { 47 class ModuleFile; 48 } 49 50 class CodeCompleteConsumer; 51 class DiagnosticsEngine; 52 class DiagnosticConsumer; 53 class FileManager; 54 class FrontendAction; 55 class Module; 56 class ModuleCache; 57 class Preprocessor; 58 class Sema; 59 class SourceManager; 60 class TargetInfo; 61 enum class DisableValidationForModuleKind; 62 63 /// CompilerInstance - Helper class for managing a single instance of the Clang 64 /// compiler. 65 /// 66 /// The CompilerInstance serves two purposes: 67 /// (1) It manages the various objects which are necessary to run the compiler, 68 /// for example the preprocessor, the target information, and the AST 69 /// context. 70 /// (2) It provides utility routines for constructing and manipulating the 71 /// common Clang objects. 72 /// 73 /// The compiler instance generally owns the instance of all the objects that it 74 /// manages. However, clients can still share objects by manually setting the 75 /// object and retaking ownership prior to destroying the CompilerInstance. 76 /// 77 /// The compiler instance is intended to simplify clients, but not to lock them 78 /// in to the compiler instance for everything. When possible, utility functions 79 /// come in two forms; a short form that reuses the CompilerInstance objects, 80 /// and a long form that takes explicit instances of any required objects. 81 class CompilerInstance : public ModuleLoader { 82 /// The options used in this compiler instance. 83 std::shared_ptr<CompilerInvocation> Invocation; 84 85 /// The diagnostics engine instance. 86 IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics; 87 88 /// The target being compiled for. 89 IntrusiveRefCntPtr<TargetInfo> Target; 90 91 /// Options for the auxiliary target. 92 std::unique_ptr<TargetOptions> AuxTargetOpts; 93 94 /// Auxiliary Target info. 95 IntrusiveRefCntPtr<TargetInfo> AuxTarget; 96 97 /// The file manager. 98 IntrusiveRefCntPtr<FileManager> FileMgr; 99 100 /// The source manager. 101 IntrusiveRefCntPtr<SourceManager> SourceMgr; 102 103 /// The cache of PCM files. 104 IntrusiveRefCntPtr<ModuleCache> ModCache; 105 106 /// Functor for getting the dependency preprocessor directives of a file. 107 std::unique_ptr<DependencyDirectivesGetter> GetDependencyDirectives; 108 109 /// The preprocessor. 110 std::shared_ptr<Preprocessor> PP; 111 112 /// The AST context. 113 IntrusiveRefCntPtr<ASTContext> Context; 114 115 /// An optional sema source that will be attached to sema. 116 IntrusiveRefCntPtr<ExternalSemaSource> ExternalSemaSrc; 117 118 /// The AST consumer. 119 std::unique_ptr<ASTConsumer> Consumer; 120 121 /// The code completion consumer. 122 std::unique_ptr<CodeCompleteConsumer> CompletionConsumer; 123 124 /// The semantic analysis object. 125 std::unique_ptr<Sema> TheSema; 126 127 /// The frontend timer group. 128 std::unique_ptr<llvm::TimerGroup> timerGroup; 129 130 /// The frontend timer. 131 std::unique_ptr<llvm::Timer> FrontendTimer; 132 133 /// The ASTReader, if one exists. 134 IntrusiveRefCntPtr<ASTReader> TheASTReader; 135 136 /// The module dependency collector for crashdumps 137 std::shared_ptr<ModuleDependencyCollector> ModuleDepCollector; 138 139 /// The module provider. 140 std::shared_ptr<PCHContainerOperations> ThePCHContainerOperations; 141 142 std::vector<std::shared_ptr<DependencyCollector>> DependencyCollectors; 143 144 /// The set of modules that failed to build. 145 /// 146 /// This value will be passed among all of the compiler instances created 147 /// to (re)build modules, so that once a module fails to build anywhere, 148 /// other instances will see that the module has failed and won't try to 149 /// build it again. 150 llvm::StringSet<> FailedModules; 151 152 /// The set of top-level modules that has already been built on the 153 /// fly as part of this overall compilation action. 154 std::map<std::string, std::string, std::less<>> BuiltModules; 155 156 /// Should we delete the BuiltModules when we're done? 157 bool DeleteBuiltModules = true; 158 159 /// The location of the module-import keyword for the last module 160 /// import. 161 SourceLocation LastModuleImportLoc; 162 163 /// The result of the last module import. 164 /// 165 ModuleLoadResult LastModuleImportResult; 166 167 /// Whether we should (re)build the global module index once we 168 /// have finished with this translation unit. 169 bool BuildGlobalModuleIndex = false; 170 171 /// We have a full global module index, with all modules. 172 bool HaveFullGlobalModuleIndex = false; 173 174 /// One or more modules failed to build. 175 bool DisableGeneratingGlobalModuleIndex = false; 176 177 /// The stream for verbose output if owned, otherwise nullptr. 178 std::unique_ptr<raw_ostream> OwnedVerboseOutputStream; 179 180 /// The stream for verbose output. 181 raw_ostream *VerboseOutputStream = &llvm::errs(); 182 183 /// Holds information about the output file. 184 /// 185 /// If TempFilename is not empty we must rename it to Filename at the end. 186 /// TempFilename may be empty and Filename non-empty if creating the temporary 187 /// failed. 188 struct OutputFile { 189 std::string Filename; 190 std::optional<llvm::sys::fs::TempFile> File; 191 OutputFileOutputFile192 OutputFile(std::string filename, 193 std::optional<llvm::sys::fs::TempFile> file) 194 : Filename(std::move(filename)), File(std::move(file)) {} 195 }; 196 197 /// The list of active output files. 198 std::list<OutputFile> OutputFiles; 199 200 /// Force an output buffer. 201 std::unique_ptr<llvm::raw_pwrite_stream> OutputStream; 202 203 CompilerInstance(const CompilerInstance &) = delete; 204 void operator=(const CompilerInstance &) = delete; 205 public: 206 explicit CompilerInstance( 207 std::shared_ptr<CompilerInvocation> Invocation = 208 std::make_shared<CompilerInvocation>(), 209 std::shared_ptr<PCHContainerOperations> PCHContainerOps = 210 std::make_shared<PCHContainerOperations>(), 211 ModuleCache *ModCache = nullptr); 212 ~CompilerInstance() override; 213 214 /// @name High-Level Operations 215 /// @{ 216 217 /// ExecuteAction - Execute the provided action against the compiler's 218 /// CompilerInvocation object. 219 /// 220 /// This function makes the following assumptions: 221 /// 222 /// - The invocation options should be initialized. This function does not 223 /// handle the '-help' or '-version' options, clients should handle those 224 /// directly. 225 /// 226 /// - The diagnostics engine should have already been created by the client. 227 /// 228 /// - No other CompilerInstance state should have been initialized (this is 229 /// an unchecked error). 230 /// 231 /// - Clients should have initialized any LLVM target features that may be 232 /// required. 233 /// 234 /// - Clients should eventually call llvm_shutdown() upon the completion of 235 /// this routine to ensure that any managed objects are properly destroyed. 236 /// 237 /// Note that this routine may write output to 'stderr'. 238 /// 239 /// \param Act - The action to execute. 240 /// \return - True on success. 241 // 242 // FIXME: Eliminate the llvm_shutdown requirement, that should either be part 243 // of the context or else not CompilerInstance specific. 244 bool ExecuteAction(FrontendAction &Act); 245 246 /// At the end of a compilation, print the number of warnings/errors. 247 void printDiagnosticStats(); 248 249 /// Load the list of plugins requested in the \c FrontendOptions. 250 void LoadRequestedPlugins(); 251 252 /// @} 253 /// @name Compiler Invocation and Options 254 /// @{ 255 getInvocation()256 CompilerInvocation &getInvocation() { return *Invocation; } 257 getInvocationPtr()258 std::shared_ptr<CompilerInvocation> getInvocationPtr() { return Invocation; } 259 260 /// Indicates whether we should (re)build the global module index. 261 bool shouldBuildGlobalModuleIndex() const; 262 263 /// Set the flag indicating whether we should (re)build the global 264 /// module index. setBuildGlobalModuleIndex(bool Build)265 void setBuildGlobalModuleIndex(bool Build) { 266 BuildGlobalModuleIndex = Build; 267 } 268 269 /// @} 270 /// @name Forwarding Methods 271 /// @{ 272 getAnalyzerOpts()273 AnalyzerOptions &getAnalyzerOpts() { return Invocation->getAnalyzerOpts(); } 274 getCodeGenOpts()275 CodeGenOptions &getCodeGenOpts() { 276 return Invocation->getCodeGenOpts(); 277 } getCodeGenOpts()278 const CodeGenOptions &getCodeGenOpts() const { 279 return Invocation->getCodeGenOpts(); 280 } 281 getDependencyOutputOpts()282 DependencyOutputOptions &getDependencyOutputOpts() { 283 return Invocation->getDependencyOutputOpts(); 284 } getDependencyOutputOpts()285 const DependencyOutputOptions &getDependencyOutputOpts() const { 286 return Invocation->getDependencyOutputOpts(); 287 } 288 getDiagnosticOpts()289 DiagnosticOptions &getDiagnosticOpts() { 290 return Invocation->getDiagnosticOpts(); 291 } getDiagnosticOpts()292 const DiagnosticOptions &getDiagnosticOpts() const { 293 return Invocation->getDiagnosticOpts(); 294 } 295 getFileSystemOpts()296 FileSystemOptions &getFileSystemOpts() { 297 return Invocation->getFileSystemOpts(); 298 } getFileSystemOpts()299 const FileSystemOptions &getFileSystemOpts() const { 300 return Invocation->getFileSystemOpts(); 301 } 302 getFrontendOpts()303 FrontendOptions &getFrontendOpts() { 304 return Invocation->getFrontendOpts(); 305 } getFrontendOpts()306 const FrontendOptions &getFrontendOpts() const { 307 return Invocation->getFrontendOpts(); 308 } 309 getHeaderSearchOpts()310 HeaderSearchOptions &getHeaderSearchOpts() { 311 return Invocation->getHeaderSearchOpts(); 312 } getHeaderSearchOpts()313 const HeaderSearchOptions &getHeaderSearchOpts() const { 314 return Invocation->getHeaderSearchOpts(); 315 } 316 getAPINotesOpts()317 APINotesOptions &getAPINotesOpts() { return Invocation->getAPINotesOpts(); } getAPINotesOpts()318 const APINotesOptions &getAPINotesOpts() const { 319 return Invocation->getAPINotesOpts(); 320 } 321 getLangOpts()322 LangOptions &getLangOpts() { return Invocation->getLangOpts(); } getLangOpts()323 const LangOptions &getLangOpts() const { return Invocation->getLangOpts(); } 324 getPreprocessorOpts()325 PreprocessorOptions &getPreprocessorOpts() { 326 return Invocation->getPreprocessorOpts(); 327 } getPreprocessorOpts()328 const PreprocessorOptions &getPreprocessorOpts() const { 329 return Invocation->getPreprocessorOpts(); 330 } 331 getPreprocessorOutputOpts()332 PreprocessorOutputOptions &getPreprocessorOutputOpts() { 333 return Invocation->getPreprocessorOutputOpts(); 334 } getPreprocessorOutputOpts()335 const PreprocessorOutputOptions &getPreprocessorOutputOpts() const { 336 return Invocation->getPreprocessorOutputOpts(); 337 } 338 getTargetOpts()339 TargetOptions &getTargetOpts() { 340 return Invocation->getTargetOpts(); 341 } getTargetOpts()342 const TargetOptions &getTargetOpts() const { 343 return Invocation->getTargetOpts(); 344 } 345 346 /// @} 347 /// @name Diagnostics Engine 348 /// @{ 349 hasDiagnostics()350 bool hasDiagnostics() const { return Diagnostics != nullptr; } 351 352 /// Get the current diagnostics engine. getDiagnostics()353 DiagnosticsEngine &getDiagnostics() const { 354 assert(Diagnostics && "Compiler instance has no diagnostics!"); 355 return *Diagnostics; 356 } 357 getDiagnosticsPtr()358 IntrusiveRefCntPtr<DiagnosticsEngine> getDiagnosticsPtr() const { 359 assert(Diagnostics && "Compiler instance has no diagnostics!"); 360 return Diagnostics; 361 } 362 363 /// setDiagnostics - Replace the current diagnostics engine. 364 void setDiagnostics(DiagnosticsEngine *Value); 365 getDiagnosticClient()366 DiagnosticConsumer &getDiagnosticClient() const { 367 assert(Diagnostics && Diagnostics->getClient() && 368 "Compiler instance has no diagnostic client!"); 369 return *Diagnostics->getClient(); 370 } 371 372 /// @} 373 /// @name VerboseOutputStream 374 /// @{ 375 376 /// Replace the current stream for verbose output. 377 void setVerboseOutputStream(raw_ostream &Value); 378 379 /// Replace the current stream for verbose output. 380 void setVerboseOutputStream(std::unique_ptr<raw_ostream> Value); 381 382 /// Get the current stream for verbose output. getVerboseOutputStream()383 raw_ostream &getVerboseOutputStream() { 384 return *VerboseOutputStream; 385 } 386 387 /// @} 388 /// @name Target Info 389 /// @{ 390 hasTarget()391 bool hasTarget() const { return Target != nullptr; } 392 getTarget()393 TargetInfo &getTarget() const { 394 assert(Target && "Compiler instance has no target!"); 395 return *Target; 396 } 397 getTargetPtr()398 IntrusiveRefCntPtr<TargetInfo> getTargetPtr() const { 399 assert(Target && "Compiler instance has no target!"); 400 return Target; 401 } 402 403 /// Replace the current Target. 404 void setTarget(TargetInfo *Value); 405 406 /// @} 407 /// @name AuxTarget Info 408 /// @{ 409 getAuxTarget()410 TargetInfo *getAuxTarget() const { return AuxTarget.get(); } 411 412 /// Replace the current AuxTarget. 413 void setAuxTarget(TargetInfo *Value); 414 415 // Create Target and AuxTarget based on current options 416 bool createTarget(); 417 418 /// @} 419 /// @name Virtual File System 420 /// @{ 421 422 llvm::vfs::FileSystem &getVirtualFileSystem() const; 423 424 /// @} 425 /// @name File Manager 426 /// @{ 427 hasFileManager()428 bool hasFileManager() const { return FileMgr != nullptr; } 429 430 /// Return the current file manager to the caller. getFileManager()431 FileManager &getFileManager() const { 432 assert(FileMgr && "Compiler instance has no file manager!"); 433 return *FileMgr; 434 } 435 getFileManagerPtr()436 IntrusiveRefCntPtr<FileManager> getFileManagerPtr() const { 437 assert(FileMgr && "Compiler instance has no file manager!"); 438 return FileMgr; 439 } 440 resetAndLeakFileManager()441 void resetAndLeakFileManager() { 442 llvm::BuryPointer(FileMgr.get()); 443 FileMgr.resetWithoutRelease(); 444 } 445 446 /// Replace the current file manager and virtual file system. 447 void setFileManager(FileManager *Value); 448 449 /// @} 450 /// @name Source Manager 451 /// @{ 452 hasSourceManager()453 bool hasSourceManager() const { return SourceMgr != nullptr; } 454 455 /// Return the current source manager. getSourceManager()456 SourceManager &getSourceManager() const { 457 assert(SourceMgr && "Compiler instance has no source manager!"); 458 return *SourceMgr; 459 } 460 getSourceManagerPtr()461 IntrusiveRefCntPtr<SourceManager> getSourceManagerPtr() const { 462 assert(SourceMgr && "Compiler instance has no source manager!"); 463 return SourceMgr; 464 } 465 resetAndLeakSourceManager()466 void resetAndLeakSourceManager() { 467 llvm::BuryPointer(SourceMgr.get()); 468 SourceMgr.resetWithoutRelease(); 469 } 470 471 /// setSourceManager - Replace the current source manager. 472 void setSourceManager(SourceManager *Value); 473 474 /// @} 475 /// @name Preprocessor 476 /// @{ 477 hasPreprocessor()478 bool hasPreprocessor() const { return PP != nullptr; } 479 480 /// Return the current preprocessor. getPreprocessor()481 Preprocessor &getPreprocessor() const { 482 assert(PP && "Compiler instance has no preprocessor!"); 483 return *PP; 484 } 485 getPreprocessorPtr()486 std::shared_ptr<Preprocessor> getPreprocessorPtr() { return PP; } 487 resetAndLeakPreprocessor()488 void resetAndLeakPreprocessor() { 489 llvm::BuryPointer(new std::shared_ptr<Preprocessor>(PP)); 490 } 491 492 /// Replace the current preprocessor. 493 void setPreprocessor(std::shared_ptr<Preprocessor> Value); 494 495 /// @} 496 /// @name ASTContext 497 /// @{ 498 hasASTContext()499 bool hasASTContext() const { return Context != nullptr; } 500 getASTContext()501 ASTContext &getASTContext() const { 502 assert(Context && "Compiler instance has no AST context!"); 503 return *Context; 504 } 505 getASTContextPtr()506 IntrusiveRefCntPtr<ASTContext> getASTContextPtr() const { 507 assert(Context && "Compiler instance has no AST context!"); 508 return Context; 509 } 510 resetAndLeakASTContext()511 void resetAndLeakASTContext() { 512 llvm::BuryPointer(Context.get()); 513 Context.resetWithoutRelease(); 514 } 515 516 /// setASTContext - Replace the current AST context. 517 void setASTContext(ASTContext *Value); 518 519 /// Replace the current Sema; the compiler instance takes ownership 520 /// of S. 521 void setSema(Sema *S); 522 523 /// @} 524 /// @name ASTConsumer 525 /// @{ 526 hasASTConsumer()527 bool hasASTConsumer() const { return (bool)Consumer; } 528 getASTConsumer()529 ASTConsumer &getASTConsumer() const { 530 assert(Consumer && "Compiler instance has no AST consumer!"); 531 return *Consumer; 532 } 533 534 /// takeASTConsumer - Remove the current AST consumer and give ownership to 535 /// the caller. takeASTConsumer()536 std::unique_ptr<ASTConsumer> takeASTConsumer() { return std::move(Consumer); } 537 538 /// setASTConsumer - Replace the current AST consumer; the compiler instance 539 /// takes ownership of \p Value. 540 void setASTConsumer(std::unique_ptr<ASTConsumer> Value); 541 542 /// @} 543 /// @name Semantic analysis 544 /// @{ hasSema()545 bool hasSema() const { return (bool)TheSema; } 546 getSema()547 Sema &getSema() const { 548 assert(TheSema && "Compiler instance has no Sema object!"); 549 return *TheSema; 550 } 551 552 std::unique_ptr<Sema> takeSema(); 553 void resetAndLeakSema(); 554 555 /// @} 556 /// @name Module Management 557 /// @{ 558 559 IntrusiveRefCntPtr<ASTReader> getASTReader() const; 560 void setASTReader(IntrusiveRefCntPtr<ASTReader> Reader); 561 562 std::shared_ptr<ModuleDependencyCollector> getModuleDepCollector() const; 563 void setModuleDepCollector( 564 std::shared_ptr<ModuleDependencyCollector> Collector); 565 getPCHContainerOperations()566 std::shared_ptr<PCHContainerOperations> getPCHContainerOperations() const { 567 return ThePCHContainerOperations; 568 } 569 570 /// Return the appropriate PCHContainerWriter depending on the 571 /// current CodeGenOptions. getPCHContainerWriter()572 const PCHContainerWriter &getPCHContainerWriter() const { 573 assert(Invocation && "cannot determine module format without invocation"); 574 StringRef Format = getHeaderSearchOpts().ModuleFormat; 575 auto *Writer = ThePCHContainerOperations->getWriterOrNull(Format); 576 if (!Writer) { 577 if (Diagnostics) 578 Diagnostics->Report(diag::err_module_format_unhandled) << Format; 579 llvm::report_fatal_error("unknown module format"); 580 } 581 return *Writer; 582 } 583 584 /// Return the appropriate PCHContainerReader depending on the 585 /// current CodeGenOptions. getPCHContainerReader()586 const PCHContainerReader &getPCHContainerReader() const { 587 assert(Invocation && "cannot determine module format without invocation"); 588 StringRef Format = getHeaderSearchOpts().ModuleFormat; 589 auto *Reader = ThePCHContainerOperations->getReaderOrNull(Format); 590 if (!Reader) { 591 if (Diagnostics) 592 Diagnostics->Report(diag::err_module_format_unhandled) << Format; 593 llvm::report_fatal_error("unknown module format"); 594 } 595 return *Reader; 596 } 597 598 /// @} 599 /// @name Code Completion 600 /// @{ 601 hasCodeCompletionConsumer()602 bool hasCodeCompletionConsumer() const { return (bool)CompletionConsumer; } 603 getCodeCompletionConsumer()604 CodeCompleteConsumer &getCodeCompletionConsumer() const { 605 assert(CompletionConsumer && 606 "Compiler instance has no code completion consumer!"); 607 return *CompletionConsumer; 608 } 609 610 /// setCodeCompletionConsumer - Replace the current code completion consumer; 611 /// the compiler instance takes ownership of \p Value. 612 void setCodeCompletionConsumer(CodeCompleteConsumer *Value); 613 614 /// @} 615 /// @name Frontend timer 616 /// @{ 617 getTimerGroup()618 llvm::TimerGroup &getTimerGroup() const { return *timerGroup; } 619 getFrontendTimer()620 llvm::Timer &getFrontendTimer() const { 621 assert(FrontendTimer && "Compiler instance has no frontend timer!"); 622 return *FrontendTimer; 623 } 624 625 /// } 626 /// @name Output Files 627 /// @{ 628 629 /// clearOutputFiles - Clear the output file list. The underlying output 630 /// streams must have been closed beforehand. 631 /// 632 /// \param EraseFiles - If true, attempt to erase the files from disk. 633 void clearOutputFiles(bool EraseFiles); 634 635 /// @} 636 /// @name Construction Utility Methods 637 /// @{ 638 639 /// Create the diagnostics engine using the invocation's diagnostic options 640 /// and replace any existing one with it. 641 /// 642 /// Note that this routine also replaces the diagnostic client, 643 /// allocating one if one is not provided. 644 /// 645 /// \param VFS is used for any IO needed when creating DiagnosticsEngine. It 646 /// doesn't replace VFS in the CompilerInstance (if any). 647 /// 648 /// \param Client If non-NULL, a diagnostic client that will be 649 /// attached to (and, then, owned by) the DiagnosticsEngine inside this AST 650 /// unit. 651 /// 652 /// \param ShouldOwnClient If Client is non-NULL, specifies whether 653 /// the diagnostic object should take ownership of the client. 654 void createDiagnostics(llvm::vfs::FileSystem &VFS, 655 DiagnosticConsumer *Client = nullptr, 656 bool ShouldOwnClient = true); 657 658 /// Create a DiagnosticsEngine object with a the TextDiagnosticPrinter. 659 /// 660 /// If no diagnostic client is provided, this creates a 661 /// DiagnosticConsumer that is owned by the returned diagnostic 662 /// object, if using directly the caller is responsible for 663 /// releasing the returned DiagnosticsEngine's client eventually. 664 /// 665 /// \param Opts - The diagnostic options; note that the created text 666 /// diagnostic object contains a reference to these options. 667 /// 668 /// \param Client If non-NULL, a diagnostic client that will be 669 /// attached to (and, then, owned by) the returned DiagnosticsEngine 670 /// object. 671 /// 672 /// \param CodeGenOpts If non-NULL, the code gen options in use, which may be 673 /// used by some diagnostics printers (for logging purposes only). 674 /// 675 /// \return The new object on success, or null on failure. 676 static IntrusiveRefCntPtr<DiagnosticsEngine> 677 createDiagnostics(llvm::vfs::FileSystem &VFS, DiagnosticOptions &Opts, 678 DiagnosticConsumer *Client = nullptr, 679 bool ShouldOwnClient = true, 680 const CodeGenOptions *CodeGenOpts = nullptr); 681 682 /// Create the file manager and replace any existing one with it. 683 /// 684 /// \return The new file manager on success, or null on failure. 685 FileManager * 686 createFileManager(IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr); 687 688 /// Create the source manager and replace any existing one with it. 689 void createSourceManager(FileManager &FileMgr); 690 691 /// Create the preprocessor, using the invocation, file, and source managers, 692 /// and replace any existing one with it. 693 void createPreprocessor(TranslationUnitKind TUKind); 694 setDependencyDirectivesGetter(std::unique_ptr<DependencyDirectivesGetter> Getter)695 void setDependencyDirectivesGetter( 696 std::unique_ptr<DependencyDirectivesGetter> Getter) { 697 GetDependencyDirectives = std::move(Getter); 698 } 699 700 std::string getSpecificModuleCachePath(StringRef ModuleHash); getSpecificModuleCachePath()701 std::string getSpecificModuleCachePath() { 702 return getSpecificModuleCachePath(getInvocation().getModuleHash()); 703 } 704 705 /// Create the AST context. 706 void createASTContext(); 707 708 /// Create an external AST source to read a PCH file and attach it to the AST 709 /// context. 710 void createPCHExternalASTSource( 711 StringRef Path, DisableValidationForModuleKind DisableValidation, 712 bool AllowPCHWithCompilerErrors, void *DeserializationListener, 713 bool OwnDeserializationListener); 714 715 /// Create an external AST source to read a PCH file. 716 /// 717 /// \return - The new object on success, or null on failure. 718 static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource( 719 StringRef Path, StringRef Sysroot, 720 DisableValidationForModuleKind DisableValidation, 721 bool AllowPCHWithCompilerErrors, Preprocessor &PP, ModuleCache &ModCache, 722 ASTContext &Context, const PCHContainerReader &PCHContainerRdr, 723 ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, 724 ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors, 725 void *DeserializationListener, bool OwnDeserializationListener, 726 bool Preamble, bool UseGlobalModuleIndex); 727 728 /// Create a code completion consumer using the invocation; note that this 729 /// will cause the source manager to truncate the input source file at the 730 /// completion point. 731 void createCodeCompletionConsumer(); 732 733 /// Create a code completion consumer to print code completion results, at 734 /// \p Filename, \p Line, and \p Column, to the given output stream \p OS. 735 static CodeCompleteConsumer *createCodeCompletionConsumer( 736 Preprocessor &PP, StringRef Filename, unsigned Line, unsigned Column, 737 const CodeCompleteOptions &Opts, raw_ostream &OS); 738 739 /// Create the Sema object to be used for parsing. 740 void createSema(TranslationUnitKind TUKind, 741 CodeCompleteConsumer *CompletionConsumer); 742 743 /// Create the frontend timer and replace any existing one with it. 744 void createFrontendTimer(); 745 746 /// Create the default output file (from the invocation's options) and add it 747 /// to the list of tracked output files. 748 /// 749 /// The files created by this are usually removed on signal, and, depending 750 /// on FrontendOptions, may also use a temporary file (that is, the data is 751 /// written to a temporary file which will atomically replace the target 752 /// output on success). 753 /// 754 /// \return - Null on error. 755 std::unique_ptr<raw_pwrite_stream> createDefaultOutputFile( 756 bool Binary = true, StringRef BaseInput = "", StringRef Extension = "", 757 bool RemoveFileOnSignal = true, bool CreateMissingDirectories = false, 758 bool ForceUseTemporary = false); 759 760 /// Create a new output file, optionally deriving the output path name, and 761 /// add it to the list of tracked output files. 762 /// 763 /// \return - Null on error. 764 std::unique_ptr<raw_pwrite_stream> 765 createOutputFile(StringRef OutputPath, bool Binary, bool RemoveFileOnSignal, 766 bool UseTemporary, bool CreateMissingDirectories = false); 767 768 private: 769 /// Create a new output file and add it to the list of tracked output files. 770 /// 771 /// If \p OutputPath is empty, then createOutputFile will derive an output 772 /// path location as \p BaseInput, with any suffix removed, and \p Extension 773 /// appended. If \p OutputPath is not stdout and \p UseTemporary 774 /// is true, createOutputFile will create a new temporary file that must be 775 /// renamed to \p OutputPath in the end. 776 /// 777 /// \param OutputPath - If given, the path to the output file. 778 /// \param Binary - The mode to open the file in. 779 /// \param RemoveFileOnSignal - Whether the file should be registered with 780 /// llvm::sys::RemoveFileOnSignal. Note that this is not safe for 781 /// multithreaded use, as the underlying signal mechanism is not reentrant 782 /// \param UseTemporary - Create a new temporary file that must be renamed to 783 /// OutputPath in the end. 784 /// \param CreateMissingDirectories - When \p UseTemporary is true, create 785 /// missing directories in the output path. 786 Expected<std::unique_ptr<raw_pwrite_stream>> 787 createOutputFileImpl(StringRef OutputPath, bool Binary, 788 bool RemoveFileOnSignal, bool UseTemporary, 789 bool CreateMissingDirectories); 790 791 public: 792 std::unique_ptr<raw_pwrite_stream> createNullOutputFile(); 793 794 /// @} 795 /// @name Initialization Utility Methods 796 /// @{ 797 798 /// InitializeSourceManager - Initialize the source manager to set InputFile 799 /// as the main file. 800 /// 801 /// \return True on success. 802 bool InitializeSourceManager(const FrontendInputFile &Input); 803 804 /// InitializeSourceManager - Initialize the source manager to set InputFile 805 /// as the main file. 806 /// 807 /// \return True on success. 808 static bool InitializeSourceManager(const FrontendInputFile &Input, 809 DiagnosticsEngine &Diags, 810 FileManager &FileMgr, 811 SourceManager &SourceMgr); 812 813 /// @} 814 setOutputStream(std::unique_ptr<llvm::raw_pwrite_stream> OutStream)815 void setOutputStream(std::unique_ptr<llvm::raw_pwrite_stream> OutStream) { 816 OutputStream = std::move(OutStream); 817 } 818 takeOutputStream()819 std::unique_ptr<llvm::raw_pwrite_stream> takeOutputStream() { 820 return std::move(OutputStream); 821 } 822 823 void createASTReader(); 824 825 bool loadModuleFile(StringRef FileName, 826 serialization::ModuleFile *&LoadedModuleFile); 827 828 /// Configuration object for making the result of \c cloneForModuleCompile() 829 /// thread-safe. 830 class ThreadSafeCloneConfig { 831 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS; 832 DiagnosticConsumer &DiagConsumer; 833 std::shared_ptr<ModuleDependencyCollector> ModuleDepCollector; 834 835 public: 836 ThreadSafeCloneConfig( 837 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, 838 DiagnosticConsumer &DiagConsumer, 839 std::shared_ptr<ModuleDependencyCollector> ModuleDepCollector = nullptr) VFS(std::move (VFS))840 : VFS(std::move(VFS)), DiagConsumer(DiagConsumer), 841 ModuleDepCollector(std::move(ModuleDepCollector)) { 842 assert(this->VFS && "Clone config requires non-null VFS"); 843 } 844 getVFS()845 IntrusiveRefCntPtr<llvm::vfs::FileSystem> getVFS() const { return VFS; } getDiagConsumer()846 DiagnosticConsumer &getDiagConsumer() const { return DiagConsumer; } getModuleDepCollector()847 std::shared_ptr<ModuleDependencyCollector> getModuleDepCollector() const { 848 return ModuleDepCollector; 849 } 850 }; 851 852 private: 853 /// Find a module, potentially compiling it, before reading its AST. This is 854 /// the guts of loadModule. 855 /// 856 /// For prebuilt modules, the Module is not expected to exist in 857 /// HeaderSearch's ModuleMap. If a ModuleFile by that name is in the 858 /// ModuleManager, then it will be loaded and looked up. 859 /// 860 /// For implicit modules, the Module is expected to already be in the 861 /// ModuleMap. First attempt to load it from the given path on disk. If that 862 /// fails, defer to compileModuleAndReadAST, which will first build and then 863 /// load it. 864 ModuleLoadResult findOrCompileModuleAndReadAST(StringRef ModuleName, 865 SourceLocation ImportLoc, 866 SourceLocation ModuleNameLoc, 867 bool IsInclusionDirective); 868 869 /// Creates a \c CompilerInstance for compiling a module. 870 /// 871 /// This expects a properly initialized \c FrontendInputFile. 872 std::unique_ptr<CompilerInstance> cloneForModuleCompileImpl( 873 SourceLocation ImportLoc, StringRef ModuleName, FrontendInputFile Input, 874 StringRef OriginalModuleMapFile, StringRef ModuleFileName, 875 std::optional<ThreadSafeCloneConfig> ThreadSafeConfig = std::nullopt); 876 877 public: 878 /// Creates a new \c CompilerInstance for compiling a module. 879 /// 880 /// This takes care of creating appropriate \c FrontendInputFile for 881 /// public/private frameworks, inferred modules and such. 882 /// 883 /// The \c ThreadSafeConfig takes precedence over the \c DiagnosticConsumer 884 /// and \c FileSystem of this instance (and disables \c FileManager sharing). 885 std::unique_ptr<CompilerInstance> cloneForModuleCompile( 886 SourceLocation ImportLoc, Module *Module, StringRef ModuleFileName, 887 std::optional<ThreadSafeCloneConfig> ThreadSafeConfig = std::nullopt); 888 889 /// Compile a module file for the given module, using the options 890 /// provided by the importing compiler instance. Returns true if the module 891 /// was built without errors. 892 // FIXME: This should be private, but it's called from static non-member 893 // functions in the implementation file. 894 bool compileModule(SourceLocation ImportLoc, StringRef ModuleName, 895 StringRef ModuleFileName, CompilerInstance &Instance); 896 897 ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, 898 Module::NameVisibilityKind Visibility, 899 bool IsInclusionDirective) override; 900 901 void createModuleFromSource(SourceLocation ImportLoc, StringRef ModuleName, 902 StringRef Source) override; 903 904 void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility, 905 SourceLocation ImportLoc) override; 906 hadModuleLoaderFatalFailure()907 bool hadModuleLoaderFatalFailure() const { 908 return ModuleLoader::HadFatalFailure; 909 } 910 911 GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override; 912 913 bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override; 914 addDependencyCollector(std::shared_ptr<DependencyCollector> Listener)915 void addDependencyCollector(std::shared_ptr<DependencyCollector> Listener) { 916 DependencyCollectors.push_back(std::move(Listener)); 917 } 918 919 void setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS); 920 getModuleCache()921 ModuleCache &getModuleCache() const { return *ModCache; } 922 }; 923 924 } // end namespace clang 925 926 #endif 927