1 //===-- CompilerInstance.h - Clang Compiler Instance ------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
11 #define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
13 #include "clang/Frontend/CompilerInvocation.h"
14 #include "clang/Lex/ModuleLoader.h"
15 #include "llvm/ADT/IntrusiveRefCntPtr.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/ADT/OwningPtr.h"
31 class CodeCompleteConsumer;
32 class DiagnosticsEngine;
33 class DiagnosticConsumer;
34 class ExternalASTSource;
42 /// CompilerInstance - Helper class for managing a single instance of the Clang
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
49 /// (2) It provides utility routines for constructing and manipulating the
50 /// common Clang objects.
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.
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 : public ModuleLoader {
61 /// The options used in this compiler instance.
62 llvm::IntrusiveRefCntPtr<CompilerInvocation> Invocation;
64 /// The diagnostics engine instance.
65 llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;
67 /// The target being compiled for.
68 llvm::IntrusiveRefCntPtr<TargetInfo> Target;
71 llvm::IntrusiveRefCntPtr<FileManager> FileMgr;
73 /// The source manager.
74 llvm::IntrusiveRefCntPtr<SourceManager> SourceMgr;
77 llvm::IntrusiveRefCntPtr<Preprocessor> PP;
80 llvm::IntrusiveRefCntPtr<ASTContext> Context;
83 llvm::OwningPtr<ASTConsumer> Consumer;
85 /// The code completion consumer.
86 llvm::OwningPtr<CodeCompleteConsumer> CompletionConsumer;
88 /// \brief The semantic analysis object.
89 llvm::OwningPtr<Sema> TheSema;
91 /// \brief The frontend timer
92 llvm::OwningPtr<llvm::Timer> FrontendTimer;
94 /// \brief Non-owning reference to the ASTReader, if one exists.
95 ASTReader *ModuleManager;
97 /// \brief Holds information about the output file.
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
103 std::string Filename;
104 std::string TempFilename;
107 OutputFile(const std::string &filename, const std::string &tempFilename,
109 : Filename(filename), TempFilename(tempFilename), OS(os) { }
112 /// The list of active output files.
113 std::list<OutputFile> OutputFiles;
115 void operator=(const CompilerInstance &); // DO NOT IMPLEMENT
116 CompilerInstance(const CompilerInstance&); // DO NOT IMPLEMENT
121 /// @name High-Level Operations
124 /// ExecuteAction - Execute the provided action against the compiler's
125 /// CompilerInvocation object.
127 /// This function makes the following assumptions:
129 /// - The invocation options should be initialized. This function does not
130 /// handle the '-help' or '-version' options, clients should handle those
133 /// - The diagnostics engine should have already been created by the client.
135 /// - No other CompilerInstance state should have been initialized (this is
136 /// an unchecked error).
138 /// - Clients should have initialized any LLVM target features that may be
141 /// - Clients should eventually call llvm_shutdown() upon the completion of
142 /// this routine to ensure that any managed objects are properly destroyed.
144 /// Note that this routine may write output to 'stderr'.
146 /// \param Act - The action to execute.
147 /// \return - True on success.
149 // FIXME: This function should take the stream to write any debugging /
150 // verbose output to as an argument.
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);
157 /// @name Compiler Invocation and Options
160 bool hasInvocation() const { return Invocation != 0; }
162 CompilerInvocation &getInvocation() {
163 assert(Invocation && "Compiler instance has no invocation!");
167 /// setInvocation - Replace the current invocation.
168 void setInvocation(CompilerInvocation *Value);
171 /// @name Forwarding Methods
174 AnalyzerOptions &getAnalyzerOpts() {
175 return Invocation->getAnalyzerOpts();
177 const AnalyzerOptions &getAnalyzerOpts() const {
178 return Invocation->getAnalyzerOpts();
181 CodeGenOptions &getCodeGenOpts() {
182 return Invocation->getCodeGenOpts();
184 const CodeGenOptions &getCodeGenOpts() const {
185 return Invocation->getCodeGenOpts();
188 DependencyOutputOptions &getDependencyOutputOpts() {
189 return Invocation->getDependencyOutputOpts();
191 const DependencyOutputOptions &getDependencyOutputOpts() const {
192 return Invocation->getDependencyOutputOpts();
195 DiagnosticOptions &getDiagnosticOpts() {
196 return Invocation->getDiagnosticOpts();
198 const DiagnosticOptions &getDiagnosticOpts() const {
199 return Invocation->getDiagnosticOpts();
202 const FileSystemOptions &getFileSystemOpts() const {
203 return Invocation->getFileSystemOpts();
206 FrontendOptions &getFrontendOpts() {
207 return Invocation->getFrontendOpts();
209 const FrontendOptions &getFrontendOpts() const {
210 return Invocation->getFrontendOpts();
213 HeaderSearchOptions &getHeaderSearchOpts() {
214 return Invocation->getHeaderSearchOpts();
216 const HeaderSearchOptions &getHeaderSearchOpts() const {
217 return Invocation->getHeaderSearchOpts();
220 LangOptions &getLangOpts() {
221 return Invocation->getLangOpts();
223 const LangOptions &getLangOpts() const {
224 return Invocation->getLangOpts();
227 PreprocessorOptions &getPreprocessorOpts() {
228 return Invocation->getPreprocessorOpts();
230 const PreprocessorOptions &getPreprocessorOpts() const {
231 return Invocation->getPreprocessorOpts();
234 PreprocessorOutputOptions &getPreprocessorOutputOpts() {
235 return Invocation->getPreprocessorOutputOpts();
237 const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
238 return Invocation->getPreprocessorOutputOpts();
241 TargetOptions &getTargetOpts() {
242 return Invocation->getTargetOpts();
244 const TargetOptions &getTargetOpts() const {
245 return Invocation->getTargetOpts();
249 /// @name Diagnostics Engine
252 bool hasDiagnostics() const { return Diagnostics != 0; }
254 /// Get the current diagnostics engine.
255 DiagnosticsEngine &getDiagnostics() const {
256 assert(Diagnostics && "Compiler instance has no diagnostics!");
260 /// setDiagnostics - Replace the current diagnostics engine.
261 void setDiagnostics(DiagnosticsEngine *Value);
263 DiagnosticConsumer &getDiagnosticClient() const {
264 assert(Diagnostics && Diagnostics->getClient() &&
265 "Compiler instance has no diagnostic client!");
266 return *Diagnostics->getClient();
270 /// @name Target Info
273 bool hasTarget() const { return Target != 0; }
275 TargetInfo &getTarget() const {
276 assert(Target && "Compiler instance has no target!");
280 /// Replace the current diagnostics engine.
281 void setTarget(TargetInfo *Value);
284 /// @name File Manager
287 bool hasFileManager() const { return FileMgr != 0; }
289 /// Return the current file manager to the caller.
290 FileManager &getFileManager() const {
291 assert(FileMgr && "Compiler instance has no file manager!");
295 void resetAndLeakFileManager() {
296 FileMgr.resetWithoutRelease();
299 /// setFileManager - Replace the current file manager.
300 void setFileManager(FileManager *Value);
303 /// @name Source Manager
306 bool hasSourceManager() const { return SourceMgr != 0; }
308 /// Return the current source manager.
309 SourceManager &getSourceManager() const {
310 assert(SourceMgr && "Compiler instance has no source manager!");
314 void resetAndLeakSourceManager() {
315 SourceMgr.resetWithoutRelease();
318 /// setSourceManager - Replace the current source manager.
319 void setSourceManager(SourceManager *Value);
322 /// @name Preprocessor
325 bool hasPreprocessor() const { return PP != 0; }
327 /// Return the current preprocessor.
328 Preprocessor &getPreprocessor() const {
329 assert(PP && "Compiler instance has no preprocessor!");
333 void resetAndLeakPreprocessor() {
334 PP.resetWithoutRelease();
337 /// Replace the current preprocessor.
338 void setPreprocessor(Preprocessor *Value);
344 bool hasASTContext() const { return Context != 0; }
346 ASTContext &getASTContext() const {
347 assert(Context && "Compiler instance has no AST context!");
351 void resetAndLeakASTContext() {
352 Context.resetWithoutRelease();
355 /// setASTContext - Replace the current AST context.
356 void setASTContext(ASTContext *Value);
358 /// \brief Replace the current Sema; the compiler instance takes ownership
360 void setSema(Sema *S);
363 /// @name ASTConsumer
366 bool hasASTConsumer() const { return Consumer != 0; }
368 ASTConsumer &getASTConsumer() const {
369 assert(Consumer && "Compiler instance has no AST consumer!");
373 /// takeASTConsumer - Remove the current AST consumer and give ownership to
375 ASTConsumer *takeASTConsumer() { return Consumer.take(); }
377 /// setASTConsumer - Replace the current AST consumer; the compiler instance
378 /// takes ownership of \arg Value.
379 void setASTConsumer(ASTConsumer *Value);
382 /// @name Semantic analysis
384 bool hasSema() const { return TheSema != 0; }
386 Sema &getSema() const {
387 assert(TheSema && "Compiler instance has no Sema object!");
391 Sema *takeSema() { return TheSema.take(); }
394 /// @name Module Management
397 ASTReader *getModuleManager() const { return ModuleManager; }
400 /// @name Code Completion
403 bool hasCodeCompletionConsumer() const { return CompletionConsumer != 0; }
405 CodeCompleteConsumer &getCodeCompletionConsumer() const {
406 assert(CompletionConsumer &&
407 "Compiler instance has no code completion consumer!");
408 return *CompletionConsumer;
411 /// takeCodeCompletionConsumer - Remove the current code completion consumer
412 /// and give ownership to the caller.
413 CodeCompleteConsumer *takeCodeCompletionConsumer() {
414 return CompletionConsumer.take();
417 /// setCodeCompletionConsumer - Replace the current code completion consumer;
418 /// the compiler instance takes ownership of \arg Value.
419 void setCodeCompletionConsumer(CodeCompleteConsumer *Value);
422 /// @name Frontend timer
425 bool hasFrontendTimer() const { return FrontendTimer != 0; }
427 llvm::Timer &getFrontendTimer() const {
428 assert(FrontendTimer && "Compiler instance has no frontend timer!");
429 return *FrontendTimer;
433 /// @name Output Files
436 /// addOutputFile - Add an output file onto the list of tracked output files.
438 /// \param OutFile - The output file info.
439 void addOutputFile(const OutputFile &OutFile);
441 /// clearOutputFiles - Clear the output file list, destroying the contained
444 /// \param EraseFiles - If true, attempt to erase the files from disk.
445 void clearOutputFiles(bool EraseFiles);
448 /// @name Construction Utility Methods
451 /// Create the diagnostics engine using the invocation's diagnostic options
452 /// and replace any existing one with it.
454 /// Note that this routine also replaces the diagnostic client,
455 /// allocating one if one is not provided.
457 /// \param Client If non-NULL, a diagnostic client that will be
458 /// attached to (and, then, owned by) the DiagnosticsEngine inside this AST
461 /// \param ShouldOwnClient If Client is non-NULL, specifies whether
462 /// the diagnostic object should take ownership of the client.
464 /// \param ShouldCloneClient If Client is non-NULL, specifies whether that
465 /// client should be cloned.
466 void createDiagnostics(int Argc, const char* const *Argv,
467 DiagnosticConsumer *Client = 0,
468 bool ShouldOwnClient = true,
469 bool ShouldCloneClient = true);
471 /// Create a DiagnosticsEngine object with a the TextDiagnosticPrinter.
473 /// The \arg Argc and \arg Argv arguments are used only for logging purposes,
474 /// when the diagnostic options indicate that the compiler should output
475 /// logging information.
477 /// If no diagnostic client is provided, this creates a
478 /// DiagnosticConsumer that is owned by the returned diagnostic
479 /// object, if using directly the caller is responsible for
480 /// releasing the returned DiagnosticsEngine's client eventually.
482 /// \param Opts - The diagnostic options; note that the created text
483 /// diagnostic object contains a reference to these options and its lifetime
484 /// must extend past that of the diagnostic engine.
486 /// \param Client If non-NULL, a diagnostic client that will be
487 /// attached to (and, then, owned by) the returned DiagnosticsEngine
490 /// \param CodeGenOpts If non-NULL, the code gen options in use, which may be
491 /// used by some diagnostics printers (for logging purposes only).
493 /// \return The new object on success, or null on failure.
494 static llvm::IntrusiveRefCntPtr<DiagnosticsEngine>
495 createDiagnostics(const DiagnosticOptions &Opts, int Argc,
496 const char* const *Argv,
497 DiagnosticConsumer *Client = 0,
498 bool ShouldOwnClient = true,
499 bool ShouldCloneClient = true,
500 const CodeGenOptions *CodeGenOpts = 0);
502 /// Create the file manager and replace any existing one with it.
503 void createFileManager();
505 /// Create the source manager and replace any existing one with it.
506 void createSourceManager(FileManager &FileMgr);
508 /// Create the preprocessor, using the invocation, file, and source managers,
509 /// and replace any existing one with it.
510 void createPreprocessor();
512 /// Create the AST context.
513 void createASTContext();
515 /// Create an external AST source to read a PCH file and attach it to the AST
517 void createPCHExternalASTSource(StringRef Path,
518 bool DisablePCHValidation,
519 bool DisableStatCache,
520 void *DeserializationListener);
522 /// Create an external AST source to read a PCH file.
524 /// \return - The new object on success, or null on failure.
525 static ExternalASTSource *
526 createPCHExternalASTSource(StringRef Path, const std::string &Sysroot,
527 bool DisablePCHValidation,
528 bool DisableStatCache,
529 Preprocessor &PP, ASTContext &Context,
530 void *DeserializationListener, bool Preamble);
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();
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
540 static CodeCompleteConsumer *
541 createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename,
542 unsigned Line, unsigned Column,
544 bool ShowCodePatterns, bool ShowGlobals,
547 /// \brief Create the Sema object to be used for parsing.
548 void createSema(TranslationUnitKind TUKind,
549 CodeCompleteConsumer *CompletionConsumer);
551 /// Create the frontend timer and replace any existing one with it.
552 void createFrontendTimer();
554 /// Create the default output file (from the invocation's options) and add it
555 /// to the list of tracked output files.
557 /// \return - Null on error.
558 llvm::raw_fd_ostream *
559 createDefaultOutputFile(bool Binary = true, StringRef BaseInput = "",
560 StringRef Extension = "");
562 /// Create a new output file and add it to the list of tracked output files,
563 /// optionally deriving the output path name.
565 /// \return - Null on error.
566 llvm::raw_fd_ostream *
567 createOutputFile(StringRef OutputPath,
568 bool Binary = true, bool RemoveFileOnSignal = true,
569 StringRef BaseInput = "",
570 StringRef Extension = "",
571 bool UseTemporary = false);
573 /// Create a new output file, optionally deriving the output path name.
575 /// If \arg OutputPath is empty, then createOutputFile will derive an output
576 /// path location as \arg BaseInput, with any suffix removed, and \arg
577 /// Extension appended. If OutputPath is not stdout and \arg UseTemporary
578 /// is true, createOutputFile will create a new temporary file that must be
579 /// renamed to OutputPath in the end.
581 /// \param OutputPath - If given, the path to the output file.
582 /// \param Error [out] - On failure, the error message.
583 /// \param BaseInput - If \arg OutputPath is empty, the input path name to use
584 /// for deriving the output path.
585 /// \param Extension - The extension to use for derived output names.
586 /// \param Binary - The mode to open the file in.
587 /// \param RemoveFileOnSignal - Whether the file should be registered with
588 /// llvm::sys::RemoveFileOnSignal. Note that this is not safe for
589 /// multithreaded use, as the underlying signal mechanism is not reentrant
590 /// \param UseTemporary - Create a new temporary file that must be renamed to
591 /// OutputPath in the end
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(StringRef OutputPath, std::string &Error,
598 bool Binary = true, bool RemoveFileOnSignal = true,
599 StringRef BaseInput = "",
600 StringRef Extension = "",
601 bool UseTemporary = false,
602 std::string *ResultPathName = 0,
603 std::string *TempPathName = 0);
606 /// @name Initialization Utility Methods
609 /// InitializeSourceManager - Initialize the source manager to set InputFile
610 /// as the main file.
612 /// \return True on success.
613 bool InitializeSourceManager(StringRef InputFile);
615 /// InitializeSourceManager - Initialize the source manager to set InputFile
616 /// as the main file.
618 /// \return True on success.
619 static bool InitializeSourceManager(StringRef InputFile,
620 DiagnosticsEngine &Diags,
621 FileManager &FileMgr,
622 SourceManager &SourceMgr,
623 const FrontendOptions &Opts);
627 virtual ModuleKey loadModule(SourceLocation ImportLoc,
628 IdentifierInfo &ModuleName,
629 SourceLocation ModuleNameLoc);
632 } // end namespace clang