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