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