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