• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- CompilerInstance.h - Clang Compiler Instance ------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
11 #define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
12 
13 #include "clang/Frontend/CompilerInvocation.h"
14 #include "llvm/ADT/IntrusiveRefCntPtr.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/ADT/OwningPtr.h"
17 #include <cassert>
18 #include <list>
19 #include <string>
20 
21 namespace llvm {
22 class raw_ostream;
23 class raw_fd_ostream;
24 class Timer;
25 }
26 
27 namespace clang {
28 class ASTContext;
29 class ASTConsumer;
30 class ASTReader;
31 class CodeCompleteConsumer;
32 class Diagnostic;
33 class DiagnosticClient;
34 class ExternalASTSource;
35 class FileManager;
36 class FrontendAction;
37 class Preprocessor;
38 class Sema;
39 class SourceManager;
40 class TargetInfo;
41 
42 /// CompilerInstance - Helper class for managing a single instance of the Clang
43 /// compiler.
44 ///
45 /// The CompilerInstance serves two purposes:
46 ///  (1) It manages the various objects which are necessary to run the compiler,
47 ///      for example the preprocessor, the target information, and the AST
48 ///      context.
49 ///  (2) It provides utility routines for constructing and manipulating the
50 ///      common Clang objects.
51 ///
52 /// The compiler instance generally owns the instance of all the objects that it
53 /// manages. However, clients can still share objects by manually setting the
54 /// object and retaking ownership prior to destroying the CompilerInstance.
55 ///
56 /// The compiler instance is intended to simplify clients, but not to lock them
57 /// in to the compiler instance for everything. When possible, utility functions
58 /// come in two forms; a short form that reuses the CompilerInstance objects,
59 /// and a long form that takes explicit instances of any required objects.
60 class CompilerInstance {
61   /// The options used in this compiler instance.
62   llvm::IntrusiveRefCntPtr<CompilerInvocation> Invocation;
63 
64   /// The diagnostics engine instance.
65   llvm::IntrusiveRefCntPtr<Diagnostic> Diagnostics;
66 
67   /// The target being compiled for.
68   llvm::IntrusiveRefCntPtr<TargetInfo> Target;
69 
70   /// The file manager.
71   llvm::IntrusiveRefCntPtr<FileManager> FileMgr;
72 
73   /// The source manager.
74   llvm::IntrusiveRefCntPtr<SourceManager> SourceMgr;
75 
76   /// The preprocessor.
77   llvm::IntrusiveRefCntPtr<Preprocessor> PP;
78 
79   /// The AST context.
80   llvm::IntrusiveRefCntPtr<ASTContext> Context;
81 
82   /// The AST consumer.
83   llvm::OwningPtr<ASTConsumer> Consumer;
84 
85   /// The code completion consumer.
86   llvm::OwningPtr<CodeCompleteConsumer> CompletionConsumer;
87 
88   /// \brief The semantic analysis object.
89   llvm::OwningPtr<Sema> TheSema;
90 
91   /// \brief The frontend timer
92   llvm::OwningPtr<llvm::Timer> FrontendTimer;
93 
94   /// \brief Non-owning reference to the ASTReader, if one exists.
95   ASTReader *ModuleManager;
96 
97   /// \brief Holds information about the output file.
98   ///
99   /// If TempFilename is not empty we must rename it to Filename at the end.
100   /// TempFilename may be empty and Filename non empty if creating the temporary
101   /// failed.
102   struct OutputFile {
103     std::string Filename;
104     std::string TempFilename;
105     llvm::raw_ostream *OS;
106 
OutputFileOutputFile107     OutputFile(const std::string &filename, const std::string &tempFilename,
108                llvm::raw_ostream *os)
109       : Filename(filename), TempFilename(tempFilename), OS(os) { }
110   };
111 
112   /// The list of active output files.
113   std::list<OutputFile> OutputFiles;
114 
115   void operator=(const CompilerInstance &);  // DO NOT IMPLEMENT
116   CompilerInstance(const CompilerInstance&); // DO NOT IMPLEMENT
117 public:
118   CompilerInstance();
119   ~CompilerInstance();
120 
121   /// @name High-Level Operations
122   /// {
123 
124   /// ExecuteAction - Execute the provided action against the compiler's
125   /// CompilerInvocation object.
126   ///
127   /// This function makes the following assumptions:
128   ///
129   ///  - The invocation options should be initialized. This function does not
130   ///    handle the '-help' or '-version' options, clients should handle those
131   ///    directly.
132   ///
133   ///  - The diagnostics engine should have already been created by the client.
134   ///
135   ///  - No other CompilerInstance state should have been initialized (this is
136   ///    an unchecked error).
137   ///
138   ///  - Clients should have initialized any LLVM target features that may be
139   ///    required.
140   ///
141   ///  - Clients should eventually call llvm_shutdown() upon the completion of
142   ///    this routine to ensure that any managed objects are properly destroyed.
143   ///
144   /// Note that this routine may write output to 'stderr'.
145   ///
146   /// \param Act - The action to execute.
147   /// \return - True on success.
148   //
149   // FIXME: This function should take the stream to write any debugging /
150   // verbose output to as an argument.
151   //
152   // FIXME: Eliminate the llvm_shutdown requirement, that should either be part
153   // of the context or else not CompilerInstance specific.
154   bool ExecuteAction(FrontendAction &Act);
155 
156   /// }
157   /// @name Compiler Invocation and Options
158   /// {
159 
hasInvocation()160   bool hasInvocation() const { return Invocation != 0; }
161 
getInvocation()162   CompilerInvocation &getInvocation() {
163     assert(Invocation && "Compiler instance has no invocation!");
164     return *Invocation;
165   }
166 
167   /// setInvocation - Replace the current invocation.
168   void setInvocation(CompilerInvocation *Value);
169 
170   /// }
171   /// @name Forwarding Methods
172   /// {
173 
getAnalyzerOpts()174   AnalyzerOptions &getAnalyzerOpts() {
175     return Invocation->getAnalyzerOpts();
176   }
getAnalyzerOpts()177   const AnalyzerOptions &getAnalyzerOpts() const {
178     return Invocation->getAnalyzerOpts();
179   }
180 
getCodeGenOpts()181   CodeGenOptions &getCodeGenOpts() {
182     return Invocation->getCodeGenOpts();
183   }
getCodeGenOpts()184   const CodeGenOptions &getCodeGenOpts() const {
185     return Invocation->getCodeGenOpts();
186   }
187 
getDependencyOutputOpts()188   DependencyOutputOptions &getDependencyOutputOpts() {
189     return Invocation->getDependencyOutputOpts();
190   }
getDependencyOutputOpts()191   const DependencyOutputOptions &getDependencyOutputOpts() const {
192     return Invocation->getDependencyOutputOpts();
193   }
194 
getDiagnosticOpts()195   DiagnosticOptions &getDiagnosticOpts() {
196     return Invocation->getDiagnosticOpts();
197   }
getDiagnosticOpts()198   const DiagnosticOptions &getDiagnosticOpts() const {
199     return Invocation->getDiagnosticOpts();
200   }
201 
getFileSystemOpts()202   const FileSystemOptions &getFileSystemOpts() const {
203     return Invocation->getFileSystemOpts();
204   }
205 
getFrontendOpts()206   FrontendOptions &getFrontendOpts() {
207     return Invocation->getFrontendOpts();
208   }
getFrontendOpts()209   const FrontendOptions &getFrontendOpts() const {
210     return Invocation->getFrontendOpts();
211   }
212 
getHeaderSearchOpts()213   HeaderSearchOptions &getHeaderSearchOpts() {
214     return Invocation->getHeaderSearchOpts();
215   }
getHeaderSearchOpts()216   const HeaderSearchOptions &getHeaderSearchOpts() const {
217     return Invocation->getHeaderSearchOpts();
218   }
219 
getLangOpts()220   LangOptions &getLangOpts() {
221     return Invocation->getLangOpts();
222   }
getLangOpts()223   const LangOptions &getLangOpts() const {
224     return Invocation->getLangOpts();
225   }
226 
getPreprocessorOpts()227   PreprocessorOptions &getPreprocessorOpts() {
228     return Invocation->getPreprocessorOpts();
229   }
getPreprocessorOpts()230   const PreprocessorOptions &getPreprocessorOpts() const {
231     return Invocation->getPreprocessorOpts();
232   }
233 
getPreprocessorOutputOpts()234   PreprocessorOutputOptions &getPreprocessorOutputOpts() {
235     return Invocation->getPreprocessorOutputOpts();
236   }
getPreprocessorOutputOpts()237   const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
238     return Invocation->getPreprocessorOutputOpts();
239   }
240 
getTargetOpts()241   TargetOptions &getTargetOpts() {
242     return Invocation->getTargetOpts();
243   }
getTargetOpts()244   const TargetOptions &getTargetOpts() const {
245     return Invocation->getTargetOpts();
246   }
247 
248   /// }
249   /// @name Diagnostics Engine
250   /// {
251 
hasDiagnostics()252   bool hasDiagnostics() const { return Diagnostics != 0; }
253 
254   /// Get the current diagnostics engine.
getDiagnostics()255   Diagnostic &getDiagnostics() const {
256     assert(Diagnostics && "Compiler instance has no diagnostics!");
257     return *Diagnostics;
258   }
259 
260   /// setDiagnostics - Replace the current diagnostics engine.
261   void setDiagnostics(Diagnostic *Value);
262 
getDiagnosticClient()263   DiagnosticClient &getDiagnosticClient() const {
264     assert(Diagnostics && Diagnostics->getClient() &&
265            "Compiler instance has no diagnostic client!");
266     return *Diagnostics->getClient();
267   }
268 
269   /// }
270   /// @name Target Info
271   /// {
272 
hasTarget()273   bool hasTarget() const { return Target != 0; }
274 
getTarget()275   TargetInfo &getTarget() const {
276     assert(Target && "Compiler instance has no target!");
277     return *Target;
278   }
279 
280   /// Replace the current diagnostics engine.
281   void setTarget(TargetInfo *Value);
282 
283   /// }
284   /// @name File Manager
285   /// {
286 
hasFileManager()287   bool hasFileManager() const { return FileMgr != 0; }
288 
289   /// Return the current file manager to the caller.
getFileManager()290   FileManager &getFileManager() const {
291     assert(FileMgr && "Compiler instance has no file manager!");
292     return *FileMgr;
293   }
294 
resetAndLeakFileManager()295   void resetAndLeakFileManager() {
296     FileMgr.resetWithoutRelease();
297   }
298 
299   /// setFileManager - Replace the current file manager.
300   void setFileManager(FileManager *Value);
301 
302   /// }
303   /// @name Source Manager
304   /// {
305 
hasSourceManager()306   bool hasSourceManager() const { return SourceMgr != 0; }
307 
308   /// Return the current source manager.
getSourceManager()309   SourceManager &getSourceManager() const {
310     assert(SourceMgr && "Compiler instance has no source manager!");
311     return *SourceMgr;
312   }
313 
resetAndLeakSourceManager()314   void resetAndLeakSourceManager() {
315     SourceMgr.resetWithoutRelease();
316   }
317 
318   /// setSourceManager - Replace the current source manager.
319   void setSourceManager(SourceManager *Value);
320 
321   /// }
322   /// @name Preprocessor
323   /// {
324 
hasPreprocessor()325   bool hasPreprocessor() const { return PP != 0; }
326 
327   /// Return the current preprocessor.
getPreprocessor()328   Preprocessor &getPreprocessor() const {
329     assert(PP && "Compiler instance has no preprocessor!");
330     return *PP;
331   }
332 
resetAndLeakPreprocessor()333   void resetAndLeakPreprocessor() {
334     PP.resetWithoutRelease();
335   }
336 
337   /// Replace the current preprocessor.
338   void setPreprocessor(Preprocessor *Value);
339 
340   /// }
341   /// @name ASTContext
342   /// {
343 
hasASTContext()344   bool hasASTContext() const { return Context != 0; }
345 
getASTContext()346   ASTContext &getASTContext() const {
347     assert(Context && "Compiler instance has no AST context!");
348     return *Context;
349   }
350 
resetAndLeakASTContext()351   void resetAndLeakASTContext() {
352     Context.resetWithoutRelease();
353   }
354 
355   /// setASTContext - Replace the current AST context.
356   void setASTContext(ASTContext *Value);
357 
358   /// \brief Replace the current Sema; the compiler instance takes ownership
359   /// of S.
360   void setSema(Sema *S);
361 
362   /// }
363   /// @name ASTConsumer
364   /// {
365 
hasASTConsumer()366   bool hasASTConsumer() const { return Consumer != 0; }
367 
getASTConsumer()368   ASTConsumer &getASTConsumer() const {
369     assert(Consumer && "Compiler instance has no AST consumer!");
370     return *Consumer;
371   }
372 
373   /// takeASTConsumer - Remove the current AST consumer and give ownership to
374   /// the caller.
takeASTConsumer()375   ASTConsumer *takeASTConsumer() { return Consumer.take(); }
376 
377   /// setASTConsumer - Replace the current AST consumer; the compiler instance
378   /// takes ownership of \arg Value.
379   void setASTConsumer(ASTConsumer *Value);
380 
381   /// }
382   /// @name Semantic analysis
383   /// {
hasSema()384   bool hasSema() const { return TheSema != 0; }
385 
getSema()386   Sema &getSema() const {
387     assert(TheSema && "Compiler instance has no Sema object!");
388     return *TheSema;
389   }
390 
takeSema()391   Sema *takeSema() { return TheSema.take(); }
392 
393   /// }
394   /// @name Module Management
395   /// {
396 
getModuleManager()397   ASTReader *getModuleManager() const { return ModuleManager; }
398 
399   /// }
400   /// @name Code Completion
401   /// {
402 
hasCodeCompletionConsumer()403   bool hasCodeCompletionConsumer() const { return CompletionConsumer != 0; }
404 
getCodeCompletionConsumer()405   CodeCompleteConsumer &getCodeCompletionConsumer() const {
406     assert(CompletionConsumer &&
407            "Compiler instance has no code completion consumer!");
408     return *CompletionConsumer;
409   }
410 
411   /// takeCodeCompletionConsumer - Remove the current code completion consumer
412   /// and give ownership to the caller.
takeCodeCompletionConsumer()413   CodeCompleteConsumer *takeCodeCompletionConsumer() {
414     return CompletionConsumer.take();
415   }
416 
417   /// setCodeCompletionConsumer - Replace the current code completion consumer;
418   /// the compiler instance takes ownership of \arg Value.
419   void setCodeCompletionConsumer(CodeCompleteConsumer *Value);
420 
421   /// }
422   /// @name Frontend timer
423   /// {
424 
hasFrontendTimer()425   bool hasFrontendTimer() const { return FrontendTimer != 0; }
426 
getFrontendTimer()427   llvm::Timer &getFrontendTimer() const {
428     assert(FrontendTimer && "Compiler instance has no frontend timer!");
429     return *FrontendTimer;
430   }
431 
432   /// }
433   /// @name Output Files
434   /// {
435 
436   /// addOutputFile - Add an output file onto the list of tracked output files.
437   ///
438   /// \param OutFile - The output file info.
439   void addOutputFile(const OutputFile &OutFile);
440 
441   /// clearOutputFiles - Clear the output file list, destroying the contained
442   /// output streams.
443   ///
444   /// \param EraseFiles - If true, attempt to erase the files from disk.
445   void clearOutputFiles(bool EraseFiles);
446 
447   /// }
448   /// @name Construction Utility Methods
449   /// {
450 
451   /// Create the diagnostics engine using the invocation's diagnostic options
452   /// and replace any existing one with it.
453   ///
454   /// Note that this routine also replaces the diagnostic client,
455   /// allocating one if one is not provided.
456   ///
457   /// \param Client If non-NULL, a diagnostic client that will be
458   /// attached to (and, then, owned by) the Diagnostic inside this AST
459   /// unit.
460   void createDiagnostics(int Argc, const char* const *Argv,
461                          DiagnosticClient *Client = 0);
462 
463   /// Create a Diagnostic object with a the TextDiagnosticPrinter.
464   ///
465   /// The \arg Argc and \arg Argv arguments are used only for logging purposes,
466   /// when the diagnostic options indicate that the compiler should output
467   /// logging information.
468   ///
469   /// If no diagnostic client is provided, this creates a
470   /// DiagnosticClient that is owned by the returned diagnostic
471   /// object, if using directly the caller is responsible for
472   /// releasing the returned Diagnostic's client eventually.
473   ///
474   /// \param Opts - The diagnostic options; note that the created text
475   /// diagnostic object contains a reference to these options and its lifetime
476   /// must extend past that of the diagnostic engine.
477   ///
478   /// \param Client If non-NULL, a diagnostic client that will be
479   /// attached to (and, then, owned by) the returned Diagnostic
480   /// object.
481   ///
482   /// \param CodeGenOpts If non-NULL, the code gen options in use, which may be
483   /// used by some diagnostics printers (for logging purposes only).
484   ///
485   /// \return The new object on success, or null on failure.
486   static llvm::IntrusiveRefCntPtr<Diagnostic>
487   createDiagnostics(const DiagnosticOptions &Opts, int Argc,
488                     const char* const *Argv,
489                     DiagnosticClient *Client = 0,
490                     const CodeGenOptions *CodeGenOpts = 0);
491 
492   /// Create the file manager and replace any existing one with it.
493   void createFileManager();
494 
495   /// Create the source manager and replace any existing one with it.
496   void createSourceManager(FileManager &FileMgr);
497 
498   /// Create the preprocessor, using the invocation, file, and source managers,
499   /// and replace any existing one with it.
500   void createPreprocessor();
501 
502   /// Create a Preprocessor object.
503   ///
504   /// Note that this also creates a new HeaderSearch object which will be owned
505   /// by the resulting Preprocessor.
506   ///
507   /// \return The new object on success, or null on failure.
508   static Preprocessor *createPreprocessor(Diagnostic &, const LangOptions &,
509                                           const PreprocessorOptions &,
510                                           const HeaderSearchOptions &,
511                                           const DependencyOutputOptions &,
512                                           const TargetInfo &,
513                                           const FrontendOptions &,
514                                           SourceManager &, FileManager &);
515 
516   /// Create the AST context.
517   void createASTContext();
518 
519   /// Create an external AST source to read a PCH file and attach it to the AST
520   /// context.
521   void createPCHExternalASTSource(llvm::StringRef Path,
522                                   bool DisablePCHValidation,
523                                   bool DisableStatCache,
524                                   void *DeserializationListener);
525 
526   /// Create an external AST source to read a PCH file.
527   ///
528   /// \return - The new object on success, or null on failure.
529   static ExternalASTSource *
530   createPCHExternalASTSource(llvm::StringRef Path, const std::string &Sysroot,
531                              bool DisablePCHValidation,
532                              bool DisableStatCache,
533                              Preprocessor &PP, ASTContext &Context,
534                              void *DeserializationListener, bool Preamble);
535 
536   /// Create a code completion consumer using the invocation; note that this
537   /// will cause the source manager to truncate the input source file at the
538   /// completion point.
539   void createCodeCompletionConsumer();
540 
541   /// Create a code completion consumer to print code completion results, at
542   /// \arg Filename, \arg Line, and \arg Column, to the given output stream \arg
543   /// OS.
544   static CodeCompleteConsumer *
545   createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename,
546                                unsigned Line, unsigned Column,
547                                bool ShowMacros,
548                                bool ShowCodePatterns, bool ShowGlobals,
549                                llvm::raw_ostream &OS);
550 
551   /// \brief Create the Sema object to be used for parsing.
552   void createSema(bool CompleteTranslationUnit,
553                   CodeCompleteConsumer *CompletionConsumer);
554 
555   /// Create the frontend timer and replace any existing one with it.
556   void createFrontendTimer();
557 
558   /// Create the default output file (from the invocation's options) and add it
559   /// to the list of tracked output files.
560   ///
561   /// \return - Null on error.
562   llvm::raw_fd_ostream *
563   createDefaultOutputFile(bool Binary = true, llvm::StringRef BaseInput = "",
564                           llvm::StringRef Extension = "");
565 
566   /// Create a new output file and add it to the list of tracked output files,
567   /// optionally deriving the output path name.
568   ///
569   /// \return - Null on error.
570   llvm::raw_fd_ostream *
571   createOutputFile(llvm::StringRef OutputPath,
572                    bool Binary = true, bool RemoveFileOnSignal = true,
573                    llvm::StringRef BaseInput = "",
574                    llvm::StringRef Extension = "");
575 
576   /// Create a new output file, optionally deriving the output path name.
577   ///
578   /// If \arg OutputPath is empty, then createOutputFile will derive an output
579   /// path location as \arg BaseInput, with any suffix removed, and \arg
580   /// Extension appended. If OutputPath is not stdout createOutputFile will
581   /// create a new temporary file that must be renamed to OutputPath in the end.
582   ///
583   /// \param OutputPath - If given, the path to the output file.
584   /// \param Error [out] - On failure, the error message.
585   /// \param BaseInput - If \arg OutputPath is empty, the input path name to use
586   /// for deriving the output path.
587   /// \param Extension - The extension to use for derived output names.
588   /// \param Binary - The mode to open the file in.
589   /// \param RemoveFileOnSignal - Whether the file should be registered with
590   /// llvm::sys::RemoveFileOnSignal. Note that this is not safe for
591   /// multithreaded use, as the underlying signal mechanism is not reentrant
592   /// \param ResultPathName [out] - If given, the result path name will be
593   /// stored here on success.
594   /// \param TempPathName [out] - If given, the temporary file path name
595   /// will be stored here on success.
596   static llvm::raw_fd_ostream *
597   createOutputFile(llvm::StringRef OutputPath, std::string &Error,
598                    bool Binary = true, bool RemoveFileOnSignal = true,
599                    llvm::StringRef BaseInput = "",
600                    llvm::StringRef Extension = "",
601                    std::string *ResultPathName = 0,
602                    std::string *TempPathName = 0);
603 
604   /// }
605   /// @name Initialization Utility Methods
606   /// {
607 
608   /// InitializeSourceManager - Initialize the source manager to set InputFile
609   /// as the main file.
610   ///
611   /// \return True on success.
612   bool InitializeSourceManager(llvm::StringRef InputFile);
613 
614   /// InitializeSourceManager - Initialize the source manager to set InputFile
615   /// as the main file.
616   ///
617   /// \return True on success.
618   static bool InitializeSourceManager(llvm::StringRef InputFile,
619                                       Diagnostic &Diags,
620                                       FileManager &FileMgr,
621                                       SourceManager &SourceMgr,
622                                       const FrontendOptions &Opts);
623 
624   /// }
625 };
626 
627 } // end namespace clang
628 
629 #endif
630