Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:55

0001 //===-- CompilerInstance.h - Clang Compiler Instance ------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
0010 #define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
0011 
0012 #include "clang/AST/ASTConsumer.h"
0013 #include "clang/Basic/Diagnostic.h"
0014 #include "clang/Basic/SourceManager.h"
0015 #include "clang/Basic/TargetInfo.h"
0016 #include "clang/Frontend/CompilerInvocation.h"
0017 #include "clang/Frontend/PCHContainerOperations.h"
0018 #include "clang/Frontend/Utils.h"
0019 #include "clang/Lex/HeaderSearchOptions.h"
0020 #include "clang/Lex/ModuleLoader.h"
0021 #include "llvm/ADT/ArrayRef.h"
0022 #include "llvm/ADT/DenseMap.h"
0023 #include "llvm/ADT/IntrusiveRefCntPtr.h"
0024 #include "llvm/ADT/StringRef.h"
0025 #include "llvm/Support/BuryPointer.h"
0026 #include "llvm/Support/FileSystem.h"
0027 #include "llvm/Support/VirtualFileSystem.h"
0028 #include <cassert>
0029 #include <list>
0030 #include <memory>
0031 #include <optional>
0032 #include <string>
0033 #include <utility>
0034 
0035 namespace llvm {
0036 class raw_fd_ostream;
0037 class Timer;
0038 class TimerGroup;
0039 }
0040 
0041 namespace clang {
0042 class ASTContext;
0043 class ASTReader;
0044 
0045 namespace serialization {
0046 class ModuleFile;
0047 }
0048 
0049 class CodeCompleteConsumer;
0050 class DiagnosticsEngine;
0051 class DiagnosticConsumer;
0052 class FileManager;
0053 class FrontendAction;
0054 class InMemoryModuleCache;
0055 class Module;
0056 class Preprocessor;
0057 class Sema;
0058 class SourceManager;
0059 class TargetInfo;
0060 enum class DisableValidationForModuleKind;
0061 
0062 /// CompilerInstance - Helper class for managing a single instance of the Clang
0063 /// compiler.
0064 ///
0065 /// The CompilerInstance serves two purposes:
0066 ///  (1) It manages the various objects which are necessary to run the compiler,
0067 ///      for example the preprocessor, the target information, and the AST
0068 ///      context.
0069 ///  (2) It provides utility routines for constructing and manipulating the
0070 ///      common Clang objects.
0071 ///
0072 /// The compiler instance generally owns the instance of all the objects that it
0073 /// manages. However, clients can still share objects by manually setting the
0074 /// object and retaking ownership prior to destroying the CompilerInstance.
0075 ///
0076 /// The compiler instance is intended to simplify clients, but not to lock them
0077 /// in to the compiler instance for everything. When possible, utility functions
0078 /// come in two forms; a short form that reuses the CompilerInstance objects,
0079 /// and a long form that takes explicit instances of any required objects.
0080 class CompilerInstance : public ModuleLoader {
0081   /// The options used in this compiler instance.
0082   std::shared_ptr<CompilerInvocation> Invocation;
0083 
0084   /// The diagnostics engine instance.
0085   IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
0086 
0087   /// The target being compiled for.
0088   IntrusiveRefCntPtr<TargetInfo> Target;
0089 
0090   /// Auxiliary Target info.
0091   IntrusiveRefCntPtr<TargetInfo> AuxTarget;
0092 
0093   /// The file manager.
0094   IntrusiveRefCntPtr<FileManager> FileMgr;
0095 
0096   /// The source manager.
0097   IntrusiveRefCntPtr<SourceManager> SourceMgr;
0098 
0099   /// The cache of PCM files.
0100   IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache;
0101 
0102   /// The preprocessor.
0103   std::shared_ptr<Preprocessor> PP;
0104 
0105   /// The AST context.
0106   IntrusiveRefCntPtr<ASTContext> Context;
0107 
0108   /// An optional sema source that will be attached to sema.
0109   IntrusiveRefCntPtr<ExternalSemaSource> ExternalSemaSrc;
0110 
0111   /// The AST consumer.
0112   std::unique_ptr<ASTConsumer> Consumer;
0113 
0114   /// The code completion consumer.
0115   std::unique_ptr<CodeCompleteConsumer> CompletionConsumer;
0116 
0117   /// The semantic analysis object.
0118   std::unique_ptr<Sema> TheSema;
0119 
0120   /// The frontend timer group.
0121   std::unique_ptr<llvm::TimerGroup> timerGroup;
0122 
0123   /// The frontend timer.
0124   std::unique_ptr<llvm::Timer> FrontendTimer;
0125 
0126   /// The ASTReader, if one exists.
0127   IntrusiveRefCntPtr<ASTReader> TheASTReader;
0128 
0129   /// The module dependency collector for crashdumps
0130   std::shared_ptr<ModuleDependencyCollector> ModuleDepCollector;
0131 
0132   /// The module provider.
0133   std::shared_ptr<PCHContainerOperations> ThePCHContainerOperations;
0134 
0135   std::vector<std::shared_ptr<DependencyCollector>> DependencyCollectors;
0136 
0137   /// Records the set of modules
0138   class FailedModulesSet {
0139     llvm::StringSet<> Failed;
0140 
0141   public:
0142     bool hasAlreadyFailed(StringRef module) { return Failed.count(module) > 0; }
0143 
0144     void addFailed(StringRef module) { Failed.insert(module); }
0145   };
0146 
0147   /// The set of modules that failed to build.
0148   ///
0149   /// This pointer will be shared among all of the compiler instances created
0150   /// to (re)build modules, so that once a module fails to build anywhere,
0151   /// other instances will see that the module has failed and won't try to
0152   /// build it again.
0153   std::shared_ptr<FailedModulesSet> FailedModules;
0154 
0155   /// The set of top-level modules that has already been built on the
0156   /// fly as part of this overall compilation action.
0157   std::map<std::string, std::string, std::less<>> BuiltModules;
0158 
0159   /// Should we delete the BuiltModules when we're done?
0160   bool DeleteBuiltModules = true;
0161 
0162   /// The location of the module-import keyword for the last module
0163   /// import.
0164   SourceLocation LastModuleImportLoc;
0165 
0166   /// The result of the last module import.
0167   ///
0168   ModuleLoadResult LastModuleImportResult;
0169 
0170   /// Whether we should (re)build the global module index once we
0171   /// have finished with this translation unit.
0172   bool BuildGlobalModuleIndex = false;
0173 
0174   /// We have a full global module index, with all modules.
0175   bool HaveFullGlobalModuleIndex = false;
0176 
0177   /// One or more modules failed to build.
0178   bool DisableGeneratingGlobalModuleIndex = false;
0179 
0180   /// The stream for verbose output if owned, otherwise nullptr.
0181   std::unique_ptr<raw_ostream> OwnedVerboseOutputStream;
0182 
0183   /// The stream for verbose output.
0184   raw_ostream *VerboseOutputStream = &llvm::errs();
0185 
0186   /// Holds information about the output file.
0187   ///
0188   /// If TempFilename is not empty we must rename it to Filename at the end.
0189   /// TempFilename may be empty and Filename non-empty if creating the temporary
0190   /// failed.
0191   struct OutputFile {
0192     std::string Filename;
0193     std::optional<llvm::sys::fs::TempFile> File;
0194 
0195     OutputFile(std::string filename,
0196                std::optional<llvm::sys::fs::TempFile> file)
0197         : Filename(std::move(filename)), File(std::move(file)) {}
0198   };
0199 
0200   /// The list of active output files.
0201   std::list<OutputFile> OutputFiles;
0202 
0203   /// Force an output buffer.
0204   std::unique_ptr<llvm::raw_pwrite_stream> OutputStream;
0205 
0206   CompilerInstance(const CompilerInstance &) = delete;
0207   void operator=(const CompilerInstance &) = delete;
0208 public:
0209   explicit CompilerInstance(
0210       std::shared_ptr<PCHContainerOperations> PCHContainerOps =
0211           std::make_shared<PCHContainerOperations>(),
0212       InMemoryModuleCache *SharedModuleCache = nullptr);
0213   ~CompilerInstance() override;
0214 
0215   /// @name High-Level Operations
0216   /// @{
0217 
0218   /// ExecuteAction - Execute the provided action against the compiler's
0219   /// CompilerInvocation object.
0220   ///
0221   /// This function makes the following assumptions:
0222   ///
0223   ///  - The invocation options should be initialized. This function does not
0224   ///    handle the '-help' or '-version' options, clients should handle those
0225   ///    directly.
0226   ///
0227   ///  - The diagnostics engine should have already been created by the client.
0228   ///
0229   ///  - No other CompilerInstance state should have been initialized (this is
0230   ///    an unchecked error).
0231   ///
0232   ///  - Clients should have initialized any LLVM target features that may be
0233   ///    required.
0234   ///
0235   ///  - Clients should eventually call llvm_shutdown() upon the completion of
0236   ///    this routine to ensure that any managed objects are properly destroyed.
0237   ///
0238   /// Note that this routine may write output to 'stderr'.
0239   ///
0240   /// \param Act - The action to execute.
0241   /// \return - True on success.
0242   //
0243   // FIXME: Eliminate the llvm_shutdown requirement, that should either be part
0244   // of the context or else not CompilerInstance specific.
0245   bool ExecuteAction(FrontendAction &Act);
0246 
0247   /// At the end of a compilation, print the number of warnings/errors.
0248   void printDiagnosticStats();
0249 
0250   /// Load the list of plugins requested in the \c FrontendOptions.
0251   void LoadRequestedPlugins();
0252 
0253   /// @}
0254   /// @name Compiler Invocation and Options
0255   /// @{
0256 
0257   bool hasInvocation() const { return Invocation != nullptr; }
0258 
0259   CompilerInvocation &getInvocation() {
0260     assert(Invocation && "Compiler instance has no invocation!");
0261     return *Invocation;
0262   }
0263 
0264   std::shared_ptr<CompilerInvocation> getInvocationPtr() { return Invocation; }
0265 
0266   /// setInvocation - Replace the current invocation.
0267   void setInvocation(std::shared_ptr<CompilerInvocation> Value);
0268 
0269   /// Indicates whether we should (re)build the global module index.
0270   bool shouldBuildGlobalModuleIndex() const;
0271 
0272   /// Set the flag indicating whether we should (re)build the global
0273   /// module index.
0274   void setBuildGlobalModuleIndex(bool Build) {
0275     BuildGlobalModuleIndex = Build;
0276   }
0277 
0278   /// @}
0279   /// @name Forwarding Methods
0280   /// @{
0281 
0282   AnalyzerOptions &getAnalyzerOpts() { return Invocation->getAnalyzerOpts(); }
0283 
0284   CodeGenOptions &getCodeGenOpts() {
0285     return Invocation->getCodeGenOpts();
0286   }
0287   const CodeGenOptions &getCodeGenOpts() const {
0288     return Invocation->getCodeGenOpts();
0289   }
0290 
0291   DependencyOutputOptions &getDependencyOutputOpts() {
0292     return Invocation->getDependencyOutputOpts();
0293   }
0294   const DependencyOutputOptions &getDependencyOutputOpts() const {
0295     return Invocation->getDependencyOutputOpts();
0296   }
0297 
0298   DiagnosticOptions &getDiagnosticOpts() {
0299     return Invocation->getDiagnosticOpts();
0300   }
0301   const DiagnosticOptions &getDiagnosticOpts() const {
0302     return Invocation->getDiagnosticOpts();
0303   }
0304 
0305   FileSystemOptions &getFileSystemOpts() {
0306     return Invocation->getFileSystemOpts();
0307   }
0308   const FileSystemOptions &getFileSystemOpts() const {
0309     return Invocation->getFileSystemOpts();
0310   }
0311 
0312   FrontendOptions &getFrontendOpts() {
0313     return Invocation->getFrontendOpts();
0314   }
0315   const FrontendOptions &getFrontendOpts() const {
0316     return Invocation->getFrontendOpts();
0317   }
0318 
0319   HeaderSearchOptions &getHeaderSearchOpts() {
0320     return Invocation->getHeaderSearchOpts();
0321   }
0322   const HeaderSearchOptions &getHeaderSearchOpts() const {
0323     return Invocation->getHeaderSearchOpts();
0324   }
0325   std::shared_ptr<HeaderSearchOptions> getHeaderSearchOptsPtr() const {
0326     return Invocation->getHeaderSearchOptsPtr();
0327   }
0328 
0329   APINotesOptions &getAPINotesOpts() { return Invocation->getAPINotesOpts(); }
0330   const APINotesOptions &getAPINotesOpts() const {
0331     return Invocation->getAPINotesOpts();
0332   }
0333 
0334   LangOptions &getLangOpts() { return Invocation->getLangOpts(); }
0335   const LangOptions &getLangOpts() const { return Invocation->getLangOpts(); }
0336   std::shared_ptr<LangOptions> getLangOptsPtr() const {
0337     return Invocation->getLangOptsPtr();
0338   }
0339 
0340   PreprocessorOptions &getPreprocessorOpts() {
0341     return Invocation->getPreprocessorOpts();
0342   }
0343   const PreprocessorOptions &getPreprocessorOpts() const {
0344     return Invocation->getPreprocessorOpts();
0345   }
0346 
0347   PreprocessorOutputOptions &getPreprocessorOutputOpts() {
0348     return Invocation->getPreprocessorOutputOpts();
0349   }
0350   const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
0351     return Invocation->getPreprocessorOutputOpts();
0352   }
0353 
0354   TargetOptions &getTargetOpts() {
0355     return Invocation->getTargetOpts();
0356   }
0357   const TargetOptions &getTargetOpts() const {
0358     return Invocation->getTargetOpts();
0359   }
0360 
0361   /// @}
0362   /// @name Diagnostics Engine
0363   /// @{
0364 
0365   bool hasDiagnostics() const { return Diagnostics != nullptr; }
0366 
0367   /// Get the current diagnostics engine.
0368   DiagnosticsEngine &getDiagnostics() const {
0369     assert(Diagnostics && "Compiler instance has no diagnostics!");
0370     return *Diagnostics;
0371   }
0372 
0373   IntrusiveRefCntPtr<DiagnosticsEngine> getDiagnosticsPtr() const {
0374     assert(Diagnostics && "Compiler instance has no diagnostics!");
0375     return Diagnostics;
0376   }
0377 
0378   /// setDiagnostics - Replace the current diagnostics engine.
0379   void setDiagnostics(DiagnosticsEngine *Value);
0380 
0381   DiagnosticConsumer &getDiagnosticClient() const {
0382     assert(Diagnostics && Diagnostics->getClient() &&
0383            "Compiler instance has no diagnostic client!");
0384     return *Diagnostics->getClient();
0385   }
0386 
0387   /// @}
0388   /// @name VerboseOutputStream
0389   /// @{
0390 
0391   /// Replace the current stream for verbose output.
0392   void setVerboseOutputStream(raw_ostream &Value);
0393 
0394   /// Replace the current stream for verbose output.
0395   void setVerboseOutputStream(std::unique_ptr<raw_ostream> Value);
0396 
0397   /// Get the current stream for verbose output.
0398   raw_ostream &getVerboseOutputStream() {
0399     return *VerboseOutputStream;
0400   }
0401 
0402   /// @}
0403   /// @name Target Info
0404   /// @{
0405 
0406   bool hasTarget() const { return Target != nullptr; }
0407 
0408   TargetInfo &getTarget() const {
0409     assert(Target && "Compiler instance has no target!");
0410     return *Target;
0411   }
0412 
0413   IntrusiveRefCntPtr<TargetInfo> getTargetPtr() const {
0414     assert(Target && "Compiler instance has no target!");
0415     return Target;
0416   }
0417 
0418   /// Replace the current Target.
0419   void setTarget(TargetInfo *Value);
0420 
0421   /// @}
0422   /// @name AuxTarget Info
0423   /// @{
0424 
0425   TargetInfo *getAuxTarget() const { return AuxTarget.get(); }
0426 
0427   /// Replace the current AuxTarget.
0428   void setAuxTarget(TargetInfo *Value);
0429 
0430   // Create Target and AuxTarget based on current options
0431   bool createTarget();
0432 
0433   /// @}
0434   /// @name Virtual File System
0435   /// @{
0436 
0437   llvm::vfs::FileSystem &getVirtualFileSystem() const;
0438 
0439   /// @}
0440   /// @name File Manager
0441   /// @{
0442 
0443   bool hasFileManager() const { return FileMgr != nullptr; }
0444 
0445   /// Return the current file manager to the caller.
0446   FileManager &getFileManager() const {
0447     assert(FileMgr && "Compiler instance has no file manager!");
0448     return *FileMgr;
0449   }
0450 
0451   IntrusiveRefCntPtr<FileManager> getFileManagerPtr() const {
0452     assert(FileMgr && "Compiler instance has no file manager!");
0453     return FileMgr;
0454   }
0455 
0456   void resetAndLeakFileManager() {
0457     llvm::BuryPointer(FileMgr.get());
0458     FileMgr.resetWithoutRelease();
0459   }
0460 
0461   /// Replace the current file manager and virtual file system.
0462   void setFileManager(FileManager *Value);
0463 
0464   /// @}
0465   /// @name Source Manager
0466   /// @{
0467 
0468   bool hasSourceManager() const { return SourceMgr != nullptr; }
0469 
0470   /// Return the current source manager.
0471   SourceManager &getSourceManager() const {
0472     assert(SourceMgr && "Compiler instance has no source manager!");
0473     return *SourceMgr;
0474   }
0475 
0476   IntrusiveRefCntPtr<SourceManager> getSourceManagerPtr() const {
0477     assert(SourceMgr && "Compiler instance has no source manager!");
0478     return SourceMgr;
0479   }
0480 
0481   void resetAndLeakSourceManager() {
0482     llvm::BuryPointer(SourceMgr.get());
0483     SourceMgr.resetWithoutRelease();
0484   }
0485 
0486   /// setSourceManager - Replace the current source manager.
0487   void setSourceManager(SourceManager *Value);
0488 
0489   /// @}
0490   /// @name Preprocessor
0491   /// @{
0492 
0493   bool hasPreprocessor() const { return PP != nullptr; }
0494 
0495   /// Return the current preprocessor.
0496   Preprocessor &getPreprocessor() const {
0497     assert(PP && "Compiler instance has no preprocessor!");
0498     return *PP;
0499   }
0500 
0501   std::shared_ptr<Preprocessor> getPreprocessorPtr() { return PP; }
0502 
0503   void resetAndLeakPreprocessor() {
0504     llvm::BuryPointer(new std::shared_ptr<Preprocessor>(PP));
0505   }
0506 
0507   /// Replace the current preprocessor.
0508   void setPreprocessor(std::shared_ptr<Preprocessor> Value);
0509 
0510   /// @}
0511   /// @name ASTContext
0512   /// @{
0513 
0514   bool hasASTContext() const { return Context != nullptr; }
0515 
0516   ASTContext &getASTContext() const {
0517     assert(Context && "Compiler instance has no AST context!");
0518     return *Context;
0519   }
0520 
0521   IntrusiveRefCntPtr<ASTContext> getASTContextPtr() const {
0522     assert(Context && "Compiler instance has no AST context!");
0523     return Context;
0524   }
0525 
0526   void resetAndLeakASTContext() {
0527     llvm::BuryPointer(Context.get());
0528     Context.resetWithoutRelease();
0529   }
0530 
0531   /// setASTContext - Replace the current AST context.
0532   void setASTContext(ASTContext *Value);
0533 
0534   /// Replace the current Sema; the compiler instance takes ownership
0535   /// of S.
0536   void setSema(Sema *S);
0537 
0538   /// @}
0539   /// @name ASTConsumer
0540   /// @{
0541 
0542   bool hasASTConsumer() const { return (bool)Consumer; }
0543 
0544   ASTConsumer &getASTConsumer() const {
0545     assert(Consumer && "Compiler instance has no AST consumer!");
0546     return *Consumer;
0547   }
0548 
0549   /// takeASTConsumer - Remove the current AST consumer and give ownership to
0550   /// the caller.
0551   std::unique_ptr<ASTConsumer> takeASTConsumer() { return std::move(Consumer); }
0552 
0553   /// setASTConsumer - Replace the current AST consumer; the compiler instance
0554   /// takes ownership of \p Value.
0555   void setASTConsumer(std::unique_ptr<ASTConsumer> Value);
0556 
0557   /// @}
0558   /// @name Semantic analysis
0559   /// @{
0560   bool hasSema() const { return (bool)TheSema; }
0561 
0562   Sema &getSema() const {
0563     assert(TheSema && "Compiler instance has no Sema object!");
0564     return *TheSema;
0565   }
0566 
0567   std::unique_ptr<Sema> takeSema();
0568   void resetAndLeakSema();
0569 
0570   /// @}
0571   /// @name Module Management
0572   /// @{
0573 
0574   IntrusiveRefCntPtr<ASTReader> getASTReader() const;
0575   void setASTReader(IntrusiveRefCntPtr<ASTReader> Reader);
0576 
0577   std::shared_ptr<ModuleDependencyCollector> getModuleDepCollector() const;
0578   void setModuleDepCollector(
0579       std::shared_ptr<ModuleDependencyCollector> Collector);
0580 
0581   std::shared_ptr<PCHContainerOperations> getPCHContainerOperations() const {
0582     return ThePCHContainerOperations;
0583   }
0584 
0585   /// Return the appropriate PCHContainerWriter depending on the
0586   /// current CodeGenOptions.
0587   const PCHContainerWriter &getPCHContainerWriter() const {
0588     assert(Invocation && "cannot determine module format without invocation");
0589     StringRef Format = getHeaderSearchOpts().ModuleFormat;
0590     auto *Writer = ThePCHContainerOperations->getWriterOrNull(Format);
0591     if (!Writer) {
0592       if (Diagnostics)
0593         Diagnostics->Report(diag::err_module_format_unhandled) << Format;
0594       llvm::report_fatal_error("unknown module format");
0595     }
0596     return *Writer;
0597   }
0598 
0599   /// Return the appropriate PCHContainerReader depending on the
0600   /// current CodeGenOptions.
0601   const PCHContainerReader &getPCHContainerReader() const {
0602     assert(Invocation && "cannot determine module format without invocation");
0603     StringRef Format = getHeaderSearchOpts().ModuleFormat;
0604     auto *Reader = ThePCHContainerOperations->getReaderOrNull(Format);
0605     if (!Reader) {
0606       if (Diagnostics)
0607         Diagnostics->Report(diag::err_module_format_unhandled) << Format;
0608       llvm::report_fatal_error("unknown module format");
0609     }
0610     return *Reader;
0611   }
0612 
0613   /// @}
0614   /// @name Code Completion
0615   /// @{
0616 
0617   bool hasCodeCompletionConsumer() const { return (bool)CompletionConsumer; }
0618 
0619   CodeCompleteConsumer &getCodeCompletionConsumer() const {
0620     assert(CompletionConsumer &&
0621            "Compiler instance has no code completion consumer!");
0622     return *CompletionConsumer;
0623   }
0624 
0625   /// setCodeCompletionConsumer - Replace the current code completion consumer;
0626   /// the compiler instance takes ownership of \p Value.
0627   void setCodeCompletionConsumer(CodeCompleteConsumer *Value);
0628 
0629   /// @}
0630   /// @name Frontend timer
0631   /// @{
0632 
0633   llvm::TimerGroup &getTimerGroup() const { return *timerGroup; }
0634 
0635   llvm::Timer &getFrontendTimer() const {
0636     assert(FrontendTimer && "Compiler instance has no frontend timer!");
0637     return *FrontendTimer;
0638   }
0639 
0640   /// @}
0641   /// @name Failed modules set
0642   /// @{
0643 
0644   bool hasFailedModulesSet() const { return (bool)FailedModules; }
0645 
0646   void createFailedModulesSet() {
0647     FailedModules = std::make_shared<FailedModulesSet>();
0648   }
0649 
0650   std::shared_ptr<FailedModulesSet> getFailedModulesSetPtr() const {
0651     return FailedModules;
0652   }
0653 
0654   void setFailedModulesSet(std::shared_ptr<FailedModulesSet> FMS) {
0655     FailedModules = FMS;
0656   }
0657 
0658   /// }
0659   /// @name Output Files
0660   /// @{
0661 
0662   /// clearOutputFiles - Clear the output file list. The underlying output
0663   /// streams must have been closed beforehand.
0664   ///
0665   /// \param EraseFiles - If true, attempt to erase the files from disk.
0666   void clearOutputFiles(bool EraseFiles);
0667 
0668   /// @}
0669   /// @name Construction Utility Methods
0670   /// @{
0671 
0672   /// Create the diagnostics engine using the invocation's diagnostic options
0673   /// and replace any existing one with it.
0674   ///
0675   /// Note that this routine also replaces the diagnostic client,
0676   /// allocating one if one is not provided.
0677   ///
0678   /// \param VFS is used for any IO needed when creating DiagnosticsEngine. It
0679   /// doesn't replace VFS in the CompilerInstance (if any).
0680   ///
0681   /// \param Client If non-NULL, a diagnostic client that will be
0682   /// attached to (and, then, owned by) the DiagnosticsEngine inside this AST
0683   /// unit.
0684   ///
0685   /// \param ShouldOwnClient If Client is non-NULL, specifies whether
0686   /// the diagnostic object should take ownership of the client.
0687   void createDiagnostics(llvm::vfs::FileSystem &VFS,
0688                          DiagnosticConsumer *Client = nullptr,
0689                          bool ShouldOwnClient = true);
0690 
0691   /// Create a DiagnosticsEngine object with a the TextDiagnosticPrinter.
0692   ///
0693   /// If no diagnostic client is provided, this creates a
0694   /// DiagnosticConsumer that is owned by the returned diagnostic
0695   /// object, if using directly the caller is responsible for
0696   /// releasing the returned DiagnosticsEngine's client eventually.
0697   ///
0698   /// \param Opts - The diagnostic options; note that the created text
0699   /// diagnostic object contains a reference to these options.
0700   ///
0701   /// \param Client If non-NULL, a diagnostic client that will be
0702   /// attached to (and, then, owned by) the returned DiagnosticsEngine
0703   /// object.
0704   ///
0705   /// \param CodeGenOpts If non-NULL, the code gen options in use, which may be
0706   /// used by some diagnostics printers (for logging purposes only).
0707   ///
0708   /// \return The new object on success, or null on failure.
0709   static IntrusiveRefCntPtr<DiagnosticsEngine>
0710   createDiagnostics(llvm::vfs::FileSystem &VFS, DiagnosticOptions *Opts,
0711                     DiagnosticConsumer *Client = nullptr,
0712                     bool ShouldOwnClient = true,
0713                     const CodeGenOptions *CodeGenOpts = nullptr);
0714 
0715   /// Create the file manager and replace any existing one with it.
0716   ///
0717   /// \return The new file manager on success, or null on failure.
0718   FileManager *
0719   createFileManager(IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
0720 
0721   /// Create the source manager and replace any existing one with it.
0722   void createSourceManager(FileManager &FileMgr);
0723 
0724   /// Create the preprocessor, using the invocation, file, and source managers,
0725   /// and replace any existing one with it.
0726   void createPreprocessor(TranslationUnitKind TUKind);
0727 
0728   std::string getSpecificModuleCachePath(StringRef ModuleHash);
0729   std::string getSpecificModuleCachePath() {
0730     return getSpecificModuleCachePath(getInvocation().getModuleHash());
0731   }
0732 
0733   /// Create the AST context.
0734   void createASTContext();
0735 
0736   /// Create an external AST source to read a PCH file and attach it to the AST
0737   /// context.
0738   void createPCHExternalASTSource(
0739       StringRef Path, DisableValidationForModuleKind DisableValidation,
0740       bool AllowPCHWithCompilerErrors, void *DeserializationListener,
0741       bool OwnDeserializationListener);
0742 
0743   /// Create an external AST source to read a PCH file.
0744   ///
0745   /// \return - The new object on success, or null on failure.
0746   static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource(
0747       StringRef Path, StringRef Sysroot,
0748       DisableValidationForModuleKind DisableValidation,
0749       bool AllowPCHWithCompilerErrors, Preprocessor &PP,
0750       InMemoryModuleCache &ModuleCache, ASTContext &Context,
0751       const PCHContainerReader &PCHContainerRdr,
0752       ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
0753       ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
0754       void *DeserializationListener, bool OwnDeserializationListener,
0755       bool Preamble, bool UseGlobalModuleIndex);
0756 
0757   /// Create a code completion consumer using the invocation; note that this
0758   /// will cause the source manager to truncate the input source file at the
0759   /// completion point.
0760   void createCodeCompletionConsumer();
0761 
0762   /// Create a code completion consumer to print code completion results, at
0763   /// \p Filename, \p Line, and \p Column, to the given output stream \p OS.
0764   static CodeCompleteConsumer *createCodeCompletionConsumer(
0765       Preprocessor &PP, StringRef Filename, unsigned Line, unsigned Column,
0766       const CodeCompleteOptions &Opts, raw_ostream &OS);
0767 
0768   /// Create the Sema object to be used for parsing.
0769   void createSema(TranslationUnitKind TUKind,
0770                   CodeCompleteConsumer *CompletionConsumer);
0771 
0772   /// Create the frontend timer and replace any existing one with it.
0773   void createFrontendTimer();
0774 
0775   /// Create the default output file (from the invocation's options) and add it
0776   /// to the list of tracked output files.
0777   ///
0778   /// The files created by this are usually removed on signal, and, depending
0779   /// on FrontendOptions, may also use a temporary file (that is, the data is
0780   /// written to a temporary file which will atomically replace the target
0781   /// output on success).
0782   ///
0783   /// \return - Null on error.
0784   std::unique_ptr<raw_pwrite_stream> createDefaultOutputFile(
0785       bool Binary = true, StringRef BaseInput = "", StringRef Extension = "",
0786       bool RemoveFileOnSignal = true, bool CreateMissingDirectories = false,
0787       bool ForceUseTemporary = false);
0788 
0789   /// Create a new output file, optionally deriving the output path name, and
0790   /// add it to the list of tracked output files.
0791   ///
0792   /// \return - Null on error.
0793   std::unique_ptr<raw_pwrite_stream>
0794   createOutputFile(StringRef OutputPath, bool Binary, bool RemoveFileOnSignal,
0795                    bool UseTemporary, bool CreateMissingDirectories = false);
0796 
0797 private:
0798   /// Create a new output file and add it to the list of tracked output files.
0799   ///
0800   /// If \p OutputPath is empty, then createOutputFile will derive an output
0801   /// path location as \p BaseInput, with any suffix removed, and \p Extension
0802   /// appended. If \p OutputPath is not stdout and \p UseTemporary
0803   /// is true, createOutputFile will create a new temporary file that must be
0804   /// renamed to \p OutputPath in the end.
0805   ///
0806   /// \param OutputPath - If given, the path to the output file.
0807   /// \param Binary - The mode to open the file in.
0808   /// \param RemoveFileOnSignal - Whether the file should be registered with
0809   /// llvm::sys::RemoveFileOnSignal. Note that this is not safe for
0810   /// multithreaded use, as the underlying signal mechanism is not reentrant
0811   /// \param UseTemporary - Create a new temporary file that must be renamed to
0812   /// OutputPath in the end.
0813   /// \param CreateMissingDirectories - When \p UseTemporary is true, create
0814   /// missing directories in the output path.
0815   Expected<std::unique_ptr<raw_pwrite_stream>>
0816   createOutputFileImpl(StringRef OutputPath, bool Binary,
0817                        bool RemoveFileOnSignal, bool UseTemporary,
0818                        bool CreateMissingDirectories);
0819 
0820 public:
0821   std::unique_ptr<raw_pwrite_stream> createNullOutputFile();
0822 
0823   /// @}
0824   /// @name Initialization Utility Methods
0825   /// @{
0826 
0827   /// InitializeSourceManager - Initialize the source manager to set InputFile
0828   /// as the main file.
0829   ///
0830   /// \return True on success.
0831   bool InitializeSourceManager(const FrontendInputFile &Input);
0832 
0833   /// InitializeSourceManager - Initialize the source manager to set InputFile
0834   /// as the main file.
0835   ///
0836   /// \return True on success.
0837   static bool InitializeSourceManager(const FrontendInputFile &Input,
0838                                       DiagnosticsEngine &Diags,
0839                                       FileManager &FileMgr,
0840                                       SourceManager &SourceMgr);
0841 
0842   /// @}
0843 
0844   void setOutputStream(std::unique_ptr<llvm::raw_pwrite_stream> OutStream) {
0845     OutputStream = std::move(OutStream);
0846   }
0847 
0848   std::unique_ptr<llvm::raw_pwrite_stream> takeOutputStream() {
0849     return std::move(OutputStream);
0850   }
0851 
0852   void createASTReader();
0853 
0854   bool loadModuleFile(StringRef FileName,
0855                       serialization::ModuleFile *&LoadedModuleFile);
0856 
0857 private:
0858   /// Find a module, potentially compiling it, before reading its AST.  This is
0859   /// the guts of loadModule.
0860   ///
0861   /// For prebuilt modules, the Module is not expected to exist in
0862   /// HeaderSearch's ModuleMap.  If a ModuleFile by that name is in the
0863   /// ModuleManager, then it will be loaded and looked up.
0864   ///
0865   /// For implicit modules, the Module is expected to already be in the
0866   /// ModuleMap.  First attempt to load it from the given path on disk.  If that
0867   /// fails, defer to compileModuleAndReadAST, which will first build and then
0868   /// load it.
0869   ModuleLoadResult findOrCompileModuleAndReadAST(StringRef ModuleName,
0870                                                  SourceLocation ImportLoc,
0871                                                  SourceLocation ModuleNameLoc,
0872                                                  bool IsInclusionDirective);
0873 
0874 public:
0875   ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
0876                               Module::NameVisibilityKind Visibility,
0877                               bool IsInclusionDirective) override;
0878 
0879   void createModuleFromSource(SourceLocation ImportLoc, StringRef ModuleName,
0880                               StringRef Source) override;
0881 
0882   void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility,
0883                          SourceLocation ImportLoc) override;
0884 
0885   bool hadModuleLoaderFatalFailure() const {
0886     return ModuleLoader::HadFatalFailure;
0887   }
0888 
0889   GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override;
0890 
0891   bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override;
0892 
0893   void addDependencyCollector(std::shared_ptr<DependencyCollector> Listener) {
0894     DependencyCollectors.push_back(std::move(Listener));
0895   }
0896 
0897   void setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS);
0898 
0899   InMemoryModuleCache &getModuleCache() const { return *ModuleCache; }
0900 };
0901 
0902 } // end namespace clang
0903 
0904 #endif