1 //===--- CompilerInstance.cpp ---------------------------------------------===// 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 #include "clang/Frontend/CompilerInstance.h" 11 #include "clang/AST/ASTContext.h" 12 #include "clang/Basic/Diagnostic.h" 13 #include "clang/Basic/FileManager.h" 14 #include "clang/Basic/SourceManager.h" 15 #include "clang/Basic/TargetInfo.h" 16 #include "clang/Lex/HeaderSearch.h" 17 #include "clang/Lex/Preprocessor.h" 18 #include "clang/Lex/PTHManager.h" 19 #include "clang/Frontend/ChainedDiagnosticClient.h" 20 #include "clang/Frontend/PCHReader.h" 21 #include "clang/Frontend/TextDiagnosticBuffer.h" 22 #include "clang/Frontend/TextDiagnosticPrinter.h" 23 #include "clang/Frontend/Utils.h" 24 #include "llvm/LLVMContext.h" 25 #include "llvm/Support/raw_ostream.h" 26 using namespace clang; 27 28 CompilerInstance::CompilerInstance(llvm::LLVMContext *_LLVMContext, 29 bool _OwnsLLVMContext) 30 : LLVMContext(_LLVMContext), 31 OwnsLLVMContext(_OwnsLLVMContext) { 32 } 33 34 CompilerInstance::~CompilerInstance() { 35 if (OwnsLLVMContext) 36 delete LLVMContext; 37 } 38 39 // Diagnostics 40 41 static void SetUpBuildDumpLog(const DiagnosticOptions &DiagOpts, 42 unsigned argc, char **argv, 43 llvm::OwningPtr<DiagnosticClient> &DiagClient) { 44 std::string ErrorInfo; 45 llvm::raw_ostream *OS = 46 new llvm::raw_fd_ostream(DiagOpts.DumpBuildInformation.c_str(), ErrorInfo); 47 if (!ErrorInfo.empty()) { 48 // FIXME: Do not fail like this. 49 llvm::errs() << "error opening -dump-build-information file '" 50 << DiagOpts.DumpBuildInformation << "', option ignored!\n"; 51 delete OS; 52 return; 53 } 54 55 (*OS) << "clang-cc command line arguments: "; 56 for (unsigned i = 0; i != argc; ++i) 57 (*OS) << argv[i] << ' '; 58 (*OS) << '\n'; 59 60 // Chain in a diagnostic client which will log the diagnostics. 61 DiagnosticClient *Logger = 62 new TextDiagnosticPrinter(*OS, DiagOpts, /*OwnsOutputStream=*/true); 63 DiagClient.reset(new ChainedDiagnosticClient(DiagClient.take(), Logger)); 64 } 65 66 void CompilerInstance::createDiagnostics(int Argc, char **Argv) { 67 Diagnostics.reset(createDiagnostics(getDiagnosticOpts(), Argc, Argv)); 68 69 if (Diagnostics) 70 DiagClient.reset(Diagnostics->getClient()); 71 } 72 73 Diagnostic *CompilerInstance::createDiagnostics(const DiagnosticOptions &Opts, 74 int Argc, char **Argv) { 75 // Create the diagnostic client for reporting errors or for 76 // implementing -verify. 77 llvm::OwningPtr<DiagnosticClient> DiagClient; 78 if (Opts.VerifyDiagnostics) { 79 // When checking diagnostics, just buffer them up. 80 DiagClient.reset(new TextDiagnosticBuffer()); 81 } else { 82 DiagClient.reset(new TextDiagnosticPrinter(llvm::errs(), Opts)); 83 } 84 85 if (!Opts.DumpBuildInformation.empty()) 86 SetUpBuildDumpLog(Opts, Argc, Argv, DiagClient); 87 88 // Configure our handling of diagnostics. 89 Diagnostic *Diags = new Diagnostic(DiagClient.take()); 90 if (ProcessWarningOptions(*Diags, Opts)) 91 return 0; 92 93 return Diags; 94 } 95 96 // File Manager 97 98 void CompilerInstance::createFileManager() { 99 FileMgr.reset(new FileManager()); 100 } 101 102 // Source Manager 103 104 void CompilerInstance::createSourceManager() { 105 SourceMgr.reset(new SourceManager()); 106 } 107 108 // Preprocessor 109 110 void CompilerInstance::createPreprocessor() { 111 PP.reset(createPreprocessor(getDiagnostics(), getLangOpts(), 112 getPreprocessorOpts(), getHeaderSearchOpts(), 113 getDependencyOutputOpts(), getTarget(), 114 getSourceManager(), getFileManager())); 115 } 116 117 Preprocessor * 118 CompilerInstance::createPreprocessor(Diagnostic &Diags, 119 const LangOptions &LangInfo, 120 const PreprocessorOptions &PPOpts, 121 const HeaderSearchOptions &HSOpts, 122 const DependencyOutputOptions &DepOpts, 123 const TargetInfo &Target, 124 SourceManager &SourceMgr, 125 FileManager &FileMgr) { 126 // Create a PTH manager if we are using some form of a token cache. 127 PTHManager *PTHMgr = 0; 128 if (!PPOpts.getTokenCache().empty()) 129 PTHMgr = PTHManager::Create(PPOpts.getTokenCache(), Diags); 130 131 // FIXME: Don't fail like this. 132 if (Diags.hasErrorOccurred()) 133 exit(1); 134 135 // Create the Preprocessor. 136 HeaderSearch *HeaderInfo = new HeaderSearch(FileMgr); 137 Preprocessor *PP = new Preprocessor(Diags, LangInfo, Target, 138 SourceMgr, *HeaderInfo, PTHMgr, 139 /*OwnsHeaderSearch=*/true); 140 141 // Note that this is different then passing PTHMgr to Preprocessor's ctor. 142 // That argument is used as the IdentifierInfoLookup argument to 143 // IdentifierTable's ctor. 144 if (PTHMgr) { 145 PTHMgr->setPreprocessor(PP); 146 PP->setPTHManager(PTHMgr); 147 } 148 149 InitializePreprocessor(*PP, PPOpts, HSOpts); 150 151 // Handle generating dependencies, if requested. 152 if (!DepOpts.OutputFile.empty()) 153 AttachDependencyFileGen(*PP, DepOpts); 154 155 return PP; 156 } 157 158 // ASTContext 159 160 void CompilerInstance::createASTContext() { 161 Preprocessor &PP = getPreprocessor(); 162 Context.reset(new ASTContext(getLangOpts(), PP.getSourceManager(), 163 getTarget(), PP.getIdentifierTable(), 164 PP.getSelectorTable(), PP.getBuiltinInfo(), 165 /*FreeMemory=*/ !getFrontendOpts().DisableFree, 166 /*size_reserve=*/ 0)); 167 } 168 169 // ExternalASTSource 170 171 void CompilerInstance::createPCHExternalASTSource(llvm::StringRef Path) { 172 llvm::OwningPtr<ExternalASTSource> Source; 173 Source.reset(createPCHExternalASTSource(Path, getHeaderSearchOpts().Sysroot, 174 getPreprocessor(), getASTContext())); 175 getASTContext().setExternalSource(Source); 176 } 177 178 ExternalASTSource * 179 CompilerInstance::createPCHExternalASTSource(llvm::StringRef Path, 180 const std::string &Sysroot, 181 Preprocessor &PP, 182 ASTContext &Context) { 183 llvm::OwningPtr<PCHReader> Reader; 184 Reader.reset(new PCHReader(PP, &Context, 185 Sysroot.empty() ? 0 : Sysroot.c_str())); 186 187 switch (Reader->ReadPCH(Path)) { 188 case PCHReader::Success: 189 // Set the predefines buffer as suggested by the PCH reader. Typically, the 190 // predefines buffer will be empty. 191 PP.setPredefines(Reader->getSuggestedPredefines()); 192 return Reader.take(); 193 194 case PCHReader::Failure: 195 // Unrecoverable failure: don't even try to process the input file. 196 break; 197 198 case PCHReader::IgnorePCH: 199 // No suitable PCH file could be found. Return an error. 200 break; 201 } 202 203 return 0; 204 } 205