clang API Documentation
00001 //===--- CompilerInstance.cpp ---------------------------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "clang/Frontend/CompilerInstance.h" 00011 #include "clang/Sema/Sema.h" 00012 #include "clang/AST/ASTConsumer.h" 00013 #include "clang/AST/ASTContext.h" 00014 #include "clang/AST/Decl.h" 00015 #include "clang/Basic/Diagnostic.h" 00016 #include "clang/Basic/FileManager.h" 00017 #include "clang/Basic/SourceManager.h" 00018 #include "clang/Basic/TargetInfo.h" 00019 #include "clang/Basic/Version.h" 00020 #include "clang/Lex/HeaderSearch.h" 00021 #include "clang/Lex/Preprocessor.h" 00022 #include "clang/Lex/PTHManager.h" 00023 #include "clang/Frontend/ChainedDiagnosticConsumer.h" 00024 #include "clang/Frontend/FrontendAction.h" 00025 #include "clang/Frontend/FrontendActions.h" 00026 #include "clang/Frontend/FrontendDiagnostic.h" 00027 #include "clang/Frontend/LogDiagnosticPrinter.h" 00028 #include "clang/Frontend/SerializedDiagnosticPrinter.h" 00029 #include "clang/Frontend/TextDiagnosticPrinter.h" 00030 #include "clang/Frontend/VerifyDiagnosticConsumer.h" 00031 #include "clang/Frontend/Utils.h" 00032 #include "clang/Serialization/ASTReader.h" 00033 #include "clang/Sema/CodeCompleteConsumer.h" 00034 #include "llvm/Support/FileSystem.h" 00035 #include "llvm/Support/MemoryBuffer.h" 00036 #include "llvm/Support/raw_ostream.h" 00037 #include "llvm/ADT/Statistic.h" 00038 #include "llvm/Support/Timer.h" 00039 #include "llvm/Support/Host.h" 00040 #include "llvm/Support/LockFileManager.h" 00041 #include "llvm/Support/Path.h" 00042 #include "llvm/Support/Program.h" 00043 #include "llvm/Support/Signals.h" 00044 #include "llvm/Support/system_error.h" 00045 #include "llvm/Support/CrashRecoveryContext.h" 00046 #include "llvm/Config/config.h" 00047 00048 using namespace clang; 00049 00050 CompilerInstance::CompilerInstance() 00051 : Invocation(new CompilerInvocation()), ModuleManager(0) { 00052 } 00053 00054 CompilerInstance::~CompilerInstance() { 00055 } 00056 00057 void CompilerInstance::setInvocation(CompilerInvocation *Value) { 00058 Invocation = Value; 00059 } 00060 00061 void CompilerInstance::setDiagnostics(DiagnosticsEngine *Value) { 00062 Diagnostics = Value; 00063 } 00064 00065 void CompilerInstance::setTarget(TargetInfo *Value) { 00066 Target = Value; 00067 } 00068 00069 void CompilerInstance::setFileManager(FileManager *Value) { 00070 FileMgr = Value; 00071 } 00072 00073 void CompilerInstance::setSourceManager(SourceManager *Value) { 00074 SourceMgr = Value; 00075 } 00076 00077 void CompilerInstance::setPreprocessor(Preprocessor *Value) { PP = Value; } 00078 00079 void CompilerInstance::setASTContext(ASTContext *Value) { Context = Value; } 00080 00081 void CompilerInstance::setSema(Sema *S) { 00082 TheSema.reset(S); 00083 } 00084 00085 void CompilerInstance::setASTConsumer(ASTConsumer *Value) { 00086 Consumer.reset(Value); 00087 } 00088 00089 void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) { 00090 CompletionConsumer.reset(Value); 00091 getFrontendOpts().SkipFunctionBodies = Value != 0; 00092 } 00093 00094 // Diagnostics 00095 static void SetUpBuildDumpLog(const DiagnosticOptions &DiagOpts, 00096 unsigned argc, const char* const *argv, 00097 DiagnosticsEngine &Diags) { 00098 std::string ErrorInfo; 00099 OwningPtr<raw_ostream> OS( 00100 new llvm::raw_fd_ostream(DiagOpts.DumpBuildInformation.c_str(), ErrorInfo)); 00101 if (!ErrorInfo.empty()) { 00102 Diags.Report(diag::err_fe_unable_to_open_logfile) 00103 << DiagOpts.DumpBuildInformation << ErrorInfo; 00104 return; 00105 } 00106 00107 (*OS) << "clang -cc1 command line arguments: "; 00108 for (unsigned i = 0; i != argc; ++i) 00109 (*OS) << argv[i] << ' '; 00110 (*OS) << '\n'; 00111 00112 // Chain in a diagnostic client which will log the diagnostics. 00113 DiagnosticConsumer *Logger = 00114 new TextDiagnosticPrinter(*OS.take(), DiagOpts, /*OwnsOutputStream=*/true); 00115 Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(), Logger)); 00116 } 00117 00118 static void SetUpDiagnosticLog(const DiagnosticOptions &DiagOpts, 00119 const CodeGenOptions *CodeGenOpts, 00120 DiagnosticsEngine &Diags) { 00121 std::string ErrorInfo; 00122 bool OwnsStream = false; 00123 raw_ostream *OS = &llvm::errs(); 00124 if (DiagOpts.DiagnosticLogFile != "-") { 00125 // Create the output stream. 00126 llvm::raw_fd_ostream *FileOS( 00127 new llvm::raw_fd_ostream(DiagOpts.DiagnosticLogFile.c_str(), 00128 ErrorInfo, llvm::raw_fd_ostream::F_Append)); 00129 if (!ErrorInfo.empty()) { 00130 Diags.Report(diag::warn_fe_cc_log_diagnostics_failure) 00131 << DiagOpts.DumpBuildInformation << ErrorInfo; 00132 } else { 00133 FileOS->SetUnbuffered(); 00134 FileOS->SetUseAtomicWrites(true); 00135 OS = FileOS; 00136 OwnsStream = true; 00137 } 00138 } 00139 00140 // Chain in the diagnostic client which will log the diagnostics. 00141 LogDiagnosticPrinter *Logger = new LogDiagnosticPrinter(*OS, DiagOpts, 00142 OwnsStream); 00143 if (CodeGenOpts) 00144 Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags); 00145 Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(), Logger)); 00146 } 00147 00148 static void SetupSerializedDiagnostics(const DiagnosticOptions &DiagOpts, 00149 DiagnosticsEngine &Diags, 00150 StringRef OutputFile) { 00151 std::string ErrorInfo; 00152 OwningPtr<llvm::raw_fd_ostream> OS; 00153 OS.reset(new llvm::raw_fd_ostream(OutputFile.str().c_str(), ErrorInfo, 00154 llvm::raw_fd_ostream::F_Binary)); 00155 00156 if (!ErrorInfo.empty()) { 00157 Diags.Report(diag::warn_fe_serialized_diag_failure) 00158 << OutputFile << ErrorInfo; 00159 return; 00160 } 00161 00162 DiagnosticConsumer *SerializedConsumer = 00163 clang::serialized_diags::create(OS.take(), DiagOpts); 00164 00165 00166 Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(), 00167 SerializedConsumer)); 00168 } 00169 00170 void CompilerInstance::createDiagnostics(int Argc, const char* const *Argv, 00171 DiagnosticConsumer *Client, 00172 bool ShouldOwnClient, 00173 bool ShouldCloneClient) { 00174 Diagnostics = createDiagnostics(getDiagnosticOpts(), Argc, Argv, Client, 00175 ShouldOwnClient, ShouldCloneClient, 00176 &getCodeGenOpts()); 00177 } 00178 00179 IntrusiveRefCntPtr<DiagnosticsEngine> 00180 CompilerInstance::createDiagnostics(const DiagnosticOptions &Opts, 00181 int Argc, const char* const *Argv, 00182 DiagnosticConsumer *Client, 00183 bool ShouldOwnClient, 00184 bool ShouldCloneClient, 00185 const CodeGenOptions *CodeGenOpts) { 00186 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 00187 IntrusiveRefCntPtr<DiagnosticsEngine> 00188 Diags(new DiagnosticsEngine(DiagID)); 00189 00190 // Create the diagnostic client for reporting errors or for 00191 // implementing -verify. 00192 if (Client) { 00193 if (ShouldCloneClient) 00194 Diags->setClient(Client->clone(*Diags), ShouldOwnClient); 00195 else 00196 Diags->setClient(Client, ShouldOwnClient); 00197 } else 00198 Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts)); 00199 00200 // Chain in -verify checker, if requested. 00201 if (Opts.VerifyDiagnostics) 00202 Diags->setClient(new VerifyDiagnosticConsumer(*Diags)); 00203 00204 // Chain in -diagnostic-log-file dumper, if requested. 00205 if (!Opts.DiagnosticLogFile.empty()) 00206 SetUpDiagnosticLog(Opts, CodeGenOpts, *Diags); 00207 00208 if (!Opts.DumpBuildInformation.empty()) 00209 SetUpBuildDumpLog(Opts, Argc, Argv, *Diags); 00210 00211 if (!Opts.DiagnosticSerializationFile.empty()) 00212 SetupSerializedDiagnostics(Opts, *Diags, 00213 Opts.DiagnosticSerializationFile); 00214 00215 // Configure our handling of diagnostics. 00216 ProcessWarningOptions(*Diags, Opts); 00217 00218 return Diags; 00219 } 00220 00221 // File Manager 00222 00223 void CompilerInstance::createFileManager() { 00224 FileMgr = new FileManager(getFileSystemOpts()); 00225 } 00226 00227 // Source Manager 00228 00229 void CompilerInstance::createSourceManager(FileManager &FileMgr) { 00230 SourceMgr = new SourceManager(getDiagnostics(), FileMgr); 00231 } 00232 00233 // Preprocessor 00234 00235 void CompilerInstance::createPreprocessor() { 00236 const PreprocessorOptions &PPOpts = getPreprocessorOpts(); 00237 00238 // Create a PTH manager if we are using some form of a token cache. 00239 PTHManager *PTHMgr = 0; 00240 if (!PPOpts.TokenCache.empty()) 00241 PTHMgr = PTHManager::Create(PPOpts.TokenCache, getDiagnostics()); 00242 00243 // Create the Preprocessor. 00244 HeaderSearch *HeaderInfo = new HeaderSearch(getFileManager(), 00245 getDiagnostics(), 00246 getLangOpts(), 00247 &getTarget()); 00248 PP = new Preprocessor(getDiagnostics(), getLangOpts(), &getTarget(), 00249 getSourceManager(), *HeaderInfo, *this, PTHMgr, 00250 /*OwnsHeaderSearch=*/true); 00251 00252 // Note that this is different then passing PTHMgr to Preprocessor's ctor. 00253 // That argument is used as the IdentifierInfoLookup argument to 00254 // IdentifierTable's ctor. 00255 if (PTHMgr) { 00256 PTHMgr->setPreprocessor(&*PP); 00257 PP->setPTHManager(PTHMgr); 00258 } 00259 00260 if (PPOpts.DetailedRecord) 00261 PP->createPreprocessingRecord(PPOpts.DetailedRecordConditionalDirectives); 00262 00263 InitializePreprocessor(*PP, PPOpts, getHeaderSearchOpts(), getFrontendOpts()); 00264 00265 // Set up the module path, including the hash for the 00266 // module-creation options. 00267 SmallString<256> SpecificModuleCache( 00268 getHeaderSearchOpts().ModuleCachePath); 00269 if (!getHeaderSearchOpts().DisableModuleHash) 00270 llvm::sys::path::append(SpecificModuleCache, 00271 getInvocation().getModuleHash()); 00272 PP->getHeaderSearchInfo().setModuleCachePath(SpecificModuleCache); 00273 00274 // Handle generating dependencies, if requested. 00275 const DependencyOutputOptions &DepOpts = getDependencyOutputOpts(); 00276 if (!DepOpts.OutputFile.empty()) 00277 AttachDependencyFileGen(*PP, DepOpts); 00278 if (!DepOpts.DOTOutputFile.empty()) 00279 AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile, 00280 getHeaderSearchOpts().Sysroot); 00281 00282 00283 // Handle generating header include information, if requested. 00284 if (DepOpts.ShowHeaderIncludes) 00285 AttachHeaderIncludeGen(*PP); 00286 if (!DepOpts.HeaderIncludeOutputFile.empty()) { 00287 StringRef OutputPath = DepOpts.HeaderIncludeOutputFile; 00288 if (OutputPath == "-") 00289 OutputPath = ""; 00290 AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/true, OutputPath, 00291 /*ShowDepth=*/false); 00292 } 00293 } 00294 00295 // ASTContext 00296 00297 void CompilerInstance::createASTContext() { 00298 Preprocessor &PP = getPreprocessor(); 00299 Context = new ASTContext(getLangOpts(), PP.getSourceManager(), 00300 &getTarget(), PP.getIdentifierTable(), 00301 PP.getSelectorTable(), PP.getBuiltinInfo(), 00302 /*size_reserve=*/ 0); 00303 } 00304 00305 // ExternalASTSource 00306 00307 void CompilerInstance::createPCHExternalASTSource(StringRef Path, 00308 bool DisablePCHValidation, 00309 bool DisableStatCache, 00310 bool AllowPCHWithCompilerErrors, 00311 void *DeserializationListener){ 00312 OwningPtr<ExternalASTSource> Source; 00313 bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0; 00314 Source.reset(createPCHExternalASTSource(Path, getHeaderSearchOpts().Sysroot, 00315 DisablePCHValidation, 00316 DisableStatCache, 00317 AllowPCHWithCompilerErrors, 00318 getPreprocessor(), getASTContext(), 00319 DeserializationListener, 00320 Preamble)); 00321 ModuleManager = static_cast<ASTReader*>(Source.get()); 00322 getASTContext().setExternalSource(Source); 00323 } 00324 00325 ExternalASTSource * 00326 CompilerInstance::createPCHExternalASTSource(StringRef Path, 00327 const std::string &Sysroot, 00328 bool DisablePCHValidation, 00329 bool DisableStatCache, 00330 bool AllowPCHWithCompilerErrors, 00331 Preprocessor &PP, 00332 ASTContext &Context, 00333 void *DeserializationListener, 00334 bool Preamble) { 00335 OwningPtr<ASTReader> Reader; 00336 Reader.reset(new ASTReader(PP, Context, 00337 Sysroot.empty() ? "" : Sysroot.c_str(), 00338 DisablePCHValidation, DisableStatCache, 00339 AllowPCHWithCompilerErrors)); 00340 00341 Reader->setDeserializationListener( 00342 static_cast<ASTDeserializationListener *>(DeserializationListener)); 00343 switch (Reader->ReadAST(Path, 00344 Preamble ? serialization::MK_Preamble 00345 : serialization::MK_PCH)) { 00346 case ASTReader::Success: 00347 // Set the predefines buffer as suggested by the PCH reader. Typically, the 00348 // predefines buffer will be empty. 00349 PP.setPredefines(Reader->getSuggestedPredefines()); 00350 return Reader.take(); 00351 00352 case ASTReader::Failure: 00353 // Unrecoverable failure: don't even try to process the input file. 00354 break; 00355 00356 case ASTReader::IgnorePCH: 00357 // No suitable PCH file could be found. Return an error. 00358 break; 00359 } 00360 00361 return 0; 00362 } 00363 00364 // Code Completion 00365 00366 static bool EnableCodeCompletion(Preprocessor &PP, 00367 const std::string &Filename, 00368 unsigned Line, 00369 unsigned Column) { 00370 // Tell the source manager to chop off the given file at a specific 00371 // line and column. 00372 const FileEntry *Entry = PP.getFileManager().getFile(Filename); 00373 if (!Entry) { 00374 PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file) 00375 << Filename; 00376 return true; 00377 } 00378 00379 // Truncate the named file at the given line/column. 00380 PP.SetCodeCompletionPoint(Entry, Line, Column); 00381 return false; 00382 } 00383 00384 void CompilerInstance::createCodeCompletionConsumer() { 00385 const ParsedSourceLocation &Loc = getFrontendOpts().CodeCompletionAt; 00386 if (!CompletionConsumer) { 00387 setCodeCompletionConsumer( 00388 createCodeCompletionConsumer(getPreprocessor(), 00389 Loc.FileName, Loc.Line, Loc.Column, 00390 getFrontendOpts().ShowMacrosInCodeCompletion, 00391 getFrontendOpts().ShowCodePatternsInCodeCompletion, 00392 getFrontendOpts().ShowGlobalSymbolsInCodeCompletion, 00393 llvm::outs())); 00394 if (!CompletionConsumer) 00395 return; 00396 } else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName, 00397 Loc.Line, Loc.Column)) { 00398 setCodeCompletionConsumer(0); 00399 return; 00400 } 00401 00402 if (CompletionConsumer->isOutputBinary() && 00403 llvm::sys::Program::ChangeStdoutToBinary()) { 00404 getPreprocessor().getDiagnostics().Report(diag::err_fe_stdout_binary); 00405 setCodeCompletionConsumer(0); 00406 } 00407 } 00408 00409 void CompilerInstance::createFrontendTimer() { 00410 FrontendTimer.reset(new llvm::Timer("Clang front-end timer")); 00411 } 00412 00413 CodeCompleteConsumer * 00414 CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP, 00415 const std::string &Filename, 00416 unsigned Line, 00417 unsigned Column, 00418 bool ShowMacros, 00419 bool ShowCodePatterns, 00420 bool ShowGlobals, 00421 raw_ostream &OS) { 00422 if (EnableCodeCompletion(PP, Filename, Line, Column)) 00423 return 0; 00424 00425 // Set up the creation routine for code-completion. 00426 return new PrintingCodeCompleteConsumer(ShowMacros, ShowCodePatterns, 00427 ShowGlobals, OS); 00428 } 00429 00430 void CompilerInstance::createSema(TranslationUnitKind TUKind, 00431 CodeCompleteConsumer *CompletionConsumer) { 00432 TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(), 00433 TUKind, CompletionConsumer)); 00434 } 00435 00436 // Output Files 00437 00438 void CompilerInstance::addOutputFile(const OutputFile &OutFile) { 00439 assert(OutFile.OS && "Attempt to add empty stream to output list!"); 00440 OutputFiles.push_back(OutFile); 00441 } 00442 00443 void CompilerInstance::clearOutputFiles(bool EraseFiles) { 00444 for (std::list<OutputFile>::iterator 00445 it = OutputFiles.begin(), ie = OutputFiles.end(); it != ie; ++it) { 00446 delete it->OS; 00447 if (!it->TempFilename.empty()) { 00448 if (EraseFiles) { 00449 bool existed; 00450 llvm::sys::fs::remove(it->TempFilename, existed); 00451 } else { 00452 SmallString<128> NewOutFile(it->Filename); 00453 00454 // If '-working-directory' was passed, the output filename should be 00455 // relative to that. 00456 FileMgr->FixupRelativePath(NewOutFile); 00457 if (llvm::error_code ec = llvm::sys::fs::rename(it->TempFilename, 00458 NewOutFile.str())) { 00459 getDiagnostics().Report(diag::err_unable_to_rename_temp) 00460 << it->TempFilename << it->Filename << ec.message(); 00461 00462 bool existed; 00463 llvm::sys::fs::remove(it->TempFilename, existed); 00464 } 00465 } 00466 } else if (!it->Filename.empty() && EraseFiles) 00467 llvm::sys::Path(it->Filename).eraseFromDisk(); 00468 00469 } 00470 OutputFiles.clear(); 00471 } 00472 00473 llvm::raw_fd_ostream * 00474 CompilerInstance::createDefaultOutputFile(bool Binary, 00475 StringRef InFile, 00476 StringRef Extension) { 00477 return createOutputFile(getFrontendOpts().OutputFile, Binary, 00478 /*RemoveFileOnSignal=*/true, InFile, Extension, 00479 /*UseTemporary=*/true); 00480 } 00481 00482 llvm::raw_fd_ostream * 00483 CompilerInstance::createOutputFile(StringRef OutputPath, 00484 bool Binary, bool RemoveFileOnSignal, 00485 StringRef InFile, 00486 StringRef Extension, 00487 bool UseTemporary, 00488 bool CreateMissingDirectories) { 00489 std::string Error, OutputPathName, TempPathName; 00490 llvm::raw_fd_ostream *OS = createOutputFile(OutputPath, Error, Binary, 00491 RemoveFileOnSignal, 00492 InFile, Extension, 00493 UseTemporary, 00494 CreateMissingDirectories, 00495 &OutputPathName, 00496 &TempPathName); 00497 if (!OS) { 00498 getDiagnostics().Report(diag::err_fe_unable_to_open_output) 00499 << OutputPath << Error; 00500 return 0; 00501 } 00502 00503 // Add the output file -- but don't try to remove "-", since this means we are 00504 // using stdin. 00505 addOutputFile(OutputFile((OutputPathName != "-") ? OutputPathName : "", 00506 TempPathName, OS)); 00507 00508 return OS; 00509 } 00510 00511 llvm::raw_fd_ostream * 00512 CompilerInstance::createOutputFile(StringRef OutputPath, 00513 std::string &Error, 00514 bool Binary, 00515 bool RemoveFileOnSignal, 00516 StringRef InFile, 00517 StringRef Extension, 00518 bool UseTemporary, 00519 bool CreateMissingDirectories, 00520 std::string *ResultPathName, 00521 std::string *TempPathName) { 00522 assert((!CreateMissingDirectories || UseTemporary) && 00523 "CreateMissingDirectories is only allowed when using temporary files"); 00524 00525 std::string OutFile, TempFile; 00526 if (!OutputPath.empty()) { 00527 OutFile = OutputPath; 00528 } else if (InFile == "-") { 00529 OutFile = "-"; 00530 } else if (!Extension.empty()) { 00531 llvm::sys::Path Path(InFile); 00532 Path.eraseSuffix(); 00533 Path.appendSuffix(Extension); 00534 OutFile = Path.str(); 00535 } else { 00536 OutFile = "-"; 00537 } 00538 00539 OwningPtr<llvm::raw_fd_ostream> OS; 00540 std::string OSFile; 00541 00542 if (UseTemporary && OutFile != "-") { 00543 // Only create the temporary if the parent directory exists (or create 00544 // missing directories is true) and we can actually write to OutPath, 00545 // otherwise we want to fail early. 00546 SmallString<256> AbsPath(OutputPath); 00547 llvm::sys::fs::make_absolute(AbsPath); 00548 llvm::sys::Path OutPath(AbsPath); 00549 bool ParentExists = false; 00550 if (llvm::sys::fs::exists(llvm::sys::path::parent_path(AbsPath.str()), 00551 ParentExists)) 00552 ParentExists = false; 00553 bool Exists; 00554 if ((CreateMissingDirectories || ParentExists) && 00555 ((llvm::sys::fs::exists(AbsPath.str(), Exists) || !Exists) || 00556 (OutPath.isRegularFile() && OutPath.canWrite()))) { 00557 // Create a temporary file. 00558 SmallString<128> TempPath; 00559 TempPath = OutFile; 00560 TempPath += "-%%%%%%%%"; 00561 int fd; 00562 if (llvm::sys::fs::unique_file(TempPath.str(), fd, TempPath, 00563 /*makeAbsolute=*/false, 0664) 00564 == llvm::errc::success) { 00565 OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true)); 00566 OSFile = TempFile = TempPath.str(); 00567 } 00568 } 00569 } 00570 00571 if (!OS) { 00572 OSFile = OutFile; 00573 OS.reset( 00574 new llvm::raw_fd_ostream(OSFile.c_str(), Error, 00575 (Binary ? llvm::raw_fd_ostream::F_Binary : 0))); 00576 if (!Error.empty()) 00577 return 0; 00578 } 00579 00580 // Make sure the out stream file gets removed if we crash. 00581 if (RemoveFileOnSignal) 00582 llvm::sys::RemoveFileOnSignal(llvm::sys::Path(OSFile)); 00583 00584 if (ResultPathName) 00585 *ResultPathName = OutFile; 00586 if (TempPathName) 00587 *TempPathName = TempFile; 00588 00589 return OS.take(); 00590 } 00591 00592 // Initialization Utilities 00593 00594 bool CompilerInstance::InitializeSourceManager(StringRef InputFile, 00595 SrcMgr::CharacteristicKind Kind){ 00596 return InitializeSourceManager(InputFile, Kind, getDiagnostics(), 00597 getFileManager(), getSourceManager(), 00598 getFrontendOpts()); 00599 } 00600 00601 bool CompilerInstance::InitializeSourceManager(StringRef InputFile, 00602 SrcMgr::CharacteristicKind Kind, 00603 DiagnosticsEngine &Diags, 00604 FileManager &FileMgr, 00605 SourceManager &SourceMgr, 00606 const FrontendOptions &Opts) { 00607 // Figure out where to get and map in the main file. 00608 if (InputFile != "-") { 00609 const FileEntry *File = FileMgr.getFile(InputFile); 00610 if (!File) { 00611 Diags.Report(diag::err_fe_error_reading) << InputFile; 00612 return false; 00613 } 00614 SourceMgr.createMainFileID(File, Kind); 00615 } else { 00616 OwningPtr<llvm::MemoryBuffer> SB; 00617 if (llvm::MemoryBuffer::getSTDIN(SB)) { 00618 // FIXME: Give ec.message() in this diag. 00619 Diags.Report(diag::err_fe_error_reading_stdin); 00620 return false; 00621 } 00622 const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(), 00623 SB->getBufferSize(), 0); 00624 SourceMgr.createMainFileID(File, Kind); 00625 SourceMgr.overrideFileContents(File, SB.take()); 00626 } 00627 00628 assert(!SourceMgr.getMainFileID().isInvalid() && 00629 "Couldn't establish MainFileID!"); 00630 return true; 00631 } 00632 00633 // High-Level Operations 00634 00635 bool CompilerInstance::ExecuteAction(FrontendAction &Act) { 00636 assert(hasDiagnostics() && "Diagnostics engine is not initialized!"); 00637 assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!"); 00638 assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!"); 00639 00640 // FIXME: Take this as an argument, once all the APIs we used have moved to 00641 // taking it as an input instead of hard-coding llvm::errs. 00642 raw_ostream &OS = llvm::errs(); 00643 00644 // Create the target instance. 00645 setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), getTargetOpts())); 00646 if (!hasTarget()) 00647 return false; 00648 00649 // Inform the target of the language options. 00650 // 00651 // FIXME: We shouldn't need to do this, the target should be immutable once 00652 // created. This complexity should be lifted elsewhere. 00653 getTarget().setForcedLangOptions(getLangOpts()); 00654 00655 // rewriter project will change target built-in bool type from its default. 00656 if (getFrontendOpts().ProgramAction == frontend::RewriteObjC) 00657 getTarget().noSignedCharForObjCBool(); 00658 00659 // Validate/process some options. 00660 if (getHeaderSearchOpts().Verbose) 00661 OS << "clang -cc1 version " CLANG_VERSION_STRING 00662 << " based upon " << PACKAGE_STRING 00663 << " default target " << llvm::sys::getDefaultTargetTriple() << "\n"; 00664 00665 if (getFrontendOpts().ShowTimers) 00666 createFrontendTimer(); 00667 00668 if (getFrontendOpts().ShowStats) 00669 llvm::EnableStatistics(); 00670 00671 for (unsigned i = 0, e = getFrontendOpts().Inputs.size(); i != e; ++i) { 00672 // Reset the ID tables if we are reusing the SourceManager. 00673 if (hasSourceManager()) 00674 getSourceManager().clearIDTables(); 00675 00676 if (Act.BeginSourceFile(*this, getFrontendOpts().Inputs[i])) { 00677 Act.Execute(); 00678 Act.EndSourceFile(); 00679 } 00680 } 00681 00682 // Notify the diagnostic client that all files were processed. 00683 getDiagnostics().getClient()->finish(); 00684 00685 if (getDiagnosticOpts().ShowCarets) { 00686 // We can have multiple diagnostics sharing one diagnostic client. 00687 // Get the total number of warnings/errors from the client. 00688 unsigned NumWarnings = getDiagnostics().getClient()->getNumWarnings(); 00689 unsigned NumErrors = getDiagnostics().getClient()->getNumErrors(); 00690 00691 if (NumWarnings) 00692 OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s"); 00693 if (NumWarnings && NumErrors) 00694 OS << " and "; 00695 if (NumErrors) 00696 OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s"); 00697 if (NumWarnings || NumErrors) 00698 OS << " generated.\n"; 00699 } 00700 00701 if (getFrontendOpts().ShowStats && hasFileManager()) { 00702 getFileManager().PrintStats(); 00703 OS << "\n"; 00704 } 00705 00706 return !getDiagnostics().getClient()->getNumErrors(); 00707 } 00708 00709 /// \brief Determine the appropriate source input kind based on language 00710 /// options. 00711 static InputKind getSourceInputKindFromOptions(const LangOptions &LangOpts) { 00712 if (LangOpts.OpenCL) 00713 return IK_OpenCL; 00714 if (LangOpts.CUDA) 00715 return IK_CUDA; 00716 if (LangOpts.ObjC1) 00717 return LangOpts.CPlusPlus? IK_ObjCXX : IK_ObjC; 00718 return LangOpts.CPlusPlus? IK_CXX : IK_C; 00719 } 00720 00721 namespace { 00722 struct CompileModuleMapData { 00723 CompilerInstance &Instance; 00724 GenerateModuleAction &CreateModuleAction; 00725 }; 00726 } 00727 00728 /// \brief Helper function that executes the module-generating action under 00729 /// a crash recovery context. 00730 static void doCompileMapModule(void *UserData) { 00731 CompileModuleMapData &Data 00732 = *reinterpret_cast<CompileModuleMapData *>(UserData); 00733 Data.Instance.ExecuteAction(Data.CreateModuleAction); 00734 } 00735 00736 /// \brief Compile a module file for the given module, using the options 00737 /// provided by the importing compiler instance. 00738 static void compileModule(CompilerInstance &ImportingInstance, 00739 Module *Module, 00740 StringRef ModuleFileName) { 00741 llvm::LockFileManager Locked(ModuleFileName); 00742 switch (Locked) { 00743 case llvm::LockFileManager::LFS_Error: 00744 return; 00745 00746 case llvm::LockFileManager::LFS_Owned: 00747 // We're responsible for building the module ourselves. Do so below. 00748 break; 00749 00750 case llvm::LockFileManager::LFS_Shared: 00751 // Someone else is responsible for building the module. Wait for them to 00752 // finish. 00753 Locked.waitForUnlock(); 00754 break; 00755 } 00756 00757 ModuleMap &ModMap 00758 = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap(); 00759 00760 // Construct a compiler invocation for creating this module. 00761 IntrusiveRefCntPtr<CompilerInvocation> Invocation 00762 (new CompilerInvocation(ImportingInstance.getInvocation())); 00763 00764 PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 00765 00766 // For any options that aren't intended to affect how a module is built, 00767 // reset them to their default values. 00768 Invocation->getLangOpts()->resetNonModularOptions(); 00769 PPOpts.resetNonModularOptions(); 00770 00771 // Note the name of the module we're building. 00772 Invocation->getLangOpts()->CurrentModule = Module->getTopLevelModuleName(); 00773 00774 // Note that this module is part of the module build path, so that we 00775 // can detect cycles in the module graph. 00776 PPOpts.ModuleBuildPath.push_back(Module->getTopLevelModuleName()); 00777 00778 // If there is a module map file, build the module using the module map. 00779 // Set up the inputs/outputs so that we build the module from its umbrella 00780 // header. 00781 FrontendOptions &FrontendOpts = Invocation->getFrontendOpts(); 00782 FrontendOpts.OutputFile = ModuleFileName.str(); 00783 FrontendOpts.DisableFree = false; 00784 FrontendOpts.Inputs.clear(); 00785 InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts()); 00786 00787 // Get or create the module map that we'll use to build this module. 00788 SmallString<128> TempModuleMapFileName; 00789 if (const FileEntry *ModuleMapFile 00790 = ModMap.getContainingModuleMapFile(Module)) { 00791 // Use the module map where this module resides. 00792 FrontendOpts.Inputs.push_back(FrontendInputFile(ModuleMapFile->getName(), 00793 IK)); 00794 } else { 00795 // Create a temporary module map file. 00796 TempModuleMapFileName = Module->Name; 00797 TempModuleMapFileName += "-%%%%%%%%.map"; 00798 int FD; 00799 if (llvm::sys::fs::unique_file(TempModuleMapFileName.str(), FD, 00800 TempModuleMapFileName, 00801 /*makeAbsolute=*/true) 00802 != llvm::errc::success) { 00803 ImportingInstance.getDiagnostics().Report(diag::err_module_map_temp_file) 00804 << TempModuleMapFileName; 00805 return; 00806 } 00807 // Print the module map to this file. 00808 llvm::raw_fd_ostream OS(FD, /*shouldClose=*/true); 00809 Module->print(OS); 00810 FrontendOpts.Inputs.push_back( 00811 FrontendInputFile(TempModuleMapFileName.str().str(), IK)); 00812 } 00813 00814 // Don't free the remapped file buffers; they are owned by our caller. 00815 PPOpts.RetainRemappedFileBuffers = true; 00816 00817 Invocation->getDiagnosticOpts().VerifyDiagnostics = 0; 00818 assert(ImportingInstance.getInvocation().getModuleHash() == 00819 Invocation->getModuleHash() && "Module hash mismatch!"); 00820 00821 // Construct a compiler instance that will be used to actually create the 00822 // module. 00823 CompilerInstance Instance; 00824 Instance.setInvocation(&*Invocation); 00825 Instance.createDiagnostics(/*argc=*/0, /*argv=*/0, 00826 &ImportingInstance.getDiagnosticClient(), 00827 /*ShouldOwnClient=*/true, 00828 /*ShouldCloneClient=*/true); 00829 00830 // Construct a module-generating action. 00831 GenerateModuleAction CreateModuleAction; 00832 00833 // Execute the action to actually build the module in-place. Use a separate 00834 // thread so that we get a stack large enough. 00835 const unsigned ThreadStackSize = 8 << 20; 00836 llvm::CrashRecoveryContext CRC; 00837 CompileModuleMapData Data = { Instance, CreateModuleAction }; 00838 CRC.RunSafelyOnThread(&doCompileMapModule, &Data, ThreadStackSize); 00839 00840 // Delete the temporary module map file. 00841 // FIXME: Even though we're executing under crash protection, it would still 00842 // be nice to do this with RemoveFileOnSignal when we can. However, that 00843 // doesn't make sense for all clients, so clean this up manually. 00844 if (!TempModuleMapFileName.empty()) 00845 llvm::sys::Path(TempModuleMapFileName).eraseFromDisk(); 00846 } 00847 00848 Module *CompilerInstance::loadModule(SourceLocation ImportLoc, 00849 ModuleIdPath Path, 00850 Module::NameVisibilityKind Visibility, 00851 bool IsInclusionDirective) { 00852 // If we've already handled this import, just return the cached result. 00853 // This one-element cache is important to eliminate redundant diagnostics 00854 // when both the preprocessor and parser see the same import declaration. 00855 if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc) { 00856 // Make the named module visible. 00857 if (LastModuleImportResult) 00858 ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility); 00859 return LastModuleImportResult; 00860 } 00861 00862 // Determine what file we're searching from. 00863 StringRef ModuleName = Path[0].first->getName(); 00864 SourceLocation ModuleNameLoc = Path[0].second; 00865 00866 clang::Module *Module = 0; 00867 00868 // If we don't already have information on this module, load the module now. 00869 llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known 00870 = KnownModules.find(Path[0].first); 00871 if (Known != KnownModules.end()) { 00872 // Retrieve the cached top-level module. 00873 Module = Known->second; 00874 } else if (ModuleName == getLangOpts().CurrentModule) { 00875 // This is the module we're building. 00876 Module = PP->getHeaderSearchInfo().getModuleMap().findModule(ModuleName); 00877 Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; 00878 } else { 00879 // Search for a module with the given name. 00880 Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); 00881 std::string ModuleFileName; 00882 if (Module) 00883 ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module); 00884 else 00885 ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(ModuleName); 00886 00887 if (ModuleFileName.empty()) { 00888 getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found) 00889 << ModuleName 00890 << SourceRange(ImportLoc, ModuleNameLoc); 00891 LastModuleImportLoc = ImportLoc; 00892 LastModuleImportResult = 0; 00893 return 0; 00894 } 00895 00896 const FileEntry *ModuleFile 00897 = getFileManager().getFile(ModuleFileName, /*OpenFile=*/false, 00898 /*CacheFailure=*/false); 00899 bool BuildingModule = false; 00900 if (!ModuleFile && Module) { 00901 // The module is not cached, but we have a module map from which we can 00902 // build the module. 00903 00904 // Check whether there is a cycle in the module graph. 00905 SmallVectorImpl<std::string> &ModuleBuildPath 00906 = getPreprocessorOpts().ModuleBuildPath; 00907 SmallVectorImpl<std::string>::iterator Pos 00908 = std::find(ModuleBuildPath.begin(), ModuleBuildPath.end(), ModuleName); 00909 if (Pos != ModuleBuildPath.end()) { 00910 SmallString<256> CyclePath; 00911 for (; Pos != ModuleBuildPath.end(); ++Pos) { 00912 CyclePath += *Pos; 00913 CyclePath += " -> "; 00914 } 00915 CyclePath += ModuleName; 00916 00917 getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle) 00918 << ModuleName << CyclePath; 00919 return 0; 00920 } 00921 00922 getDiagnostics().Report(ModuleNameLoc, diag::warn_module_build) 00923 << ModuleName; 00924 BuildingModule = true; 00925 compileModule(*this, Module, ModuleFileName); 00926 ModuleFile = FileMgr->getFile(ModuleFileName); 00927 } 00928 00929 if (!ModuleFile) { 00930 getDiagnostics().Report(ModuleNameLoc, 00931 BuildingModule? diag::err_module_not_built 00932 : diag::err_module_not_found) 00933 << ModuleName 00934 << SourceRange(ImportLoc, ModuleNameLoc); 00935 return 0; 00936 } 00937 00938 // If we don't already have an ASTReader, create one now. 00939 if (!ModuleManager) { 00940 if (!hasASTContext()) 00941 createASTContext(); 00942 00943 std::string Sysroot = getHeaderSearchOpts().Sysroot; 00944 const PreprocessorOptions &PPOpts = getPreprocessorOpts(); 00945 ModuleManager = new ASTReader(getPreprocessor(), *Context, 00946 Sysroot.empty() ? "" : Sysroot.c_str(), 00947 PPOpts.DisablePCHValidation, 00948 PPOpts.DisableStatCache); 00949 if (hasASTConsumer()) { 00950 ModuleManager->setDeserializationListener( 00951 getASTConsumer().GetASTDeserializationListener()); 00952 getASTContext().setASTMutationListener( 00953 getASTConsumer().GetASTMutationListener()); 00954 } 00955 OwningPtr<ExternalASTSource> Source; 00956 Source.reset(ModuleManager); 00957 getASTContext().setExternalSource(Source); 00958 if (hasSema()) 00959 ModuleManager->InitializeSema(getSema()); 00960 if (hasASTConsumer()) 00961 ModuleManager->StartTranslationUnit(&getASTConsumer()); 00962 } 00963 00964 // Try to load the module we found. 00965 switch (ModuleManager->ReadAST(ModuleFile->getName(), 00966 serialization::MK_Module)) { 00967 case ASTReader::Success: 00968 break; 00969 00970 case ASTReader::IgnorePCH: 00971 // FIXME: The ASTReader will already have complained, but can we showhorn 00972 // that diagnostic information into a more useful form? 00973 KnownModules[Path[0].first] = 0; 00974 return 0; 00975 00976 case ASTReader::Failure: 00977 // Already complained, but note now that we failed. 00978 KnownModules[Path[0].first] = 0; 00979 return 0; 00980 } 00981 00982 if (!Module) { 00983 // If we loaded the module directly, without finding a module map first, 00984 // we'll have loaded the module's information from the module itself. 00985 Module = PP->getHeaderSearchInfo().getModuleMap() 00986 .findModule((Path[0].first->getName())); 00987 } 00988 00989 // Cache the result of this top-level module lookup for later. 00990 Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; 00991 } 00992 00993 // If we never found the module, fail. 00994 if (!Module) 00995 return 0; 00996 00997 // Verify that the rest of the module path actually corresponds to 00998 // a submodule. 00999 if (Path.size() > 1) { 01000 for (unsigned I = 1, N = Path.size(); I != N; ++I) { 01001 StringRef Name = Path[I].first->getName(); 01002 clang::Module *Sub = Module->findSubmodule(Name); 01003 01004 if (!Sub) { 01005 // Attempt to perform typo correction to find a module name that works. 01006 llvm::SmallVector<StringRef, 2> Best; 01007 unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)(); 01008 01009 for (clang::Module::submodule_iterator J = Module->submodule_begin(), 01010 JEnd = Module->submodule_end(); 01011 J != JEnd; ++J) { 01012 unsigned ED = Name.edit_distance((*J)->Name, 01013 /*AllowReplacements=*/true, 01014 BestEditDistance); 01015 if (ED <= BestEditDistance) { 01016 if (ED < BestEditDistance) { 01017 Best.clear(); 01018 BestEditDistance = ED; 01019 } 01020 01021 Best.push_back((*J)->Name); 01022 } 01023 } 01024 01025 // If there was a clear winner, user it. 01026 if (Best.size() == 1) { 01027 getDiagnostics().Report(Path[I].second, 01028 diag::err_no_submodule_suggest) 01029 << Path[I].first << Module->getFullModuleName() << Best[0] 01030 << SourceRange(Path[0].second, Path[I-1].second) 01031 << FixItHint::CreateReplacement(SourceRange(Path[I].second), 01032 Best[0]); 01033 01034 Sub = Module->findSubmodule(Best[0]); 01035 } 01036 } 01037 01038 if (!Sub) { 01039 // No submodule by this name. Complain, and don't look for further 01040 // submodules. 01041 getDiagnostics().Report(Path[I].second, diag::err_no_submodule) 01042 << Path[I].first << Module->getFullModuleName() 01043 << SourceRange(Path[0].second, Path[I-1].second); 01044 break; 01045 } 01046 01047 Module = Sub; 01048 } 01049 } 01050 01051 // Make the named module visible, if it's not already part of the module 01052 // we are parsing. 01053 if (ModuleName != getLangOpts().CurrentModule) { 01054 if (!Module->IsFromModuleFile) { 01055 // We have an umbrella header or directory that doesn't actually include 01056 // all of the headers within the directory it covers. Complain about 01057 // this missing submodule and recover by forgetting that we ever saw 01058 // this submodule. 01059 // FIXME: Should we detect this at module load time? It seems fairly 01060 // expensive (and rare). 01061 getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule) 01062 << Module->getFullModuleName() 01063 << SourceRange(Path.front().second, Path.back().second); 01064 01065 return 0; 01066 } 01067 01068 // Check whether this module is available. 01069 StringRef Feature; 01070 if (!Module->isAvailable(getLangOpts(), getTarget(), Feature)) { 01071 getDiagnostics().Report(ImportLoc, diag::err_module_unavailable) 01072 << Module->getFullModuleName() 01073 << Feature 01074 << SourceRange(Path.front().second, Path.back().second); 01075 LastModuleImportLoc = ImportLoc; 01076 LastModuleImportResult = 0; 01077 return 0; 01078 } 01079 01080 ModuleManager->makeModuleVisible(Module, Visibility); 01081 } 01082 01083 // If this module import was due to an inclusion directive, create an 01084 // implicit import declaration to capture it in the AST. 01085 if (IsInclusionDirective && hasASTContext()) { 01086 TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl(); 01087 TU->addDecl(ImportDecl::CreateImplicit(getASTContext(), TU, 01088 ImportLoc, Module, 01089 Path.back().second)); 01090 } 01091 01092 LastModuleImportLoc = ImportLoc; 01093 LastModuleImportResult = Module; 01094 return Module; 01095 }