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 "clang/Lex/ModuleLoader.h" 15 #include "llvm/ADT/IntrusiveRefCntPtr.h" 16 #include "llvm/ADT/StringRef.h" 17 #include "llvm/ADT/OwningPtr.h" 18 #include <cassert> 19 #include <list> 20 #include <string> 21 22 namespace llvm { 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 DiagnosticsEngine; 33 class DiagnosticConsumer; 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 : public ModuleLoader { 61 /// The options used in this compiler instance. 62 llvm::IntrusiveRefCntPtr<CompilerInvocation> Invocation; 63 64 /// The diagnostics engine instance. 65 llvm::IntrusiveRefCntPtr<DiagnosticsEngine> 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 raw_ostream *OS; 106 107 OutputFile(const std::string &filename, const std::string &tempFilename, 108 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 160 bool hasInvocation() const { return Invocation != 0; } 161 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 174 AnalyzerOptions &getAnalyzerOpts() { 175 return Invocation->getAnalyzerOpts(); 176 } 177 const AnalyzerOptions &getAnalyzerOpts() const { 178 return Invocation->getAnalyzerOpts(); 179 } 180 181 CodeGenOptions &getCodeGenOpts() { 182 return Invocation->getCodeGenOpts(); 183 } 184 const CodeGenOptions &getCodeGenOpts() const { 185 return Invocation->getCodeGenOpts(); 186 } 187 188 DependencyOutputOptions &getDependencyOutputOpts() { 189 return Invocation->getDependencyOutputOpts(); 190 } 191 const DependencyOutputOptions &getDependencyOutputOpts() const { 192 return Invocation->getDependencyOutputOpts(); 193 } 194 195 DiagnosticOptions &getDiagnosticOpts() { 196 return Invocation->getDiagnosticOpts(); 197 } 198 const DiagnosticOptions &getDiagnosticOpts() const { 199 return Invocation->getDiagnosticOpts(); 200 } 201 202 const FileSystemOptions &getFileSystemOpts() const { 203 return Invocation->getFileSystemOpts(); 204 } 205 206 FrontendOptions &getFrontendOpts() { 207 return Invocation->getFrontendOpts(); 208 } 209 const FrontendOptions &getFrontendOpts() const { 210 return Invocation->getFrontendOpts(); 211 } 212 213 HeaderSearchOptions &getHeaderSearchOpts() { 214 return Invocation->getHeaderSearchOpts(); 215 } 216 const HeaderSearchOptions &getHeaderSearchOpts() const { 217 return Invocation->getHeaderSearchOpts(); 218 } 219 220 LangOptions &getLangOpts() { 221 return Invocation->getLangOpts(); 222 } 223 const LangOptions &getLangOpts() const { 224 return Invocation->getLangOpts(); 225 } 226 227 PreprocessorOptions &getPreprocessorOpts() { 228 return Invocation->getPreprocessorOpts(); 229 } 230 const PreprocessorOptions &getPreprocessorOpts() const { 231 return Invocation->getPreprocessorOpts(); 232 } 233 234 PreprocessorOutputOptions &getPreprocessorOutputOpts() { 235 return Invocation->getPreprocessorOutputOpts(); 236 } 237 const PreprocessorOutputOptions &getPreprocessorOutputOpts() const { 238 return Invocation->getPreprocessorOutputOpts(); 239 } 240 241 TargetOptions &getTargetOpts() { 242 return Invocation->getTargetOpts(); 243 } 244 const TargetOptions &getTargetOpts() const { 245 return Invocation->getTargetOpts(); 246 } 247 248 /// } 249 /// @name Diagnostics Engine 250 /// { 251 252 bool hasDiagnostics() const { return Diagnostics != 0; } 253 254 /// Get the current diagnostics engine. 255 DiagnosticsEngine &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(DiagnosticsEngine *Value); 262 263 DiagnosticConsumer &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 273 bool hasTarget() const { return Target != 0; } 274 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 287 bool hasFileManager() const { return FileMgr != 0; } 288 289 /// Return the current file manager to the caller. 290 FileManager &getFileManager() const { 291 assert(FileMgr && "Compiler instance has no file manager!"); 292 return *FileMgr; 293 } 294 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 306 bool hasSourceManager() const { return SourceMgr != 0; } 307 308 /// Return the current source manager. 309 SourceManager &getSourceManager() const { 310 assert(SourceMgr && "Compiler instance has no source manager!"); 311 return *SourceMgr; 312 } 313 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 325 bool hasPreprocessor() const { return PP != 0; } 326 327 /// Return the current preprocessor. 328 Preprocessor &getPreprocessor() const { 329 assert(PP && "Compiler instance has no preprocessor!"); 330 return *PP; 331 } 332 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 344 bool hasASTContext() const { return Context != 0; } 345 346 ASTContext &getASTContext() const { 347 assert(Context && "Compiler instance has no AST context!"); 348 return *Context; 349 } 350 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 366 bool hasASTConsumer() const { return Consumer != 0; } 367 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. 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 /// { 384 bool hasSema() const { return TheSema != 0; } 385 386 Sema &getSema() const { 387 assert(TheSema && "Compiler instance has no Sema object!"); 388 return *TheSema; 389 } 390 391 Sema *takeSema() { return TheSema.take(); } 392 393 /// } 394 /// @name Module Management 395 /// { 396 397 ASTReader *getModuleManager() const { return ModuleManager; } 398 399 /// } 400 /// @name Code Completion 401 /// { 402 403 bool hasCodeCompletionConsumer() const { return CompletionConsumer != 0; } 404 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. 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 425 bool hasFrontendTimer() const { return FrontendTimer != 0; } 426 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 DiagnosticsEngine inside this AST 459 /// unit. 460 /// 461 /// \param ShouldOwnClient If Client is non-NULL, specifies whether 462 /// the diagnostic object should take ownership of the client. 463 /// 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); 470 471 /// Create a DiagnosticsEngine object with a the TextDiagnosticPrinter. 472 /// 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. 476 /// 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. 481 /// 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. 485 /// 486 /// \param Client If non-NULL, a diagnostic client that will be 487 /// attached to (and, then, owned by) the returned DiagnosticsEngine 488 /// object. 489 /// 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). 492 /// 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); 501 502 /// Create the file manager and replace any existing one with it. 503 void createFileManager(); 504 505 /// Create the source manager and replace any existing one with it. 506 void createSourceManager(FileManager &FileMgr); 507 508 /// Create the preprocessor, using the invocation, file, and source managers, 509 /// and replace any existing one with it. 510 void createPreprocessor(); 511 512 /// Create the AST context. 513 void createASTContext(); 514 515 /// Create an external AST source to read a PCH file and attach it to the AST 516 /// context. 517 void createPCHExternalASTSource(StringRef Path, 518 bool DisablePCHValidation, 519 bool DisableStatCache, 520 void *DeserializationListener); 521 522 /// Create an external AST source to read a PCH file. 523 /// 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); 531 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(); 536 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 539 /// OS. 540 static CodeCompleteConsumer * 541 createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename, 542 unsigned Line, unsigned Column, 543 bool ShowMacros, 544 bool ShowCodePatterns, bool ShowGlobals, 545 raw_ostream &OS); 546 547 /// \brief Create the Sema object to be used for parsing. 548 void createSema(TranslationUnitKind TUKind, 549 CodeCompleteConsumer *CompletionConsumer); 550 551 /// Create the frontend timer and replace any existing one with it. 552 void createFrontendTimer(); 553 554 /// Create the default output file (from the invocation's options) and add it 555 /// to the list of tracked output files. 556 /// 557 /// \return - Null on error. 558 llvm::raw_fd_ostream * 559 createDefaultOutputFile(bool Binary = true, StringRef BaseInput = "", 560 StringRef Extension = ""); 561 562 /// Create a new output file and add it to the list of tracked output files, 563 /// optionally deriving the output path name. 564 /// 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); 572 573 /// Create a new output file, optionally deriving the output path name. 574 /// 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. 580 /// 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); 604 605 /// } 606 /// @name Initialization Utility Methods 607 /// { 608 609 /// InitializeSourceManager - Initialize the source manager to set InputFile 610 /// as the main file. 611 /// 612 /// \return True on success. 613 bool InitializeSourceManager(StringRef InputFile); 614 615 /// InitializeSourceManager - Initialize the source manager to set InputFile 616 /// as the main file. 617 /// 618 /// \return True on success. 619 static bool InitializeSourceManager(StringRef InputFile, 620 DiagnosticsEngine &Diags, 621 FileManager &FileMgr, 622 SourceManager &SourceMgr, 623 const FrontendOptions &Opts); 624 625 /// } 626 627 virtual ModuleKey loadModule(SourceLocation ImportLoc, 628 IdentifierInfo &ModuleName, 629 SourceLocation ModuleNameLoc); 630 }; 631 632 } // end namespace clang 633 634 #endif 635