CompilerInstance.h revision c4e265f67e63d870b4a188be5af1bcd848214802
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/StringRef.h"
15#include "llvm/ADT/OwningPtr.h"
16#include <cassert>
17#include <list>
18#include <string>
19
20namespace llvm {
21class LLVMContext;
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 Preprocessor;
36class Source;
37class SourceManager;
38class TargetInfo;
39
40/// CompilerInstance - Helper class for managing a single instance of the Clang
41/// compiler.
42///
43/// The CompilerInstance serves two purposes:
44///  (1) It manages the various objects which are necessary to run the compiler,
45///      for example the preprocessor, the target information, and the AST
46///      context.
47///  (2) It provides utility routines for constructing and manipulating the
48///      common Clang objects.
49///
50/// The compiler instance generally owns the instance of all the objects that it
51/// manages. However, clients can still share objects by manually setting the
52/// object and retaking ownership prior to destroying the CompilerInstance.
53///
54/// The compiler instance is intended to simplify clients, but not to lock them
55/// in to the compiler instance for everything. When possible, utility functions
56/// come in two forms; a short form that reuses the CompilerInstance objects,
57/// and a long form that takes explicit instances of any required objects.
58class CompilerInstance {
59  /// The LLVM context used for this instance.
60  llvm::LLVMContext *LLVMContext;
61  bool OwnsLLVMContext;
62
63  /// The options used in this compiler instance.
64  CompilerInvocation Invocation;
65
66  /// The diagnostics engine instance.
67  llvm::OwningPtr<Diagnostic> Diagnostics;
68
69  /// The diagnostics client instance.
70  llvm::OwningPtr<DiagnosticClient> DiagClient;
71
72  /// The target being compiled for.
73  llvm::OwningPtr<TargetInfo> Target;
74
75  /// The file manager.
76  llvm::OwningPtr<FileManager> FileMgr;
77
78  /// The source manager.
79  llvm::OwningPtr<SourceManager> SourceMgr;
80
81  /// The preprocessor.
82  llvm::OwningPtr<Preprocessor> PP;
83
84  /// The AST context.
85  llvm::OwningPtr<ASTContext> Context;
86
87  /// The AST consumer.
88  llvm::OwningPtr<ASTConsumer> Consumer;
89
90  /// The code completion consumer.
91  llvm::OwningPtr<CodeCompleteConsumer> CompletionConsumer;
92
93  /// The frontend timer
94  llvm::OwningPtr<llvm::Timer> FrontendTimer;
95
96  /// The list of active output files.
97  std::list< std::pair<std::string, llvm::raw_ostream*> > OutputFiles;
98
99public:
100  /// Create a new compiler instance with the given LLVM context, optionally
101  /// taking ownership of it.
102  CompilerInstance(llvm::LLVMContext *_LLVMContext = 0,
103                   bool _OwnsLLVMContext = true);
104  ~CompilerInstance();
105
106  /// @name LLVM Context
107  /// {
108
109  bool hasLLVMContext() const { return LLVMContext != 0; }
110
111  llvm::LLVMContext &getLLVMContext() const {
112    assert(LLVMContext && "Compiler instance has no LLVM context!");
113    return *LLVMContext;
114  }
115
116  /// setLLVMContext - Replace the current LLVM context and take ownership of
117  /// \arg Value.
118  void setLLVMContext(llvm::LLVMContext *Value, bool TakeOwnership = true) {
119    LLVMContext = Value;
120    OwnsLLVMContext = TakeOwnership;
121  }
122
123  /// }
124  /// @name Compiler Invocation and Options
125  /// {
126
127  CompilerInvocation &getInvocation() { return Invocation; }
128  const CompilerInvocation &getInvocation() const { return Invocation; }
129  void setInvocation(const CompilerInvocation &Value) { Invocation = Value; }
130
131  /// }
132  /// @name Forwarding Methods
133  /// {
134
135  AnalyzerOptions &getAnalyzerOpts() {
136    return Invocation.getAnalyzerOpts();
137  }
138  const AnalyzerOptions &getAnalyzerOpts() const {
139    return Invocation.getAnalyzerOpts();
140  }
141
142  CodeGenOptions &getCodeGenOpts() {
143    return Invocation.getCodeGenOpts();
144  }
145  const CodeGenOptions &getCodeGenOpts() const {
146    return Invocation.getCodeGenOpts();
147  }
148
149  DependencyOutputOptions &getDependencyOutputOpts() {
150    return Invocation.getDependencyOutputOpts();
151  }
152  const DependencyOutputOptions &getDependencyOutputOpts() const {
153    return Invocation.getDependencyOutputOpts();
154  }
155
156  DiagnosticOptions &getDiagnosticOpts() {
157    return Invocation.getDiagnosticOpts();
158  }
159  const DiagnosticOptions &getDiagnosticOpts() const {
160    return Invocation.getDiagnosticOpts();
161  }
162
163  FrontendOptions &getFrontendOpts() {
164    return Invocation.getFrontendOpts();
165  }
166  const FrontendOptions &getFrontendOpts() const {
167    return Invocation.getFrontendOpts();
168  }
169
170  HeaderSearchOptions &getHeaderSearchOpts() {
171    return Invocation.getHeaderSearchOpts();
172  }
173  const HeaderSearchOptions &getHeaderSearchOpts() const {
174    return Invocation.getHeaderSearchOpts();
175  }
176
177  LangOptions &getLangOpts() {
178    return Invocation.getLangOpts();
179  }
180  const LangOptions &getLangOpts() const {
181    return Invocation.getLangOpts();
182  }
183
184  PreprocessorOptions &getPreprocessorOpts() {
185    return Invocation.getPreprocessorOpts();
186  }
187  const PreprocessorOptions &getPreprocessorOpts() const {
188    return Invocation.getPreprocessorOpts();
189  }
190
191  PreprocessorOutputOptions &getPreprocessorOutputOpts() {
192    return Invocation.getPreprocessorOutputOpts();
193  }
194  const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
195    return Invocation.getPreprocessorOutputOpts();
196  }
197
198  TargetOptions &getTargetOpts() {
199    return Invocation.getTargetOpts();
200  }
201  const TargetOptions &getTargetOpts() const {
202    return Invocation.getTargetOpts();
203  }
204
205  /// }
206  /// @name Diagnostics Engine
207  /// {
208
209  bool hasDiagnostics() const { return Diagnostics != 0; }
210
211  Diagnostic &getDiagnostics() const {
212    assert(Diagnostics && "Compiler instance has no diagnostics!");
213    return *Diagnostics;
214  }
215
216  /// takeDiagnostics - Remove the current diagnostics engine and give ownership
217  /// to the caller.
218  Diagnostic *takeDiagnostics() { return Diagnostics.take(); }
219
220  /// setDiagnostics - Replace the current diagnostics engine; the compiler
221  /// instance takes ownership of \arg Value.
222  void setDiagnostics(Diagnostic *Value);
223
224  DiagnosticClient &getDiagnosticClient() const {
225    assert(DiagClient && "Compiler instance has no diagnostic client!");
226    return *DiagClient;
227  }
228
229  /// takeDiagnosticClient - Remove the current diagnostics client and give
230  /// ownership to the caller.
231  DiagnosticClient *takeDiagnosticClient() { return DiagClient.take(); }
232
233  /// setDiagnosticClient - Replace the current diagnostics client; the compiler
234  /// instance takes ownership of \arg Value.
235  void setDiagnosticClient(DiagnosticClient *Value);
236
237  /// }
238  /// @name Target Info
239  /// {
240
241  bool hasTarget() const { return Target != 0; }
242
243  TargetInfo &getTarget() const {
244    assert(Target && "Compiler instance has no target!");
245    return *Target;
246  }
247
248  /// takeTarget - Remove the current diagnostics engine and give ownership
249  /// to the caller.
250  TargetInfo *takeTarget() { return Target.take(); }
251
252  /// setTarget - Replace the current diagnostics engine; the compiler
253  /// instance takes ownership of \arg Value.
254  void setTarget(TargetInfo *Value);
255
256  /// }
257  /// @name File Manager
258  /// {
259
260  bool hasFileManager() const { return FileMgr != 0; }
261
262  FileManager &getFileManager() const {
263    assert(FileMgr && "Compiler instance has no file manager!");
264    return *FileMgr;
265  }
266
267  /// takeFileManager - Remove the current file manager and give ownership to
268  /// the caller.
269  FileManager *takeFileManager() { return FileMgr.take(); }
270
271  /// setFileManager - Replace the current file manager; the compiler instance
272  /// takes ownership of \arg Value.
273  void setFileManager(FileManager *Value);
274
275  /// }
276  /// @name Source Manager
277  /// {
278
279  bool hasSourceManager() const { return SourceMgr != 0; }
280
281  SourceManager &getSourceManager() const {
282    assert(SourceMgr && "Compiler instance has no source manager!");
283    return *SourceMgr;
284  }
285
286  /// takeSourceManager - Remove the current source manager and give ownership
287  /// to the caller.
288  SourceManager *takeSourceManager() { return SourceMgr.take(); }
289
290  /// setSourceManager - Replace the current source manager; the compiler
291  /// instance takes ownership of \arg Value.
292  void setSourceManager(SourceManager *Value);
293
294  /// }
295  /// @name Preprocessor
296  /// {
297
298  bool hasPreprocessor() const { return PP != 0; }
299
300  Preprocessor &getPreprocessor() const {
301    assert(PP && "Compiler instance has no preprocessor!");
302    return *PP;
303  }
304
305  /// takePreprocessor - Remove the current preprocessor and give ownership to
306  /// the caller.
307  Preprocessor *takePreprocessor() { return PP.take(); }
308
309  /// setPreprocessor - Replace the current preprocessor; the compiler instance
310  /// takes ownership of \arg Value.
311  void setPreprocessor(Preprocessor *Value);
312
313  /// }
314  /// @name ASTContext
315  /// {
316
317  bool hasASTContext() const { return Context != 0; }
318
319  ASTContext &getASTContext() const {
320    assert(Context && "Compiler instance has no AST context!");
321    return *Context;
322  }
323
324  /// takeASTContext - Remove the current AST context and give ownership to the
325  /// caller.
326  ASTContext *takeASTContext() { return Context.take(); }
327
328  /// setASTContext - Replace the current AST context; the compiler instance
329  /// takes ownership of \arg Value.
330  void setASTContext(ASTContext *Value);
331
332  /// }
333  /// @name ASTConsumer
334  /// {
335
336  bool hasASTConsumer() const { return Consumer != 0; }
337
338  ASTConsumer &getASTConsumer() const {
339    assert(Consumer && "Compiler instance has no AST consumer!");
340    return *Consumer;
341  }
342
343  /// takeASTConsumer - Remove the current AST consumer and give ownership to
344  /// the caller.
345  ASTConsumer *takeASTConsumer() { return Consumer.take(); }
346
347  /// setASTConsumer - Replace the current AST consumer; the compiler instance
348  /// takes ownership of \arg Value.
349  void setASTConsumer(ASTConsumer *Value);
350
351  /// }
352  /// @name Code Completion
353  /// {
354
355  bool hasCodeCompletionConsumer() const { return CompletionConsumer != 0; }
356
357  CodeCompleteConsumer &getCodeCompletionConsumer() const {
358    assert(CompletionConsumer &&
359           "Compiler instance has no code completion consumer!");
360    return *CompletionConsumer;
361  }
362
363  /// takeCodeCompletionConsumer - Remove the current code completion consumer
364  /// and give ownership to the caller.
365  CodeCompleteConsumer *takeCodeCompletionConsumer() {
366    return CompletionConsumer.take();
367  }
368
369  /// setCodeCompletionConsumer - Replace the current code completion consumer;
370  /// the compiler instance takes ownership of \arg Value.
371  void setCodeCompletionConsumer(CodeCompleteConsumer *Value);
372
373  /// }
374  /// @name Frontend timer
375  /// {
376
377  bool hasFrontendTimer() const { return FrontendTimer != 0; }
378
379  llvm::Timer &getFrontendTimer() const {
380    assert(FrontendTimer && "Compiler instance has no frontend timer!");
381    return *FrontendTimer;
382  }
383
384  /// }
385  /// @name Output Files
386  /// {
387
388  /// getOutputFileList - Get the list of (path, output stream) pairs of output
389  /// files; the path may be empty but the stream will always be non-null.
390  const std::list< std::pair<std::string,
391                             llvm::raw_ostream*> > &getOutputFileList() const;
392
393  /// addOutputFile - Add an output file onto the list of tracked output files.
394  ///
395  /// \param Path - The path to the output file, or empty.
396  /// \param OS - The output stream, which should be non-null.
397  void addOutputFile(llvm::StringRef Path, llvm::raw_ostream *OS);
398
399  /// ClearOutputFiles - Clear the output file list, destroying the contained
400  /// output streams.
401  ///
402  /// \param EraseFiles - If true, attempt to erase the files from disk.
403  void ClearOutputFiles(bool EraseFiles);
404
405  /// }
406  /// @name Construction Utility Methods
407  /// {
408
409  /// Create the diagnostics engine using the invocation's diagnostic options
410  /// and replace any existing one with it.
411  ///
412  /// Note that this routine also replaces the diagnostic client.
413  void createDiagnostics(int Argc, char **Argv);
414
415  /// Create a Diagnostic object with a the TextDiagnosticPrinter.
416  ///
417  /// The \arg Argc and \arg Argv arguments are used only for logging purposes,
418  /// when the diagnostic options indicate that the compiler should output
419  /// logging information.
420  ///
421  /// Note that this creates an unowned DiagnosticClient, if using directly the
422  /// caller is responsible for releaseing the returned Diagnostic's client
423  /// eventually.
424  ///
425  /// \return The new object on success, or null on failure.
426  static Diagnostic *createDiagnostics(const DiagnosticOptions &Opts,
427                                       int Argc, char **Argv);
428
429  /// Create the file manager and replace any existing one with it.
430  void createFileManager();
431
432  /// Create the source manager and replace any existing one with it.
433  void createSourceManager();
434
435  /// Create the preprocessor, using the invocation, file, and source managers,
436  /// and replace any existing one with it.
437  void createPreprocessor();
438
439  /// Create a Preprocessor object.
440  ///
441  /// Note that this also creates a new HeaderSearch object which will be owned
442  /// by the resulting Preprocessor.
443  ///
444  /// \return The new object on success, or null on failure.
445  static Preprocessor *createPreprocessor(Diagnostic &, const LangOptions &,
446                                          const PreprocessorOptions &,
447                                          const HeaderSearchOptions &,
448                                          const DependencyOutputOptions &,
449                                          const TargetInfo &,
450                                          SourceManager &, FileManager &);
451
452  /// Create the AST context.
453  void createASTContext();
454
455  /// Create an external AST source to read a PCH file and attach it to the AST
456  /// context.
457  void createPCHExternalASTSource(llvm::StringRef Path);
458
459  /// Create an external AST source to read a PCH file.
460  ///
461  /// \return - The new object on success, or null on failure.
462  static ExternalASTSource *
463  createPCHExternalASTSource(llvm::StringRef Path, const std::string &Sysroot,
464                             Preprocessor &PP, ASTContext &Context);
465
466  /// Create a code completion consumer using the invocation; note that this
467  /// will cause the source manager to truncate the input source file at the
468  /// completion point.
469  void createCodeCompletionConsumer();
470
471  /// Create a code completion consumer to print code completion results, at
472  /// \arg Filename, \arg Line, and \arg Column, to the given output stream \arg
473  /// OS.
474  static CodeCompleteConsumer *
475  createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename,
476                               unsigned Line, unsigned Column,
477                               bool UseDebugPrinter, bool ShowMacros,
478                               llvm::raw_ostream &OS);
479
480  /// Create the frontend timer and replace any existing one with it.
481  void createFrontendTimer();
482
483  /// Create the default output file (from the invocation's options) and add it
484  /// to the list of tracked output files.
485  llvm::raw_fd_ostream *
486  createDefaultOutputFile(bool Binary = true, llvm::StringRef BaseInput = "",
487                          llvm::StringRef Extension = "");
488
489  /// Create a new output file and add it to the list of tracked output files,
490  /// optionally deriving the output path name.
491  llvm::raw_fd_ostream *
492  createOutputFile(llvm::StringRef OutputPath, bool Binary = true,
493                   llvm::StringRef BaseInput = "",
494                   llvm::StringRef Extension = "");
495
496  /// Create a new output file, optionally deriving the output path name.
497  ///
498  /// If \arg OutputPath is empty, then createOutputFile will derive an output
499  /// path location as \arg BaseInput, with any suffix removed, and \arg
500  /// Extension appended.
501  ///
502  /// \param OutputPath - If given, the path to the output file.
503  /// \param Error [out] - On failure, the error message.
504  /// \param BaseInput - If \arg OutputPath is empty, the input path name to use
505  /// for deriving the output path.
506  /// \param Extension - The extension to use for derived output names.
507  /// \param Binary - The mode to open the file in.
508  /// \param ResultPathName [out] - If given, the result path name will be
509  /// stored here on success.
510  static llvm::raw_fd_ostream *
511  createOutputFile(llvm::StringRef OutputPath, std::string &Error,
512                   bool Binary = true, llvm::StringRef BaseInput = "",
513                   llvm::StringRef Extension = "",
514                   std::string *ResultPathName = 0);
515
516  /// }
517  /// @name Initialization Utility Methods
518  /// {
519
520  /// InitializeSourceManager - Initialize the source manager to set InputFile
521  /// as the main file.
522  ///
523  /// \return True on success.
524  bool InitializeSourceManager(llvm::StringRef InputFile);
525
526  /// InitializeSourceManager - Initialize the source manager to set InputFile
527  /// as the main file.
528  ///
529  /// \return True on success.
530  static bool InitializeSourceManager(llvm::StringRef InputFile,
531                                      Diagnostic &Diags,
532                                      FileManager &FileMgr,
533                                      SourceManager &SourceMgr,
534                                      const FrontendOptions &Opts);
535
536  /// }
537};
538
539} // end namespace clang
540
541#endif
542