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