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