1199482Srdivacky//===-- CompilerInstance.h - Clang Compiler Instance ------------*- C++ -*-===//
2199482Srdivacky//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6199482Srdivacky//
7199482Srdivacky//===----------------------------------------------------------------------===//
8199482Srdivacky
9199482Srdivacky#ifndef LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
10199482Srdivacky#define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
11199482Srdivacky
12280031Sdim#include "clang/AST/ASTConsumer.h"
13243830Sdim#include "clang/Basic/Diagnostic.h"
14234353Sdim#include "clang/Basic/SourceManager.h"
15249423Sdim#include "clang/Frontend/CompilerInvocation.h"
16314564Sdim#include "clang/Frontend/PCHContainerOperations.h"
17276479Sdim#include "clang/Frontend/Utils.h"
18314564Sdim#include "clang/Lex/HeaderSearchOptions.h"
19226633Sdim#include "clang/Lex/ModuleLoader.h"
20234353Sdim#include "llvm/ADT/ArrayRef.h"
21234353Sdim#include "llvm/ADT/DenseMap.h"
22206275Srdivacky#include "llvm/ADT/IntrusiveRefCntPtr.h"
23199482Srdivacky#include "llvm/ADT/StringRef.h"
24344779Sdim#include "llvm/Support/BuryPointer.h"
25199482Srdivacky#include <cassert>
26199482Srdivacky#include <list>
27276479Sdim#include <memory>
28199482Srdivacky#include <string>
29234353Sdim#include <utility>
30199482Srdivacky
31199482Srdivackynamespace llvm {
32199482Srdivackyclass raw_fd_ostream;
33199990Srdivackyclass Timer;
34288943Sdimclass TimerGroup;
35199482Srdivacky}
36199482Srdivacky
37199482Srdivackynamespace clang {
38199482Srdivackyclass ASTContext;
39226633Sdimclass ASTReader;
40199482Srdivackyclass CodeCompleteConsumer;
41226633Sdimclass DiagnosticsEngine;
42226633Sdimclass DiagnosticConsumer;
43199482Srdivackyclass ExternalASTSource;
44234353Sdimclass FileEntry;
45199482Srdivackyclass FileManager;
46202379Srdivackyclass FrontendAction;
47353358Sdimclass InMemoryModuleCache;
48234353Sdimclass Module;
49199482Srdivackyclass Preprocessor;
50212904Sdimclass Sema;
51199482Srdivackyclass SourceManager;
52199482Srdivackyclass TargetInfo;
53199482Srdivacky
54199482Srdivacky/// CompilerInstance - Helper class for managing a single instance of the Clang
55199482Srdivacky/// compiler.
56199482Srdivacky///
57199482Srdivacky/// The CompilerInstance serves two purposes:
58199482Srdivacky///  (1) It manages the various objects which are necessary to run the compiler,
59199482Srdivacky///      for example the preprocessor, the target information, and the AST
60199482Srdivacky///      context.
61199482Srdivacky///  (2) It provides utility routines for constructing and manipulating the
62199482Srdivacky///      common Clang objects.
63199482Srdivacky///
64199482Srdivacky/// The compiler instance generally owns the instance of all the objects that it
65199482Srdivacky/// manages. However, clients can still share objects by manually setting the
66199482Srdivacky/// object and retaking ownership prior to destroying the CompilerInstance.
67199482Srdivacky///
68199482Srdivacky/// The compiler instance is intended to simplify clients, but not to lock them
69199482Srdivacky/// in to the compiler instance for everything. When possible, utility functions
70199482Srdivacky/// come in two forms; a short form that reuses the CompilerInstance objects,
71199482Srdivacky/// and a long form that takes explicit instances of any required objects.
72226633Sdimclass CompilerInstance : public ModuleLoader {
73199482Srdivacky  /// The options used in this compiler instance.
74314564Sdim  std::shared_ptr<CompilerInvocation> Invocation;
75199482Srdivacky
76199482Srdivacky  /// The diagnostics engine instance.
77234353Sdim  IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
78199482Srdivacky
79199482Srdivacky  /// The target being compiled for.
80234353Sdim  IntrusiveRefCntPtr<TargetInfo> Target;
81199482Srdivacky
82296417Sdim  /// Auxiliary Target info.
83296417Sdim  IntrusiveRefCntPtr<TargetInfo> AuxTarget;
84296417Sdim
85199482Srdivacky  /// The file manager.
86234353Sdim  IntrusiveRefCntPtr<FileManager> FileMgr;
87199482Srdivacky
88199482Srdivacky  /// The source manager.
89234353Sdim  IntrusiveRefCntPtr<SourceManager> SourceMgr;
90199482Srdivacky
91321369Sdim  /// The cache of PCM files.
92353358Sdim  IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache;
93321369Sdim
94199482Srdivacky  /// The preprocessor.
95314564Sdim  std::shared_ptr<Preprocessor> PP;
96199482Srdivacky
97199482Srdivacky  /// The AST context.
98234353Sdim  IntrusiveRefCntPtr<ASTContext> Context;
99199482Srdivacky
100314564Sdim  /// An optional sema source that will be attached to sema.
101314564Sdim  IntrusiveRefCntPtr<ExternalSemaSource> ExternalSemaSrc;
102314564Sdim
103199482Srdivacky  /// The AST consumer.
104276479Sdim  std::unique_ptr<ASTConsumer> Consumer;
105199482Srdivacky
106199482Srdivacky  /// The code completion consumer.
107276479Sdim  std::unique_ptr<CodeCompleteConsumer> CompletionConsumer;
108199482Srdivacky
109341825Sdim  /// The semantic analysis object.
110276479Sdim  std::unique_ptr<Sema> TheSema;
111249423Sdim
112341825Sdim  /// The frontend timer group.
113288943Sdim  std::unique_ptr<llvm::TimerGroup> FrontendTimerGroup;
114288943Sdim
115341825Sdim  /// The frontend timer.
116276479Sdim  std::unique_ptr<llvm::Timer> FrontendTimer;
117199990Srdivacky
118341825Sdim  /// The ASTReader, if one exists.
119360784Sdim  IntrusiveRefCntPtr<ASTReader> TheASTReader;
120226633Sdim
121341825Sdim  /// The module dependency collector for crashdumps
122276479Sdim  std::shared_ptr<ModuleDependencyCollector> ModuleDepCollector;
123276479Sdim
124341825Sdim  /// The module provider.
125288943Sdim  std::shared_ptr<PCHContainerOperations> ThePCHContainerOperations;
126288943Sdim
127276479Sdim  std::vector<std::shared_ptr<DependencyCollector>> DependencyCollectors;
128276479Sdim
129341825Sdim  /// The set of top-level modules that has already been built on the
130321369Sdim  /// fly as part of this overall compilation action.
131321369Sdim  std::map<std::string, std::string> BuiltModules;
132321369Sdim
133321369Sdim  /// Should we delete the BuiltModules when we're done?
134321369Sdim  bool DeleteBuiltModules = true;
135321369Sdim
136341825Sdim  /// The location of the module-import keyword for the last module
137341825Sdim  /// import.
138234353Sdim  SourceLocation LastModuleImportLoc;
139341825Sdim
140341825Sdim  /// The result of the last module import.
141234353Sdim  ///
142249423Sdim  ModuleLoadResult LastModuleImportResult;
143249423Sdim
144341825Sdim  /// Whether we should (re)build the global module index once we
145249423Sdim  /// have finished with this translation unit.
146321369Sdim  bool BuildGlobalModuleIndex = false;
147249423Sdim
148341825Sdim  /// We have a full global module index, with all modules.
149321369Sdim  bool HaveFullGlobalModuleIndex = false;
150276479Sdim
151341825Sdim  /// One or more modules failed to build.
152321369Sdim  bool ModuleBuildFailed = false;
153249423Sdim
154360784Sdim  /// The stream for verbose output if owned, otherwise nullptr.
155360784Sdim  std::unique_ptr<raw_ostream> OwnedVerboseOutputStream;
156360784Sdim
157360784Sdim  /// The stream for verbose output.
158360784Sdim  raw_ostream *VerboseOutputStream = &llvm::errs();
159360784Sdim
160341825Sdim  /// Holds information about the output file.
161218893Sdim  ///
162218893Sdim  /// If TempFilename is not empty we must rename it to Filename at the end.
163276479Sdim  /// TempFilename may be empty and Filename non-empty if creating the temporary
164218893Sdim  /// failed.
165218893Sdim  struct OutputFile {
166218893Sdim    std::string Filename;
167218893Sdim    std::string TempFilename;
168218893Sdim
169309124Sdim    OutputFile(std::string filename, std::string tempFilename)
170309124Sdim        : Filename(std::move(filename)), TempFilename(std::move(tempFilename)) {
171309124Sdim    }
172218893Sdim  };
173218893Sdim
174288943Sdim  /// If the output doesn't support seeking (terminal, pipe). we switch
175288943Sdim  /// the stream to a buffer_ostream. These are the buffer and the original
176288943Sdim  /// stream.
177288943Sdim  std::unique_ptr<llvm::raw_fd_ostream> NonSeekStream;
178288943Sdim
179199482Srdivacky  /// The list of active output files.
180218893Sdim  std::list<OutputFile> OutputFiles;
181199482Srdivacky
182341825Sdim  /// Force an output buffer.
183341825Sdim  std::unique_ptr<llvm::raw_pwrite_stream> OutputStream;
184341825Sdim
185288943Sdim  CompilerInstance(const CompilerInstance &) = delete;
186288943Sdim  void operator=(const CompilerInstance &) = delete;
187199482Srdivackypublic:
188288943Sdim  explicit CompilerInstance(
189288943Sdim      std::shared_ptr<PCHContainerOperations> PCHContainerOps =
190288943Sdim          std::make_shared<PCHContainerOperations>(),
191353358Sdim      InMemoryModuleCache *SharedModuleCache = nullptr);
192288943Sdim  ~CompilerInstance() override;
193199482Srdivacky
194202379Srdivacky  /// @name High-Level Operations
195202379Srdivacky  /// {
196202379Srdivacky
197202379Srdivacky  /// ExecuteAction - Execute the provided action against the compiler's
198202379Srdivacky  /// CompilerInvocation object.
199202379Srdivacky  ///
200202379Srdivacky  /// This function makes the following assumptions:
201202379Srdivacky  ///
202202379Srdivacky  ///  - The invocation options should be initialized. This function does not
203202379Srdivacky  ///    handle the '-help' or '-version' options, clients should handle those
204202379Srdivacky  ///    directly.
205202379Srdivacky  ///
206202379Srdivacky  ///  - The diagnostics engine should have already been created by the client.
207202379Srdivacky  ///
208202379Srdivacky  ///  - No other CompilerInstance state should have been initialized (this is
209202379Srdivacky  ///    an unchecked error).
210202379Srdivacky  ///
211202379Srdivacky  ///  - Clients should have initialized any LLVM target features that may be
212202379Srdivacky  ///    required.
213202379Srdivacky  ///
214202379Srdivacky  ///  - Clients should eventually call llvm_shutdown() upon the completion of
215202379Srdivacky  ///    this routine to ensure that any managed objects are properly destroyed.
216202379Srdivacky  ///
217202379Srdivacky  /// Note that this routine may write output to 'stderr'.
218202379Srdivacky  ///
219202379Srdivacky  /// \param Act - The action to execute.
220202379Srdivacky  /// \return - True on success.
221202379Srdivacky  //
222202379Srdivacky  // FIXME: Eliminate the llvm_shutdown requirement, that should either be part
223202379Srdivacky  // of the context or else not CompilerInstance specific.
224202379Srdivacky  bool ExecuteAction(FrontendAction &Act);
225202379Srdivacky
226202379Srdivacky  /// }
227199482Srdivacky  /// @name Compiler Invocation and Options
228199482Srdivacky  /// {
229199482Srdivacky
230276479Sdim  bool hasInvocation() const { return Invocation != nullptr; }
231199482Srdivacky
232203955Srdivacky  CompilerInvocation &getInvocation() {
233203955Srdivacky    assert(Invocation && "Compiler instance has no invocation!");
234203955Srdivacky    return *Invocation;
235203955Srdivacky  }
236203955Srdivacky
237221345Sdim  /// setInvocation - Replace the current invocation.
238314564Sdim  void setInvocation(std::shared_ptr<CompilerInvocation> Value);
239203955Srdivacky
240341825Sdim  /// Indicates whether we should (re)build the global module index.
241249423Sdim  bool shouldBuildGlobalModuleIndex() const;
242341825Sdim
243341825Sdim  /// Set the flag indicating whether we should (re)build the global
244249423Sdim  /// module index.
245249423Sdim  void setBuildGlobalModuleIndex(bool Build) {
246249423Sdim    BuildGlobalModuleIndex = Build;
247249423Sdim  }
248249423Sdim
249199482Srdivacky  /// }
250199482Srdivacky  /// @name Forwarding Methods
251199482Srdivacky  /// {
252199482Srdivacky
253243830Sdim  AnalyzerOptionsRef getAnalyzerOpts() {
254203955Srdivacky    return Invocation->getAnalyzerOpts();
255199482Srdivacky  }
256199482Srdivacky
257199482Srdivacky  CodeGenOptions &getCodeGenOpts() {
258203955Srdivacky    return Invocation->getCodeGenOpts();
259199482Srdivacky  }
260199482Srdivacky  const CodeGenOptions &getCodeGenOpts() const {
261203955Srdivacky    return Invocation->getCodeGenOpts();
262199482Srdivacky  }
263199482Srdivacky
264199482Srdivacky  DependencyOutputOptions &getDependencyOutputOpts() {
265203955Srdivacky    return Invocation->getDependencyOutputOpts();
266199482Srdivacky  }
267199482Srdivacky  const DependencyOutputOptions &getDependencyOutputOpts() const {
268203955Srdivacky    return Invocation->getDependencyOutputOpts();
269199482Srdivacky  }
270199482Srdivacky
271199482Srdivacky  DiagnosticOptions &getDiagnosticOpts() {
272203955Srdivacky    return Invocation->getDiagnosticOpts();
273199482Srdivacky  }
274199482Srdivacky  const DiagnosticOptions &getDiagnosticOpts() const {
275203955Srdivacky    return Invocation->getDiagnosticOpts();
276199482Srdivacky  }
277199482Srdivacky
278280031Sdim  FileSystemOptions &getFileSystemOpts() {
279280031Sdim    return Invocation->getFileSystemOpts();
280280031Sdim  }
281218893Sdim  const FileSystemOptions &getFileSystemOpts() const {
282218893Sdim    return Invocation->getFileSystemOpts();
283218893Sdim  }
284218893Sdim
285199482Srdivacky  FrontendOptions &getFrontendOpts() {
286203955Srdivacky    return Invocation->getFrontendOpts();
287199482Srdivacky  }
288199482Srdivacky  const FrontendOptions &getFrontendOpts() const {
289203955Srdivacky    return Invocation->getFrontendOpts();
290199482Srdivacky  }
291199482Srdivacky
292199482Srdivacky  HeaderSearchOptions &getHeaderSearchOpts() {
293203955Srdivacky    return Invocation->getHeaderSearchOpts();
294199482Srdivacky  }
295199482Srdivacky  const HeaderSearchOptions &getHeaderSearchOpts() const {
296203955Srdivacky    return Invocation->getHeaderSearchOpts();
297199482Srdivacky  }
298314564Sdim  std::shared_ptr<HeaderSearchOptions> getHeaderSearchOptsPtr() const {
299314564Sdim    return Invocation->getHeaderSearchOptsPtr();
300314564Sdim  }
301199482Srdivacky
302199482Srdivacky  LangOptions &getLangOpts() {
303234353Sdim    return *Invocation->getLangOpts();
304199482Srdivacky  }
305199482Srdivacky  const LangOptions &getLangOpts() const {
306234353Sdim    return *Invocation->getLangOpts();
307199482Srdivacky  }
308199482Srdivacky
309199482Srdivacky  PreprocessorOptions &getPreprocessorOpts() {
310203955Srdivacky    return Invocation->getPreprocessorOpts();
311199482Srdivacky  }
312199482Srdivacky  const PreprocessorOptions &getPreprocessorOpts() const {
313203955Srdivacky    return Invocation->getPreprocessorOpts();
314199482Srdivacky  }
315199482Srdivacky
316199482Srdivacky  PreprocessorOutputOptions &getPreprocessorOutputOpts() {
317203955Srdivacky    return Invocation->getPreprocessorOutputOpts();
318199482Srdivacky  }
319199482Srdivacky  const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
320203955Srdivacky    return Invocation->getPreprocessorOutputOpts();
321199482Srdivacky  }
322199482Srdivacky
323199482Srdivacky  TargetOptions &getTargetOpts() {
324203955Srdivacky    return Invocation->getTargetOpts();
325199482Srdivacky  }
326199482Srdivacky  const TargetOptions &getTargetOpts() const {
327203955Srdivacky    return Invocation->getTargetOpts();
328199482Srdivacky  }
329199482Srdivacky
330199482Srdivacky  /// }
331199482Srdivacky  /// @name Diagnostics Engine
332199482Srdivacky  /// {
333199482Srdivacky
334276479Sdim  bool hasDiagnostics() const { return Diagnostics != nullptr; }
335199482Srdivacky
336221345Sdim  /// Get the current diagnostics engine.
337226633Sdim  DiagnosticsEngine &getDiagnostics() const {
338199482Srdivacky    assert(Diagnostics && "Compiler instance has no diagnostics!");
339199482Srdivacky    return *Diagnostics;
340199482Srdivacky  }
341199482Srdivacky
342221345Sdim  /// setDiagnostics - Replace the current diagnostics engine.
343226633Sdim  void setDiagnostics(DiagnosticsEngine *Value);
344199482Srdivacky
345226633Sdim  DiagnosticConsumer &getDiagnosticClient() const {
346341825Sdim    assert(Diagnostics && Diagnostics->getClient() &&
347212904Sdim           "Compiler instance has no diagnostic client!");
348212904Sdim    return *Diagnostics->getClient();
349199482Srdivacky  }
350199482Srdivacky
351199482Srdivacky  /// }
352360784Sdim  /// @name VerboseOutputStream
353360784Sdim  /// }
354360784Sdim
355360784Sdim  /// Replace the current stream for verbose output.
356360784Sdim  void setVerboseOutputStream(raw_ostream &Value);
357360784Sdim
358360784Sdim  /// Replace the current stream for verbose output.
359360784Sdim  void setVerboseOutputStream(std::unique_ptr<raw_ostream> Value);
360360784Sdim
361360784Sdim  /// Get the current stream for verbose output.
362360784Sdim  raw_ostream &getVerboseOutputStream() {
363360784Sdim    return *VerboseOutputStream;
364360784Sdim  }
365360784Sdim
366360784Sdim  /// }
367199482Srdivacky  /// @name Target Info
368199482Srdivacky  /// {
369199482Srdivacky
370276479Sdim  bool hasTarget() const { return Target != nullptr; }
371199482Srdivacky
372199482Srdivacky  TargetInfo &getTarget() const {
373199482Srdivacky    assert(Target && "Compiler instance has no target!");
374199482Srdivacky    return *Target;
375199482Srdivacky  }
376199482Srdivacky
377296417Sdim  /// Replace the current Target.
378199482Srdivacky  void setTarget(TargetInfo *Value);
379199482Srdivacky
380199482Srdivacky  /// }
381296417Sdim  /// @name AuxTarget Info
382296417Sdim  /// {
383296417Sdim
384296417Sdim  TargetInfo *getAuxTarget() const { return AuxTarget.get(); }
385296417Sdim
386296417Sdim  /// Replace the current AuxTarget.
387296417Sdim  void setAuxTarget(TargetInfo *Value);
388296417Sdim
389296417Sdim  /// }
390276479Sdim  /// @name Virtual File System
391276479Sdim  /// {
392276479Sdim
393344779Sdim  llvm::vfs::FileSystem &getVirtualFileSystem() const {
394353358Sdim    return getFileManager().getVirtualFileSystem();
395276479Sdim  }
396276479Sdim
397276479Sdim  /// }
398199482Srdivacky  /// @name File Manager
399199482Srdivacky  /// {
400199482Srdivacky
401276479Sdim  bool hasFileManager() const { return FileMgr != nullptr; }
402199482Srdivacky
403221345Sdim  /// Return the current file manager to the caller.
404199482Srdivacky  FileManager &getFileManager() const {
405199482Srdivacky    assert(FileMgr && "Compiler instance has no file manager!");
406199482Srdivacky    return *FileMgr;
407199482Srdivacky  }
408341825Sdim
409221345Sdim  void resetAndLeakFileManager() {
410344779Sdim    llvm::BuryPointer(FileMgr.get());
411221345Sdim    FileMgr.resetWithoutRelease();
412221345Sdim  }
413199482Srdivacky
414341825Sdim  /// Replace the current file manager and virtual file system.
415199482Srdivacky  void setFileManager(FileManager *Value);
416199482Srdivacky
417199482Srdivacky  /// }
418199482Srdivacky  /// @name Source Manager
419199482Srdivacky  /// {
420199482Srdivacky
421276479Sdim  bool hasSourceManager() const { return SourceMgr != nullptr; }
422199482Srdivacky
423221345Sdim  /// Return the current source manager.
424199482Srdivacky  SourceManager &getSourceManager() const {
425199482Srdivacky    assert(SourceMgr && "Compiler instance has no source manager!");
426199482Srdivacky    return *SourceMgr;
427199482Srdivacky  }
428341825Sdim
429221345Sdim  void resetAndLeakSourceManager() {
430344779Sdim    llvm::BuryPointer(SourceMgr.get());
431221345Sdim    SourceMgr.resetWithoutRelease();
432221345Sdim  }
433199482Srdivacky
434221345Sdim  /// setSourceManager - Replace the current source manager.
435199482Srdivacky  void setSourceManager(SourceManager *Value);
436199482Srdivacky
437199482Srdivacky  /// }
438199482Srdivacky  /// @name Preprocessor
439199482Srdivacky  /// {
440199482Srdivacky
441276479Sdim  bool hasPreprocessor() const { return PP != nullptr; }
442199482Srdivacky
443221345Sdim  /// Return the current preprocessor.
444199482Srdivacky  Preprocessor &getPreprocessor() const {
445199482Srdivacky    assert(PP && "Compiler instance has no preprocessor!");
446199482Srdivacky    return *PP;
447199482Srdivacky  }
448199482Srdivacky
449314564Sdim  std::shared_ptr<Preprocessor> getPreprocessorPtr() { return PP; }
450314564Sdim
451221345Sdim  void resetAndLeakPreprocessor() {
452344779Sdim    llvm::BuryPointer(new std::shared_ptr<Preprocessor>(PP));
453221345Sdim  }
454199482Srdivacky
455221345Sdim  /// Replace the current preprocessor.
456314564Sdim  void setPreprocessor(std::shared_ptr<Preprocessor> Value);
457199482Srdivacky
458199482Srdivacky  /// }
459199482Srdivacky  /// @name ASTContext
460199482Srdivacky  /// {
461199482Srdivacky
462276479Sdim  bool hasASTContext() const { return Context != nullptr; }
463199482Srdivacky
464199482Srdivacky  ASTContext &getASTContext() const {
465199482Srdivacky    assert(Context && "Compiler instance has no AST context!");
466199482Srdivacky    return *Context;
467199482Srdivacky  }
468341825Sdim
469221345Sdim  void resetAndLeakASTContext() {
470344779Sdim    llvm::BuryPointer(Context.get());
471221345Sdim    Context.resetWithoutRelease();
472221345Sdim  }
473199482Srdivacky
474221345Sdim  /// setASTContext - Replace the current AST context.
475199482Srdivacky  void setASTContext(ASTContext *Value);
476199482Srdivacky
477341825Sdim  /// Replace the current Sema; the compiler instance takes ownership
478212904Sdim  /// of S.
479212904Sdim  void setSema(Sema *S);
480341825Sdim
481199482Srdivacky  /// }
482199482Srdivacky  /// @name ASTConsumer
483199482Srdivacky  /// {
484199482Srdivacky
485276479Sdim  bool hasASTConsumer() const { return (bool)Consumer; }
486199482Srdivacky
487199482Srdivacky  ASTConsumer &getASTConsumer() const {
488199482Srdivacky    assert(Consumer && "Compiler instance has no AST consumer!");
489199482Srdivacky    return *Consumer;
490199482Srdivacky  }
491199482Srdivacky
492199482Srdivacky  /// takeASTConsumer - Remove the current AST consumer and give ownership to
493199482Srdivacky  /// the caller.
494280031Sdim  std::unique_ptr<ASTConsumer> takeASTConsumer() { return std::move(Consumer); }
495199482Srdivacky
496199482Srdivacky  /// setASTConsumer - Replace the current AST consumer; the compiler instance
497243830Sdim  /// takes ownership of \p Value.
498280031Sdim  void setASTConsumer(std::unique_ptr<ASTConsumer> Value);
499199482Srdivacky
500199482Srdivacky  /// }
501212904Sdim  /// @name Semantic analysis
502212904Sdim  /// {
503276479Sdim  bool hasSema() const { return (bool)TheSema; }
504276479Sdim
505341825Sdim  Sema &getSema() const {
506212904Sdim    assert(TheSema && "Compiler instance has no Sema object!");
507212904Sdim    return *TheSema;
508212904Sdim  }
509276479Sdim
510280031Sdim  std::unique_ptr<Sema> takeSema();
511280031Sdim  void resetAndLeakSema();
512276479Sdim
513212904Sdim  /// }
514226633Sdim  /// @name Module Management
515226633Sdim  /// {
516226633Sdim
517360784Sdim  IntrusiveRefCntPtr<ASTReader> getASTReader() const;
518276479Sdim  void setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader);
519226633Sdim
520276479Sdim  std::shared_ptr<ModuleDependencyCollector> getModuleDepCollector() const;
521276479Sdim  void setModuleDepCollector(
522276479Sdim      std::shared_ptr<ModuleDependencyCollector> Collector);
523276479Sdim
524288943Sdim  std::shared_ptr<PCHContainerOperations> getPCHContainerOperations() const {
525288943Sdim    return ThePCHContainerOperations;
526288943Sdim  }
527288943Sdim
528288943Sdim  /// Return the appropriate PCHContainerWriter depending on the
529288943Sdim  /// current CodeGenOptions.
530288943Sdim  const PCHContainerWriter &getPCHContainerWriter() const {
531288943Sdim    assert(Invocation && "cannot determine module format without invocation");
532288943Sdim    StringRef Format = getHeaderSearchOpts().ModuleFormat;
533288943Sdim    auto *Writer = ThePCHContainerOperations->getWriterOrNull(Format);
534288943Sdim    if (!Writer) {
535288943Sdim      if (Diagnostics)
536288943Sdim        Diagnostics->Report(diag::err_module_format_unhandled) << Format;
537288943Sdim      llvm::report_fatal_error("unknown module format");
538288943Sdim    }
539288943Sdim    return *Writer;
540288943Sdim  }
541288943Sdim
542288943Sdim  /// Return the appropriate PCHContainerReader depending on the
543288943Sdim  /// current CodeGenOptions.
544288943Sdim  const PCHContainerReader &getPCHContainerReader() const {
545288943Sdim    assert(Invocation && "cannot determine module format without invocation");
546288943Sdim    StringRef Format = getHeaderSearchOpts().ModuleFormat;
547288943Sdim    auto *Reader = ThePCHContainerOperations->getReaderOrNull(Format);
548288943Sdim    if (!Reader) {
549288943Sdim      if (Diagnostics)
550288943Sdim        Diagnostics->Report(diag::err_module_format_unhandled) << Format;
551288943Sdim      llvm::report_fatal_error("unknown module format");
552288943Sdim    }
553288943Sdim    return *Reader;
554288943Sdim  }
555288943Sdim
556226633Sdim  /// }
557199482Srdivacky  /// @name Code Completion
558199482Srdivacky  /// {
559199482Srdivacky
560276479Sdim  bool hasCodeCompletionConsumer() const { return (bool)CompletionConsumer; }
561199482Srdivacky
562199482Srdivacky  CodeCompleteConsumer &getCodeCompletionConsumer() const {
563199482Srdivacky    assert(CompletionConsumer &&
564199482Srdivacky           "Compiler instance has no code completion consumer!");
565199482Srdivacky    return *CompletionConsumer;
566199482Srdivacky  }
567199482Srdivacky
568199482Srdivacky  /// setCodeCompletionConsumer - Replace the current code completion consumer;
569243830Sdim  /// the compiler instance takes ownership of \p Value.
570199482Srdivacky  void setCodeCompletionConsumer(CodeCompleteConsumer *Value);
571199482Srdivacky
572199482Srdivacky  /// }
573199990Srdivacky  /// @name Frontend timer
574199990Srdivacky  /// {
575199990Srdivacky
576276479Sdim  bool hasFrontendTimer() const { return (bool)FrontendTimer; }
577199990Srdivacky
578199990Srdivacky  llvm::Timer &getFrontendTimer() const {
579199990Srdivacky    assert(FrontendTimer && "Compiler instance has no frontend timer!");
580199990Srdivacky    return *FrontendTimer;
581199990Srdivacky  }
582199990Srdivacky
583199990Srdivacky  /// }
584199482Srdivacky  /// @name Output Files
585199482Srdivacky  /// {
586199482Srdivacky
587199482Srdivacky  /// addOutputFile - Add an output file onto the list of tracked output files.
588199482Srdivacky  ///
589218893Sdim  /// \param OutFile - The output file info.
590288943Sdim  void addOutputFile(OutputFile &&OutFile);
591199482Srdivacky
592309124Sdim  /// clearOutputFiles - Clear the output file list. The underlying output
593309124Sdim  /// streams must have been closed beforehand.
594199482Srdivacky  ///
595199482Srdivacky  /// \param EraseFiles - If true, attempt to erase the files from disk.
596204962Srdivacky  void clearOutputFiles(bool EraseFiles);
597199482Srdivacky
598199482Srdivacky  /// }
599199482Srdivacky  /// @name Construction Utility Methods
600199482Srdivacky  /// {
601199482Srdivacky
602199482Srdivacky  /// Create the diagnostics engine using the invocation's diagnostic options
603199482Srdivacky  /// and replace any existing one with it.
604199482Srdivacky  ///
605218893Sdim  /// Note that this routine also replaces the diagnostic client,
606218893Sdim  /// allocating one if one is not provided.
607218893Sdim  ///
608218893Sdim  /// \param Client If non-NULL, a diagnostic client that will be
609226633Sdim  /// attached to (and, then, owned by) the DiagnosticsEngine inside this AST
610218893Sdim  /// unit.
611226633Sdim  ///
612341825Sdim  /// \param ShouldOwnClient If Client is non-NULL, specifies whether
613226633Sdim  /// the diagnostic object should take ownership of the client.
614276479Sdim  void createDiagnostics(DiagnosticConsumer *Client = nullptr,
615251662Sdim                         bool ShouldOwnClient = true);
616199482Srdivacky
617226633Sdim  /// Create a DiagnosticsEngine object with a the TextDiagnosticPrinter.
618199482Srdivacky  ///
619218893Sdim  /// If no diagnostic client is provided, this creates a
620226633Sdim  /// DiagnosticConsumer that is owned by the returned diagnostic
621218893Sdim  /// object, if using directly the caller is responsible for
622226633Sdim  /// releasing the returned DiagnosticsEngine's client eventually.
623199482Srdivacky  ///
624200583Srdivacky  /// \param Opts - The diagnostic options; note that the created text
625243830Sdim  /// diagnostic object contains a reference to these options.
626200583Srdivacky  ///
627218893Sdim  /// \param Client If non-NULL, a diagnostic client that will be
628226633Sdim  /// attached to (and, then, owned by) the returned DiagnosticsEngine
629218893Sdim  /// object.
630218893Sdim  ///
631221345Sdim  /// \param CodeGenOpts If non-NULL, the code gen options in use, which may be
632221345Sdim  /// used by some diagnostics printers (for logging purposes only).
633221345Sdim  ///
634199482Srdivacky  /// \return The new object on success, or null on failure.
635234353Sdim  static IntrusiveRefCntPtr<DiagnosticsEngine>
636249423Sdim  createDiagnostics(DiagnosticOptions *Opts,
637276479Sdim                    DiagnosticConsumer *Client = nullptr,
638226633Sdim                    bool ShouldOwnClient = true,
639276479Sdim                    const CodeGenOptions *CodeGenOpts = nullptr);
640199482Srdivacky
641199482Srdivacky  /// Create the file manager and replace any existing one with it.
642327952Sdim  ///
643327952Sdim  /// \return The new file manager on success, or null on failure.
644353358Sdim  FileManager *
645353358Sdim  createFileManager(IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);
646199482Srdivacky
647199482Srdivacky  /// Create the source manager and replace any existing one with it.
648218893Sdim  void createSourceManager(FileManager &FileMgr);
649199482Srdivacky
650199482Srdivacky  /// Create the preprocessor, using the invocation, file, and source managers,
651199482Srdivacky  /// and replace any existing one with it.
652276479Sdim  void createPreprocessor(TranslationUnitKind TUKind);
653199482Srdivacky
654288943Sdim  std::string getSpecificModuleCachePath();
655288943Sdim
656199482Srdivacky  /// Create the AST context.
657199482Srdivacky  void createASTContext();
658199482Srdivacky
659199482Srdivacky  /// Create an external AST source to read a PCH file and attach it to the AST
660199482Srdivacky  /// context.
661276479Sdim  void createPCHExternalASTSource(StringRef Path, bool DisablePCHValidation,
662234353Sdim                                  bool AllowPCHWithCompilerErrors,
663276479Sdim                                  void *DeserializationListener,
664276479Sdim                                  bool OwnDeserializationListener);
665199482Srdivacky
666199482Srdivacky  /// Create an external AST source to read a PCH file.
667199482Srdivacky  ///
668199482Srdivacky  /// \return - The new object on success, or null on failure.
669288943Sdim  static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource(
670288943Sdim      StringRef Path, StringRef Sysroot, bool DisablePCHValidation,
671353358Sdim      bool AllowPCHWithCompilerErrors, Preprocessor &PP,
672353358Sdim      InMemoryModuleCache &ModuleCache, ASTContext &Context,
673288943Sdim      const PCHContainerReader &PCHContainerRdr,
674314564Sdim      ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
675321369Sdim      ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
676276479Sdim      void *DeserializationListener, bool OwnDeserializationListener,
677276479Sdim      bool Preamble, bool UseGlobalModuleIndex);
678199482Srdivacky
679199482Srdivacky  /// Create a code completion consumer using the invocation; note that this
680199482Srdivacky  /// will cause the source manager to truncate the input source file at the
681199482Srdivacky  /// completion point.
682199482Srdivacky  void createCodeCompletionConsumer();
683199482Srdivacky
684199482Srdivacky  /// Create a code completion consumer to print code completion results, at
685243830Sdim  /// \p Filename, \p Line, and \p Column, to the given output stream \p OS.
686288943Sdim  static CodeCompleteConsumer *createCodeCompletionConsumer(
687288943Sdim      Preprocessor &PP, StringRef Filename, unsigned Line, unsigned Column,
688288943Sdim      const CodeCompleteOptions &Opts, raw_ostream &OS);
689199482Srdivacky
690341825Sdim  /// Create the Sema object to be used for parsing.
691226633Sdim  void createSema(TranslationUnitKind TUKind,
692212904Sdim                  CodeCompleteConsumer *CompletionConsumer);
693341825Sdim
694199990Srdivacky  /// Create the frontend timer and replace any existing one with it.
695199990Srdivacky  void createFrontendTimer();
696199990Srdivacky
697199482Srdivacky  /// Create the default output file (from the invocation's options) and add it
698199482Srdivacky  /// to the list of tracked output files.
699200583Srdivacky  ///
700234353Sdim  /// The files created by this function always use temporary files to write to
701234353Sdim  /// their result (that is, the data is written to a temporary file which will
702234353Sdim  /// atomically replace the target output on success).
703234353Sdim  ///
704200583Srdivacky  /// \return - Null on error.
705309124Sdim  std::unique_ptr<raw_pwrite_stream>
706309124Sdim  createDefaultOutputFile(bool Binary = true, StringRef BaseInput = "",
707309124Sdim                          StringRef Extension = "");
708199482Srdivacky
709199482Srdivacky  /// Create a new output file and add it to the list of tracked output files,
710199482Srdivacky  /// optionally deriving the output path name.
711200583Srdivacky  ///
712200583Srdivacky  /// \return - Null on error.
713309124Sdim  std::unique_ptr<raw_pwrite_stream>
714309124Sdim  createOutputFile(StringRef OutputPath, bool Binary, bool RemoveFileOnSignal,
715309124Sdim                   StringRef BaseInput, StringRef Extension, bool UseTemporary,
716309124Sdim                   bool CreateMissingDirectories = false);
717199482Srdivacky
718199482Srdivacky  /// Create a new output file, optionally deriving the output path name.
719199482Srdivacky  ///
720243830Sdim  /// If \p OutputPath is empty, then createOutputFile will derive an output
721243830Sdim  /// path location as \p BaseInput, with any suffix removed, and \p Extension
722243830Sdim  /// appended. If \p OutputPath is not stdout and \p UseTemporary
723226633Sdim  /// is true, createOutputFile will create a new temporary file that must be
724243830Sdim  /// renamed to \p OutputPath in the end.
725199482Srdivacky  ///
726199482Srdivacky  /// \param OutputPath - If given, the path to the output file.
727280031Sdim  /// \param Error [out] - On failure, the error.
728243830Sdim  /// \param BaseInput - If \p OutputPath is empty, the input path name to use
729199482Srdivacky  /// for deriving the output path.
730199482Srdivacky  /// \param Extension - The extension to use for derived output names.
731199482Srdivacky  /// \param Binary - The mode to open the file in.
732218893Sdim  /// \param RemoveFileOnSignal - Whether the file should be registered with
733218893Sdim  /// llvm::sys::RemoveFileOnSignal. Note that this is not safe for
734218893Sdim  /// multithreaded use, as the underlying signal mechanism is not reentrant
735226633Sdim  /// \param UseTemporary - Create a new temporary file that must be renamed to
736234353Sdim  /// OutputPath in the end.
737243830Sdim  /// \param CreateMissingDirectories - When \p UseTemporary is true, create
738234353Sdim  /// missing directories in the output path.
739199482Srdivacky  /// \param ResultPathName [out] - If given, the result path name will be
740199482Srdivacky  /// stored here on success.
741218893Sdim  /// \param TempPathName [out] - If given, the temporary file path name
742218893Sdim  /// will be stored here on success.
743288943Sdim  std::unique_ptr<raw_pwrite_stream>
744280031Sdim  createOutputFile(StringRef OutputPath, std::error_code &Error, bool Binary,
745280031Sdim                   bool RemoveFileOnSignal, StringRef BaseInput,
746280031Sdim                   StringRef Extension, bool UseTemporary,
747280031Sdim                   bool CreateMissingDirectories, std::string *ResultPathName,
748261991Sdim                   std::string *TempPathName);
749199482Srdivacky
750309124Sdim  std::unique_ptr<raw_pwrite_stream> createNullOutputFile();
751276479Sdim
752199482Srdivacky  /// }
753199482Srdivacky  /// @name Initialization Utility Methods
754199482Srdivacky  /// {
755199482Srdivacky
756199482Srdivacky  /// InitializeSourceManager - Initialize the source manager to set InputFile
757199482Srdivacky  /// as the main file.
758199482Srdivacky  ///
759199482Srdivacky  /// \return True on success.
760243830Sdim  bool InitializeSourceManager(const FrontendInputFile &Input);
761199482Srdivacky
762199482Srdivacky  /// InitializeSourceManager - Initialize the source manager to set InputFile
763199482Srdivacky  /// as the main file.
764199482Srdivacky  ///
765199482Srdivacky  /// \return True on success.
766243830Sdim  static bool InitializeSourceManager(const FrontendInputFile &Input,
767309124Sdim                                      DiagnosticsEngine &Diags,
768309124Sdim                                      FileManager &FileMgr,
769309124Sdim                                      SourceManager &SourceMgr,
770309124Sdim                                      HeaderSearch *HS,
771309124Sdim                                      DependencyOutputOptions &DepOpts,
772309124Sdim                                      const FrontendOptions &Opts);
773199482Srdivacky
774199482Srdivacky  /// }
775249423Sdim
776341825Sdim  void setOutputStream(std::unique_ptr<llvm::raw_pwrite_stream> OutStream) {
777341825Sdim    OutputStream = std::move(OutStream);
778341825Sdim  }
779341825Sdim
780341825Sdim  std::unique_ptr<llvm::raw_pwrite_stream> takeOutputStream() {
781341825Sdim    return std::move(OutputStream);
782341825Sdim  }
783341825Sdim
784276479Sdim  // Create module manager.
785360784Sdim  void createASTReader();
786249423Sdim
787280031Sdim  bool loadModuleFile(StringRef FileName);
788280031Sdim
789360784Sdimprivate:
790360784Sdim  /// Find a module, potentially compiling it, before reading its AST.  This is
791360784Sdim  /// the guts of loadModule.
792360784Sdim  ///
793360784Sdim  /// For prebuilt modules, the Module is not expected to exist in
794360784Sdim  /// HeaderSearch's ModuleMap.  If a ModuleFile by that name is in the
795360784Sdim  /// ModuleManager, then it will be loaded and looked up.
796360784Sdim  ///
797360784Sdim  /// For implicit modules, the Module is expected to already be in the
798360784Sdim  /// ModuleMap.  First attempt to load it from the given path on disk.  If that
799360784Sdim  /// fails, defer to compileModuleAndReadAST, which will first build and then
800360784Sdim  /// load it.
801360784Sdim  ModuleLoadResult findOrCompileModuleAndReadAST(StringRef ModuleName,
802360784Sdim                                                 SourceLocation ImportLoc,
803360784Sdim                                                 SourceLocation ModuleNameLoc,
804360784Sdim                                                 bool IsInclusionDirective);
805360784Sdim
806360784Sdimpublic:
807276479Sdim  ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
808276479Sdim                              Module::NameVisibilityKind Visibility,
809276479Sdim                              bool IsInclusionDirective) override;
810276479Sdim
811360784Sdim  void createModuleFromSource(SourceLocation ImportLoc, StringRef ModuleName,
812360784Sdim                              StringRef Source) override;
813321369Sdim
814276479Sdim  void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility,
815288943Sdim                         SourceLocation ImportLoc) override;
816276479Sdim
817261991Sdim  bool hadModuleLoaderFatalFailure() const {
818261991Sdim    return ModuleLoader::HadFatalFailure;
819261991Sdim  }
820261991Sdim
821276479Sdim  GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override;
822276479Sdim
823276479Sdim  bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override;
824276479Sdim
825276479Sdim  void addDependencyCollector(std::shared_ptr<DependencyCollector> Listener) {
826276479Sdim    DependencyCollectors.push_back(std::move(Listener));
827276479Sdim  }
828314564Sdim
829314564Sdim  void setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS);
830321369Sdim
831353358Sdim  InMemoryModuleCache &getModuleCache() const { return *ModuleCache; }
832199482Srdivacky};
833199482Srdivacky
834199482Srdivacky} // end namespace clang
835199482Srdivacky
836199482Srdivacky#endif
837