CompilerInstance.h revision 218893
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
21namespace llvm {
22class raw_ostream;
23class raw_fd_ostream;
24class Timer;
25}
26
27namespace clang {
28class ASTContext;
29class ASTConsumer;
30class CodeCompleteConsumer;
31class Diagnostic;
32class DiagnosticClient;
33class ExternalASTSource;
34class FileManager;
35class FrontendAction;
36class ASTReader;
37class Preprocessor;
38class Sema;
39class SourceManager;
40class 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.
60class CompilerInstance {
61  /// The options used in this compiler instance.
62  llvm::OwningPtr<CompilerInvocation> Invocation;
63
64  /// The diagnostics engine instance.
65  llvm::IntrusiveRefCntPtr<Diagnostic> Diagnostics;
66
67  /// The target being compiled for.
68  llvm::OwningPtr<TargetInfo> Target;
69
70  /// The file manager.
71  llvm::OwningPtr<FileManager> FileMgr;
72
73  /// The source manager.
74  llvm::OwningPtr<SourceManager> SourceMgr;
75
76  /// The preprocessor.
77  llvm::OwningPtr<Preprocessor> PP;
78
79  /// The AST context.
80  llvm::OwningPtr<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  /// The frontend timer
92  llvm::OwningPtr<llvm::Timer> FrontendTimer;
93
94  /// \brief Holds information about the output file.
95  ///
96  /// If TempFilename is not empty we must rename it to Filename at the end.
97  /// TempFilename may be empty and Filename non empty if creating the temporary
98  /// failed.
99  struct OutputFile {
100    std::string Filename;
101    std::string TempFilename;
102    llvm::raw_ostream *OS;
103
104    OutputFile(const std::string &filename, const std::string &tempFilename,
105               llvm::raw_ostream *os)
106      : Filename(filename), TempFilename(tempFilename), OS(os) { }
107  };
108
109  /// The list of active output files.
110  std::list<OutputFile> OutputFiles;
111
112  void operator=(const CompilerInstance &);  // DO NOT IMPLEMENT
113  CompilerInstance(const CompilerInstance&); // DO NOT IMPLEMENT
114public:
115  CompilerInstance();
116  ~CompilerInstance();
117
118  /// @name High-Level Operations
119  /// {
120
121  /// ExecuteAction - Execute the provided action against the compiler's
122  /// CompilerInvocation object.
123  ///
124  /// This function makes the following assumptions:
125  ///
126  ///  - The invocation options should be initialized. This function does not
127  ///    handle the '-help' or '-version' options, clients should handle those
128  ///    directly.
129  ///
130  ///  - The diagnostics engine should have already been created by the client.
131  ///
132  ///  - No other CompilerInstance state should have been initialized (this is
133  ///    an unchecked error).
134  ///
135  ///  - Clients should have initialized any LLVM target features that may be
136  ///    required.
137  ///
138  ///  - Clients should eventually call llvm_shutdown() upon the completion of
139  ///    this routine to ensure that any managed objects are properly destroyed.
140  ///
141  /// Note that this routine may write output to 'stderr'.
142  ///
143  /// \param Act - The action to execute.
144  /// \return - True on success.
145  //
146  // FIXME: This function should take the stream to write any debugging /
147  // verbose output to as an argument.
148  //
149  // FIXME: Eliminate the llvm_shutdown requirement, that should either be part
150  // of the context or else not CompilerInstance specific.
151  bool ExecuteAction(FrontendAction &Act);
152
153  /// }
154  /// @name Compiler Invocation and Options
155  /// {
156
157  bool hasInvocation() const { return Invocation != 0; }
158
159  CompilerInvocation &getInvocation() {
160    assert(Invocation && "Compiler instance has no invocation!");
161    return *Invocation;
162  }
163
164  CompilerInvocation *takeInvocation() { return Invocation.take(); }
165
166  /// setInvocation - Replace the current invocation; the compiler instance
167  /// takes ownership of \arg Value.
168  void setInvocation(CompilerInvocation *Value);
169
170  /// }
171  /// @name Forwarding Methods
172  /// {
173
174  AnalyzerOptions &getAnalyzerOpts() {
175    return Invocation->getAnalyzerOpts();
176  }
177  const AnalyzerOptions &getAnalyzerOpts() const {
178    return Invocation->getAnalyzerOpts();
179  }
180
181  CodeGenOptions &getCodeGenOpts() {
182    return Invocation->getCodeGenOpts();
183  }
184  const CodeGenOptions &getCodeGenOpts() const {
185    return Invocation->getCodeGenOpts();
186  }
187
188  DependencyOutputOptions &getDependencyOutputOpts() {
189    return Invocation->getDependencyOutputOpts();
190  }
191  const DependencyOutputOptions &getDependencyOutputOpts() const {
192    return Invocation->getDependencyOutputOpts();
193  }
194
195  DiagnosticOptions &getDiagnosticOpts() {
196    return Invocation->getDiagnosticOpts();
197  }
198  const DiagnosticOptions &getDiagnosticOpts() const {
199    return Invocation->getDiagnosticOpts();
200  }
201
202  const FileSystemOptions &getFileSystemOpts() const {
203    return Invocation->getFileSystemOpts();
204  }
205
206  FrontendOptions &getFrontendOpts() {
207    return Invocation->getFrontendOpts();
208  }
209  const FrontendOptions &getFrontendOpts() const {
210    return Invocation->getFrontendOpts();
211  }
212
213  HeaderSearchOptions &getHeaderSearchOpts() {
214    return Invocation->getHeaderSearchOpts();
215  }
216  const HeaderSearchOptions &getHeaderSearchOpts() const {
217    return Invocation->getHeaderSearchOpts();
218  }
219
220  LangOptions &getLangOpts() {
221    return Invocation->getLangOpts();
222  }
223  const LangOptions &getLangOpts() const {
224    return Invocation->getLangOpts();
225  }
226
227  PreprocessorOptions &getPreprocessorOpts() {
228    return Invocation->getPreprocessorOpts();
229  }
230  const PreprocessorOptions &getPreprocessorOpts() const {
231    return Invocation->getPreprocessorOpts();
232  }
233
234  PreprocessorOutputOptions &getPreprocessorOutputOpts() {
235    return Invocation->getPreprocessorOutputOpts();
236  }
237  const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
238    return Invocation->getPreprocessorOutputOpts();
239  }
240
241  TargetOptions &getTargetOpts() {
242    return Invocation->getTargetOpts();
243  }
244  const TargetOptions &getTargetOpts() const {
245    return Invocation->getTargetOpts();
246  }
247
248  /// }
249  /// @name Diagnostics Engine
250  /// {
251
252  bool hasDiagnostics() const { return Diagnostics != 0; }
253
254  Diagnostic &getDiagnostics() const {
255    assert(Diagnostics && "Compiler instance has no diagnostics!");
256    return *Diagnostics;
257  }
258
259  /// setDiagnostics - Replace the current diagnostics engine; the compiler
260  /// instance takes ownership of \arg Value.
261  void setDiagnostics(Diagnostic *Value);
262
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
273  bool hasTarget() const { return Target != 0; }
274
275  TargetInfo &getTarget() const {
276    assert(Target && "Compiler instance has no target!");
277    return *Target;
278  }
279
280  /// takeTarget - Remove the current diagnostics engine and give ownership
281  /// to the caller.
282  TargetInfo *takeTarget() { return Target.take(); }
283
284  /// setTarget - Replace the current diagnostics engine; the compiler
285  /// instance takes ownership of \arg Value.
286  void setTarget(TargetInfo *Value);
287
288  /// }
289  /// @name File Manager
290  /// {
291
292  bool hasFileManager() const { return FileMgr != 0; }
293
294  FileManager &getFileManager() const {
295    assert(FileMgr && "Compiler instance has no file manager!");
296    return *FileMgr;
297  }
298
299  /// takeFileManager - Remove the current file manager and give ownership to
300  /// the caller.
301  FileManager *takeFileManager() { return FileMgr.take(); }
302
303  /// setFileManager - Replace the current file manager; the compiler instance
304  /// takes ownership of \arg Value.
305  void setFileManager(FileManager *Value);
306
307  /// }
308  /// @name Source Manager
309  /// {
310
311  bool hasSourceManager() const { return SourceMgr != 0; }
312
313  SourceManager &getSourceManager() const {
314    assert(SourceMgr && "Compiler instance has no source manager!");
315    return *SourceMgr;
316  }
317
318  /// takeSourceManager - Remove the current source manager and give ownership
319  /// to the caller.
320  SourceManager *takeSourceManager() { return SourceMgr.take(); }
321
322  /// setSourceManager - Replace the current source manager; the compiler
323  /// instance takes ownership of \arg Value.
324  void setSourceManager(SourceManager *Value);
325
326  /// }
327  /// @name Preprocessor
328  /// {
329
330  bool hasPreprocessor() const { return PP != 0; }
331
332  Preprocessor &getPreprocessor() const {
333    assert(PP && "Compiler instance has no preprocessor!");
334    return *PP;
335  }
336
337  /// takePreprocessor - Remove the current preprocessor and give ownership to
338  /// the caller.
339  Preprocessor *takePreprocessor() { return PP.take(); }
340
341  /// setPreprocessor - Replace the current preprocessor; the compiler instance
342  /// takes ownership of \arg Value.
343  void setPreprocessor(Preprocessor *Value);
344
345  /// }
346  /// @name ASTContext
347  /// {
348
349  bool hasASTContext() const { return Context != 0; }
350
351  ASTContext &getASTContext() const {
352    assert(Context && "Compiler instance has no AST context!");
353    return *Context;
354  }
355
356  /// takeASTContext - Remove the current AST context and give ownership to the
357  /// caller.
358  ASTContext *takeASTContext() { return Context.take(); }
359
360  /// setASTContext - Replace the current AST context; the compiler instance
361  /// takes ownership of \arg Value.
362  void setASTContext(ASTContext *Value);
363
364  /// \brief Replace the current Sema; the compiler instance takes ownership
365  /// of S.
366  void setSema(Sema *S);
367
368  /// }
369  /// @name ASTConsumer
370  /// {
371
372  bool hasASTConsumer() const { return Consumer != 0; }
373
374  ASTConsumer &getASTConsumer() const {
375    assert(Consumer && "Compiler instance has no AST consumer!");
376    return *Consumer;
377  }
378
379  /// takeASTConsumer - Remove the current AST consumer and give ownership to
380  /// the caller.
381  ASTConsumer *takeASTConsumer() { return Consumer.take(); }
382
383  /// setASTConsumer - Replace the current AST consumer; the compiler instance
384  /// takes ownership of \arg Value.
385  void setASTConsumer(ASTConsumer *Value);
386
387  /// }
388  /// @name Semantic analysis
389  /// {
390  bool hasSema() const { return TheSema != 0; }
391
392  Sema &getSema() const {
393    assert(TheSema && "Compiler instance has no Sema object!");
394    return *TheSema;
395  }
396
397  Sema *takeSema() { return TheSema.take(); }
398
399  /// }
400  /// @name Code Completion
401  /// {
402
403  bool hasCodeCompletionConsumer() const { return CompletionConsumer != 0; }
404
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.
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
425  bool hasFrontendTimer() const { return FrontendTimer != 0; }
426
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  /// \return The new object on success, or null on failure.
483  static llvm::IntrusiveRefCntPtr<Diagnostic>
484  createDiagnostics(const DiagnosticOptions &Opts, int Argc,
485                    const char* const *Argv,
486                    DiagnosticClient *Client = 0);
487
488  /// Create the file manager and replace any existing one with it.
489  void createFileManager();
490
491  /// Create the source manager and replace any existing one with it.
492  void createSourceManager(FileManager &FileMgr);
493
494  /// Create the preprocessor, using the invocation, file, and source managers,
495  /// and replace any existing one with it.
496  void createPreprocessor();
497
498  /// Create a Preprocessor object.
499  ///
500  /// Note that this also creates a new HeaderSearch object which will be owned
501  /// by the resulting Preprocessor.
502  ///
503  /// \return The new object on success, or null on failure.
504  static Preprocessor *createPreprocessor(Diagnostic &, const LangOptions &,
505                                          const PreprocessorOptions &,
506                                          const HeaderSearchOptions &,
507                                          const DependencyOutputOptions &,
508                                          const TargetInfo &,
509                                          const FrontendOptions &,
510                                          SourceManager &, FileManager &);
511
512  /// Create the AST context.
513  void createASTContext();
514
515  /// Create an external AST source to read a PCH file and attach it to the AST
516  /// context.
517  void createPCHExternalASTSource(llvm::StringRef Path,
518                                  bool DisablePCHValidation,
519                                  bool DisableStatCache,
520                                  void *DeserializationListener);
521
522  /// Create an external AST source to read a PCH file.
523  ///
524  /// \return - The new object on success, or null on failure.
525  static ExternalASTSource *
526  createPCHExternalASTSource(llvm::StringRef Path, const std::string &Sysroot,
527                             bool DisablePCHValidation,
528                             bool DisableStatCache,
529                             Preprocessor &PP, ASTContext &Context,
530                             void *DeserializationListener, bool Preamble);
531
532  /// Create a code completion consumer using the invocation; note that this
533  /// will cause the source manager to truncate the input source file at the
534  /// completion point.
535  void createCodeCompletionConsumer();
536
537  /// Create a code completion consumer to print code completion results, at
538  /// \arg Filename, \arg Line, and \arg Column, to the given output stream \arg
539  /// OS.
540  static CodeCompleteConsumer *
541  createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename,
542                               unsigned Line, unsigned Column,
543                               bool ShowMacros,
544                               bool ShowCodePatterns, bool ShowGlobals,
545                               llvm::raw_ostream &OS);
546
547  /// \brief Create the Sema object to be used for parsing.
548  void createSema(bool CompleteTranslationUnit,
549                  CodeCompleteConsumer *CompletionConsumer);
550
551  /// Create the frontend timer and replace any existing one with it.
552  void createFrontendTimer();
553
554  /// Create the default output file (from the invocation's options) and add it
555  /// to the list of tracked output files.
556  ///
557  /// \return - Null on error.
558  llvm::raw_fd_ostream *
559  createDefaultOutputFile(bool Binary = true, llvm::StringRef BaseInput = "",
560                          llvm::StringRef Extension = "");
561
562  /// Create a new output file and add it to the list of tracked output files,
563  /// optionally deriving the output path name.
564  ///
565  /// \return - Null on error.
566  llvm::raw_fd_ostream *
567  createOutputFile(llvm::StringRef OutputPath,
568                   bool Binary = true, bool RemoveFileOnSignal = true,
569                   llvm::StringRef BaseInput = "",
570                   llvm::StringRef Extension = "");
571
572  /// Create a new output file, optionally deriving the output path name.
573  ///
574  /// If \arg OutputPath is empty, then createOutputFile will derive an output
575  /// path location as \arg BaseInput, with any suffix removed, and \arg
576  /// Extension appended. If OutputPath is not stdout createOutputFile will
577  /// create a new temporary file that must be renamed to OutputPath in the end.
578  ///
579  /// \param OutputPath - If given, the path to the output file.
580  /// \param Error [out] - On failure, the error message.
581  /// \param BaseInput - If \arg OutputPath is empty, the input path name to use
582  /// for deriving the output path.
583  /// \param Extension - The extension to use for derived output names.
584  /// \param Binary - The mode to open the file in.
585  /// \param RemoveFileOnSignal - Whether the file should be registered with
586  /// llvm::sys::RemoveFileOnSignal. Note that this is not safe for
587  /// multithreaded use, as the underlying signal mechanism is not reentrant
588  /// \param ResultPathName [out] - If given, the result path name will be
589  /// stored here on success.
590  /// \param TempPathName [out] - If given, the temporary file path name
591  /// will be stored here on success.
592  static llvm::raw_fd_ostream *
593  createOutputFile(llvm::StringRef OutputPath, std::string &Error,
594                   bool Binary = true, bool RemoveFileOnSignal = true,
595                   llvm::StringRef BaseInput = "",
596                   llvm::StringRef Extension = "",
597                   std::string *ResultPathName = 0,
598                   std::string *TempPathName = 0);
599
600  /// }
601  /// @name Initialization Utility Methods
602  /// {
603
604  /// InitializeSourceManager - Initialize the source manager to set InputFile
605  /// as the main file.
606  ///
607  /// \return True on success.
608  bool InitializeSourceManager(llvm::StringRef InputFile);
609
610  /// InitializeSourceManager - Initialize the source manager to set InputFile
611  /// as the main file.
612  ///
613  /// \return True on success.
614  static bool InitializeSourceManager(llvm::StringRef InputFile,
615                                      Diagnostic &Diags,
616                                      FileManager &FileMgr,
617                                      SourceManager &SourceMgr,
618                                      const FrontendOptions &Opts);
619
620  /// }
621};
622
623} // end namespace clang
624
625#endif
626