1636404a3SDaniel Dunbar //===--- CompilerInstance.cpp ---------------------------------------------===// 2636404a3SDaniel Dunbar // 3636404a3SDaniel Dunbar // The LLVM Compiler Infrastructure 4636404a3SDaniel Dunbar // 5636404a3SDaniel Dunbar // This file is distributed under the University of Illinois Open Source 6636404a3SDaniel Dunbar // License. See LICENSE.TXT for details. 7636404a3SDaniel Dunbar // 8636404a3SDaniel Dunbar //===----------------------------------------------------------------------===// 9636404a3SDaniel Dunbar 10636404a3SDaniel Dunbar #include "clang/Frontend/CompilerInstance.h" 1156d9c293SDaniel Dunbar #include "clang/AST/ASTConsumer.h" 12df3e30c4SDaniel Dunbar #include "clang/AST/ASTContext.h" 13bcfc7d02SDouglas Gregor #include "clang/AST/Decl.h" 14636404a3SDaniel Dunbar #include "clang/Basic/Diagnostic.h" 15546a676aSDaniel Dunbar #include "clang/Basic/FileManager.h" 16546a676aSDaniel Dunbar #include "clang/Basic/SourceManager.h" 17636404a3SDaniel Dunbar #include "clang/Basic/TargetInfo.h" 184f2bc55dSDaniel Dunbar #include "clang/Basic/Version.h" 19f988d006SAlp Toker #include "clang/Config/config.h" 208b00dcb0SDavid Blaikie #include "clang/Frontend/ChainedDiagnosticConsumer.h" 214f2bc55dSDaniel Dunbar #include "clang/Frontend/FrontendAction.h" 22faeb1d46SDouglas Gregor #include "clang/Frontend/FrontendActions.h" 23f7093b5aSDaniel Dunbar #include "clang/Frontend/FrontendDiagnostic.h" 242083c32fSDaniel Dunbar #include "clang/Frontend/LogDiagnosticPrinter.h" 254610ea2bSTed Kremenek #include "clang/Frontend/SerializedDiagnosticPrinter.h" 267d75afc5SDaniel Dunbar #include "clang/Frontend/TextDiagnosticPrinter.h" 27aaa148fdSDaniel Dunbar #include "clang/Frontend/Utils.h" 283a02247dSChandler Carruth #include "clang/Frontend/VerifyDiagnosticConsumer.h" 293a02247dSChandler Carruth #include "clang/Lex/HeaderSearch.h" 303a02247dSChandler Carruth #include "clang/Lex/PTHManager.h" 313a02247dSChandler Carruth #include "clang/Lex/Preprocessor.h" 32f7093b5aSDaniel Dunbar #include "clang/Sema/CodeCompleteConsumer.h" 333a02247dSChandler Carruth #include "clang/Sema/Sema.h" 343a02247dSChandler Carruth #include "clang/Serialization/ASTReader.h" 352255f2ceSJohn Thompson #include "clang/Serialization/GlobalModuleIndex.h" 36171b780cSDouglas Gregor #include "llvm/ADT/Statistic.h" 373a02247dSChandler Carruth #include "llvm/Support/CrashRecoveryContext.h" 3871de0b61SRafael Espindola #include "llvm/Support/Errc.h" 393a02247dSChandler Carruth #include "llvm/Support/FileSystem.h" 408aaf4995SMichael J. Spencer #include "llvm/Support/Host.h" 41e212489fSDouglas Gregor #include "llvm/Support/LockFileManager.h" 423a02247dSChandler Carruth #include "llvm/Support/MemoryBuffer.h" 438aaf4995SMichael J. Spencer #include "llvm/Support/Path.h" 448aaf4995SMichael J. Spencer #include "llvm/Support/Program.h" 458aaf4995SMichael J. Spencer #include "llvm/Support/Signals.h" 463a02247dSChandler Carruth #include "llvm/Support/Timer.h" 473a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h" 48527b1c95SDouglas Gregor #include <sys/stat.h> 498a8e554aSRafael Espindola #include <system_error> 5037da327cSDouglas Gregor #include <time.h> 5154a88810SDouglas Gregor 52636404a3SDaniel Dunbar using namespace clang; 53636404a3SDaniel Dunbar 542255f2ceSJohn Thompson CompilerInstance::CompilerInstance(bool BuildingModule) 552255f2ceSJohn Thompson : ModuleLoader(BuildingModule), 5649a2790fSCraig Topper Invocation(new CompilerInvocation()), ModuleManager(nullptr), 572255f2ceSJohn Thompson BuildGlobalModuleIndex(false), HaveFullGlobalModuleIndex(false), 582255f2ceSJohn Thompson ModuleBuildFailed(false) { 59636404a3SDaniel Dunbar } 60636404a3SDaniel Dunbar 61636404a3SDaniel Dunbar CompilerInstance::~CompilerInstance() { 623c717b45SBenjamin Kramer assert(OutputFiles.empty() && "Still output files in flight?"); 63e922d9bdSDaniel Dunbar } 64e922d9bdSDaniel Dunbar 6568242254SDaniel Dunbar void CompilerInstance::setInvocation(CompilerInvocation *Value) { 665e14d39aSTed Kremenek Invocation = Value; 6768242254SDaniel Dunbar } 6868242254SDaniel Dunbar 69c1bbec85SDouglas Gregor bool CompilerInstance::shouldBuildGlobalModuleIndex() const { 70e060e57bSDouglas Gregor return (BuildGlobalModuleIndex || 7111ef0b77SDouglas Gregor (ModuleManager && ModuleManager->isGlobalIndexUnavailable() && 7211ef0b77SDouglas Gregor getFrontendOpts().GenerateGlobalModuleIndex)) && 73e060e57bSDouglas Gregor !ModuleBuildFailed; 74c1bbec85SDouglas Gregor } 75c1bbec85SDouglas Gregor 769c902b55SDavid Blaikie void CompilerInstance::setDiagnostics(DiagnosticsEngine *Value) { 777f95d26eSDouglas Gregor Diagnostics = Value; 78e01dc86dSDaniel Dunbar } 79e01dc86dSDaniel Dunbar 80e01dc86dSDaniel Dunbar void CompilerInstance::setTarget(TargetInfo *Value) { 815e14d39aSTed Kremenek Target = Value; 82e01dc86dSDaniel Dunbar } 83e01dc86dSDaniel Dunbar 84e01dc86dSDaniel Dunbar void CompilerInstance::setFileManager(FileManager *Value) { 855e14d39aSTed Kremenek FileMgr = Value; 86c8130a74SBen Langmuir if (Value) 87c8130a74SBen Langmuir VirtualFileSystem = Value->getVirtualFileSystem(); 88c8130a74SBen Langmuir else 89c8130a74SBen Langmuir VirtualFileSystem.reset(); 90e01dc86dSDaniel Dunbar } 91e01dc86dSDaniel Dunbar 92e01dc86dSDaniel Dunbar void CompilerInstance::setSourceManager(SourceManager *Value) { 935e14d39aSTed Kremenek SourceMgr = Value; 94e01dc86dSDaniel Dunbar } 95e01dc86dSDaniel Dunbar 965e14d39aSTed Kremenek void CompilerInstance::setPreprocessor(Preprocessor *Value) { PP = Value; } 97e01dc86dSDaniel Dunbar 985e14d39aSTed Kremenek void CompilerInstance::setASTContext(ASTContext *Value) { Context = Value; } 99e01dc86dSDaniel Dunbar 1000e93f017SDouglas Gregor void CompilerInstance::setSema(Sema *S) { 1010e93f017SDouglas Gregor TheSema.reset(S); 1020e93f017SDouglas Gregor } 1030e93f017SDouglas Gregor 1046beb6aa8SDavid Blaikie void CompilerInstance::setASTConsumer(std::unique_ptr<ASTConsumer> Value) { 1056beb6aa8SDavid Blaikie Consumer = std::move(Value); 10656d9c293SDaniel Dunbar } 10756d9c293SDaniel Dunbar 108e01dc86dSDaniel Dunbar void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) { 109e01dc86dSDaniel Dunbar CompletionConsumer.reset(Value); 110e01dc86dSDaniel Dunbar } 111e01dc86dSDaniel Dunbar 1126153581aSDavid Blaikie std::unique_ptr<Sema> CompilerInstance::takeSema() { 1136153581aSDavid Blaikie return std::move(TheSema); 1146153581aSDavid Blaikie } 1156153581aSDavid Blaikie 1161b7ed91eSArgyrios Kyrtzidis IntrusiveRefCntPtr<ASTReader> CompilerInstance::getModuleManager() const { 1171b7ed91eSArgyrios Kyrtzidis return ModuleManager; 1181b7ed91eSArgyrios Kyrtzidis } 1191b7ed91eSArgyrios Kyrtzidis void CompilerInstance::setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader) { 1201b7ed91eSArgyrios Kyrtzidis ModuleManager = Reader; 1211b7ed91eSArgyrios Kyrtzidis } 1221b7ed91eSArgyrios Kyrtzidis 12386d1259cSJustin Bogner std::shared_ptr<ModuleDependencyCollector> 12486d1259cSJustin Bogner CompilerInstance::getModuleDepCollector() const { 12586d1259cSJustin Bogner return ModuleDepCollector; 12686d1259cSJustin Bogner } 12786d1259cSJustin Bogner 12886d1259cSJustin Bogner void CompilerInstance::setModuleDepCollector( 12986d1259cSJustin Bogner std::shared_ptr<ModuleDependencyCollector> Collector) { 13086d1259cSJustin Bogner ModuleDepCollector = Collector; 13186d1259cSJustin Bogner } 13286d1259cSJustin Bogner 1337d75afc5SDaniel Dunbar // Diagnostics 134811db4eaSDouglas Gregor static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts, 1357b83306dSDaniel Dunbar const CodeGenOptions *CodeGenOpts, 1369c902b55SDavid Blaikie DiagnosticsEngine &Diags) { 137dae941a6SRafael Espindola std::error_code EC; 1382083c32fSDaniel Dunbar bool OwnsStream = false; 1390e62c1ccSChris Lattner raw_ostream *OS = &llvm::errs(); 140811db4eaSDouglas Gregor if (DiagOpts->DiagnosticLogFile != "-") { 1412083c32fSDaniel Dunbar // Create the output stream. 1424fbd3738SRafael Espindola llvm::raw_fd_ostream *FileOS(new llvm::raw_fd_ostream( 143dae941a6SRafael Espindola DiagOpts->DiagnosticLogFile, EC, 1444fbd3738SRafael Espindola llvm::sys::fs::F_Append | llvm::sys::fs::F_Text)); 145dae941a6SRafael Espindola if (EC) { 1462083c32fSDaniel Dunbar Diags.Report(diag::warn_fe_cc_log_diagnostics_failure) 147dae941a6SRafael Espindola << DiagOpts->DiagnosticLogFile << EC.message(); 1482083c32fSDaniel Dunbar } else { 1492083c32fSDaniel Dunbar FileOS->SetUnbuffered(); 1502083c32fSDaniel Dunbar FileOS->SetUseAtomicWrites(true); 1512083c32fSDaniel Dunbar OS = FileOS; 1522083c32fSDaniel Dunbar OwnsStream = true; 1532083c32fSDaniel Dunbar } 1542083c32fSDaniel Dunbar } 1552083c32fSDaniel Dunbar 1562083c32fSDaniel Dunbar // Chain in the diagnostic client which will log the diagnostics. 1577b83306dSDaniel Dunbar LogDiagnosticPrinter *Logger = new LogDiagnosticPrinter(*OS, DiagOpts, 1582083c32fSDaniel Dunbar OwnsStream); 1597b83306dSDaniel Dunbar if (CodeGenOpts) 1607b83306dSDaniel Dunbar Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags); 1618b00dcb0SDavid Blaikie Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(), Logger)); 1622083c32fSDaniel Dunbar } 1632083c32fSDaniel Dunbar 164811db4eaSDouglas Gregor static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts, 1654610ea2bSTed Kremenek DiagnosticsEngine &Diags, 1664610ea2bSTed Kremenek StringRef OutputFile) { 167dae941a6SRafael Espindola std::error_code EC; 168b8984329SAhmed Charles std::unique_ptr<llvm::raw_fd_ostream> OS; 169dae941a6SRafael Espindola OS.reset( 170dae941a6SRafael Espindola new llvm::raw_fd_ostream(OutputFile.str(), EC, llvm::sys::fs::F_None)); 1714610ea2bSTed Kremenek 172dae941a6SRafael Espindola if (EC) { 173dae941a6SRafael Espindola Diags.Report(diag::warn_fe_serialized_diag_failure) << OutputFile 174dae941a6SRafael Espindola << EC.message(); 1754610ea2bSTed Kremenek return; 1764610ea2bSTed Kremenek } 1774610ea2bSTed Kremenek 1784610ea2bSTed Kremenek DiagnosticConsumer *SerializedConsumer = 1799a16beb8SAhmed Charles clang::serialized_diags::create(OS.release(), DiagOpts); 1804610ea2bSTed Kremenek 1814610ea2bSTed Kremenek Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(), 1824610ea2bSTed Kremenek SerializedConsumer)); 1834610ea2bSTed Kremenek } 1844610ea2bSTed Kremenek 185f1b49e23SSean Silva void CompilerInstance::createDiagnostics(DiagnosticConsumer *Client, 18630071ceaSDouglas Gregor bool ShouldOwnClient) { 187f1b49e23SSean Silva Diagnostics = createDiagnostics(&getDiagnosticOpts(), Client, 18830071ceaSDouglas Gregor ShouldOwnClient, &getCodeGenOpts()); 1897d75afc5SDaniel Dunbar } 1907d75afc5SDaniel Dunbar 191c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> 192811db4eaSDouglas Gregor CompilerInstance::createDiagnostics(DiagnosticOptions *Opts, 193e2eefaecSDavid Blaikie DiagnosticConsumer *Client, 1942b9b4642SDouglas Gregor bool ShouldOwnClient, 1957b83306dSDaniel Dunbar const CodeGenOptions *CodeGenOpts) { 196c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 197c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> 198811db4eaSDouglas Gregor Diags(new DiagnosticsEngine(DiagID, Opts)); 1991b39a2edSDaniel Dunbar 2007d75afc5SDaniel Dunbar // Create the diagnostic client for reporting errors or for 2017d75afc5SDaniel Dunbar // implementing -verify. 202d0e9e3a6SDouglas Gregor if (Client) { 203d0e9e3a6SDouglas Gregor Diags->setClient(Client, ShouldOwnClient); 204d0e9e3a6SDouglas Gregor } else 2052dd19f1dSDouglas Gregor Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts)); 20650ec0da0SDaniel Dunbar 20750ec0da0SDaniel Dunbar // Chain in -verify checker, if requested. 208811db4eaSDouglas Gregor if (Opts->VerifyDiagnostics) 20969609dceSDavid Blaikie Diags->setClient(new VerifyDiagnosticConsumer(*Diags)); 2107d75afc5SDaniel Dunbar 2112083c32fSDaniel Dunbar // Chain in -diagnostic-log-file dumper, if requested. 212811db4eaSDouglas Gregor if (!Opts->DiagnosticLogFile.empty()) 2137b83306dSDaniel Dunbar SetUpDiagnosticLog(Opts, CodeGenOpts, *Diags); 2142083c32fSDaniel Dunbar 215811db4eaSDouglas Gregor if (!Opts->DiagnosticSerializationFile.empty()) 2164610ea2bSTed Kremenek SetupSerializedDiagnostics(Opts, *Diags, 217811db4eaSDouglas Gregor Opts->DiagnosticSerializationFile); 2184610ea2bSTed Kremenek 2197d75afc5SDaniel Dunbar // Configure our handling of diagnostics. 220811db4eaSDouglas Gregor ProcessWarningOptions(*Diags, *Opts); 2217d75afc5SDaniel Dunbar 2227f95d26eSDouglas Gregor return Diags; 2237d75afc5SDaniel Dunbar } 2247d75afc5SDaniel Dunbar 2257d75afc5SDaniel Dunbar // File Manager 2267d75afc5SDaniel Dunbar 227546a676aSDaniel Dunbar void CompilerInstance::createFileManager() { 228c8130a74SBen Langmuir if (!hasVirtualFileSystem()) { 229c8130a74SBen Langmuir // TODO: choose the virtual file system based on the CompilerInvocation. 230c8130a74SBen Langmuir setVirtualFileSystem(vfs::getRealFileSystem()); 231c8130a74SBen Langmuir } 232c8130a74SBen Langmuir FileMgr = new FileManager(getFileSystemOpts(), VirtualFileSystem); 233546a676aSDaniel Dunbar } 234546a676aSDaniel Dunbar 2357d75afc5SDaniel Dunbar // Source Manager 2367d75afc5SDaniel Dunbar 2375159f616SChris Lattner void CompilerInstance::createSourceManager(FileManager &FileMgr) { 2385e14d39aSTed Kremenek SourceMgr = new SourceManager(getDiagnostics(), FileMgr); 239546a676aSDaniel Dunbar } 240aaa148fdSDaniel Dunbar 241c358000eSAlp Toker // Initialize the remapping of files to alternative contents, e.g., 242c358000eSAlp Toker // those specified through other files. 243c358000eSAlp Toker static void InitializeFileRemapping(DiagnosticsEngine &Diags, 244c358000eSAlp Toker SourceManager &SourceMgr, 245c358000eSAlp Toker FileManager &FileMgr, 246c358000eSAlp Toker const PreprocessorOptions &InitOpts) { 247c358000eSAlp Toker // Remap files in the source manager (with buffers). 2481b070d25SAlp Toker for (const auto &RB : InitOpts.RemappedFileBuffers) { 249c358000eSAlp Toker // Create the file entry for the file that we're mapping from. 250c358000eSAlp Toker const FileEntry *FromFile = 2511b070d25SAlp Toker FileMgr.getVirtualFile(RB.first, RB.second->getBufferSize(), 0); 252c358000eSAlp Toker if (!FromFile) { 2531b070d25SAlp Toker Diags.Report(diag::err_fe_remap_missing_from_file) << RB.first; 254c358000eSAlp Toker if (!InitOpts.RetainRemappedFileBuffers) 2551b070d25SAlp Toker delete RB.second; 256c358000eSAlp Toker continue; 257c358000eSAlp Toker } 258c358000eSAlp Toker 259c358000eSAlp Toker // Override the contents of the "from" file with the contents of 260c358000eSAlp Toker // the "to" file. 2611b070d25SAlp Toker SourceMgr.overrideFileContents(FromFile, RB.second, 262c358000eSAlp Toker InitOpts.RetainRemappedFileBuffers); 263c358000eSAlp Toker } 264c358000eSAlp Toker 265c358000eSAlp Toker // Remap files in the source manager (with other files). 2661b070d25SAlp Toker for (const auto &RF : InitOpts.RemappedFiles) { 267c358000eSAlp Toker // Find the file that we're mapping to. 2681b070d25SAlp Toker const FileEntry *ToFile = FileMgr.getFile(RF.second); 269c358000eSAlp Toker if (!ToFile) { 2701b070d25SAlp Toker Diags.Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second; 271c358000eSAlp Toker continue; 272c358000eSAlp Toker } 273c358000eSAlp Toker 274c358000eSAlp Toker // Create the file entry for the file that we're mapping from. 275c358000eSAlp Toker const FileEntry *FromFile = 2761b070d25SAlp Toker FileMgr.getVirtualFile(RF.first, ToFile->getSize(), 0); 277c358000eSAlp Toker if (!FromFile) { 2781b070d25SAlp Toker Diags.Report(diag::err_fe_remap_missing_from_file) << RF.first; 279c358000eSAlp Toker continue; 280c358000eSAlp Toker } 281c358000eSAlp Toker 282c358000eSAlp Toker // Override the contents of the "from" file with the contents of 283c358000eSAlp Toker // the "to" file. 284c358000eSAlp Toker SourceMgr.overrideFileContents(FromFile, ToFile); 285c358000eSAlp Toker } 286c358000eSAlp Toker 287c358000eSAlp Toker SourceMgr.setOverridenFilesKeepOriginalName( 288c358000eSAlp Toker InitOpts.RemappedFilesKeepOriginalName); 289c358000eSAlp Toker } 290c358000eSAlp Toker 2917d75afc5SDaniel Dunbar // Preprocessor 2927d75afc5SDaniel Dunbar 293e1974dcdSArgyrios Kyrtzidis void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) { 29408142534SDouglas Gregor const PreprocessorOptions &PPOpts = getPreprocessorOpts(); 295aaa148fdSDaniel Dunbar 296aaa148fdSDaniel Dunbar // Create a PTH manager if we are using some form of a token cache. 29749a2790fSCraig Topper PTHManager *PTHMgr = nullptr; 298d6ea9028SDaniel Dunbar if (!PPOpts.TokenCache.empty()) 29908142534SDouglas Gregor PTHMgr = PTHManager::Create(PPOpts.TokenCache, getDiagnostics()); 300aaa148fdSDaniel Dunbar 301aaa148fdSDaniel Dunbar // Create the Preprocessor. 302b85b9ccbSDouglas Gregor HeaderSearch *HeaderInfo = new HeaderSearch(&getHeaderSearchOpts(), 3031f76c4e8SManuel Klimek getSourceManager(), 3041fb5c3a6SDouglas Gregor getDiagnostics(), 30589929282SDouglas Gregor getLangOpts(), 30689929282SDouglas Gregor &getTarget()); 3079663780eSAlp Toker PP = new Preprocessor(&getPreprocessorOpts(), getDiagnostics(), getLangOpts(), 30808142534SDouglas Gregor getSourceManager(), *HeaderInfo, *this, PTHMgr, 3099663780eSAlp Toker /*OwnsHeaderSearch=*/true, TUKind); 3101ae02f68SAlp Toker PP->Initialize(getTarget()); 311aaa148fdSDaniel Dunbar 312aaa148fdSDaniel Dunbar // Note that this is different then passing PTHMgr to Preprocessor's ctor. 313aaa148fdSDaniel Dunbar // That argument is used as the IdentifierInfoLookup argument to 314aaa148fdSDaniel Dunbar // IdentifierTable's ctor. 315aaa148fdSDaniel Dunbar if (PTHMgr) { 31608142534SDouglas Gregor PTHMgr->setPreprocessor(&*PP); 317aaa148fdSDaniel Dunbar PP->setPTHManager(PTHMgr); 318aaa148fdSDaniel Dunbar } 319aaa148fdSDaniel Dunbar 3207f6d60dcSDouglas Gregor if (PPOpts.DetailedRecord) 321f3d587eaSArgyrios Kyrtzidis PP->createPreprocessingRecord(); 3227f6d60dcSDouglas Gregor 323c358000eSAlp Toker // Apply remappings to the source manager. 324c358000eSAlp Toker InitializeFileRemapping(PP->getDiagnostics(), PP->getSourceManager(), 325c358000eSAlp Toker PP->getFileManager(), PPOpts); 326c358000eSAlp Toker 327c358000eSAlp Toker // Predefine macros and configure the preprocessor. 328c358000eSAlp Toker InitializePreprocessor(*PP, PPOpts, getFrontendOpts()); 329c358000eSAlp Toker 330c358000eSAlp Toker // Initialize the header search object. 331c358000eSAlp Toker ApplyHeaderSearchOptions(PP->getHeaderSearchInfo(), getHeaderSearchOpts(), 332c358000eSAlp Toker PP->getLangOpts(), PP->getTargetInfo().getTriple()); 333aaa148fdSDaniel Dunbar 33417441589SJordan Rose PP->setPreprocessedOutput(getPreprocessorOutputOpts().ShowCPP); 33517441589SJordan Rose 3361735f4e7SDouglas Gregor // Set up the module path, including the hash for the 3371735f4e7SDouglas Gregor // module-creation options. 3382c1dd271SDylan Noblesmith SmallString<256> SpecificModuleCache( 3391735f4e7SDouglas Gregor getHeaderSearchOpts().ModuleCachePath); 3401735f4e7SDouglas Gregor if (!getHeaderSearchOpts().DisableModuleHash) 3411735f4e7SDouglas Gregor llvm::sys::path::append(SpecificModuleCache, 3421735f4e7SDouglas Gregor getInvocation().getModuleHash()); 3432537a364SDouglas Gregor PP->getHeaderSearchInfo().setModuleCachePath(SpecificModuleCache); 3441735f4e7SDouglas Gregor 345aaa148fdSDaniel Dunbar // Handle generating dependencies, if requested. 34608142534SDouglas Gregor const DependencyOutputOptions &DepOpts = getDependencyOutputOpts(); 347aaa148fdSDaniel Dunbar if (!DepOpts.OutputFile.empty()) 348cb69b57bSBen Langmuir TheDependencyFileGenerator.reset( 349cb69b57bSBen Langmuir DependencyFileGenerator::CreateAndAttachToPreprocessor(*PP, DepOpts)); 3502e129659SDouglas Gregor if (!DepOpts.DOTOutputFile.empty()) 3512e129659SDouglas Gregor AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile, 35283d46be3SDouglas Gregor getHeaderSearchOpts().Sysroot); 35383d46be3SDouglas Gregor 35433c8090aSBen Langmuir for (auto &Listener : DependencyCollectors) 35533c8090aSBen Langmuir Listener->attachToPreprocessor(*PP); 35633c8090aSBen Langmuir 35786d1259cSJustin Bogner // If we don't have a collector, but we are collecting module dependencies, 35886d1259cSJustin Bogner // then we're the top level compiler instance and need to create one. 35986d1259cSJustin Bogner if (!ModuleDepCollector && !DepOpts.ModuleDependencyOutputDir.empty()) 36086d1259cSJustin Bogner ModuleDepCollector = std::make_shared<ModuleDependencyCollector>( 36186d1259cSJustin Bogner DepOpts.ModuleDependencyOutputDir); 362aaa148fdSDaniel Dunbar 36327734fdbSDaniel Dunbar // Handle generating header include information, if requested. 36427734fdbSDaniel Dunbar if (DepOpts.ShowHeaderIncludes) 36527734fdbSDaniel Dunbar AttachHeaderIncludeGen(*PP); 3661af1d275SDaniel Dunbar if (!DepOpts.HeaderIncludeOutputFile.empty()) { 3670e62c1ccSChris Lattner StringRef OutputPath = DepOpts.HeaderIncludeOutputFile; 3681af1d275SDaniel Dunbar if (OutputPath == "-") 3691af1d275SDaniel Dunbar OutputPath = ""; 370fe908a80SDaniel Dunbar AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/true, OutputPath, 371fe908a80SDaniel Dunbar /*ShowDepth=*/false); 3720fd6207dSHans Wennborg } 3730fd6207dSHans Wennborg 3740fd6207dSHans Wennborg if (DepOpts.PrintShowIncludes) { 3750fd6207dSHans Wennborg AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/false, /*OutputPath=*/"", 3760fd6207dSHans Wennborg /*ShowDepth=*/true, /*MSStyle=*/true); 3771af1d275SDaniel Dunbar } 378aaa148fdSDaniel Dunbar } 379df3e30c4SDaniel Dunbar 380df3e30c4SDaniel Dunbar // ASTContext 381df3e30c4SDaniel Dunbar 382df3e30c4SDaniel Dunbar void CompilerInstance::createASTContext() { 383df3e30c4SDaniel Dunbar Preprocessor &PP = getPreprocessor(); 3845e14d39aSTed Kremenek Context = new ASTContext(getLangOpts(), PP.getSourceManager(), 38508043437SAlp Toker PP.getIdentifierTable(), PP.getSelectorTable(), 38608043437SAlp Toker PP.getBuiltinInfo()); 38708043437SAlp Toker Context->InitBuiltinTypes(getTarget()); 388df3e30c4SDaniel Dunbar } 389599313efSDaniel Dunbar 390599313efSDaniel Dunbar // ExternalASTSource 391599313efSDaniel Dunbar 392824285ecSNico Weber void CompilerInstance::createPCHExternalASTSource( 393824285ecSNico Weber StringRef Path, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors, 394824285ecSNico Weber void *DeserializationListener, bool OwnDeserializationListener) { 3951b7ed91eSArgyrios Kyrtzidis IntrusiveRefCntPtr<ExternalASTSource> Source; 396009e7f20SSebastian Redl bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0; 397824285ecSNico Weber Source = createPCHExternalASTSource( 398824285ecSNico Weber Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation, 399824285ecSNico Weber AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(), 400824285ecSNico Weber DeserializationListener, OwnDeserializationListener, Preamble, 4011b7ed91eSArgyrios Kyrtzidis getFrontendOpts().UseGlobalModuleIndex); 402f994cef8SAlp Toker ModuleManager = static_cast<ASTReader*>(Source.get()); 403599313efSDaniel Dunbar getASTContext().setExternalSource(Source); 404599313efSDaniel Dunbar } 405599313efSDaniel Dunbar 406824285ecSNico Weber ExternalASTSource *CompilerInstance::createPCHExternalASTSource( 407824285ecSNico Weber StringRef Path, const std::string &Sysroot, bool DisablePCHValidation, 408824285ecSNico Weber bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context, 409824285ecSNico Weber void *DeserializationListener, bool OwnDeserializationListener, 410824285ecSNico Weber bool Preamble, bool UseGlobalModuleIndex) { 411dcf73861SBen Langmuir HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts(); 412dcf73861SBen Langmuir 413b8984329SAhmed Charles std::unique_ptr<ASTReader> Reader; 4148835e03cSDouglas Gregor Reader.reset(new ASTReader(PP, Context, 415c567ba26SDouglas Gregor Sysroot.empty() ? "" : Sysroot.c_str(), 416d7c16b25SArgyrios Kyrtzidis DisablePCHValidation, 417c1bbec85SDouglas Gregor AllowPCHWithCompilerErrors, 4183d4417c7SBen Langmuir /*AllowConfigurationMismatch*/false, 419dcf73861SBen Langmuir HSOpts.ModulesValidateSystemHeaders, 420c1bbec85SDouglas Gregor UseGlobalModuleIndex)); 421599313efSDaniel Dunbar 42207a89a83SSebastian Redl Reader->setDeserializationListener( 423824285ecSNico Weber static_cast<ASTDeserializationListener *>(DeserializationListener), 424824285ecSNico Weber /*TakeOwnership=*/OwnDeserializationListener); 425009e7f20SSebastian Redl switch (Reader->ReadAST(Path, 426a6895d8aSDouglas Gregor Preamble ? serialization::MK_Preamble 4274b29c16eSDouglas Gregor : serialization::MK_PCH, 4282ec29367SArgyrios Kyrtzidis SourceLocation(), 4293d4417c7SBen Langmuir ASTReader::ARR_None)) { 4302c499f65SSebastian Redl case ASTReader::Success: 431599313efSDaniel Dunbar // Set the predefines buffer as suggested by the PCH reader. Typically, the 432599313efSDaniel Dunbar // predefines buffer will be empty. 433599313efSDaniel Dunbar PP.setPredefines(Reader->getSuggestedPredefines()); 4349a16beb8SAhmed Charles return Reader.release(); 435599313efSDaniel Dunbar 4362c499f65SSebastian Redl case ASTReader::Failure: 437599313efSDaniel Dunbar // Unrecoverable failure: don't even try to process the input file. 438599313efSDaniel Dunbar break; 439599313efSDaniel Dunbar 4407029ce1aSDouglas Gregor case ASTReader::Missing: 441c9ad5fb6SDouglas Gregor case ASTReader::OutOfDate: 442c9ad5fb6SDouglas Gregor case ASTReader::VersionMismatch: 443c9ad5fb6SDouglas Gregor case ASTReader::ConfigurationMismatch: 444c9ad5fb6SDouglas Gregor case ASTReader::HadErrors: 445599313efSDaniel Dunbar // No suitable PCH file could be found. Return an error. 446599313efSDaniel Dunbar break; 447599313efSDaniel Dunbar } 448599313efSDaniel Dunbar 44949a2790fSCraig Topper return nullptr; 450599313efSDaniel Dunbar } 451f7093b5aSDaniel Dunbar 452f7093b5aSDaniel Dunbar // Code Completion 453f7093b5aSDaniel Dunbar 4548e984da8SDouglas Gregor static bool EnableCodeCompletion(Preprocessor &PP, 4558e984da8SDouglas Gregor const std::string &Filename, 4568e984da8SDouglas Gregor unsigned Line, 4578e984da8SDouglas Gregor unsigned Column) { 4588e984da8SDouglas Gregor // Tell the source manager to chop off the given file at a specific 4598e984da8SDouglas Gregor // line and column. 4605159f616SChris Lattner const FileEntry *Entry = PP.getFileManager().getFile(Filename); 4618e984da8SDouglas Gregor if (!Entry) { 4628e984da8SDouglas Gregor PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file) 4638e984da8SDouglas Gregor << Filename; 4648e984da8SDouglas Gregor return true; 4658e984da8SDouglas Gregor } 4668e984da8SDouglas Gregor 4678e984da8SDouglas Gregor // Truncate the named file at the given line/column. 4688e984da8SDouglas Gregor PP.SetCodeCompletionPoint(Entry, Line, Column); 4698e984da8SDouglas Gregor return false; 4708e984da8SDouglas Gregor } 4718e984da8SDouglas Gregor 472f7093b5aSDaniel Dunbar void CompilerInstance::createCodeCompletionConsumer() { 473f7093b5aSDaniel Dunbar const ParsedSourceLocation &Loc = getFrontendOpts().CodeCompletionAt; 4748e984da8SDouglas Gregor if (!CompletionConsumer) { 4752fca3c2cSErik Verbruggen setCodeCompletionConsumer( 476f7093b5aSDaniel Dunbar createCodeCompletionConsumer(getPreprocessor(), 477f7093b5aSDaniel Dunbar Loc.FileName, Loc.Line, Loc.Column, 4783292d06aSDmitri Gribenko getFrontendOpts().CodeCompleteOpts, 479f7093b5aSDaniel Dunbar llvm::outs())); 48000a0cf70SDouglas Gregor if (!CompletionConsumer) 48100a0cf70SDouglas Gregor return; 4828e984da8SDouglas Gregor } else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName, 4838e984da8SDouglas Gregor Loc.Line, Loc.Column)) { 48449a2790fSCraig Topper setCodeCompletionConsumer(nullptr); 4858e984da8SDouglas Gregor return; 4868e984da8SDouglas Gregor } 487f09935f1SDouglas Gregor 488f09935f1SDouglas Gregor if (CompletionConsumer->isOutputBinary() && 489a3346d87SRafael Espindola llvm::sys::ChangeStdoutToBinary()) { 490f09935f1SDouglas Gregor getPreprocessor().getDiagnostics().Report(diag::err_fe_stdout_binary); 49149a2790fSCraig Topper setCodeCompletionConsumer(nullptr); 492f09935f1SDouglas Gregor } 493f7093b5aSDaniel Dunbar } 494f7093b5aSDaniel Dunbar 4955505dff8SKovarththanan Rajaratnam void CompilerInstance::createFrontendTimer() { 4965505dff8SKovarththanan Rajaratnam FrontendTimer.reset(new llvm::Timer("Clang front-end timer")); 4975505dff8SKovarththanan Rajaratnam } 4985505dff8SKovarththanan Rajaratnam 499f7093b5aSDaniel Dunbar CodeCompleteConsumer * 500f7093b5aSDaniel Dunbar CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP, 501f7093b5aSDaniel Dunbar const std::string &Filename, 502f7093b5aSDaniel Dunbar unsigned Line, 503f7093b5aSDaniel Dunbar unsigned Column, 5043292d06aSDmitri Gribenko const CodeCompleteOptions &Opts, 5050e62c1ccSChris Lattner raw_ostream &OS) { 5068e984da8SDouglas Gregor if (EnableCodeCompletion(PP, Filename, Line, Column)) 50749a2790fSCraig Topper return nullptr; 508f7093b5aSDaniel Dunbar 509f7093b5aSDaniel Dunbar // Set up the creation routine for code-completion. 5103292d06aSDmitri Gribenko return new PrintingCodeCompleteConsumer(Opts, OS); 511f7093b5aSDaniel Dunbar } 512566eeb2dSDaniel Dunbar 51369f74f80SDouglas Gregor void CompilerInstance::createSema(TranslationUnitKind TUKind, 5140e93f017SDouglas Gregor CodeCompleteConsumer *CompletionConsumer) { 5150e93f017SDouglas Gregor TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(), 51669f74f80SDouglas Gregor TUKind, CompletionConsumer)); 5170e93f017SDouglas Gregor } 5180e93f017SDouglas Gregor 519566eeb2dSDaniel Dunbar // Output Files 520566eeb2dSDaniel Dunbar 52169f3528cSNAKAMURA Takumi void CompilerInstance::addOutputFile(const OutputFile &OutFile) { 522d0599970SArgyrios Kyrtzidis assert(OutFile.OS && "Attempt to add empty stream to output list!"); 52369f3528cSNAKAMURA Takumi OutputFiles.push_back(OutFile); 524566eeb2dSDaniel Dunbar } 525566eeb2dSDaniel Dunbar 5261c558cd7SKovarththanan Rajaratnam void CompilerInstance::clearOutputFiles(bool EraseFiles) { 527d0599970SArgyrios Kyrtzidis for (std::list<OutputFile>::iterator 528566eeb2dSDaniel Dunbar it = OutputFiles.begin(), ie = OutputFiles.end(); it != ie; ++it) { 52969f3528cSNAKAMURA Takumi delete it->OS; 530d0599970SArgyrios Kyrtzidis if (!it->TempFilename.empty()) { 531b5c356a4SAnders Carlsson if (EraseFiles) { 5322a008784SRafael Espindola llvm::sys::fs::remove(it->TempFilename); 533b5c356a4SAnders Carlsson } else { 5342c1dd271SDylan Noblesmith SmallString<128> NewOutFile(it->Filename); 535b5c356a4SAnders Carlsson 53671731d6bSArgyrios Kyrtzidis // If '-working-directory' was passed, the output filename should be 53771731d6bSArgyrios Kyrtzidis // relative to that. 5389ba8fb1eSAnders Carlsson FileMgr->FixupRelativePath(NewOutFile); 539c080917eSRafael Espindola if (std::error_code ec = 540c080917eSRafael Espindola llvm::sys::fs::rename(it->TempFilename, NewOutFile.str())) { 5413ef9c447SManuel Klimek getDiagnostics().Report(diag::err_unable_to_rename_temp) 542b5c356a4SAnders Carlsson << it->TempFilename << it->Filename << ec.message(); 543b5c356a4SAnders Carlsson 5442a008784SRafael Espindola llvm::sys::fs::remove(it->TempFilename); 545d0599970SArgyrios Kyrtzidis } 546d0599970SArgyrios Kyrtzidis } 547d0599970SArgyrios Kyrtzidis } else if (!it->Filename.empty() && EraseFiles) 548399ab33aSRafael Espindola llvm::sys::fs::remove(it->Filename); 549d0599970SArgyrios Kyrtzidis 550566eeb2dSDaniel Dunbar } 551566eeb2dSDaniel Dunbar OutputFiles.clear(); 552566eeb2dSDaniel Dunbar } 553566eeb2dSDaniel Dunbar 554420b0f1bSDaniel Dunbar llvm::raw_fd_ostream * 555420b0f1bSDaniel Dunbar CompilerInstance::createDefaultOutputFile(bool Binary, 5560e62c1ccSChris Lattner StringRef InFile, 5570e62c1ccSChris Lattner StringRef Extension) { 558420b0f1bSDaniel Dunbar return createOutputFile(getFrontendOpts().OutputFile, Binary, 559ae77b3dfSDaniel Dunbar /*RemoveFileOnSignal=*/true, InFile, Extension, 560ae77b3dfSDaniel Dunbar /*UseTemporary=*/true); 561420b0f1bSDaniel Dunbar } 562420b0f1bSDaniel Dunbar 563ea04672cSAlp Toker llvm::raw_null_ostream *CompilerInstance::createNullOutputFile() { 56469f3528cSNAKAMURA Takumi llvm::raw_null_ostream *OS = new llvm::raw_null_ostream(); 56569f3528cSNAKAMURA Takumi addOutputFile(OutputFile("", "", OS)); 56669f3528cSNAKAMURA Takumi return OS; 567ea04672cSAlp Toker } 568ea04672cSAlp Toker 569420b0f1bSDaniel Dunbar llvm::raw_fd_ostream * 5700e62c1ccSChris Lattner CompilerInstance::createOutputFile(StringRef OutputPath, 571e326f9bbSDaniel Dunbar bool Binary, bool RemoveFileOnSignal, 5720e62c1ccSChris Lattner StringRef InFile, 57308a2bfd2SArgyrios Kyrtzidis StringRef Extension, 574b9c62c07SDaniel Dunbar bool UseTemporary, 575b9c62c07SDaniel Dunbar bool CreateMissingDirectories) { 576dae941a6SRafael Espindola std::string OutputPathName, TempPathName; 577dae941a6SRafael Espindola std::error_code EC; 578dae941a6SRafael Espindola llvm::raw_fd_ostream *OS = createOutputFile( 579dae941a6SRafael Espindola OutputPath, EC, Binary, RemoveFileOnSignal, InFile, Extension, 580dae941a6SRafael Espindola UseTemporary, CreateMissingDirectories, &OutputPathName, &TempPathName); 581420b0f1bSDaniel Dunbar if (!OS) { 582dae941a6SRafael Espindola getDiagnostics().Report(diag::err_fe_unable_to_open_output) << OutputPath 583dae941a6SRafael Espindola << EC.message(); 58449a2790fSCraig Topper return nullptr; 585420b0f1bSDaniel Dunbar } 586420b0f1bSDaniel Dunbar 587420b0f1bSDaniel Dunbar // Add the output file -- but don't try to remove "-", since this means we are 588420b0f1bSDaniel Dunbar // using stdin. 589d0599970SArgyrios Kyrtzidis addOutputFile(OutputFile((OutputPathName != "-") ? OutputPathName : "", 59069f3528cSNAKAMURA Takumi TempPathName, OS)); 591420b0f1bSDaniel Dunbar 59269f3528cSNAKAMURA Takumi return OS; 593420b0f1bSDaniel Dunbar } 594420b0f1bSDaniel Dunbar 595dae941a6SRafael Espindola llvm::raw_fd_ostream *CompilerInstance::createOutputFile( 596dae941a6SRafael Espindola StringRef OutputPath, std::error_code &Error, bool Binary, 597dae941a6SRafael Espindola bool RemoveFileOnSignal, StringRef InFile, StringRef Extension, 598dae941a6SRafael Espindola bool UseTemporary, bool CreateMissingDirectories, 599dae941a6SRafael Espindola std::string *ResultPathName, std::string *TempPathName) { 600b9c62c07SDaniel Dunbar assert((!CreateMissingDirectories || UseTemporary) && 601b9c62c07SDaniel Dunbar "CreateMissingDirectories is only allowed when using temporary files"); 602b9c62c07SDaniel Dunbar 603d0599970SArgyrios Kyrtzidis std::string OutFile, TempFile; 604420b0f1bSDaniel Dunbar if (!OutputPath.empty()) { 605420b0f1bSDaniel Dunbar OutFile = OutputPath; 606420b0f1bSDaniel Dunbar } else if (InFile == "-") { 607420b0f1bSDaniel Dunbar OutFile = "-"; 608420b0f1bSDaniel Dunbar } else if (!Extension.empty()) { 609399ab33aSRafael Espindola SmallString<128> Path(InFile); 610399ab33aSRafael Espindola llvm::sys::path::replace_extension(Path, Extension); 611420b0f1bSDaniel Dunbar OutFile = Path.str(); 612420b0f1bSDaniel Dunbar } else { 613420b0f1bSDaniel Dunbar OutFile = "-"; 614420b0f1bSDaniel Dunbar } 615420b0f1bSDaniel Dunbar 616b8984329SAhmed Charles std::unique_ptr<llvm::raw_fd_ostream> OS; 61708a2bfd2SArgyrios Kyrtzidis std::string OSFile; 61808a2bfd2SArgyrios Kyrtzidis 61973c23a71SRafael Espindola if (UseTemporary) { 62073c23a71SRafael Espindola if (OutFile == "-") 62173c23a71SRafael Espindola UseTemporary = false; 62273c23a71SRafael Espindola else { 62373c23a71SRafael Espindola llvm::sys::fs::file_status Status; 62473c23a71SRafael Espindola llvm::sys::fs::status(OutputPath, Status); 62573c23a71SRafael Espindola if (llvm::sys::fs::exists(Status)) { 62673c23a71SRafael Espindola // Fail early if we can't write to the final destination. 62773c23a71SRafael Espindola if (!llvm::sys::fs::can_write(OutputPath)) 62849a2790fSCraig Topper return nullptr; 62973c23a71SRafael Espindola 63073c23a71SRafael Espindola // Don't use a temporary if the output is a special file. This handles 63173c23a71SRafael Espindola // things like '-o /dev/null' 63273c23a71SRafael Espindola if (!llvm::sys::fs::is_regular_file(Status)) 63373c23a71SRafael Espindola UseTemporary = false; 63473c23a71SRafael Espindola } 63573c23a71SRafael Espindola } 63673c23a71SRafael Espindola } 63773c23a71SRafael Espindola 63873c23a71SRafael Espindola if (UseTemporary) { 639d0599970SArgyrios Kyrtzidis // Create a temporary file. 6402c1dd271SDylan Noblesmith SmallString<128> TempPath; 64108a2bfd2SArgyrios Kyrtzidis TempPath = OutFile; 64208a2bfd2SArgyrios Kyrtzidis TempPath += "-%%%%%%%%"; 64308a2bfd2SArgyrios Kyrtzidis int fd; 644c080917eSRafael Espindola std::error_code EC = 64518627115SRafael Espindola llvm::sys::fs::createUniqueFile(TempPath.str(), fd, TempPath); 646157f34bdSRafael Espindola 647157f34bdSRafael Espindola if (CreateMissingDirectories && 64871de0b61SRafael Espindola EC == llvm::errc::no_such_file_or_directory) { 649157f34bdSRafael Espindola StringRef Parent = llvm::sys::path::parent_path(OutputPath); 650157f34bdSRafael Espindola EC = llvm::sys::fs::create_directories(Parent); 651157f34bdSRafael Espindola if (!EC) { 65218627115SRafael Espindola EC = llvm::sys::fs::createUniqueFile(TempPath.str(), fd, TempPath); 653157f34bdSRafael Espindola } 654157f34bdSRafael Espindola } 655157f34bdSRafael Espindola 656157f34bdSRafael Espindola if (!EC) { 65769f3528cSNAKAMURA Takumi OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true)); 65808a2bfd2SArgyrios Kyrtzidis OSFile = TempFile = TempPath.str(); 65908a2bfd2SArgyrios Kyrtzidis } 66073c23a71SRafael Espindola // If we failed to create the temporary, fallback to writing to the file 66173c23a71SRafael Espindola // directly. This handles the corner case where we cannot write to the 66273c23a71SRafael Espindola // directory, but can write to the file. 663d0599970SArgyrios Kyrtzidis } 664d0599970SArgyrios Kyrtzidis 66508a2bfd2SArgyrios Kyrtzidis if (!OS) { 66608a2bfd2SArgyrios Kyrtzidis OSFile = OutFile; 66769f3528cSNAKAMURA Takumi OS.reset(new llvm::raw_fd_ostream( 668dae941a6SRafael Espindola OSFile, Error, 66969f3528cSNAKAMURA Takumi (Binary ? llvm::sys::fs::F_None : llvm::sys::fs::F_Text))); 670dae941a6SRafael Espindola if (Error) 67149a2790fSCraig Topper return nullptr; 67208a2bfd2SArgyrios Kyrtzidis } 673420b0f1bSDaniel Dunbar 674d0599970SArgyrios Kyrtzidis // Make sure the out stream file gets removed if we crash. 675e326f9bbSDaniel Dunbar if (RemoveFileOnSignal) 67618556de3SRafael Espindola llvm::sys::RemoveFileOnSignal(OSFile); 677d0599970SArgyrios Kyrtzidis 678420b0f1bSDaniel Dunbar if (ResultPathName) 679420b0f1bSDaniel Dunbar *ResultPathName = OutFile; 680d0599970SArgyrios Kyrtzidis if (TempPathName) 681d0599970SArgyrios Kyrtzidis *TempPathName = TempFile; 682420b0f1bSDaniel Dunbar 68369f3528cSNAKAMURA Takumi return OS.release(); 684420b0f1bSDaniel Dunbar } 685409e890fSDaniel Dunbar 686409e890fSDaniel Dunbar // Initialization Utilities 687409e890fSDaniel Dunbar 6881b3240b0SArgyrios Kyrtzidis bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input){ 6891b3240b0SArgyrios Kyrtzidis return InitializeSourceManager(Input, getDiagnostics(), 690a686e1b0SDouglas Gregor getFileManager(), getSourceManager(), 691a686e1b0SDouglas Gregor getFrontendOpts()); 692409e890fSDaniel Dunbar } 693409e890fSDaniel Dunbar 6941b3240b0SArgyrios Kyrtzidis bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input, 6959c902b55SDavid Blaikie DiagnosticsEngine &Diags, 696409e890fSDaniel Dunbar FileManager &FileMgr, 697409e890fSDaniel Dunbar SourceManager &SourceMgr, 698409e890fSDaniel Dunbar const FrontendOptions &Opts) { 6991b3240b0SArgyrios Kyrtzidis SrcMgr::CharacteristicKind 700873c8583SArgyrios Kyrtzidis Kind = Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User; 7011b3240b0SArgyrios Kyrtzidis 7026566e23eSArgyrios Kyrtzidis if (Input.isBuffer()) { 703b671e34cSAlp Toker SourceMgr.setMainFileID(SourceMgr.createFileID(Input.getBuffer(), Kind)); 7046566e23eSArgyrios Kyrtzidis assert(!SourceMgr.getMainFileID().isInvalid() && 7056566e23eSArgyrios Kyrtzidis "Couldn't establish MainFileID!"); 7066566e23eSArgyrios Kyrtzidis return true; 7076566e23eSArgyrios Kyrtzidis } 7086566e23eSArgyrios Kyrtzidis 7096566e23eSArgyrios Kyrtzidis StringRef InputFile = Input.getFile(); 7106566e23eSArgyrios Kyrtzidis 7117c06d866SArgyrios Kyrtzidis // Figure out where to get and map in the main file. 7127c06d866SArgyrios Kyrtzidis if (InputFile != "-") { 7133841fa38SBenjamin Kramer const FileEntry *File = FileMgr.getFile(InputFile, /*OpenFile=*/true); 71452765215SDan Gohman if (!File) { 715409e890fSDaniel Dunbar Diags.Report(diag::err_fe_error_reading) << InputFile; 716409e890fSDaniel Dunbar return false; 717409e890fSDaniel Dunbar } 718e2951f48SDaniel Dunbar 719e2951f48SDaniel Dunbar // The natural SourceManager infrastructure can't currently handle named 720e2951f48SDaniel Dunbar // pipes, but we would at least like to accept them for the main 7213841fa38SBenjamin Kramer // file. Detect them here, read them with the volatile flag so FileMgr will 7223841fa38SBenjamin Kramer // pick up the correct size, and simply override their contents as we do for 7233841fa38SBenjamin Kramer // STDIN. 724e2951f48SDaniel Dunbar if (File->isNamedPipe()) { 7253841fa38SBenjamin Kramer std::string ErrorStr; 7266406f7b8SRafael Espindola if (std::unique_ptr<llvm::MemoryBuffer> MB = 7273841fa38SBenjamin Kramer FileMgr.getBufferForFile(File, &ErrorStr, /*isVolatile=*/true)) { 728db0745abSDaniel Dunbar // Create a new virtual file that will have the correct size. 729db0745abSDaniel Dunbar File = FileMgr.getVirtualFile(InputFile, MB->getBufferSize(), 0); 7306406f7b8SRafael Espindola SourceMgr.overrideFileContents(File, MB.release()); 7313841fa38SBenjamin Kramer } else { 7323841fa38SBenjamin Kramer Diags.Report(diag::err_cannot_open_file) << InputFile << ErrorStr; 7333841fa38SBenjamin Kramer return false; 7343841fa38SBenjamin Kramer } 735e2951f48SDaniel Dunbar } 736db0745abSDaniel Dunbar 737b671e34cSAlp Toker SourceMgr.setMainFileID( 738b671e34cSAlp Toker SourceMgr.createFileID(File, SourceLocation(), Kind)); 739409e890fSDaniel Dunbar } else { 7402d2b420aSRafael Espindola llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> SBOrErr = 7412d2b420aSRafael Espindola llvm::MemoryBuffer::getSTDIN(); 7422d2b420aSRafael Espindola if (std::error_code EC = SBOrErr.getError()) { 7432d2b420aSRafael Espindola Diags.Report(diag::err_fe_error_reading_stdin) << EC.message(); 744409e890fSDaniel Dunbar return false; 745409e890fSDaniel Dunbar } 7462d2b420aSRafael Espindola std::unique_ptr<llvm::MemoryBuffer> SB = std::move(SBOrErr.get()); 7472d2b420aSRafael Espindola 7482f76cd75SDan Gohman const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(), 7495159f616SChris Lattner SB->getBufferSize(), 0); 750b671e34cSAlp Toker SourceMgr.setMainFileID( 751b671e34cSAlp Toker SourceMgr.createFileID(File, SourceLocation(), Kind)); 7529a16beb8SAhmed Charles SourceMgr.overrideFileContents(File, SB.release()); 753409e890fSDaniel Dunbar } 754409e890fSDaniel Dunbar 75552765215SDan Gohman assert(!SourceMgr.getMainFileID().isInvalid() && 75652765215SDan Gohman "Couldn't establish MainFileID!"); 757409e890fSDaniel Dunbar return true; 758409e890fSDaniel Dunbar } 7594f2bc55dSDaniel Dunbar 7604f2bc55dSDaniel Dunbar // High-Level Operations 7614f2bc55dSDaniel Dunbar 7624f2bc55dSDaniel Dunbar bool CompilerInstance::ExecuteAction(FrontendAction &Act) { 7634f2bc55dSDaniel Dunbar assert(hasDiagnostics() && "Diagnostics engine is not initialized!"); 7644f2bc55dSDaniel Dunbar assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!"); 7654f2bc55dSDaniel Dunbar assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!"); 7664f2bc55dSDaniel Dunbar 7674f2bc55dSDaniel Dunbar // FIXME: Take this as an argument, once all the APIs we used have moved to 7684f2bc55dSDaniel Dunbar // taking it as an input instead of hard-coding llvm::errs. 7690e62c1ccSChris Lattner raw_ostream &OS = llvm::errs(); 7704f2bc55dSDaniel Dunbar 7714f2bc55dSDaniel Dunbar // Create the target instance. 77280758084SAlp Toker setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), 77380758084SAlp Toker getInvocation().TargetOpts)); 7744f2bc55dSDaniel Dunbar if (!hasTarget()) 7754f2bc55dSDaniel Dunbar return false; 7764f2bc55dSDaniel Dunbar 7774f2bc55dSDaniel Dunbar // Inform the target of the language options. 7784f2bc55dSDaniel Dunbar // 7794f2bc55dSDaniel Dunbar // FIXME: We shouldn't need to do this, the target should be immutable once 7804f2bc55dSDaniel Dunbar // created. This complexity should be lifted elsewhere. 78174437975SAlp Toker getTarget().adjust(getLangOpts()); 7824f2bc55dSDaniel Dunbar 78329898f45SFariborz Jahanian // rewriter project will change target built-in bool type from its default. 78429898f45SFariborz Jahanian if (getFrontendOpts().ProgramAction == frontend::RewriteObjC) 78529898f45SFariborz Jahanian getTarget().noSignedCharForObjCBool(); 78629898f45SFariborz Jahanian 7874f2bc55dSDaniel Dunbar // Validate/process some options. 7884f2bc55dSDaniel Dunbar if (getHeaderSearchOpts().Verbose) 7894f2bc55dSDaniel Dunbar OS << "clang -cc1 version " CLANG_VERSION_STRING 790f988d006SAlp Toker << " based upon " << BACKEND_PACKAGE_STRING 7918188c8a1SSebastian Pop << " default target " << llvm::sys::getDefaultTargetTriple() << "\n"; 7924f2bc55dSDaniel Dunbar 7934f2bc55dSDaniel Dunbar if (getFrontendOpts().ShowTimers) 7944f2bc55dSDaniel Dunbar createFrontendTimer(); 7954f2bc55dSDaniel Dunbar 796171b780cSDouglas Gregor if (getFrontendOpts().ShowStats) 797171b780cSDouglas Gregor llvm::EnableStatistics(); 798171b780cSDouglas Gregor 7994f2bc55dSDaniel Dunbar for (unsigned i = 0, e = getFrontendOpts().Inputs.size(); i != e; ++i) { 800eeccb30bSTed Kremenek // Reset the ID tables if we are reusing the SourceManager and parsing 801eeccb30bSTed Kremenek // regular files. 802eeccb30bSTed Kremenek if (hasSourceManager() && !Act.isModelParsingAction()) 8034f2bc55dSDaniel Dunbar getSourceManager().clearIDTables(); 8044f2bc55dSDaniel Dunbar 80532fbe312SDouglas Gregor if (Act.BeginSourceFile(*this, getFrontendOpts().Inputs[i])) { 8064f2bc55dSDaniel Dunbar Act.Execute(); 8074f2bc55dSDaniel Dunbar Act.EndSourceFile(); 8084f2bc55dSDaniel Dunbar } 8094f2bc55dSDaniel Dunbar } 8104f2bc55dSDaniel Dunbar 8117910d7b7SArgyrios Kyrtzidis // Notify the diagnostic client that all files were processed. 8127910d7b7SArgyrios Kyrtzidis getDiagnostics().getClient()->finish(); 8137910d7b7SArgyrios Kyrtzidis 814198cb4dfSChris Lattner if (getDiagnosticOpts().ShowCarets) { 815c79346a5SArgyrios Kyrtzidis // We can have multiple diagnostics sharing one diagnostic client. 816c79346a5SArgyrios Kyrtzidis // Get the total number of warnings/errors from the client. 817c79346a5SArgyrios Kyrtzidis unsigned NumWarnings = getDiagnostics().getClient()->getNumWarnings(); 818c79346a5SArgyrios Kyrtzidis unsigned NumErrors = getDiagnostics().getClient()->getNumErrors(); 819198cb4dfSChris Lattner 820198cb4dfSChris Lattner if (NumWarnings) 821198cb4dfSChris Lattner OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s"); 822198cb4dfSChris Lattner if (NumWarnings && NumErrors) 823198cb4dfSChris Lattner OS << " and "; 824198cb4dfSChris Lattner if (NumErrors) 825198cb4dfSChris Lattner OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s"); 826198cb4dfSChris Lattner if (NumWarnings || NumErrors) 827198cb4dfSChris Lattner OS << " generated.\n"; 828198cb4dfSChris Lattner } 8294f2bc55dSDaniel Dunbar 830aed46fcbSDaniel Dunbar if (getFrontendOpts().ShowStats && hasFileManager()) { 8314f2bc55dSDaniel Dunbar getFileManager().PrintStats(); 8324f2bc55dSDaniel Dunbar OS << "\n"; 8334f2bc55dSDaniel Dunbar } 8344f2bc55dSDaniel Dunbar 835bc467933SArgyrios Kyrtzidis return !getDiagnostics().getClient()->getNumErrors(); 8364f2bc55dSDaniel Dunbar } 8374f2bc55dSDaniel Dunbar 838faeb1d46SDouglas Gregor /// \brief Determine the appropriate source input kind based on language 839faeb1d46SDouglas Gregor /// options. 840faeb1d46SDouglas Gregor static InputKind getSourceInputKindFromOptions(const LangOptions &LangOpts) { 841faeb1d46SDouglas Gregor if (LangOpts.OpenCL) 842faeb1d46SDouglas Gregor return IK_OpenCL; 843faeb1d46SDouglas Gregor if (LangOpts.CUDA) 844faeb1d46SDouglas Gregor return IK_CUDA; 845faeb1d46SDouglas Gregor if (LangOpts.ObjC1) 846faeb1d46SDouglas Gregor return LangOpts.CPlusPlus? IK_ObjCXX : IK_ObjC; 847faeb1d46SDouglas Gregor return LangOpts.CPlusPlus? IK_CXX : IK_C; 848faeb1d46SDouglas Gregor } 849faeb1d46SDouglas Gregor 850514b636aSDouglas Gregor /// \brief Compile a module file for the given module, using the options 851b797d59fSBen Langmuir /// provided by the importing compiler instance. Returns true if the module 852b797d59fSBen Langmuir /// was built without errors. 853b797d59fSBen Langmuir static bool compileModuleImpl(CompilerInstance &ImportingInstance, 854af8f0263SDouglas Gregor SourceLocation ImportLoc, 855de3ef502SDouglas Gregor Module *Module, 8566dc57927SDouglas Gregor StringRef ModuleFileName) { 857514b636aSDouglas Gregor ModuleMap &ModMap 858514b636aSDouglas Gregor = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap(); 859514b636aSDouglas Gregor 860faeb1d46SDouglas Gregor // Construct a compiler invocation for creating this module. 861c95d8192SDylan Noblesmith IntrusiveRefCntPtr<CompilerInvocation> Invocation 862faeb1d46SDouglas Gregor (new CompilerInvocation(ImportingInstance.getInvocation())); 86344bf68d8SDouglas Gregor 864f545f67dSDouglas Gregor PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 865f545f67dSDouglas Gregor 86644bf68d8SDouglas Gregor // For any options that aren't intended to affect how a module is built, 86744bf68d8SDouglas Gregor // reset them to their default values. 8688cf47df7STed Kremenek Invocation->getLangOpts()->resetNonModularOptions(); 869f545f67dSDouglas Gregor PPOpts.resetNonModularOptions(); 87044bf68d8SDouglas Gregor 8715dc3899cSDouglas Gregor // Remove any macro definitions that are explicitly ignored by the module. 8725dc3899cSDouglas Gregor // They aren't supposed to affect how the module is built anyway. 8735dc3899cSDouglas Gregor const HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts(); 874bbdd7640SBenjamin Kramer PPOpts.Macros.erase( 875bbdd7640SBenjamin Kramer std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(), 876bbdd7640SBenjamin Kramer [&HSOpts](const std::pair<std::string, bool> &def) { 877bbdd7640SBenjamin Kramer StringRef MacroDef = def.first; 878bbdd7640SBenjamin Kramer return HSOpts.ModulesIgnoreMacros.count(MacroDef.split('=').first) > 0; 879bbdd7640SBenjamin Kramer }), 8805dc3899cSDouglas Gregor PPOpts.Macros.end()); 8815dc3899cSDouglas Gregor 8827d106e42SDouglas Gregor // Note the name of the module we're building. 8836dc57927SDouglas Gregor Invocation->getLangOpts()->CurrentModule = Module->getTopLevelModuleName(); 8847d106e42SDouglas Gregor 8857a626570SDouglas Gregor // Make sure that the failed-module structure has been allocated in 8867a626570SDouglas Gregor // the importing instance, and propagate the pointer to the newly-created 8877a626570SDouglas Gregor // instance. 8887a626570SDouglas Gregor PreprocessorOptions &ImportingPPOpts 8897a626570SDouglas Gregor = ImportingInstance.getInvocation().getPreprocessorOpts(); 8907a626570SDouglas Gregor if (!ImportingPPOpts.FailedModules) 8917a626570SDouglas Gregor ImportingPPOpts.FailedModules = new PreprocessorOptions::FailedModulesSet; 8927a626570SDouglas Gregor PPOpts.FailedModules = ImportingPPOpts.FailedModules; 8937a626570SDouglas Gregor 894514b636aSDouglas Gregor // If there is a module map file, build the module using the module map. 895514b636aSDouglas Gregor // Set up the inputs/outputs so that we build the module from its umbrella 896514b636aSDouglas Gregor // header. 897514b636aSDouglas Gregor FrontendOptions &FrontendOpts = Invocation->getFrontendOpts(); 898514b636aSDouglas Gregor FrontendOpts.OutputFile = ModuleFileName.str(); 899514b636aSDouglas Gregor FrontendOpts.DisableFree = false; 900c1bbec85SDouglas Gregor FrontendOpts.GenerateGlobalModuleIndex = false; 901514b636aSDouglas Gregor FrontendOpts.Inputs.clear(); 902f545f67dSDouglas Gregor InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts()); 903f545f67dSDouglas Gregor 904f545f67dSDouglas Gregor // Don't free the remapped file buffers; they are owned by our caller. 905f545f67dSDouglas Gregor PPOpts.RetainRemappedFileBuffers = true; 906514b636aSDouglas Gregor 907514b636aSDouglas Gregor Invocation->getDiagnosticOpts().VerifyDiagnostics = 0; 908514b636aSDouglas Gregor assert(ImportingInstance.getInvocation().getModuleHash() == 909514b636aSDouglas Gregor Invocation->getModuleHash() && "Module hash mismatch!"); 910514b636aSDouglas Gregor 911514b636aSDouglas Gregor // Construct a compiler instance that will be used to actually create the 912514b636aSDouglas Gregor // module. 9132255f2ceSJohn Thompson CompilerInstance Instance(/*BuildingModule=*/true); 914514b636aSDouglas Gregor Instance.setInvocation(&*Invocation); 9156b930967SDouglas Gregor 9166b930967SDouglas Gregor Instance.createDiagnostics(new ForwardingDiagnosticConsumer( 9176b930967SDouglas Gregor ImportingInstance.getDiagnosticClient()), 91830071ceaSDouglas Gregor /*ShouldOwnClient=*/true); 919514b636aSDouglas Gregor 920c8130a74SBen Langmuir Instance.setVirtualFileSystem(&ImportingInstance.getVirtualFileSystem()); 921c8130a74SBen Langmuir 92263365431SDouglas Gregor // Note that this module is part of the module build stack, so that we 923af8f0263SDouglas Gregor // can detect cycles in the module graph. 924d066d4c8SBen Langmuir Instance.setFileManager(&ImportingInstance.getFileManager()); 925af8f0263SDouglas Gregor Instance.createSourceManager(Instance.getFileManager()); 926af8f0263SDouglas Gregor SourceManager &SourceMgr = Instance.getSourceManager(); 92763365431SDouglas Gregor SourceMgr.setModuleBuildStack( 92863365431SDouglas Gregor ImportingInstance.getSourceManager().getModuleBuildStack()); 92963365431SDouglas Gregor SourceMgr.pushModuleBuildStack(Module->getTopLevelModuleName(), 930af8f0263SDouglas Gregor FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager())); 931af8f0263SDouglas Gregor 93286d1259cSJustin Bogner // If we're collecting module dependencies, we need to share a collector 93386d1259cSJustin Bogner // between all of the module CompilerInstances. 93486d1259cSJustin Bogner Instance.setModuleDepCollector(ImportingInstance.getModuleDepCollector()); 93586d1259cSJustin Bogner 9361f76c4e8SManuel Klimek // Get or create the module map that we'll use to build this module. 9371f76c4e8SManuel Klimek std::string InferredModuleMapContent; 9381f76c4e8SManuel Klimek if (const FileEntry *ModuleMapFile = 9391f76c4e8SManuel Klimek ModMap.getContainingModuleMapFile(Module)) { 9401f76c4e8SManuel Klimek // Use the module map where this module resides. 9411f76c4e8SManuel Klimek FrontendOpts.Inputs.push_back( 9421f76c4e8SManuel Klimek FrontendInputFile(ModuleMapFile->getName(), IK)); 9431f76c4e8SManuel Klimek } else { 9441f76c4e8SManuel Klimek llvm::raw_string_ostream OS(InferredModuleMapContent); 9451f76c4e8SManuel Klimek Module->print(OS); 9461f76c4e8SManuel Klimek OS.flush(); 9471f76c4e8SManuel Klimek FrontendOpts.Inputs.push_back( 9481f76c4e8SManuel Klimek FrontendInputFile("__inferred_module.map", IK)); 9491f76c4e8SManuel Klimek 950*d87f8d76SRafael Espindola std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer = 9511f76c4e8SManuel Klimek llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent); 9521f76c4e8SManuel Klimek ModuleMapFile = Instance.getFileManager().getVirtualFile( 9531f76c4e8SManuel Klimek "__inferred_module.map", InferredModuleMapContent.size(), 0); 954*d87f8d76SRafael Espindola SourceMgr.overrideFileContents(ModuleMapFile, ModuleMapBuffer.release()); 9551f76c4e8SManuel Klimek } 956af8f0263SDouglas Gregor 9579d6448b1SBen Langmuir // Construct a module-generating action. Passing through the module map is 958beee15e7SBen Langmuir // safe because the FileManager is shared between the compiler instances. 9599d6448b1SBen Langmuir GenerateModuleAction CreateModuleAction( 9609d6448b1SBen Langmuir ModMap.getModuleMapFileForUniquing(Module), Module->IsSystem); 961514b636aSDouglas Gregor 962514b636aSDouglas Gregor // Execute the action to actually build the module in-place. Use a separate 963514b636aSDouglas Gregor // thread so that we get a stack large enough. 964514b636aSDouglas Gregor const unsigned ThreadStackSize = 8 << 20; 965514b636aSDouglas Gregor llvm::CrashRecoveryContext CRC; 966841f1c78SRichard Smith CRC.RunSafelyOnThread([&]() { Instance.ExecuteAction(CreateModuleAction); }, 967841f1c78SRichard Smith ThreadStackSize); 9686b930967SDouglas Gregor 969f545f67dSDouglas Gregor // Delete the temporary module map file. 970f545f67dSDouglas Gregor // FIXME: Even though we're executing under crash protection, it would still 971f545f67dSDouglas Gregor // be nice to do this with RemoveFileOnSignal when we can. However, that 972f545f67dSDouglas Gregor // doesn't make sense for all clients, so clean this up manually. 97313afbf42SBenjamin Kramer Instance.clearOutputFiles(/*EraseFiles=*/true); 9745e306b12SDouglas Gregor 9755e306b12SDouglas Gregor // We've rebuilt a module. If we're allowed to generate or update the global 9765e306b12SDouglas Gregor // module index, record that fact in the importing compiler instance. 977c1bbec85SDouglas Gregor if (ImportingInstance.getFrontendOpts().GenerateGlobalModuleIndex) { 9785e306b12SDouglas Gregor ImportingInstance.setBuildGlobalModuleIndex(true); 9795e306b12SDouglas Gregor } 980b797d59fSBen Langmuir 981b797d59fSBen Langmuir return !Instance.getDiagnostics().hasErrorOccurred(); 982faeb1d46SDouglas Gregor } 983faeb1d46SDouglas Gregor 984dbdc0368SBen Langmuir static bool compileAndLoadModule(CompilerInstance &ImportingInstance, 9854382fe74SArgyrios Kyrtzidis SourceLocation ImportLoc, 986b797d59fSBen Langmuir SourceLocation ModuleNameLoc, Module *Module, 9874382fe74SArgyrios Kyrtzidis StringRef ModuleFileName) { 988b797d59fSBen Langmuir auto diagnoseBuildFailure = [&] { 989b797d59fSBen Langmuir ImportingInstance.getDiagnostics().Report(ModuleNameLoc, 990b797d59fSBen Langmuir diag::err_module_not_built) 991b797d59fSBen Langmuir << Module->Name << SourceRange(ImportLoc, ModuleNameLoc); 992b797d59fSBen Langmuir }; 993b797d59fSBen Langmuir 9944382fe74SArgyrios Kyrtzidis // FIXME: have LockFileManager return an error_code so that we can 9954382fe74SArgyrios Kyrtzidis // avoid the mkdir when the directory already exists. 9964382fe74SArgyrios Kyrtzidis StringRef Dir = llvm::sys::path::parent_path(ModuleFileName); 9974382fe74SArgyrios Kyrtzidis llvm::sys::fs::create_directories(Dir); 9984382fe74SArgyrios Kyrtzidis 9994382fe74SArgyrios Kyrtzidis while (1) { 1000dbdc0368SBen Langmuir unsigned ModuleLoadCapabilities = ASTReader::ARR_Missing; 10014382fe74SArgyrios Kyrtzidis llvm::LockFileManager Locked(ModuleFileName); 10024382fe74SArgyrios Kyrtzidis switch (Locked) { 10034382fe74SArgyrios Kyrtzidis case llvm::LockFileManager::LFS_Error: 1004dbdc0368SBen Langmuir return false; 10054382fe74SArgyrios Kyrtzidis 10064382fe74SArgyrios Kyrtzidis case llvm::LockFileManager::LFS_Owned: 1007dbdc0368SBen Langmuir // We're responsible for building the module ourselves. 1008b797d59fSBen Langmuir if (!compileModuleImpl(ImportingInstance, ModuleNameLoc, Module, 1009b797d59fSBen Langmuir ModuleFileName)) { 1010b797d59fSBen Langmuir diagnoseBuildFailure(); 1011b797d59fSBen Langmuir return false; 1012b797d59fSBen Langmuir } 10134382fe74SArgyrios Kyrtzidis break; 10144382fe74SArgyrios Kyrtzidis 10154382fe74SArgyrios Kyrtzidis case llvm::LockFileManager::LFS_Shared: 10164382fe74SArgyrios Kyrtzidis // Someone else is responsible for building the module. Wait for them to 10174382fe74SArgyrios Kyrtzidis // finish. 10184382fe74SArgyrios Kyrtzidis if (Locked.waitForUnlock() == llvm::LockFileManager::Res_OwnerDied) 10194382fe74SArgyrios Kyrtzidis continue; // try again to get the lock. 1020dbdc0368SBen Langmuir ModuleLoadCapabilities |= ASTReader::ARR_OutOfDate; 1021dbdc0368SBen Langmuir break; 10224382fe74SArgyrios Kyrtzidis } 10234382fe74SArgyrios Kyrtzidis 1024dbdc0368SBen Langmuir // Try to read the module file, now that we've compiled it. 1025dbdc0368SBen Langmuir ASTReader::ASTReadResult ReadResult = 1026dbdc0368SBen Langmuir ImportingInstance.getModuleManager()->ReadAST( 1027dbdc0368SBen Langmuir ModuleFileName, serialization::MK_Module, ImportLoc, 1028dbdc0368SBen Langmuir ModuleLoadCapabilities); 1029dbdc0368SBen Langmuir 1030dbdc0368SBen Langmuir if (ReadResult == ASTReader::OutOfDate && 1031dbdc0368SBen Langmuir Locked == llvm::LockFileManager::LFS_Shared) { 1032dbdc0368SBen Langmuir // The module may be out of date in the presence of file system races, 1033dbdc0368SBen Langmuir // or if one of its imports depends on header search paths that are not 1034dbdc0368SBen Langmuir // consistent with this ImportingInstance. Try again... 1035dbdc0368SBen Langmuir continue; 1036dbdc0368SBen Langmuir } else if (ReadResult == ASTReader::Missing) { 1037b797d59fSBen Langmuir diagnoseBuildFailure(); 1038dbdc0368SBen Langmuir } 1039dbdc0368SBen Langmuir return ReadResult == ASTReader::Success; 10404382fe74SArgyrios Kyrtzidis } 10414382fe74SArgyrios Kyrtzidis } 10424382fe74SArgyrios Kyrtzidis 104335b13eceSDouglas Gregor /// \brief Diagnose differences between the current definition of the given 104435b13eceSDouglas Gregor /// configuration macro and the definition provided on the command line. 104535b13eceSDouglas Gregor static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro, 104635b13eceSDouglas Gregor Module *Mod, SourceLocation ImportLoc) { 104735b13eceSDouglas Gregor IdentifierInfo *Id = PP.getIdentifierInfo(ConfigMacro); 104835b13eceSDouglas Gregor SourceManager &SourceMgr = PP.getSourceManager(); 104935b13eceSDouglas Gregor 105035b13eceSDouglas Gregor // If this identifier has never had a macro definition, then it could 105135b13eceSDouglas Gregor // not have changed. 105235b13eceSDouglas Gregor if (!Id->hadMacroDefinition()) 105335b13eceSDouglas Gregor return; 105435b13eceSDouglas Gregor 105535b13eceSDouglas Gregor // If this identifier does not currently have a macro definition, 105635b13eceSDouglas Gregor // check whether it had one on the command line. 105735b13eceSDouglas Gregor if (!Id->hasMacroDefinition()) { 1058b6210dffSArgyrios Kyrtzidis MacroDirective::DefInfo LatestDef = 1059b6210dffSArgyrios Kyrtzidis PP.getMacroDirectiveHistory(Id)->getDefinition(); 1060b6210dffSArgyrios Kyrtzidis for (MacroDirective::DefInfo Def = LatestDef; Def; 1061b6210dffSArgyrios Kyrtzidis Def = Def.getPreviousDefinition()) { 1062b6210dffSArgyrios Kyrtzidis FileID FID = SourceMgr.getFileID(Def.getLocation()); 106335b13eceSDouglas Gregor if (FID.isInvalid()) 106435b13eceSDouglas Gregor continue; 106535b13eceSDouglas Gregor 106635b13eceSDouglas Gregor // We only care about the predefines buffer. 106705ba2a05SDouglas Gregor if (FID != PP.getPredefinesFileID()) 106835b13eceSDouglas Gregor continue; 106935b13eceSDouglas Gregor 107035b13eceSDouglas Gregor // This macro was defined on the command line, then #undef'd later. 107135b13eceSDouglas Gregor // Complain. 107235b13eceSDouglas Gregor PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 107335b13eceSDouglas Gregor << true << ConfigMacro << Mod->getFullModuleName(); 1074b6210dffSArgyrios Kyrtzidis if (LatestDef.isUndefined()) 1075b6210dffSArgyrios Kyrtzidis PP.Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here) 107635b13eceSDouglas Gregor << true; 107735b13eceSDouglas Gregor return; 107835b13eceSDouglas Gregor } 107935b13eceSDouglas Gregor 108035b13eceSDouglas Gregor // Okay: no definition in the predefines buffer. 108135b13eceSDouglas Gregor return; 108235b13eceSDouglas Gregor } 108335b13eceSDouglas Gregor 108435b13eceSDouglas Gregor // This identifier has a macro definition. Check whether we had a definition 108535b13eceSDouglas Gregor // on the command line. 1086b6210dffSArgyrios Kyrtzidis MacroDirective::DefInfo LatestDef = 1087b6210dffSArgyrios Kyrtzidis PP.getMacroDirectiveHistory(Id)->getDefinition(); 1088b6210dffSArgyrios Kyrtzidis MacroDirective::DefInfo PredefinedDef; 1089b6210dffSArgyrios Kyrtzidis for (MacroDirective::DefInfo Def = LatestDef; Def; 1090b6210dffSArgyrios Kyrtzidis Def = Def.getPreviousDefinition()) { 1091b6210dffSArgyrios Kyrtzidis FileID FID = SourceMgr.getFileID(Def.getLocation()); 109235b13eceSDouglas Gregor if (FID.isInvalid()) 109335b13eceSDouglas Gregor continue; 109435b13eceSDouglas Gregor 109535b13eceSDouglas Gregor // We only care about the predefines buffer. 109605ba2a05SDouglas Gregor if (FID != PP.getPredefinesFileID()) 109735b13eceSDouglas Gregor continue; 109835b13eceSDouglas Gregor 1099b6210dffSArgyrios Kyrtzidis PredefinedDef = Def; 110035b13eceSDouglas Gregor break; 110135b13eceSDouglas Gregor } 110235b13eceSDouglas Gregor 110335b13eceSDouglas Gregor // If there was no definition for this macro in the predefines buffer, 110435b13eceSDouglas Gregor // complain. 1105b6210dffSArgyrios Kyrtzidis if (!PredefinedDef || 1106b6210dffSArgyrios Kyrtzidis (!PredefinedDef.getLocation().isValid() && 1107b6210dffSArgyrios Kyrtzidis PredefinedDef.getUndefLocation().isValid())) { 110835b13eceSDouglas Gregor PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 110935b13eceSDouglas Gregor << false << ConfigMacro << Mod->getFullModuleName(); 1110b6210dffSArgyrios Kyrtzidis PP.Diag(LatestDef.getLocation(), diag::note_module_def_undef_here) 111135b13eceSDouglas Gregor << false; 111235b13eceSDouglas Gregor return; 111335b13eceSDouglas Gregor } 111435b13eceSDouglas Gregor 111535b13eceSDouglas Gregor // If the current macro definition is the same as the predefined macro 111635b13eceSDouglas Gregor // definition, it's okay. 1117b6210dffSArgyrios Kyrtzidis if (LatestDef.getMacroInfo() == PredefinedDef.getMacroInfo() || 11180c2f30b9SArgyrios Kyrtzidis LatestDef.getMacroInfo()->isIdenticalTo(*PredefinedDef.getMacroInfo(),PP, 11190c2f30b9SArgyrios Kyrtzidis /*Syntactically=*/true)) 112035b13eceSDouglas Gregor return; 112135b13eceSDouglas Gregor 112235b13eceSDouglas Gregor // The macro definitions differ. 112335b13eceSDouglas Gregor PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 112435b13eceSDouglas Gregor << false << ConfigMacro << Mod->getFullModuleName(); 1125b6210dffSArgyrios Kyrtzidis PP.Diag(LatestDef.getLocation(), diag::note_module_def_undef_here) 112635b13eceSDouglas Gregor << false; 112735b13eceSDouglas Gregor } 112835b13eceSDouglas Gregor 1129527b1c95SDouglas Gregor /// \brief Write a new timestamp file with the given path. 1130527b1c95SDouglas Gregor static void writeTimestampFile(StringRef TimestampFile) { 1131dae941a6SRafael Espindola std::error_code EC; 1132dae941a6SRafael Espindola llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::F_None); 1133527b1c95SDouglas Gregor } 1134527b1c95SDouglas Gregor 1135527b1c95SDouglas Gregor /// \brief Prune the module cache of modules that haven't been accessed in 1136527b1c95SDouglas Gregor /// a long time. 1137527b1c95SDouglas Gregor static void pruneModuleCache(const HeaderSearchOptions &HSOpts) { 1138527b1c95SDouglas Gregor struct stat StatBuf; 1139527b1c95SDouglas Gregor llvm::SmallString<128> TimestampFile; 1140527b1c95SDouglas Gregor TimestampFile = HSOpts.ModuleCachePath; 1141527b1c95SDouglas Gregor llvm::sys::path::append(TimestampFile, "modules.timestamp"); 1142527b1c95SDouglas Gregor 1143527b1c95SDouglas Gregor // Try to stat() the timestamp file. 1144527b1c95SDouglas Gregor if (::stat(TimestampFile.c_str(), &StatBuf)) { 1145527b1c95SDouglas Gregor // If the timestamp file wasn't there, create one now. 1146527b1c95SDouglas Gregor if (errno == ENOENT) { 1147527b1c95SDouglas Gregor writeTimestampFile(TimestampFile); 1148527b1c95SDouglas Gregor } 1149527b1c95SDouglas Gregor return; 1150527b1c95SDouglas Gregor } 1151527b1c95SDouglas Gregor 1152527b1c95SDouglas Gregor // Check whether the time stamp is older than our pruning interval. 1153527b1c95SDouglas Gregor // If not, do nothing. 1154527b1c95SDouglas Gregor time_t TimeStampModTime = StatBuf.st_mtime; 115549a2790fSCraig Topper time_t CurrentTime = time(nullptr); 1156dbcf5037SBenjamin Kramer if (CurrentTime - TimeStampModTime <= time_t(HSOpts.ModuleCachePruneInterval)) 1157527b1c95SDouglas Gregor return; 1158527b1c95SDouglas Gregor 1159527b1c95SDouglas Gregor // Write a new timestamp file so that nobody else attempts to prune. 1160527b1c95SDouglas Gregor // There is a benign race condition here, if two Clang instances happen to 1161527b1c95SDouglas Gregor // notice at the same time that the timestamp is out-of-date. 1162527b1c95SDouglas Gregor writeTimestampFile(TimestampFile); 1163527b1c95SDouglas Gregor 1164527b1c95SDouglas Gregor // Walk the entire module cache, looking for unused module files and module 1165527b1c95SDouglas Gregor // indices. 1166c080917eSRafael Espindola std::error_code EC; 1167527b1c95SDouglas Gregor SmallString<128> ModuleCachePathNative; 1168527b1c95SDouglas Gregor llvm::sys::path::native(HSOpts.ModuleCachePath, ModuleCachePathNative); 1169527b1c95SDouglas Gregor for (llvm::sys::fs::directory_iterator 1170527b1c95SDouglas Gregor Dir(ModuleCachePathNative.str(), EC), DirEnd; 1171527b1c95SDouglas Gregor Dir != DirEnd && !EC; Dir.increment(EC)) { 1172527b1c95SDouglas Gregor // If we don't have a directory, there's nothing to look into. 1173a07f720aSRafael Espindola if (!llvm::sys::fs::is_directory(Dir->path())) 1174527b1c95SDouglas Gregor continue; 1175527b1c95SDouglas Gregor 1176527b1c95SDouglas Gregor // Walk all of the files within this directory. 1177527b1c95SDouglas Gregor for (llvm::sys::fs::directory_iterator File(Dir->path(), EC), FileEnd; 1178527b1c95SDouglas Gregor File != FileEnd && !EC; File.increment(EC)) { 1179527b1c95SDouglas Gregor // We only care about module and global module index files. 1180f430da4dSDmitri Gribenko StringRef Extension = llvm::sys::path::extension(File->path()); 1181f430da4dSDmitri Gribenko if (Extension != ".pcm" && Extension != ".timestamp" && 1182f430da4dSDmitri Gribenko llvm::sys::path::filename(File->path()) != "modules.idx") 1183527b1c95SDouglas Gregor continue; 1184527b1c95SDouglas Gregor 1185527b1c95SDouglas Gregor // Look at this file. If we can't stat it, there's nothing interesting 1186527b1c95SDouglas Gregor // there. 1187f430da4dSDmitri Gribenko if (::stat(File->path().c_str(), &StatBuf)) 1188527b1c95SDouglas Gregor continue; 1189527b1c95SDouglas Gregor 1190527b1c95SDouglas Gregor // If the file has been used recently enough, leave it there. 1191527b1c95SDouglas Gregor time_t FileAccessTime = StatBuf.st_atime; 1192dbcf5037SBenjamin Kramer if (CurrentTime - FileAccessTime <= 1193dbcf5037SBenjamin Kramer time_t(HSOpts.ModuleCachePruneAfter)) { 1194527b1c95SDouglas Gregor continue; 1195527b1c95SDouglas Gregor } 1196527b1c95SDouglas Gregor 1197527b1c95SDouglas Gregor // Remove the file. 1198f430da4dSDmitri Gribenko llvm::sys::fs::remove(File->path()); 1199f430da4dSDmitri Gribenko 1200f430da4dSDmitri Gribenko // Remove the timestamp file. 1201f430da4dSDmitri Gribenko std::string TimpestampFilename = File->path() + ".timestamp"; 1202f430da4dSDmitri Gribenko llvm::sys::fs::remove(TimpestampFilename); 1203527b1c95SDouglas Gregor } 1204527b1c95SDouglas Gregor 1205527b1c95SDouglas Gregor // If we removed all of the files in the directory, remove the directory 1206527b1c95SDouglas Gregor // itself. 1207f430da4dSDmitri Gribenko if (llvm::sys::fs::directory_iterator(Dir->path(), EC) == 1208f430da4dSDmitri Gribenko llvm::sys::fs::directory_iterator() && !EC) 12092a008784SRafael Espindola llvm::sys::fs::remove(Dir->path()); 1210527b1c95SDouglas Gregor } 1211527b1c95SDouglas Gregor } 1212527b1c95SDouglas Gregor 12132255f2ceSJohn Thompson void CompilerInstance::createModuleManager() { 12142255f2ceSJohn Thompson if (!ModuleManager) { 12152255f2ceSJohn Thompson if (!hasASTContext()) 12162255f2ceSJohn Thompson createASTContext(); 12172255f2ceSJohn Thompson 12182255f2ceSJohn Thompson // If we're not recursively building a module, check whether we 12192255f2ceSJohn Thompson // need to prune the module cache. 12202255f2ceSJohn Thompson if (getSourceManager().getModuleBuildStack().empty() && 12212255f2ceSJohn Thompson getHeaderSearchOpts().ModuleCachePruneInterval > 0 && 12222255f2ceSJohn Thompson getHeaderSearchOpts().ModuleCachePruneAfter > 0) { 12232255f2ceSJohn Thompson pruneModuleCache(getHeaderSearchOpts()); 12242255f2ceSJohn Thompson } 12252255f2ceSJohn Thompson 12262255f2ceSJohn Thompson HeaderSearchOptions &HSOpts = getHeaderSearchOpts(); 12272255f2ceSJohn Thompson std::string Sysroot = HSOpts.Sysroot; 12282255f2ceSJohn Thompson const PreprocessorOptions &PPOpts = getPreprocessorOpts(); 12292255f2ceSJohn Thompson ModuleManager = new ASTReader(getPreprocessor(), *Context, 12302255f2ceSJohn Thompson Sysroot.empty() ? "" : Sysroot.c_str(), 12312255f2ceSJohn Thompson PPOpts.DisablePCHValidation, 12322255f2ceSJohn Thompson /*AllowASTWithCompilerErrors=*/false, 12332255f2ceSJohn Thompson /*AllowConfigurationMismatch=*/false, 12342255f2ceSJohn Thompson HSOpts.ModulesValidateSystemHeaders, 12352255f2ceSJohn Thompson getFrontendOpts().UseGlobalModuleIndex); 12362255f2ceSJohn Thompson if (hasASTConsumer()) { 12372255f2ceSJohn Thompson ModuleManager->setDeserializationListener( 12382255f2ceSJohn Thompson getASTConsumer().GetASTDeserializationListener()); 12392255f2ceSJohn Thompson getASTContext().setASTMutationListener( 12402255f2ceSJohn Thompson getASTConsumer().GetASTMutationListener()); 12412255f2ceSJohn Thompson } 12422255f2ceSJohn Thompson getASTContext().setExternalSource(ModuleManager); 12432255f2ceSJohn Thompson if (hasSema()) 12442255f2ceSJohn Thompson ModuleManager->InitializeSema(getSema()); 12452255f2ceSJohn Thompson if (hasASTConsumer()) 12462255f2ceSJohn Thompson ModuleManager->StartTranslationUnit(&getASTConsumer()); 12472255f2ceSJohn Thompson } 12482255f2ceSJohn Thompson } 12492255f2ceSJohn Thompson 12507a626570SDouglas Gregor ModuleLoadResult 12517a626570SDouglas Gregor CompilerInstance::loadModule(SourceLocation ImportLoc, 1252ff2be53fSDouglas Gregor ModuleIdPath Path, 1253bcfc7d02SDouglas Gregor Module::NameVisibilityKind Visibility, 1254bcfc7d02SDouglas Gregor bool IsInclusionDirective) { 125592304e00SRichard Smith // Determine what file we're searching from. 125692304e00SRichard Smith StringRef ModuleName = Path[0].first->getName(); 125792304e00SRichard Smith SourceLocation ModuleNameLoc = Path[0].second; 125892304e00SRichard Smith 12591805b8a4SDouglas Gregor // If we've already handled this import, just return the cached result. 12601805b8a4SDouglas Gregor // This one-element cache is important to eliminate redundant diagnostics 12611805b8a4SDouglas Gregor // when both the preprocessor and parser see the same import declaration. 1262ff2be53fSDouglas Gregor if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc) { 1263ff2be53fSDouglas Gregor // Make the named module visible. 1264b537a3a6SBen Langmuir if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule && 1265b537a3a6SBen Langmuir ModuleName != getLangOpts().ImplementationOfModule) 1266125df058SArgyrios Kyrtzidis ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility, 1267fb912657SDouglas Gregor ImportLoc, /*Complain=*/false); 126869021974SDouglas Gregor return LastModuleImportResult; 1269ff2be53fSDouglas Gregor } 12701805b8a4SDouglas Gregor 127149a2790fSCraig Topper clang::Module *Module = nullptr; 12725196bc6bSDouglas Gregor 12735196bc6bSDouglas Gregor // If we don't already have information on this module, load the module now. 1274de3ef502SDouglas Gregor llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known 127569021974SDouglas Gregor = KnownModules.find(Path[0].first); 12762537a364SDouglas Gregor if (Known != KnownModules.end()) { 12772537a364SDouglas Gregor // Retrieve the cached top-level module. 12782537a364SDouglas Gregor Module = Known->second; 1279b537a3a6SBen Langmuir } else if (ModuleName == getLangOpts().CurrentModule || 1280b537a3a6SBen Langmuir ModuleName == getLangOpts().ImplementationOfModule) { 12812537a364SDouglas Gregor // This is the module we're building. 1282527040e0SBen Langmuir Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); 12832537a364SDouglas Gregor Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; 12842537a364SDouglas Gregor } else { 12855196bc6bSDouglas Gregor // Search for a module with the given name. 1286279a6c37SDouglas Gregor Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); 12879eb229bfSBen Langmuir if (!Module) { 12889eb229bfSBen Langmuir getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found) 12899eb229bfSBen Langmuir << ModuleName 12909eb229bfSBen Langmuir << SourceRange(ImportLoc, ModuleNameLoc); 12919eb229bfSBen Langmuir ModuleBuildFailed = true; 12929eb229bfSBen Langmuir return ModuleLoadResult(); 12939eb229bfSBen Langmuir } 12949eb229bfSBen Langmuir 1295f24d9c91SJustin Bogner std::string ModuleFileName = 1296f24d9c91SJustin Bogner PP->getHeaderSearchInfo().getModuleFileName(Module); 1297faeb1d46SDouglas Gregor 129808142534SDouglas Gregor // If we don't already have an ASTReader, create one now. 12992255f2ceSJohn Thompson if (!ModuleManager) 13002255f2ceSJohn Thompson createModuleManager(); 130108142534SDouglas Gregor 1302cb69b57bSBen Langmuir if (TheDependencyFileGenerator) 1303cb69b57bSBen Langmuir TheDependencyFileGenerator->AttachToASTReader(*ModuleManager); 1304cb69b57bSBen Langmuir 130586d1259cSJustin Bogner if (ModuleDepCollector) 130686d1259cSJustin Bogner ModuleDepCollector->attachToASTReader(*ModuleManager); 130786d1259cSJustin Bogner 130833c8090aSBen Langmuir for (auto &Listener : DependencyCollectors) 130933c8090aSBen Langmuir Listener->attachToASTReader(*ModuleManager); 131033c8090aSBen Langmuir 13117029ce1aSDouglas Gregor // Try to load the module file. 13127029ce1aSDouglas Gregor unsigned ARRFlags = ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing; 13137029ce1aSDouglas Gregor switch (ModuleManager->ReadAST(ModuleFileName, serialization::MK_Module, 13147029ce1aSDouglas Gregor ImportLoc, ARRFlags)) { 131508142534SDouglas Gregor case ASTReader::Success: 131608142534SDouglas Gregor break; 131708142534SDouglas Gregor 1318963ff2c3SEli Friedman case ASTReader::OutOfDate: 13197029ce1aSDouglas Gregor case ASTReader::Missing: { 1320963ff2c3SEli Friedman // The module file is missing or out-of-date. Build it. 13219eb229bfSBen Langmuir assert(Module && "missing module file"); 13227029ce1aSDouglas Gregor // Check whether there is a cycle in the module graph. 13237029ce1aSDouglas Gregor ModuleBuildStack ModPath = getSourceManager().getModuleBuildStack(); 13247029ce1aSDouglas Gregor ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end(); 13257029ce1aSDouglas Gregor for (; Pos != PosEnd; ++Pos) { 13267029ce1aSDouglas Gregor if (Pos->first == ModuleName) 13277029ce1aSDouglas Gregor break; 13287029ce1aSDouglas Gregor } 13297029ce1aSDouglas Gregor 13307029ce1aSDouglas Gregor if (Pos != PosEnd) { 13317029ce1aSDouglas Gregor SmallString<256> CyclePath; 13327029ce1aSDouglas Gregor for (; Pos != PosEnd; ++Pos) { 13337029ce1aSDouglas Gregor CyclePath += Pos->first; 13347029ce1aSDouglas Gregor CyclePath += " -> "; 13357029ce1aSDouglas Gregor } 13367029ce1aSDouglas Gregor CyclePath += ModuleName; 13377029ce1aSDouglas Gregor 13387029ce1aSDouglas Gregor getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle) 13397029ce1aSDouglas Gregor << ModuleName << CyclePath; 13407029ce1aSDouglas Gregor return ModuleLoadResult(); 13417029ce1aSDouglas Gregor } 13427a626570SDouglas Gregor 1343c95e5648SBen Langmuir getDiagnostics().Report(ImportLoc, diag::remark_module_build) 13441ecf750eSBen Langmuir << ModuleName << ModuleFileName; 13451ecf750eSBen Langmuir 13467a626570SDouglas Gregor // Check whether we have already attempted to build this module (but 13477a626570SDouglas Gregor // failed). 13487a626570SDouglas Gregor if (getPreprocessorOpts().FailedModules && 13497a626570SDouglas Gregor getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) { 13507a626570SDouglas Gregor getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built) 13517a626570SDouglas Gregor << ModuleName 13527a626570SDouglas Gregor << SourceRange(ImportLoc, ModuleNameLoc); 1353c1bbec85SDouglas Gregor ModuleBuildFailed = true; 13547a626570SDouglas Gregor return ModuleLoadResult(); 13557a626570SDouglas Gregor } 13567a626570SDouglas Gregor 1357dbdc0368SBen Langmuir // Try to compile and then load the module. 1358dbdc0368SBen Langmuir if (!compileAndLoadModule(*this, ImportLoc, ModuleNameLoc, Module, 1359dbdc0368SBen Langmuir ModuleFileName)) { 13600f2b4635SDouglas Gregor if (getPreprocessorOpts().FailedModules) 13617a626570SDouglas Gregor getPreprocessorOpts().FailedModules->addFailed(ModuleName); 136249a2790fSCraig Topper KnownModules[Path[0].first] = nullptr; 1363c1bbec85SDouglas Gregor ModuleBuildFailed = true; 13647a626570SDouglas Gregor return ModuleLoadResult(); 1365188dbef2SDouglas Gregor } 1366188dbef2SDouglas Gregor 1367188dbef2SDouglas Gregor // Okay, we've rebuilt and now loaded the module. 1368188dbef2SDouglas Gregor break; 1369188dbef2SDouglas Gregor } 1370188dbef2SDouglas Gregor 1371c9ad5fb6SDouglas Gregor case ASTReader::VersionMismatch: 1372c9ad5fb6SDouglas Gregor case ASTReader::ConfigurationMismatch: 1373c9ad5fb6SDouglas Gregor case ASTReader::HadErrors: 1374dc9fdaf2SArgyrios Kyrtzidis ModuleLoader::HadFatalFailure = true; 137508142534SDouglas Gregor // FIXME: The ASTReader will already have complained, but can we showhorn 137608142534SDouglas Gregor // that diagnostic information into a more useful form? 137749a2790fSCraig Topper KnownModules[Path[0].first] = nullptr; 13787a626570SDouglas Gregor return ModuleLoadResult(); 137908142534SDouglas Gregor 138008142534SDouglas Gregor case ASTReader::Failure: 1381dc9fdaf2SArgyrios Kyrtzidis ModuleLoader::HadFatalFailure = true; 138269021974SDouglas Gregor // Already complained, but note now that we failed. 138349a2790fSCraig Topper KnownModules[Path[0].first] = nullptr; 1384c1bbec85SDouglas Gregor ModuleBuildFailed = true; 13857a626570SDouglas Gregor return ModuleLoadResult(); 138608142534SDouglas Gregor } 138708142534SDouglas Gregor 138869021974SDouglas Gregor // Cache the result of this top-level module lookup for later. 138969021974SDouglas Gregor Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; 139069021974SDouglas Gregor } 139169021974SDouglas Gregor 139269021974SDouglas Gregor // If we never found the module, fail. 139369021974SDouglas Gregor if (!Module) 13947a626570SDouglas Gregor return ModuleLoadResult(); 139569021974SDouglas Gregor 13965196bc6bSDouglas Gregor // Verify that the rest of the module path actually corresponds to 13975196bc6bSDouglas Gregor // a submodule. 139869021974SDouglas Gregor if (Path.size() > 1) { 13995196bc6bSDouglas Gregor for (unsigned I = 1, N = Path.size(); I != N; ++I) { 14005196bc6bSDouglas Gregor StringRef Name = Path[I].first->getName(); 1401eb90e830SDouglas Gregor clang::Module *Sub = Module->findSubmodule(Name); 14025196bc6bSDouglas Gregor 1403eb90e830SDouglas Gregor if (!Sub) { 14045196bc6bSDouglas Gregor // Attempt to perform typo correction to find a module name that works. 1405f857950dSDmitri Gribenko SmallVector<StringRef, 2> Best; 14065196bc6bSDouglas Gregor unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)(); 14075196bc6bSDouglas Gregor 1408eb90e830SDouglas Gregor for (clang::Module::submodule_iterator J = Module->submodule_begin(), 1409eb90e830SDouglas Gregor JEnd = Module->submodule_end(); 1410eb44edadSMatt Beaumont-Gay J != JEnd; ++J) { 1411eb90e830SDouglas Gregor unsigned ED = Name.edit_distance((*J)->Name, 14125196bc6bSDouglas Gregor /*AllowReplacements=*/true, 14135196bc6bSDouglas Gregor BestEditDistance); 14145196bc6bSDouglas Gregor if (ED <= BestEditDistance) { 1415eb90e830SDouglas Gregor if (ED < BestEditDistance) { 14165196bc6bSDouglas Gregor Best.clear(); 1417eb90e830SDouglas Gregor BestEditDistance = ED; 1418eb90e830SDouglas Gregor } 1419eb90e830SDouglas Gregor 1420eb90e830SDouglas Gregor Best.push_back((*J)->Name); 14215196bc6bSDouglas Gregor } 14225196bc6bSDouglas Gregor } 14235196bc6bSDouglas Gregor 14245196bc6bSDouglas Gregor // If there was a clear winner, user it. 14255196bc6bSDouglas Gregor if (Best.size() == 1) { 14265196bc6bSDouglas Gregor getDiagnostics().Report(Path[I].second, 14275196bc6bSDouglas Gregor diag::err_no_submodule_suggest) 142869021974SDouglas Gregor << Path[I].first << Module->getFullModuleName() << Best[0] 14295196bc6bSDouglas Gregor << SourceRange(Path[0].second, Path[I-1].second) 14305196bc6bSDouglas Gregor << FixItHint::CreateReplacement(SourceRange(Path[I].second), 14315196bc6bSDouglas Gregor Best[0]); 1432eb90e830SDouglas Gregor 1433eb90e830SDouglas Gregor Sub = Module->findSubmodule(Best[0]); 14345196bc6bSDouglas Gregor } 14355196bc6bSDouglas Gregor } 14365196bc6bSDouglas Gregor 1437eb90e830SDouglas Gregor if (!Sub) { 14385196bc6bSDouglas Gregor // No submodule by this name. Complain, and don't look for further 14395196bc6bSDouglas Gregor // submodules. 14405196bc6bSDouglas Gregor getDiagnostics().Report(Path[I].second, diag::err_no_submodule) 144169021974SDouglas Gregor << Path[I].first << Module->getFullModuleName() 14425196bc6bSDouglas Gregor << SourceRange(Path[0].second, Path[I-1].second); 14435196bc6bSDouglas Gregor break; 14445196bc6bSDouglas Gregor } 14455196bc6bSDouglas Gregor 1446eb90e830SDouglas Gregor Module = Sub; 14475196bc6bSDouglas Gregor } 14485196bc6bSDouglas Gregor } 14495196bc6bSDouglas Gregor 1450b537a3a6SBen Langmuir // Don't make the module visible if we are in the implementation. 1451b537a3a6SBen Langmuir if (ModuleName == getLangOpts().ImplementationOfModule) 1452b537a3a6SBen Langmuir return ModuleLoadResult(Module, false); 1453b537a3a6SBen Langmuir 14542537a364SDouglas Gregor // Make the named module visible, if it's not already part of the module 14552537a364SDouglas Gregor // we are parsing. 145698a52db8SDouglas Gregor if (ModuleName != getLangOpts().CurrentModule) { 145798a52db8SDouglas Gregor if (!Module->IsFromModuleFile) { 145898a52db8SDouglas Gregor // We have an umbrella header or directory that doesn't actually include 145998a52db8SDouglas Gregor // all of the headers within the directory it covers. Complain about 146098a52db8SDouglas Gregor // this missing submodule and recover by forgetting that we ever saw 146198a52db8SDouglas Gregor // this submodule. 146298a52db8SDouglas Gregor // FIXME: Should we detect this at module load time? It seems fairly 146398a52db8SDouglas Gregor // expensive (and rare). 146498a52db8SDouglas Gregor getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule) 146598a52db8SDouglas Gregor << Module->getFullModuleName() 146698a52db8SDouglas Gregor << SourceRange(Path.front().second, Path.back().second); 146798a52db8SDouglas Gregor 146849a2790fSCraig Topper return ModuleLoadResult(nullptr, true); 146998a52db8SDouglas Gregor } 14701fb5c3a6SDouglas Gregor 14711fb5c3a6SDouglas Gregor // Check whether this module is available. 1472a3feee2aSRichard Smith clang::Module::Requirement Requirement; 14730761a8a0SDaniel Jasper clang::Module::HeaderDirective MissingHeader; 14740761a8a0SDaniel Jasper if (!Module->isAvailable(getLangOpts(), getTarget(), Requirement, 14750761a8a0SDaniel Jasper MissingHeader)) { 14760761a8a0SDaniel Jasper if (MissingHeader.FileNameLoc.isValid()) { 14770761a8a0SDaniel Jasper getDiagnostics().Report(MissingHeader.FileNameLoc, 14780761a8a0SDaniel Jasper diag::err_module_header_missing) 14790761a8a0SDaniel Jasper << MissingHeader.IsUmbrella << MissingHeader.FileName; 14800761a8a0SDaniel Jasper } else { 14811fb5c3a6SDouglas Gregor getDiagnostics().Report(ImportLoc, diag::err_module_unavailable) 14821fb5c3a6SDouglas Gregor << Module->getFullModuleName() 1483a3feee2aSRichard Smith << Requirement.second << Requirement.first 14841fb5c3a6SDouglas Gregor << SourceRange(Path.front().second, Path.back().second); 14850761a8a0SDaniel Jasper } 14861fb5c3a6SDouglas Gregor LastModuleImportLoc = ImportLoc; 14877a626570SDouglas Gregor LastModuleImportResult = ModuleLoadResult(); 14887a626570SDouglas Gregor return ModuleLoadResult(); 14891fb5c3a6SDouglas Gregor } 14901fb5c3a6SDouglas Gregor 1491fb912657SDouglas Gregor ModuleManager->makeModuleVisible(Module, Visibility, ImportLoc, 1492fb912657SDouglas Gregor /*Complain=*/true); 149398a52db8SDouglas Gregor } 14945196bc6bSDouglas Gregor 149535b13eceSDouglas Gregor // Check for any configuration macros that have changed. 149635b13eceSDouglas Gregor clang::Module *TopModule = Module->getTopLevelModule(); 149735b13eceSDouglas Gregor for (unsigned I = 0, N = TopModule->ConfigMacros.size(); I != N; ++I) { 149835b13eceSDouglas Gregor checkConfigMacro(getPreprocessor(), TopModule->ConfigMacros[I], 149935b13eceSDouglas Gregor Module, ImportLoc); 150035b13eceSDouglas Gregor } 150135b13eceSDouglas Gregor 1502bcfc7d02SDouglas Gregor // If this module import was due to an inclusion directive, create an 1503bcfc7d02SDouglas Gregor // implicit import declaration to capture it in the AST. 1504bcfc7d02SDouglas Gregor if (IsInclusionDirective && hasASTContext()) { 1505bcfc7d02SDouglas Gregor TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl(); 150672d1aa3cSArgyrios Kyrtzidis ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU, 1507bcfc7d02SDouglas Gregor ImportLoc, Module, 150872d1aa3cSArgyrios Kyrtzidis Path.back().second); 150972d1aa3cSArgyrios Kyrtzidis TU->addDecl(ImportD); 151072d1aa3cSArgyrios Kyrtzidis if (Consumer) 151172d1aa3cSArgyrios Kyrtzidis Consumer->HandleImplicitImportDecl(ImportD); 1512bcfc7d02SDouglas Gregor } 1513bcfc7d02SDouglas Gregor 15141805b8a4SDouglas Gregor LastModuleImportLoc = ImportLoc; 15157a626570SDouglas Gregor LastModuleImportResult = ModuleLoadResult(Module, false); 15167a626570SDouglas Gregor return LastModuleImportResult; 151708142534SDouglas Gregor } 1518c147b0bcSDouglas Gregor 1519c147b0bcSDouglas Gregor void CompilerInstance::makeModuleVisible(Module *Mod, 1520125df058SArgyrios Kyrtzidis Module::NameVisibilityKind Visibility, 1521fb912657SDouglas Gregor SourceLocation ImportLoc, 1522fb912657SDouglas Gregor bool Complain){ 1523fb912657SDouglas Gregor ModuleManager->makeModuleVisible(Mod, Visibility, ImportLoc, Complain); 1524c147b0bcSDouglas Gregor } 1525c147b0bcSDouglas Gregor 15262255f2ceSJohn Thompson GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex( 15272255f2ceSJohn Thompson SourceLocation TriggerLoc) { 15282255f2ceSJohn Thompson if (!ModuleManager) 15292255f2ceSJohn Thompson createModuleManager(); 15302255f2ceSJohn Thompson // Can't do anything if we don't have the module manager. 15312255f2ceSJohn Thompson if (!ModuleManager) 153249a2790fSCraig Topper return nullptr; 15332255f2ceSJohn Thompson // Get an existing global index. This loads it if not already 15342255f2ceSJohn Thompson // loaded. 15352255f2ceSJohn Thompson ModuleManager->loadGlobalIndex(); 15362255f2ceSJohn Thompson GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex(); 15372255f2ceSJohn Thompson // If the global index doesn't exist, create it. 15382255f2ceSJohn Thompson if (!GlobalIndex && shouldBuildGlobalModuleIndex() && hasFileManager() && 15392255f2ceSJohn Thompson hasPreprocessor()) { 15402255f2ceSJohn Thompson llvm::sys::fs::create_directories( 15412255f2ceSJohn Thompson getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); 15422255f2ceSJohn Thompson GlobalModuleIndex::writeIndex( 15432255f2ceSJohn Thompson getFileManager(), 15442255f2ceSJohn Thompson getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); 15452255f2ceSJohn Thompson ModuleManager->resetForReload(); 15462255f2ceSJohn Thompson ModuleManager->loadGlobalIndex(); 15472255f2ceSJohn Thompson GlobalIndex = ModuleManager->getGlobalIndex(); 15482255f2ceSJohn Thompson } 15492255f2ceSJohn Thompson // For finding modules needing to be imported for fixit messages, 15502255f2ceSJohn Thompson // we need to make the global index cover all modules, so we do that here. 15512255f2ceSJohn Thompson if (!HaveFullGlobalModuleIndex && GlobalIndex && !buildingModule()) { 15522255f2ceSJohn Thompson ModuleMap &MMap = getPreprocessor().getHeaderSearchInfo().getModuleMap(); 15532255f2ceSJohn Thompson bool RecreateIndex = false; 15542255f2ceSJohn Thompson for (ModuleMap::module_iterator I = MMap.module_begin(), 15552255f2ceSJohn Thompson E = MMap.module_end(); I != E; ++I) { 15562255f2ceSJohn Thompson Module *TheModule = I->second; 15572255f2ceSJohn Thompson const FileEntry *Entry = TheModule->getASTFile(); 15582255f2ceSJohn Thompson if (!Entry) { 15592255f2ceSJohn Thompson SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path; 15602255f2ceSJohn Thompson Path.push_back(std::make_pair( 15612255f2ceSJohn Thompson getPreprocessor().getIdentifierInfo(TheModule->Name), TriggerLoc)); 15622255f2ceSJohn Thompson std::reverse(Path.begin(), Path.end()); 15632255f2ceSJohn Thompson // Load a module as hidden. This also adds it to the global index. 1564e0a5afe8SJohn Thompson loadModule(TheModule->DefinitionLoc, Path, 15652255f2ceSJohn Thompson Module::Hidden, false); 15662255f2ceSJohn Thompson RecreateIndex = true; 15672255f2ceSJohn Thompson } 15682255f2ceSJohn Thompson } 15692255f2ceSJohn Thompson if (RecreateIndex) { 15702255f2ceSJohn Thompson GlobalModuleIndex::writeIndex( 15712255f2ceSJohn Thompson getFileManager(), 15722255f2ceSJohn Thompson getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); 15732255f2ceSJohn Thompson ModuleManager->resetForReload(); 15742255f2ceSJohn Thompson ModuleManager->loadGlobalIndex(); 15752255f2ceSJohn Thompson GlobalIndex = ModuleManager->getGlobalIndex(); 15762255f2ceSJohn Thompson } 15772255f2ceSJohn Thompson HaveFullGlobalModuleIndex = true; 15782255f2ceSJohn Thompson } 15792255f2ceSJohn Thompson return GlobalIndex; 15802255f2ceSJohn Thompson } 15812d94bbb0SJohn Thompson 15822d94bbb0SJohn Thompson // Check global module index for missing imports. 15832d94bbb0SJohn Thompson bool 15842d94bbb0SJohn Thompson CompilerInstance::lookupMissingImports(StringRef Name, 15852d94bbb0SJohn Thompson SourceLocation TriggerLoc) { 15862d94bbb0SJohn Thompson // Look for the symbol in non-imported modules, but only if an error 15872d94bbb0SJohn Thompson // actually occurred. 15882d94bbb0SJohn Thompson if (!buildingModule()) { 15892d94bbb0SJohn Thompson // Load global module index, or retrieve a previously loaded one. 15902d94bbb0SJohn Thompson GlobalModuleIndex *GlobalIndex = loadGlobalModuleIndex( 15912d94bbb0SJohn Thompson TriggerLoc); 15922d94bbb0SJohn Thompson 15932d94bbb0SJohn Thompson // Only if we have a global index. 15942d94bbb0SJohn Thompson if (GlobalIndex) { 15952d94bbb0SJohn Thompson GlobalModuleIndex::HitSet FoundModules; 15962d94bbb0SJohn Thompson 15972d94bbb0SJohn Thompson // Find the modules that reference the identifier. 15982d94bbb0SJohn Thompson // Note that this only finds top-level modules. 15992d94bbb0SJohn Thompson // We'll let diagnoseTypo find the actual declaration module. 16002d94bbb0SJohn Thompson if (GlobalIndex->lookupIdentifier(Name, FoundModules)) 16012d94bbb0SJohn Thompson return true; 16022d94bbb0SJohn Thompson } 16032d94bbb0SJohn Thompson } 16042d94bbb0SJohn Thompson 16052d94bbb0SJohn Thompson return false; 16062d94bbb0SJohn Thompson } 1607