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