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 54bb165fb0SAdrian Prantl CompilerInstance::CompilerInstance( 55bb165fb0SAdrian Prantl std::shared_ptr<PCHContainerOperations> PCHContainerOps, 56bb165fb0SAdrian Prantl bool BuildingModule) 57bb165fb0SAdrian Prantl : ModuleLoader(BuildingModule), Invocation(new CompilerInvocation()), 58bb165fb0SAdrian Prantl ModuleManager(nullptr), ThePCHContainerOperations(PCHContainerOps), 592255f2ceSJohn Thompson BuildGlobalModuleIndex(false), HaveFullGlobalModuleIndex(false), 60bb165fb0SAdrian Prantl ModuleBuildFailed(false) {} 61636404a3SDaniel Dunbar 62636404a3SDaniel Dunbar CompilerInstance::~CompilerInstance() { 633c717b45SBenjamin Kramer assert(OutputFiles.empty() && "Still output files in flight?"); 64e922d9bdSDaniel Dunbar } 65e922d9bdSDaniel Dunbar 6668242254SDaniel Dunbar void CompilerInstance::setInvocation(CompilerInvocation *Value) { 675e14d39aSTed Kremenek Invocation = Value; 6868242254SDaniel Dunbar } 6968242254SDaniel Dunbar 70c1bbec85SDouglas Gregor bool CompilerInstance::shouldBuildGlobalModuleIndex() const { 71e060e57bSDouglas Gregor return (BuildGlobalModuleIndex || 7211ef0b77SDouglas Gregor (ModuleManager && ModuleManager->isGlobalIndexUnavailable() && 7311ef0b77SDouglas Gregor getFrontendOpts().GenerateGlobalModuleIndex)) && 74e060e57bSDouglas Gregor !ModuleBuildFailed; 75c1bbec85SDouglas Gregor } 76c1bbec85SDouglas Gregor 779c902b55SDavid Blaikie void CompilerInstance::setDiagnostics(DiagnosticsEngine *Value) { 787f95d26eSDouglas Gregor Diagnostics = Value; 79e01dc86dSDaniel Dunbar } 80e01dc86dSDaniel Dunbar 81b5bc923aSArtem Belevich void CompilerInstance::setTarget(TargetInfo *Value) { Target = Value; } 82b5bc923aSArtem Belevich void CompilerInstance::setAuxTarget(TargetInfo *Value) { AuxTarget = Value; } 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 98293534b1SRichard Smith void CompilerInstance::setASTContext(ASTContext *Value) { 99293534b1SRichard Smith Context = Value; 100293534b1SRichard Smith 101293534b1SRichard Smith if (Context && Consumer) 102293534b1SRichard Smith getASTConsumer().Initialize(getASTContext()); 103293534b1SRichard Smith } 104e01dc86dSDaniel Dunbar 1050e93f017SDouglas Gregor void CompilerInstance::setSema(Sema *S) { 1060e93f017SDouglas Gregor TheSema.reset(S); 1070e93f017SDouglas Gregor } 1080e93f017SDouglas Gregor 1096beb6aa8SDavid Blaikie void CompilerInstance::setASTConsumer(std::unique_ptr<ASTConsumer> Value) { 1106beb6aa8SDavid Blaikie Consumer = std::move(Value); 111293534b1SRichard Smith 112293534b1SRichard Smith if (Context && Consumer) 113293534b1SRichard Smith getASTConsumer().Initialize(getASTContext()); 11456d9c293SDaniel Dunbar } 11556d9c293SDaniel Dunbar 116e01dc86dSDaniel Dunbar void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) { 117e01dc86dSDaniel Dunbar CompletionConsumer.reset(Value); 118e01dc86dSDaniel Dunbar } 119e01dc86dSDaniel Dunbar 1206153581aSDavid Blaikie std::unique_ptr<Sema> CompilerInstance::takeSema() { 1216153581aSDavid Blaikie return std::move(TheSema); 1226153581aSDavid Blaikie } 1236153581aSDavid Blaikie 1241b7ed91eSArgyrios Kyrtzidis IntrusiveRefCntPtr<ASTReader> CompilerInstance::getModuleManager() const { 1251b7ed91eSArgyrios Kyrtzidis return ModuleManager; 1261b7ed91eSArgyrios Kyrtzidis } 1271b7ed91eSArgyrios Kyrtzidis void CompilerInstance::setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader) { 1281b7ed91eSArgyrios Kyrtzidis ModuleManager = Reader; 1291b7ed91eSArgyrios Kyrtzidis } 1301b7ed91eSArgyrios Kyrtzidis 13186d1259cSJustin Bogner std::shared_ptr<ModuleDependencyCollector> 13286d1259cSJustin Bogner CompilerInstance::getModuleDepCollector() const { 13386d1259cSJustin Bogner return ModuleDepCollector; 13486d1259cSJustin Bogner } 13586d1259cSJustin Bogner 13686d1259cSJustin Bogner void CompilerInstance::setModuleDepCollector( 13786d1259cSJustin Bogner std::shared_ptr<ModuleDependencyCollector> Collector) { 13886d1259cSJustin Bogner ModuleDepCollector = Collector; 13986d1259cSJustin Bogner } 14086d1259cSJustin Bogner 1417d75afc5SDaniel Dunbar // Diagnostics 142811db4eaSDouglas Gregor static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts, 1437b83306dSDaniel Dunbar const CodeGenOptions *CodeGenOpts, 1449c902b55SDavid Blaikie DiagnosticsEngine &Diags) { 145dae941a6SRafael Espindola std::error_code EC; 14611f8a943SDavid Blaikie std::unique_ptr<raw_ostream> StreamOwner; 1470e62c1ccSChris Lattner raw_ostream *OS = &llvm::errs(); 148811db4eaSDouglas Gregor if (DiagOpts->DiagnosticLogFile != "-") { 1492083c32fSDaniel Dunbar // Create the output stream. 15011f8a943SDavid Blaikie auto FileOS = llvm::make_unique<llvm::raw_fd_ostream>( 151dae941a6SRafael Espindola DiagOpts->DiagnosticLogFile, EC, 15211f8a943SDavid Blaikie llvm::sys::fs::F_Append | llvm::sys::fs::F_Text); 153dae941a6SRafael Espindola if (EC) { 1542083c32fSDaniel Dunbar Diags.Report(diag::warn_fe_cc_log_diagnostics_failure) 155dae941a6SRafael Espindola << DiagOpts->DiagnosticLogFile << EC.message(); 1562083c32fSDaniel Dunbar } else { 1572083c32fSDaniel Dunbar FileOS->SetUnbuffered(); 1582083c32fSDaniel Dunbar FileOS->SetUseAtomicWrites(true); 15911f8a943SDavid Blaikie OS = FileOS.get(); 16011f8a943SDavid Blaikie StreamOwner = std::move(FileOS); 1612083c32fSDaniel Dunbar } 1622083c32fSDaniel Dunbar } 1632083c32fSDaniel Dunbar 1642083c32fSDaniel Dunbar // Chain in the diagnostic client which will log the diagnostics. 1657ee25502SDavid Blaikie auto Logger = llvm::make_unique<LogDiagnosticPrinter>(*OS, DiagOpts, 1667ee25502SDavid Blaikie std::move(StreamOwner)); 1677b83306dSDaniel Dunbar if (CodeGenOpts) 1687b83306dSDaniel Dunbar Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags); 1697ee25502SDavid Blaikie assert(Diags.ownsClient()); 17041c247a6SAlexander Kornienko Diags.setClient( 17141c247a6SAlexander Kornienko new ChainedDiagnosticConsumer(Diags.takeClient(), std::move(Logger))); 1722083c32fSDaniel Dunbar } 1732083c32fSDaniel Dunbar 174811db4eaSDouglas Gregor static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts, 1754610ea2bSTed Kremenek DiagnosticsEngine &Diags, 1764610ea2bSTed Kremenek StringRef OutputFile) { 1777ee25502SDavid Blaikie auto SerializedConsumer = 1785a6a2fcdSJustin Bogner clang::serialized_diags::create(OutputFile, DiagOpts); 1794610ea2bSTed Kremenek 180254b7dbaSAlexander Kornienko if (Diags.ownsClient()) { 1817ee25502SDavid Blaikie Diags.setClient(new ChainedDiagnosticConsumer( 18241c247a6SAlexander Kornienko Diags.takeClient(), std::move(SerializedConsumer))); 183254b7dbaSAlexander Kornienko } else { 184254b7dbaSAlexander Kornienko Diags.setClient(new ChainedDiagnosticConsumer( 1854c0ef379SAlexander Kornienko Diags.getClient(), std::move(SerializedConsumer))); 186254b7dbaSAlexander Kornienko } 1874610ea2bSTed Kremenek } 1884610ea2bSTed Kremenek 189f1b49e23SSean Silva void CompilerInstance::createDiagnostics(DiagnosticConsumer *Client, 19030071ceaSDouglas Gregor bool ShouldOwnClient) { 191f1b49e23SSean Silva Diagnostics = createDiagnostics(&getDiagnosticOpts(), Client, 19230071ceaSDouglas Gregor ShouldOwnClient, &getCodeGenOpts()); 1937d75afc5SDaniel Dunbar } 1947d75afc5SDaniel Dunbar 195c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> 196811db4eaSDouglas Gregor CompilerInstance::createDiagnostics(DiagnosticOptions *Opts, 197e2eefaecSDavid Blaikie DiagnosticConsumer *Client, 1982b9b4642SDouglas Gregor bool ShouldOwnClient, 1997b83306dSDaniel Dunbar const CodeGenOptions *CodeGenOpts) { 200c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 201c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> 202811db4eaSDouglas Gregor Diags(new DiagnosticsEngine(DiagID, Opts)); 2031b39a2edSDaniel Dunbar 2047d75afc5SDaniel Dunbar // Create the diagnostic client for reporting errors or for 2057d75afc5SDaniel Dunbar // implementing -verify. 206d0e9e3a6SDouglas Gregor if (Client) { 207d0e9e3a6SDouglas Gregor Diags->setClient(Client, ShouldOwnClient); 208d0e9e3a6SDouglas Gregor } else 2092dd19f1dSDouglas Gregor Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts)); 21050ec0da0SDaniel Dunbar 21150ec0da0SDaniel Dunbar // Chain in -verify checker, if requested. 212811db4eaSDouglas Gregor if (Opts->VerifyDiagnostics) 21369609dceSDavid Blaikie Diags->setClient(new VerifyDiagnosticConsumer(*Diags)); 2147d75afc5SDaniel Dunbar 2152083c32fSDaniel Dunbar // Chain in -diagnostic-log-file dumper, if requested. 216811db4eaSDouglas Gregor if (!Opts->DiagnosticLogFile.empty()) 2177b83306dSDaniel Dunbar SetUpDiagnosticLog(Opts, CodeGenOpts, *Diags); 2182083c32fSDaniel Dunbar 219811db4eaSDouglas Gregor if (!Opts->DiagnosticSerializationFile.empty()) 2204610ea2bSTed Kremenek SetupSerializedDiagnostics(Opts, *Diags, 221811db4eaSDouglas Gregor Opts->DiagnosticSerializationFile); 2224610ea2bSTed Kremenek 2237d75afc5SDaniel Dunbar // Configure our handling of diagnostics. 224811db4eaSDouglas Gregor ProcessWarningOptions(*Diags, *Opts); 2257d75afc5SDaniel Dunbar 2267f95d26eSDouglas Gregor return Diags; 2277d75afc5SDaniel Dunbar } 2287d75afc5SDaniel Dunbar 2297d75afc5SDaniel Dunbar // File Manager 2307d75afc5SDaniel Dunbar 231546a676aSDaniel Dunbar void CompilerInstance::createFileManager() { 232c8130a74SBen Langmuir if (!hasVirtualFileSystem()) { 233c8130a74SBen Langmuir // TODO: choose the virtual file system based on the CompilerInvocation. 234c8130a74SBen Langmuir setVirtualFileSystem(vfs::getRealFileSystem()); 235c8130a74SBen Langmuir } 236c8130a74SBen Langmuir FileMgr = new FileManager(getFileSystemOpts(), VirtualFileSystem); 237546a676aSDaniel Dunbar } 238546a676aSDaniel Dunbar 2397d75afc5SDaniel Dunbar // Source Manager 2407d75afc5SDaniel Dunbar 2415159f616SChris Lattner void CompilerInstance::createSourceManager(FileManager &FileMgr) { 2425e14d39aSTed Kremenek SourceMgr = new SourceManager(getDiagnostics(), FileMgr); 243546a676aSDaniel Dunbar } 244aaa148fdSDaniel Dunbar 245c358000eSAlp Toker // Initialize the remapping of files to alternative contents, e.g., 246c358000eSAlp Toker // those specified through other files. 247c358000eSAlp Toker static void InitializeFileRemapping(DiagnosticsEngine &Diags, 248c358000eSAlp Toker SourceManager &SourceMgr, 249c358000eSAlp Toker FileManager &FileMgr, 250c358000eSAlp Toker const PreprocessorOptions &InitOpts) { 251c358000eSAlp Toker // Remap files in the source manager (with buffers). 2521b070d25SAlp Toker for (const auto &RB : InitOpts.RemappedFileBuffers) { 253c358000eSAlp Toker // Create the file entry for the file that we're mapping from. 254c358000eSAlp Toker const FileEntry *FromFile = 2551b070d25SAlp Toker FileMgr.getVirtualFile(RB.first, RB.second->getBufferSize(), 0); 256c358000eSAlp Toker if (!FromFile) { 2571b070d25SAlp Toker Diags.Report(diag::err_fe_remap_missing_from_file) << RB.first; 258c358000eSAlp Toker if (!InitOpts.RetainRemappedFileBuffers) 2591b070d25SAlp Toker delete RB.second; 260c358000eSAlp Toker continue; 261c358000eSAlp Toker } 262c358000eSAlp Toker 263c358000eSAlp Toker // Override the contents of the "from" file with the contents of 264c358000eSAlp Toker // the "to" file. 2651b070d25SAlp Toker SourceMgr.overrideFileContents(FromFile, RB.second, 266c358000eSAlp Toker InitOpts.RetainRemappedFileBuffers); 267c358000eSAlp Toker } 268c358000eSAlp Toker 269c358000eSAlp Toker // Remap files in the source manager (with other files). 2701b070d25SAlp Toker for (const auto &RF : InitOpts.RemappedFiles) { 271c358000eSAlp Toker // Find the file that we're mapping to. 2721b070d25SAlp Toker const FileEntry *ToFile = FileMgr.getFile(RF.second); 273c358000eSAlp Toker if (!ToFile) { 2741b070d25SAlp Toker Diags.Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second; 275c358000eSAlp Toker continue; 276c358000eSAlp Toker } 277c358000eSAlp Toker 278c358000eSAlp Toker // Create the file entry for the file that we're mapping from. 279c358000eSAlp Toker const FileEntry *FromFile = 2801b070d25SAlp Toker FileMgr.getVirtualFile(RF.first, ToFile->getSize(), 0); 281c358000eSAlp Toker if (!FromFile) { 2821b070d25SAlp Toker Diags.Report(diag::err_fe_remap_missing_from_file) << RF.first; 283c358000eSAlp Toker continue; 284c358000eSAlp Toker } 285c358000eSAlp Toker 286c358000eSAlp Toker // Override the contents of the "from" file with the contents of 287c358000eSAlp Toker // the "to" file. 288c358000eSAlp Toker SourceMgr.overrideFileContents(FromFile, ToFile); 289c358000eSAlp Toker } 290c358000eSAlp Toker 291c358000eSAlp Toker SourceMgr.setOverridenFilesKeepOriginalName( 292c358000eSAlp Toker InitOpts.RemappedFilesKeepOriginalName); 293c358000eSAlp Toker } 294c358000eSAlp Toker 2957d75afc5SDaniel Dunbar // Preprocessor 2967d75afc5SDaniel Dunbar 297e1974dcdSArgyrios Kyrtzidis void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) { 29808142534SDouglas Gregor const PreprocessorOptions &PPOpts = getPreprocessorOpts(); 299aaa148fdSDaniel Dunbar 300aaa148fdSDaniel Dunbar // Create a PTH manager if we are using some form of a token cache. 30149a2790fSCraig Topper PTHManager *PTHMgr = nullptr; 302d6ea9028SDaniel Dunbar if (!PPOpts.TokenCache.empty()) 30308142534SDouglas Gregor PTHMgr = PTHManager::Create(PPOpts.TokenCache, getDiagnostics()); 304aaa148fdSDaniel Dunbar 305aaa148fdSDaniel Dunbar // Create the Preprocessor. 306b85b9ccbSDouglas Gregor HeaderSearch *HeaderInfo = new HeaderSearch(&getHeaderSearchOpts(), 3071f76c4e8SManuel Klimek getSourceManager(), 3081fb5c3a6SDouglas Gregor getDiagnostics(), 30989929282SDouglas Gregor getLangOpts(), 31089929282SDouglas Gregor &getTarget()); 3119663780eSAlp Toker PP = new Preprocessor(&getPreprocessorOpts(), getDiagnostics(), getLangOpts(), 31208142534SDouglas Gregor getSourceManager(), *HeaderInfo, *this, PTHMgr, 3139663780eSAlp Toker /*OwnsHeaderSearch=*/true, TUKind); 314b5bc923aSArtem Belevich PP->Initialize(getTarget(), getAuxTarget()); 315aaa148fdSDaniel Dunbar 316aaa148fdSDaniel Dunbar // Note that this is different then passing PTHMgr to Preprocessor's ctor. 317aaa148fdSDaniel Dunbar // That argument is used as the IdentifierInfoLookup argument to 318aaa148fdSDaniel Dunbar // IdentifierTable's ctor. 319aaa148fdSDaniel Dunbar if (PTHMgr) { 32008142534SDouglas Gregor PTHMgr->setPreprocessor(&*PP); 321aaa148fdSDaniel Dunbar PP->setPTHManager(PTHMgr); 322aaa148fdSDaniel Dunbar } 323aaa148fdSDaniel Dunbar 3247f6d60dcSDouglas Gregor if (PPOpts.DetailedRecord) 325f3d587eaSArgyrios Kyrtzidis PP->createPreprocessingRecord(); 3267f6d60dcSDouglas Gregor 327c358000eSAlp Toker // Apply remappings to the source manager. 328c358000eSAlp Toker InitializeFileRemapping(PP->getDiagnostics(), PP->getSourceManager(), 329c358000eSAlp Toker PP->getFileManager(), PPOpts); 330c358000eSAlp Toker 331c358000eSAlp Toker // Predefine macros and configure the preprocessor. 332fb2398d0SAdrian Prantl InitializePreprocessor(*PP, PPOpts, getPCHContainerReader(), 333bb165fb0SAdrian Prantl getFrontendOpts()); 334c358000eSAlp Toker 335c358000eSAlp Toker // Initialize the header search object. 336c358000eSAlp Toker ApplyHeaderSearchOptions(PP->getHeaderSearchInfo(), getHeaderSearchOpts(), 337c358000eSAlp Toker PP->getLangOpts(), PP->getTargetInfo().getTriple()); 338aaa148fdSDaniel Dunbar 33917441589SJordan Rose PP->setPreprocessedOutput(getPreprocessorOutputOpts().ShowCPP); 34017441589SJordan Rose 3413938f0c7SRichard Smith if (PP->getLangOpts().Modules && PP->getLangOpts().ImplicitModules) 342bd0b651bSArgyrios Kyrtzidis PP->getHeaderSearchInfo().setModuleCachePath(getSpecificModuleCachePath()); 3431735f4e7SDouglas Gregor 344aaa148fdSDaniel Dunbar // Handle generating dependencies, if requested. 34508142534SDouglas Gregor const DependencyOutputOptions &DepOpts = getDependencyOutputOpts(); 346aaa148fdSDaniel Dunbar if (!DepOpts.OutputFile.empty()) 347cb69b57bSBen Langmuir TheDependencyFileGenerator.reset( 348cb69b57bSBen Langmuir DependencyFileGenerator::CreateAndAttachToPreprocessor(*PP, DepOpts)); 3492e129659SDouglas Gregor if (!DepOpts.DOTOutputFile.empty()) 3502e129659SDouglas Gregor AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile, 35183d46be3SDouglas Gregor getHeaderSearchOpts().Sysroot); 35283d46be3SDouglas Gregor 35333c8090aSBen Langmuir for (auto &Listener : DependencyCollectors) 35433c8090aSBen Langmuir Listener->attachToPreprocessor(*PP); 35533c8090aSBen Langmuir 35686d1259cSJustin Bogner // If we don't have a collector, but we are collecting module dependencies, 35786d1259cSJustin Bogner // then we're the top level compiler instance and need to create one. 35886d1259cSJustin Bogner if (!ModuleDepCollector && !DepOpts.ModuleDependencyOutputDir.empty()) 35986d1259cSJustin Bogner ModuleDepCollector = std::make_shared<ModuleDependencyCollector>( 36086d1259cSJustin Bogner DepOpts.ModuleDependencyOutputDir); 361aaa148fdSDaniel Dunbar 36227734fdbSDaniel Dunbar // Handle generating header include information, if requested. 36327734fdbSDaniel Dunbar if (DepOpts.ShowHeaderIncludes) 3641193f2cbSIvan Krasin AttachHeaderIncludeGen(*PP, DepOpts.ExtraDeps); 3651af1d275SDaniel Dunbar if (!DepOpts.HeaderIncludeOutputFile.empty()) { 3660e62c1ccSChris Lattner StringRef OutputPath = DepOpts.HeaderIncludeOutputFile; 3671af1d275SDaniel Dunbar if (OutputPath == "-") 3681af1d275SDaniel Dunbar OutputPath = ""; 3691193f2cbSIvan Krasin AttachHeaderIncludeGen(*PP, DepOpts.ExtraDeps, 3701193f2cbSIvan Krasin /*ShowAllHeaders=*/true, OutputPath, 371fe908a80SDaniel Dunbar /*ShowDepth=*/false); 3720fd6207dSHans Wennborg } 3730fd6207dSHans Wennborg 3740fd6207dSHans Wennborg if (DepOpts.PrintShowIncludes) { 3751193f2cbSIvan Krasin AttachHeaderIncludeGen(*PP, DepOpts.ExtraDeps, 3761193f2cbSIvan Krasin /*ShowAllHeaders=*/false, /*OutputPath=*/"", 3770fd6207dSHans Wennborg /*ShowDepth=*/true, /*MSStyle=*/true); 3781af1d275SDaniel Dunbar } 379aaa148fdSDaniel Dunbar } 380df3e30c4SDaniel Dunbar 381bd0b651bSArgyrios Kyrtzidis std::string CompilerInstance::getSpecificModuleCachePath() { 382bd0b651bSArgyrios Kyrtzidis // Set up the module path, including the hash for the 383bd0b651bSArgyrios Kyrtzidis // module-creation options. 384d520a250SRichard Smith SmallString<256> SpecificModuleCache(getHeaderSearchOpts().ModuleCachePath); 385d520a250SRichard Smith if (!SpecificModuleCache.empty() && !getHeaderSearchOpts().DisableModuleHash) 386bd0b651bSArgyrios Kyrtzidis llvm::sys::path::append(SpecificModuleCache, 387bd0b651bSArgyrios Kyrtzidis getInvocation().getModuleHash()); 388bd0b651bSArgyrios Kyrtzidis return SpecificModuleCache.str(); 389bd0b651bSArgyrios Kyrtzidis } 390bd0b651bSArgyrios Kyrtzidis 391df3e30c4SDaniel Dunbar // ASTContext 392df3e30c4SDaniel Dunbar 393df3e30c4SDaniel Dunbar void CompilerInstance::createASTContext() { 394df3e30c4SDaniel Dunbar Preprocessor &PP = getPreprocessor(); 395293534b1SRichard Smith auto *Context = new ASTContext(getLangOpts(), PP.getSourceManager(), 39608043437SAlp Toker PP.getIdentifierTable(), PP.getSelectorTable(), 39708043437SAlp Toker PP.getBuiltinInfo()); 398b5bc923aSArtem Belevich Context->InitBuiltinTypes(getTarget(), getAuxTarget()); 399293534b1SRichard Smith setASTContext(Context); 400df3e30c4SDaniel Dunbar } 401599313efSDaniel Dunbar 402599313efSDaniel Dunbar // ExternalASTSource 403599313efSDaniel Dunbar 404824285ecSNico Weber void CompilerInstance::createPCHExternalASTSource( 405824285ecSNico Weber StringRef Path, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors, 406824285ecSNico Weber void *DeserializationListener, bool OwnDeserializationListener) { 407009e7f20SSebastian Redl bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0; 4084eca9b93SRichard Smith ModuleManager = createPCHExternalASTSource( 409824285ecSNico Weber Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation, 410824285ecSNico Weber AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(), 411fb2398d0SAdrian Prantl getPCHContainerReader(), DeserializationListener, 412bb165fb0SAdrian Prantl OwnDeserializationListener, Preamble, 4131b7ed91eSArgyrios Kyrtzidis getFrontendOpts().UseGlobalModuleIndex); 414599313efSDaniel Dunbar } 415599313efSDaniel Dunbar 4164eca9b93SRichard Smith IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource( 4175b816061SYaron Keren StringRef Path, StringRef Sysroot, bool DisablePCHValidation, 418824285ecSNico Weber bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context, 419fb2398d0SAdrian Prantl const PCHContainerReader &PCHContainerRdr, 420824285ecSNico Weber void *DeserializationListener, bool OwnDeserializationListener, 421824285ecSNico Weber bool Preamble, bool UseGlobalModuleIndex) { 422dcf73861SBen Langmuir HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts(); 423dcf73861SBen Langmuir 424bb165fb0SAdrian Prantl IntrusiveRefCntPtr<ASTReader> Reader(new ASTReader( 425fb2398d0SAdrian Prantl PP, Context, PCHContainerRdr, Sysroot.empty() ? "" : Sysroot.data(), 4264eca9b93SRichard Smith DisablePCHValidation, AllowPCHWithCompilerErrors, 427bb165fb0SAdrian Prantl /*AllowConfigurationMismatch*/ false, HSOpts.ModulesValidateSystemHeaders, 428bb165fb0SAdrian Prantl UseGlobalModuleIndex)); 4294eca9b93SRichard Smith 4304eca9b93SRichard Smith // We need the external source to be set up before we read the AST, because 4314eca9b93SRichard Smith // eagerly-deserialized declarations may use it. 4324eca9b93SRichard Smith Context.setExternalSource(Reader.get()); 433599313efSDaniel Dunbar 43407a89a83SSebastian Redl Reader->setDeserializationListener( 435824285ecSNico Weber static_cast<ASTDeserializationListener *>(DeserializationListener), 436824285ecSNico Weber /*TakeOwnership=*/OwnDeserializationListener); 437009e7f20SSebastian Redl switch (Reader->ReadAST(Path, 438a6895d8aSDouglas Gregor Preamble ? serialization::MK_Preamble 4394b29c16eSDouglas Gregor : serialization::MK_PCH, 4402ec29367SArgyrios Kyrtzidis SourceLocation(), 4413d4417c7SBen Langmuir ASTReader::ARR_None)) { 4422c499f65SSebastian Redl case ASTReader::Success: 443599313efSDaniel Dunbar // Set the predefines buffer as suggested by the PCH reader. Typically, the 444599313efSDaniel Dunbar // predefines buffer will be empty. 445599313efSDaniel Dunbar PP.setPredefines(Reader->getSuggestedPredefines()); 4464eca9b93SRichard Smith return Reader; 447599313efSDaniel Dunbar 4482c499f65SSebastian Redl case ASTReader::Failure: 449599313efSDaniel Dunbar // Unrecoverable failure: don't even try to process the input file. 450599313efSDaniel Dunbar break; 451599313efSDaniel Dunbar 4527029ce1aSDouglas Gregor case ASTReader::Missing: 453c9ad5fb6SDouglas Gregor case ASTReader::OutOfDate: 454c9ad5fb6SDouglas Gregor case ASTReader::VersionMismatch: 455c9ad5fb6SDouglas Gregor case ASTReader::ConfigurationMismatch: 456c9ad5fb6SDouglas Gregor case ASTReader::HadErrors: 457599313efSDaniel Dunbar // No suitable PCH file could be found. Return an error. 458599313efSDaniel Dunbar break; 459599313efSDaniel Dunbar } 460599313efSDaniel Dunbar 4614eca9b93SRichard Smith Context.setExternalSource(nullptr); 46249a2790fSCraig Topper return nullptr; 463599313efSDaniel Dunbar } 464f7093b5aSDaniel Dunbar 465f7093b5aSDaniel Dunbar // Code Completion 466f7093b5aSDaniel Dunbar 4678e984da8SDouglas Gregor static bool EnableCodeCompletion(Preprocessor &PP, 4688e984da8SDouglas Gregor const std::string &Filename, 4698e984da8SDouglas Gregor unsigned Line, 4708e984da8SDouglas Gregor unsigned Column) { 4718e984da8SDouglas Gregor // Tell the source manager to chop off the given file at a specific 4728e984da8SDouglas Gregor // line and column. 4735159f616SChris Lattner const FileEntry *Entry = PP.getFileManager().getFile(Filename); 4748e984da8SDouglas Gregor if (!Entry) { 4758e984da8SDouglas Gregor PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file) 4768e984da8SDouglas Gregor << Filename; 4778e984da8SDouglas Gregor return true; 4788e984da8SDouglas Gregor } 4798e984da8SDouglas Gregor 4808e984da8SDouglas Gregor // Truncate the named file at the given line/column. 4818e984da8SDouglas Gregor PP.SetCodeCompletionPoint(Entry, Line, Column); 4828e984da8SDouglas Gregor return false; 4838e984da8SDouglas Gregor } 4848e984da8SDouglas Gregor 485f7093b5aSDaniel Dunbar void CompilerInstance::createCodeCompletionConsumer() { 486f7093b5aSDaniel Dunbar const ParsedSourceLocation &Loc = getFrontendOpts().CodeCompletionAt; 4878e984da8SDouglas Gregor if (!CompletionConsumer) { 4882fca3c2cSErik Verbruggen setCodeCompletionConsumer( 489f7093b5aSDaniel Dunbar createCodeCompletionConsumer(getPreprocessor(), 490f7093b5aSDaniel Dunbar Loc.FileName, Loc.Line, Loc.Column, 4913292d06aSDmitri Gribenko getFrontendOpts().CodeCompleteOpts, 492f7093b5aSDaniel Dunbar llvm::outs())); 49300a0cf70SDouglas Gregor if (!CompletionConsumer) 49400a0cf70SDouglas Gregor return; 4958e984da8SDouglas Gregor } else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName, 4968e984da8SDouglas Gregor Loc.Line, Loc.Column)) { 49749a2790fSCraig Topper setCodeCompletionConsumer(nullptr); 4988e984da8SDouglas Gregor return; 4998e984da8SDouglas Gregor } 500f09935f1SDouglas Gregor 501f09935f1SDouglas Gregor if (CompletionConsumer->isOutputBinary() && 502a3346d87SRafael Espindola llvm::sys::ChangeStdoutToBinary()) { 503f09935f1SDouglas Gregor getPreprocessor().getDiagnostics().Report(diag::err_fe_stdout_binary); 50449a2790fSCraig Topper setCodeCompletionConsumer(nullptr); 505f09935f1SDouglas Gregor } 506f7093b5aSDaniel Dunbar } 507f7093b5aSDaniel Dunbar 5085505dff8SKovarththanan Rajaratnam void CompilerInstance::createFrontendTimer() { 509ce18a187SRichard Smith FrontendTimerGroup.reset(new llvm::TimerGroup("Clang front-end time report")); 510ce18a187SRichard Smith FrontendTimer.reset( 511ce18a187SRichard Smith new llvm::Timer("Clang front-end timer", *FrontendTimerGroup)); 5125505dff8SKovarththanan Rajaratnam } 5135505dff8SKovarththanan Rajaratnam 514f7093b5aSDaniel Dunbar CodeCompleteConsumer * 515f7093b5aSDaniel Dunbar CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP, 5165b816061SYaron Keren StringRef Filename, 517f7093b5aSDaniel Dunbar unsigned Line, 518f7093b5aSDaniel Dunbar unsigned Column, 5193292d06aSDmitri Gribenko const CodeCompleteOptions &Opts, 5200e62c1ccSChris Lattner raw_ostream &OS) { 5218e984da8SDouglas Gregor if (EnableCodeCompletion(PP, Filename, Line, Column)) 52249a2790fSCraig Topper return nullptr; 523f7093b5aSDaniel Dunbar 524f7093b5aSDaniel Dunbar // Set up the creation routine for code-completion. 5253292d06aSDmitri Gribenko return new PrintingCodeCompleteConsumer(Opts, OS); 526f7093b5aSDaniel Dunbar } 527566eeb2dSDaniel Dunbar 52869f74f80SDouglas Gregor void CompilerInstance::createSema(TranslationUnitKind TUKind, 5290e93f017SDouglas Gregor CodeCompleteConsumer *CompletionConsumer) { 5300e93f017SDouglas Gregor TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(), 53169f74f80SDouglas Gregor TUKind, CompletionConsumer)); 5320e93f017SDouglas Gregor } 5330e93f017SDouglas Gregor 534566eeb2dSDaniel Dunbar // Output Files 535566eeb2dSDaniel Dunbar 536269ec0f4SRafael Espindola void CompilerInstance::addOutputFile(OutputFile &&OutFile) { 537d0599970SArgyrios Kyrtzidis assert(OutFile.OS && "Attempt to add empty stream to output list!"); 538269ec0f4SRafael Espindola OutputFiles.push_back(std::move(OutFile)); 539566eeb2dSDaniel Dunbar } 540566eeb2dSDaniel Dunbar 5411c558cd7SKovarththanan Rajaratnam void CompilerInstance::clearOutputFiles(bool EraseFiles) { 5420aa128e2SReid Kleckner for (OutputFile &OF : OutputFiles) { 5430aa128e2SReid Kleckner // Manually close the stream before we rename it. 5440aa128e2SReid Kleckner OF.OS.reset(); 5450aa128e2SReid Kleckner 5460aa128e2SReid Kleckner if (!OF.TempFilename.empty()) { 547b5c356a4SAnders Carlsson if (EraseFiles) { 5480aa128e2SReid Kleckner llvm::sys::fs::remove(OF.TempFilename); 549b5c356a4SAnders Carlsson } else { 5500aa128e2SReid Kleckner SmallString<128> NewOutFile(OF.Filename); 551b5c356a4SAnders Carlsson 55271731d6bSArgyrios Kyrtzidis // If '-working-directory' was passed, the output filename should be 55371731d6bSArgyrios Kyrtzidis // relative to that. 5549ba8fb1eSAnders Carlsson FileMgr->FixupRelativePath(NewOutFile); 555c080917eSRafael Espindola if (std::error_code ec = 5560aa128e2SReid Kleckner llvm::sys::fs::rename(OF.TempFilename, NewOutFile)) { 5573ef9c447SManuel Klimek getDiagnostics().Report(diag::err_unable_to_rename_temp) 5580aa128e2SReid Kleckner << OF.TempFilename << OF.Filename << ec.message(); 559b5c356a4SAnders Carlsson 5600aa128e2SReid Kleckner llvm::sys::fs::remove(OF.TempFilename); 561d0599970SArgyrios Kyrtzidis } 562d0599970SArgyrios Kyrtzidis } 5630aa128e2SReid Kleckner } else if (!OF.Filename.empty() && EraseFiles) 5640aa128e2SReid Kleckner llvm::sys::fs::remove(OF.Filename); 565d0599970SArgyrios Kyrtzidis 566566eeb2dSDaniel Dunbar } 567566eeb2dSDaniel Dunbar OutputFiles.clear(); 5682f16bc10SRafael Espindola NonSeekStream.reset(); 569566eeb2dSDaniel Dunbar } 570566eeb2dSDaniel Dunbar 5712f16bc10SRafael Espindola raw_pwrite_stream * 5722f16bc10SRafael Espindola CompilerInstance::createDefaultOutputFile(bool Binary, StringRef InFile, 5730e62c1ccSChris Lattner StringRef Extension) { 574420b0f1bSDaniel Dunbar return createOutputFile(getFrontendOpts().OutputFile, Binary, 575ae77b3dfSDaniel Dunbar /*RemoveFileOnSignal=*/true, InFile, Extension, 576ae77b3dfSDaniel Dunbar /*UseTemporary=*/true); 577420b0f1bSDaniel Dunbar } 578420b0f1bSDaniel Dunbar 579ea04672cSAlp Toker llvm::raw_null_ostream *CompilerInstance::createNullOutputFile() { 580269ec0f4SRafael Espindola auto OS = llvm::make_unique<llvm::raw_null_ostream>(); 581269ec0f4SRafael Espindola llvm::raw_null_ostream *Ret = OS.get(); 582269ec0f4SRafael Espindola addOutputFile(OutputFile("", "", std::move(OS))); 583269ec0f4SRafael Espindola return Ret; 584ea04672cSAlp Toker } 585ea04672cSAlp Toker 5862f16bc10SRafael Espindola raw_pwrite_stream * 5872f16bc10SRafael Espindola CompilerInstance::createOutputFile(StringRef OutputPath, bool Binary, 5882f16bc10SRafael Espindola bool RemoveFileOnSignal, StringRef InFile, 5892f16bc10SRafael Espindola StringRef Extension, bool UseTemporary, 590b9c62c07SDaniel Dunbar bool CreateMissingDirectories) { 591dae941a6SRafael Espindola std::string OutputPathName, TempPathName; 592dae941a6SRafael Espindola std::error_code EC; 5932f16bc10SRafael Espindola std::unique_ptr<raw_pwrite_stream> OS = createOutputFile( 594dae941a6SRafael Espindola OutputPath, EC, Binary, RemoveFileOnSignal, InFile, Extension, 595c80a4066SRafael Espindola UseTemporary, CreateMissingDirectories, &OutputPathName, &TempPathName); 596420b0f1bSDaniel Dunbar if (!OS) { 597dae941a6SRafael Espindola getDiagnostics().Report(diag::err_fe_unable_to_open_output) << OutputPath 598dae941a6SRafael Espindola << EC.message(); 59949a2790fSCraig Topper return nullptr; 600420b0f1bSDaniel Dunbar } 601420b0f1bSDaniel Dunbar 6022f16bc10SRafael Espindola raw_pwrite_stream *Ret = OS.get(); 603420b0f1bSDaniel Dunbar // Add the output file -- but don't try to remove "-", since this means we are 604420b0f1bSDaniel Dunbar // using stdin. 605d0599970SArgyrios Kyrtzidis addOutputFile(OutputFile((OutputPathName != "-") ? OutputPathName : "", 606269ec0f4SRafael Espindola TempPathName, std::move(OS))); 607420b0f1bSDaniel Dunbar 608269ec0f4SRafael Espindola return Ret; 609420b0f1bSDaniel Dunbar } 610420b0f1bSDaniel Dunbar 6112f16bc10SRafael Espindola std::unique_ptr<llvm::raw_pwrite_stream> CompilerInstance::createOutputFile( 612dae941a6SRafael Espindola StringRef OutputPath, std::error_code &Error, bool Binary, 613dae941a6SRafael Espindola bool RemoveFileOnSignal, StringRef InFile, StringRef Extension, 614dae941a6SRafael Espindola bool UseTemporary, bool CreateMissingDirectories, 615dae941a6SRafael Espindola std::string *ResultPathName, std::string *TempPathName) { 616b9c62c07SDaniel Dunbar assert((!CreateMissingDirectories || UseTemporary) && 617b9c62c07SDaniel Dunbar "CreateMissingDirectories is only allowed when using temporary files"); 618b9c62c07SDaniel Dunbar 619d0599970SArgyrios Kyrtzidis std::string OutFile, TempFile; 620420b0f1bSDaniel Dunbar if (!OutputPath.empty()) { 621420b0f1bSDaniel Dunbar OutFile = OutputPath; 622420b0f1bSDaniel Dunbar } else if (InFile == "-") { 623420b0f1bSDaniel Dunbar OutFile = "-"; 624420b0f1bSDaniel Dunbar } else if (!Extension.empty()) { 625399ab33aSRafael Espindola SmallString<128> Path(InFile); 626399ab33aSRafael Espindola llvm::sys::path::replace_extension(Path, Extension); 627420b0f1bSDaniel Dunbar OutFile = Path.str(); 628420b0f1bSDaniel Dunbar } else { 629420b0f1bSDaniel Dunbar OutFile = "-"; 630420b0f1bSDaniel Dunbar } 631420b0f1bSDaniel Dunbar 632b8984329SAhmed Charles std::unique_ptr<llvm::raw_fd_ostream> OS; 63308a2bfd2SArgyrios Kyrtzidis std::string OSFile; 63408a2bfd2SArgyrios Kyrtzidis 63573c23a71SRafael Espindola if (UseTemporary) { 63673c23a71SRafael Espindola if (OutFile == "-") 63773c23a71SRafael Espindola UseTemporary = false; 63873c23a71SRafael Espindola else { 63973c23a71SRafael Espindola llvm::sys::fs::file_status Status; 64073c23a71SRafael Espindola llvm::sys::fs::status(OutputPath, Status); 64173c23a71SRafael Espindola if (llvm::sys::fs::exists(Status)) { 64273c23a71SRafael Espindola // Fail early if we can't write to the final destination. 6438bfac2c5SDouglas Katzman if (!llvm::sys::fs::can_write(OutputPath)) { 644*ee4e08baSRafael Espindola Error = make_error_code(llvm::errc::operation_not_permitted); 64549a2790fSCraig Topper return nullptr; 6468bfac2c5SDouglas Katzman } 64773c23a71SRafael Espindola 64873c23a71SRafael Espindola // Don't use a temporary if the output is a special file. This handles 64973c23a71SRafael Espindola // things like '-o /dev/null' 65073c23a71SRafael Espindola if (!llvm::sys::fs::is_regular_file(Status)) 65173c23a71SRafael Espindola UseTemporary = false; 65273c23a71SRafael Espindola } 65373c23a71SRafael Espindola } 65473c23a71SRafael Espindola } 65573c23a71SRafael Espindola 65673c23a71SRafael Espindola if (UseTemporary) { 657d0599970SArgyrios Kyrtzidis // Create a temporary file. 6582c1dd271SDylan Noblesmith SmallString<128> TempPath; 65908a2bfd2SArgyrios Kyrtzidis TempPath = OutFile; 66008a2bfd2SArgyrios Kyrtzidis TempPath += "-%%%%%%%%"; 66108a2bfd2SArgyrios Kyrtzidis int fd; 662c080917eSRafael Espindola std::error_code EC = 66392e1b62dSYaron Keren llvm::sys::fs::createUniqueFile(TempPath, fd, TempPath); 664157f34bdSRafael Espindola 665157f34bdSRafael Espindola if (CreateMissingDirectories && 66671de0b61SRafael Espindola EC == llvm::errc::no_such_file_or_directory) { 667157f34bdSRafael Espindola StringRef Parent = llvm::sys::path::parent_path(OutputPath); 668157f34bdSRafael Espindola EC = llvm::sys::fs::create_directories(Parent); 669157f34bdSRafael Espindola if (!EC) { 67092e1b62dSYaron Keren EC = llvm::sys::fs::createUniqueFile(TempPath, fd, TempPath); 671157f34bdSRafael Espindola } 672157f34bdSRafael Espindola } 673157f34bdSRafael Espindola 674157f34bdSRafael Espindola if (!EC) { 67569f3528cSNAKAMURA Takumi OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true)); 67608a2bfd2SArgyrios Kyrtzidis OSFile = TempFile = TempPath.str(); 67708a2bfd2SArgyrios Kyrtzidis } 67873c23a71SRafael Espindola // If we failed to create the temporary, fallback to writing to the file 67973c23a71SRafael Espindola // directly. This handles the corner case where we cannot write to the 68073c23a71SRafael Espindola // directory, but can write to the file. 681d0599970SArgyrios Kyrtzidis } 682d0599970SArgyrios Kyrtzidis 68308a2bfd2SArgyrios Kyrtzidis if (!OS) { 68408a2bfd2SArgyrios Kyrtzidis OSFile = OutFile; 68569f3528cSNAKAMURA Takumi OS.reset(new llvm::raw_fd_ostream( 686dae941a6SRafael Espindola OSFile, Error, 68769f3528cSNAKAMURA Takumi (Binary ? llvm::sys::fs::F_None : llvm::sys::fs::F_Text))); 688dae941a6SRafael Espindola if (Error) 68949a2790fSCraig Topper return nullptr; 69008a2bfd2SArgyrios Kyrtzidis } 691420b0f1bSDaniel Dunbar 692d0599970SArgyrios Kyrtzidis // Make sure the out stream file gets removed if we crash. 693e326f9bbSDaniel Dunbar if (RemoveFileOnSignal) 69418556de3SRafael Espindola llvm::sys::RemoveFileOnSignal(OSFile); 695d0599970SArgyrios Kyrtzidis 696420b0f1bSDaniel Dunbar if (ResultPathName) 697420b0f1bSDaniel Dunbar *ResultPathName = OutFile; 698d0599970SArgyrios Kyrtzidis if (TempPathName) 699d0599970SArgyrios Kyrtzidis *TempPathName = TempFile; 700420b0f1bSDaniel Dunbar 7012f16bc10SRafael Espindola if (!Binary || OS->supportsSeeking()) 7022f16bc10SRafael Espindola return std::move(OS); 7032f16bc10SRafael Espindola 7042f16bc10SRafael Espindola auto B = llvm::make_unique<llvm::buffer_ostream>(*OS); 7052f16bc10SRafael Espindola assert(!NonSeekStream); 7062f16bc10SRafael Espindola NonSeekStream = std::move(OS); 7072f16bc10SRafael Espindola return std::move(B); 708420b0f1bSDaniel Dunbar } 709409e890fSDaniel Dunbar 710409e890fSDaniel Dunbar // Initialization Utilities 711409e890fSDaniel Dunbar 7121b3240b0SArgyrios Kyrtzidis bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input){ 7131b3240b0SArgyrios Kyrtzidis return InitializeSourceManager(Input, getDiagnostics(), 714a686e1b0SDouglas Gregor getFileManager(), getSourceManager(), 715a686e1b0SDouglas Gregor getFrontendOpts()); 716409e890fSDaniel Dunbar } 717409e890fSDaniel Dunbar 7181b3240b0SArgyrios Kyrtzidis bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input, 7199c902b55SDavid Blaikie DiagnosticsEngine &Diags, 720409e890fSDaniel Dunbar FileManager &FileMgr, 721409e890fSDaniel Dunbar SourceManager &SourceMgr, 722409e890fSDaniel Dunbar const FrontendOptions &Opts) { 7231b3240b0SArgyrios Kyrtzidis SrcMgr::CharacteristicKind 724873c8583SArgyrios Kyrtzidis Kind = Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User; 7251b3240b0SArgyrios Kyrtzidis 7266566e23eSArgyrios Kyrtzidis if (Input.isBuffer()) { 72750a5f97eSDavid Blaikie SourceMgr.setMainFileID(SourceMgr.createFileID( 72850a5f97eSDavid Blaikie std::unique_ptr<llvm::MemoryBuffer>(Input.getBuffer()), Kind)); 7298b563665SYaron Keren assert(SourceMgr.getMainFileID().isValid() && 7306566e23eSArgyrios Kyrtzidis "Couldn't establish MainFileID!"); 7316566e23eSArgyrios Kyrtzidis return true; 7326566e23eSArgyrios Kyrtzidis } 7336566e23eSArgyrios Kyrtzidis 7346566e23eSArgyrios Kyrtzidis StringRef InputFile = Input.getFile(); 7356566e23eSArgyrios Kyrtzidis 7367c06d866SArgyrios Kyrtzidis // Figure out where to get and map in the main file. 7377c06d866SArgyrios Kyrtzidis if (InputFile != "-") { 7383841fa38SBenjamin Kramer const FileEntry *File = FileMgr.getFile(InputFile, /*OpenFile=*/true); 73952765215SDan Gohman if (!File) { 740409e890fSDaniel Dunbar Diags.Report(diag::err_fe_error_reading) << InputFile; 741409e890fSDaniel Dunbar return false; 742409e890fSDaniel Dunbar } 743e2951f48SDaniel Dunbar 744e2951f48SDaniel Dunbar // The natural SourceManager infrastructure can't currently handle named 745e2951f48SDaniel Dunbar // pipes, but we would at least like to accept them for the main 7463841fa38SBenjamin Kramer // file. Detect them here, read them with the volatile flag so FileMgr will 7473841fa38SBenjamin Kramer // pick up the correct size, and simply override their contents as we do for 7483841fa38SBenjamin Kramer // STDIN. 749e2951f48SDaniel Dunbar if (File->isNamedPipe()) { 750a885796dSBenjamin Kramer auto MB = FileMgr.getBufferForFile(File, /*isVolatile=*/true); 751a885796dSBenjamin Kramer if (MB) { 752db0745abSDaniel Dunbar // Create a new virtual file that will have the correct size. 753a885796dSBenjamin Kramer File = FileMgr.getVirtualFile(InputFile, (*MB)->getBufferSize(), 0); 754a885796dSBenjamin Kramer SourceMgr.overrideFileContents(File, std::move(*MB)); 7553841fa38SBenjamin Kramer } else { 756a885796dSBenjamin Kramer Diags.Report(diag::err_cannot_open_file) << InputFile 757a885796dSBenjamin Kramer << MB.getError().message(); 7583841fa38SBenjamin Kramer return false; 7593841fa38SBenjamin Kramer } 760e2951f48SDaniel Dunbar } 761db0745abSDaniel Dunbar 762b671e34cSAlp Toker SourceMgr.setMainFileID( 763b671e34cSAlp Toker SourceMgr.createFileID(File, SourceLocation(), Kind)); 764409e890fSDaniel Dunbar } else { 7652d2b420aSRafael Espindola llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> SBOrErr = 7662d2b420aSRafael Espindola llvm::MemoryBuffer::getSTDIN(); 7672d2b420aSRafael Espindola if (std::error_code EC = SBOrErr.getError()) { 7682d2b420aSRafael Espindola Diags.Report(diag::err_fe_error_reading_stdin) << EC.message(); 769409e890fSDaniel Dunbar return false; 770409e890fSDaniel Dunbar } 7712d2b420aSRafael Espindola std::unique_ptr<llvm::MemoryBuffer> SB = std::move(SBOrErr.get()); 7722d2b420aSRafael Espindola 7732f76cd75SDan Gohman const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(), 7745159f616SChris Lattner SB->getBufferSize(), 0); 775b671e34cSAlp Toker SourceMgr.setMainFileID( 776b671e34cSAlp Toker SourceMgr.createFileID(File, SourceLocation(), Kind)); 77749cc3181SDavid Blaikie SourceMgr.overrideFileContents(File, std::move(SB)); 778409e890fSDaniel Dunbar } 779409e890fSDaniel Dunbar 7808b563665SYaron Keren assert(SourceMgr.getMainFileID().isValid() && 78152765215SDan Gohman "Couldn't establish MainFileID!"); 782409e890fSDaniel Dunbar return true; 783409e890fSDaniel Dunbar } 7844f2bc55dSDaniel Dunbar 7854f2bc55dSDaniel Dunbar // High-Level Operations 7864f2bc55dSDaniel Dunbar 7874f2bc55dSDaniel Dunbar bool CompilerInstance::ExecuteAction(FrontendAction &Act) { 7884f2bc55dSDaniel Dunbar assert(hasDiagnostics() && "Diagnostics engine is not initialized!"); 7894f2bc55dSDaniel Dunbar assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!"); 7904f2bc55dSDaniel Dunbar assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!"); 7914f2bc55dSDaniel Dunbar 7924f2bc55dSDaniel Dunbar // FIXME: Take this as an argument, once all the APIs we used have moved to 7934f2bc55dSDaniel Dunbar // taking it as an input instead of hard-coding llvm::errs. 7940e62c1ccSChris Lattner raw_ostream &OS = llvm::errs(); 7954f2bc55dSDaniel Dunbar 7964f2bc55dSDaniel Dunbar // Create the target instance. 79780758084SAlp Toker setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), 79880758084SAlp Toker getInvocation().TargetOpts)); 7994f2bc55dSDaniel Dunbar if (!hasTarget()) 8004f2bc55dSDaniel Dunbar return false; 8014f2bc55dSDaniel Dunbar 802b5bc923aSArtem Belevich // Create TargetInfo for the other side of CUDA compilation. 803b5bc923aSArtem Belevich if (getLangOpts().CUDA && !getFrontendOpts().AuxTriple.empty()) { 804b5bc923aSArtem Belevich std::shared_ptr<TargetOptions> TO(new TargetOptions); 805b5bc923aSArtem Belevich TO->Triple = getFrontendOpts().AuxTriple; 806b5bc923aSArtem Belevich setAuxTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), TO)); 807b5bc923aSArtem Belevich } 808b5bc923aSArtem Belevich 8094f2bc55dSDaniel Dunbar // Inform the target of the language options. 8104f2bc55dSDaniel Dunbar // 8114f2bc55dSDaniel Dunbar // FIXME: We shouldn't need to do this, the target should be immutable once 8124f2bc55dSDaniel Dunbar // created. This complexity should be lifted elsewhere. 81374437975SAlp Toker getTarget().adjust(getLangOpts()); 8144f2bc55dSDaniel Dunbar 81529898f45SFariborz Jahanian // rewriter project will change target built-in bool type from its default. 81629898f45SFariborz Jahanian if (getFrontendOpts().ProgramAction == frontend::RewriteObjC) 81729898f45SFariborz Jahanian getTarget().noSignedCharForObjCBool(); 81829898f45SFariborz Jahanian 8194f2bc55dSDaniel Dunbar // Validate/process some options. 8204f2bc55dSDaniel Dunbar if (getHeaderSearchOpts().Verbose) 8214f2bc55dSDaniel Dunbar OS << "clang -cc1 version " CLANG_VERSION_STRING 822f988d006SAlp Toker << " based upon " << BACKEND_PACKAGE_STRING 8238188c8a1SSebastian Pop << " default target " << llvm::sys::getDefaultTargetTriple() << "\n"; 8244f2bc55dSDaniel Dunbar 8254f2bc55dSDaniel Dunbar if (getFrontendOpts().ShowTimers) 8264f2bc55dSDaniel Dunbar createFrontendTimer(); 8274f2bc55dSDaniel Dunbar 828171b780cSDouglas Gregor if (getFrontendOpts().ShowStats) 829171b780cSDouglas Gregor llvm::EnableStatistics(); 830171b780cSDouglas Gregor 8314f2bc55dSDaniel Dunbar for (unsigned i = 0, e = getFrontendOpts().Inputs.size(); i != e; ++i) { 832eeccb30bSTed Kremenek // Reset the ID tables if we are reusing the SourceManager and parsing 833eeccb30bSTed Kremenek // regular files. 834eeccb30bSTed Kremenek if (hasSourceManager() && !Act.isModelParsingAction()) 8354f2bc55dSDaniel Dunbar getSourceManager().clearIDTables(); 8364f2bc55dSDaniel Dunbar 83732fbe312SDouglas Gregor if (Act.BeginSourceFile(*this, getFrontendOpts().Inputs[i])) { 8384f2bc55dSDaniel Dunbar Act.Execute(); 8394f2bc55dSDaniel Dunbar Act.EndSourceFile(); 8404f2bc55dSDaniel Dunbar } 8414f2bc55dSDaniel Dunbar } 8424f2bc55dSDaniel Dunbar 8437910d7b7SArgyrios Kyrtzidis // Notify the diagnostic client that all files were processed. 8447910d7b7SArgyrios Kyrtzidis getDiagnostics().getClient()->finish(); 8457910d7b7SArgyrios Kyrtzidis 846198cb4dfSChris Lattner if (getDiagnosticOpts().ShowCarets) { 847c79346a5SArgyrios Kyrtzidis // We can have multiple diagnostics sharing one diagnostic client. 848c79346a5SArgyrios Kyrtzidis // Get the total number of warnings/errors from the client. 849c79346a5SArgyrios Kyrtzidis unsigned NumWarnings = getDiagnostics().getClient()->getNumWarnings(); 850c79346a5SArgyrios Kyrtzidis unsigned NumErrors = getDiagnostics().getClient()->getNumErrors(); 851198cb4dfSChris Lattner 852198cb4dfSChris Lattner if (NumWarnings) 853198cb4dfSChris Lattner OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s"); 854198cb4dfSChris Lattner if (NumWarnings && NumErrors) 855198cb4dfSChris Lattner OS << " and "; 856198cb4dfSChris Lattner if (NumErrors) 857198cb4dfSChris Lattner OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s"); 858198cb4dfSChris Lattner if (NumWarnings || NumErrors) 859198cb4dfSChris Lattner OS << " generated.\n"; 860198cb4dfSChris Lattner } 8614f2bc55dSDaniel Dunbar 862aed46fcbSDaniel Dunbar if (getFrontendOpts().ShowStats && hasFileManager()) { 8634f2bc55dSDaniel Dunbar getFileManager().PrintStats(); 8644f2bc55dSDaniel Dunbar OS << "\n"; 8654f2bc55dSDaniel Dunbar } 8664f2bc55dSDaniel Dunbar 867bc467933SArgyrios Kyrtzidis return !getDiagnostics().getClient()->getNumErrors(); 8684f2bc55dSDaniel Dunbar } 8694f2bc55dSDaniel Dunbar 870faeb1d46SDouglas Gregor /// \brief Determine the appropriate source input kind based on language 871faeb1d46SDouglas Gregor /// options. 872faeb1d46SDouglas Gregor static InputKind getSourceInputKindFromOptions(const LangOptions &LangOpts) { 873faeb1d46SDouglas Gregor if (LangOpts.OpenCL) 874faeb1d46SDouglas Gregor return IK_OpenCL; 875faeb1d46SDouglas Gregor if (LangOpts.CUDA) 876faeb1d46SDouglas Gregor return IK_CUDA; 877faeb1d46SDouglas Gregor if (LangOpts.ObjC1) 878faeb1d46SDouglas Gregor return LangOpts.CPlusPlus? IK_ObjCXX : IK_ObjC; 879faeb1d46SDouglas Gregor return LangOpts.CPlusPlus? IK_CXX : IK_C; 880faeb1d46SDouglas Gregor } 881faeb1d46SDouglas Gregor 882514b636aSDouglas Gregor /// \brief Compile a module file for the given module, using the options 883b797d59fSBen Langmuir /// provided by the importing compiler instance. Returns true if the module 884b797d59fSBen Langmuir /// was built without errors. 885b797d59fSBen Langmuir static bool compileModuleImpl(CompilerInstance &ImportingInstance, 886af8f0263SDouglas Gregor SourceLocation ImportLoc, 887de3ef502SDouglas Gregor Module *Module, 8886dc57927SDouglas Gregor StringRef ModuleFileName) { 889514b636aSDouglas Gregor ModuleMap &ModMap 890514b636aSDouglas Gregor = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap(); 891514b636aSDouglas Gregor 892faeb1d46SDouglas Gregor // Construct a compiler invocation for creating this module. 893c95d8192SDylan Noblesmith IntrusiveRefCntPtr<CompilerInvocation> Invocation 894faeb1d46SDouglas Gregor (new CompilerInvocation(ImportingInstance.getInvocation())); 89544bf68d8SDouglas Gregor 896f545f67dSDouglas Gregor PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 897f545f67dSDouglas Gregor 89844bf68d8SDouglas Gregor // For any options that aren't intended to affect how a module is built, 89944bf68d8SDouglas Gregor // reset them to their default values. 9008cf47df7STed Kremenek Invocation->getLangOpts()->resetNonModularOptions(); 901f545f67dSDouglas Gregor PPOpts.resetNonModularOptions(); 90244bf68d8SDouglas Gregor 9035dc3899cSDouglas Gregor // Remove any macro definitions that are explicitly ignored by the module. 9045dc3899cSDouglas Gregor // They aren't supposed to affect how the module is built anyway. 9055dc3899cSDouglas Gregor const HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts(); 906bbdd7640SBenjamin Kramer PPOpts.Macros.erase( 907bbdd7640SBenjamin Kramer std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(), 908bbdd7640SBenjamin Kramer [&HSOpts](const std::pair<std::string, bool> &def) { 909bbdd7640SBenjamin Kramer StringRef MacroDef = def.first; 910bbdd7640SBenjamin Kramer return HSOpts.ModulesIgnoreMacros.count(MacroDef.split('=').first) > 0; 911bbdd7640SBenjamin Kramer }), 9125dc3899cSDouglas Gregor PPOpts.Macros.end()); 9135dc3899cSDouglas Gregor 9147d106e42SDouglas Gregor // Note the name of the module we're building. 9156dc57927SDouglas Gregor Invocation->getLangOpts()->CurrentModule = Module->getTopLevelModuleName(); 9167d106e42SDouglas Gregor 9177a626570SDouglas Gregor // Make sure that the failed-module structure has been allocated in 9187a626570SDouglas Gregor // the importing instance, and propagate the pointer to the newly-created 9197a626570SDouglas Gregor // instance. 9207a626570SDouglas Gregor PreprocessorOptions &ImportingPPOpts 9217a626570SDouglas Gregor = ImportingInstance.getInvocation().getPreprocessorOpts(); 9227a626570SDouglas Gregor if (!ImportingPPOpts.FailedModules) 9237a626570SDouglas Gregor ImportingPPOpts.FailedModules = new PreprocessorOptions::FailedModulesSet; 9247a626570SDouglas Gregor PPOpts.FailedModules = ImportingPPOpts.FailedModules; 9257a626570SDouglas Gregor 926514b636aSDouglas Gregor // If there is a module map file, build the module using the module map. 927514b636aSDouglas Gregor // Set up the inputs/outputs so that we build the module from its umbrella 928514b636aSDouglas Gregor // header. 929514b636aSDouglas Gregor FrontendOptions &FrontendOpts = Invocation->getFrontendOpts(); 930514b636aSDouglas Gregor FrontendOpts.OutputFile = ModuleFileName.str(); 931514b636aSDouglas Gregor FrontendOpts.DisableFree = false; 932c1bbec85SDouglas Gregor FrontendOpts.GenerateGlobalModuleIndex = false; 933e75ee0f0SRichard Smith FrontendOpts.BuildingImplicitModule = true; 934514b636aSDouglas Gregor FrontendOpts.Inputs.clear(); 935f545f67dSDouglas Gregor InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts()); 936f545f67dSDouglas Gregor 937f545f67dSDouglas Gregor // Don't free the remapped file buffers; they are owned by our caller. 938f545f67dSDouglas Gregor PPOpts.RetainRemappedFileBuffers = true; 939514b636aSDouglas Gregor 940514b636aSDouglas Gregor Invocation->getDiagnosticOpts().VerifyDiagnostics = 0; 941514b636aSDouglas Gregor assert(ImportingInstance.getInvocation().getModuleHash() == 942514b636aSDouglas Gregor Invocation->getModuleHash() && "Module hash mismatch!"); 943514b636aSDouglas Gregor 944514b636aSDouglas Gregor // Construct a compiler instance that will be used to actually create the 945514b636aSDouglas Gregor // module. 946bb165fb0SAdrian Prantl CompilerInstance Instance(ImportingInstance.getPCHContainerOperations(), 947bb165fb0SAdrian Prantl /*BuildingModule=*/true); 948514b636aSDouglas Gregor Instance.setInvocation(&*Invocation); 9496b930967SDouglas Gregor 9506b930967SDouglas Gregor Instance.createDiagnostics(new ForwardingDiagnosticConsumer( 9516b930967SDouglas Gregor ImportingInstance.getDiagnosticClient()), 95230071ceaSDouglas Gregor /*ShouldOwnClient=*/true); 953514b636aSDouglas Gregor 954c8130a74SBen Langmuir Instance.setVirtualFileSystem(&ImportingInstance.getVirtualFileSystem()); 955c8130a74SBen Langmuir 95663365431SDouglas Gregor // Note that this module is part of the module build stack, so that we 957af8f0263SDouglas Gregor // can detect cycles in the module graph. 958d066d4c8SBen Langmuir Instance.setFileManager(&ImportingInstance.getFileManager()); 959af8f0263SDouglas Gregor Instance.createSourceManager(Instance.getFileManager()); 960af8f0263SDouglas Gregor SourceManager &SourceMgr = Instance.getSourceManager(); 96163365431SDouglas Gregor SourceMgr.setModuleBuildStack( 96263365431SDouglas Gregor ImportingInstance.getSourceManager().getModuleBuildStack()); 96363365431SDouglas Gregor SourceMgr.pushModuleBuildStack(Module->getTopLevelModuleName(), 964af8f0263SDouglas Gregor FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager())); 965af8f0263SDouglas Gregor 96686d1259cSJustin Bogner // If we're collecting module dependencies, we need to share a collector 96738c1e6d3SRichard Smith // between all of the module CompilerInstances. Other than that, we don't 96838c1e6d3SRichard Smith // want to produce any dependency output from the module build. 96986d1259cSJustin Bogner Instance.setModuleDepCollector(ImportingInstance.getModuleDepCollector()); 97038c1e6d3SRichard Smith Invocation->getDependencyOutputOpts() = DependencyOutputOptions(); 97186d1259cSJustin Bogner 9721f76c4e8SManuel Klimek // Get or create the module map that we'll use to build this module. 9731f76c4e8SManuel Klimek std::string InferredModuleMapContent; 9741f76c4e8SManuel Klimek if (const FileEntry *ModuleMapFile = 9751f76c4e8SManuel Klimek ModMap.getContainingModuleMapFile(Module)) { 9761f76c4e8SManuel Klimek // Use the module map where this module resides. 9773204b152SBenjamin Kramer FrontendOpts.Inputs.emplace_back(ModuleMapFile->getName(), IK); 9781f76c4e8SManuel Klimek } else { 9792b63d15fSRichard Smith SmallString<128> FakeModuleMapFile(Module->Directory->getName()); 9802b63d15fSRichard Smith llvm::sys::path::append(FakeModuleMapFile, "__inferred_module.map"); 9813204b152SBenjamin Kramer FrontendOpts.Inputs.emplace_back(FakeModuleMapFile, IK); 9822b63d15fSRichard Smith 9831f76c4e8SManuel Klimek llvm::raw_string_ostream OS(InferredModuleMapContent); 9841f76c4e8SManuel Klimek Module->print(OS); 9851f76c4e8SManuel Klimek OS.flush(); 9861f76c4e8SManuel Klimek 987d87f8d76SRafael Espindola std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer = 9881f76c4e8SManuel Klimek llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent); 9891f76c4e8SManuel Klimek ModuleMapFile = Instance.getFileManager().getVirtualFile( 9902b63d15fSRichard Smith FakeModuleMapFile, InferredModuleMapContent.size(), 0); 99149cc3181SDavid Blaikie SourceMgr.overrideFileContents(ModuleMapFile, std::move(ModuleMapBuffer)); 9921f76c4e8SManuel Klimek } 993af8f0263SDouglas Gregor 9949d6448b1SBen Langmuir // Construct a module-generating action. Passing through the module map is 995beee15e7SBen Langmuir // safe because the FileManager is shared between the compiler instances. 9969d6448b1SBen Langmuir GenerateModuleAction CreateModuleAction( 9979d6448b1SBen Langmuir ModMap.getModuleMapFileForUniquing(Module), Module->IsSystem); 998514b636aSDouglas Gregor 99999891da7SRichard Smith ImportingInstance.getDiagnostics().Report(ImportLoc, 100099891da7SRichard Smith diag::remark_module_build) 100199891da7SRichard Smith << Module->Name << ModuleFileName; 100299891da7SRichard Smith 1003514b636aSDouglas Gregor // Execute the action to actually build the module in-place. Use a separate 1004514b636aSDouglas Gregor // thread so that we get a stack large enough. 1005514b636aSDouglas Gregor const unsigned ThreadStackSize = 8 << 20; 1006514b636aSDouglas Gregor llvm::CrashRecoveryContext CRC; 1007841f1c78SRichard Smith CRC.RunSafelyOnThread([&]() { Instance.ExecuteAction(CreateModuleAction); }, 1008841f1c78SRichard Smith ThreadStackSize); 10096b930967SDouglas Gregor 101099891da7SRichard Smith ImportingInstance.getDiagnostics().Report(ImportLoc, 101199891da7SRichard Smith diag::remark_module_build_done) 101299891da7SRichard Smith << Module->Name; 101399891da7SRichard Smith 1014f545f67dSDouglas Gregor // Delete the temporary module map file. 1015f545f67dSDouglas Gregor // FIXME: Even though we're executing under crash protection, it would still 1016f545f67dSDouglas Gregor // be nice to do this with RemoveFileOnSignal when we can. However, that 1017f545f67dSDouglas Gregor // doesn't make sense for all clients, so clean this up manually. 101813afbf42SBenjamin Kramer Instance.clearOutputFiles(/*EraseFiles=*/true); 10195e306b12SDouglas Gregor 10205e306b12SDouglas Gregor // We've rebuilt a module. If we're allowed to generate or update the global 10215e306b12SDouglas Gregor // module index, record that fact in the importing compiler instance. 1022c1bbec85SDouglas Gregor if (ImportingInstance.getFrontendOpts().GenerateGlobalModuleIndex) { 10235e306b12SDouglas Gregor ImportingInstance.setBuildGlobalModuleIndex(true); 10245e306b12SDouglas Gregor } 1025b797d59fSBen Langmuir 1026b797d59fSBen Langmuir return !Instance.getDiagnostics().hasErrorOccurred(); 1027faeb1d46SDouglas Gregor } 1028faeb1d46SDouglas Gregor 1029dbdc0368SBen Langmuir static bool compileAndLoadModule(CompilerInstance &ImportingInstance, 10304382fe74SArgyrios Kyrtzidis SourceLocation ImportLoc, 1031b797d59fSBen Langmuir SourceLocation ModuleNameLoc, Module *Module, 10324382fe74SArgyrios Kyrtzidis StringRef ModuleFileName) { 1033d213aab7SBen Langmuir DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics(); 1034d213aab7SBen Langmuir 1035b797d59fSBen Langmuir auto diagnoseBuildFailure = [&] { 1036d213aab7SBen Langmuir Diags.Report(ModuleNameLoc, diag::err_module_not_built) 1037b797d59fSBen Langmuir << Module->Name << SourceRange(ImportLoc, ModuleNameLoc); 1038b797d59fSBen Langmuir }; 1039b797d59fSBen Langmuir 10404382fe74SArgyrios Kyrtzidis // FIXME: have LockFileManager return an error_code so that we can 10414382fe74SArgyrios Kyrtzidis // avoid the mkdir when the directory already exists. 10424382fe74SArgyrios Kyrtzidis StringRef Dir = llvm::sys::path::parent_path(ModuleFileName); 10434382fe74SArgyrios Kyrtzidis llvm::sys::fs::create_directories(Dir); 10444382fe74SArgyrios Kyrtzidis 10454382fe74SArgyrios Kyrtzidis while (1) { 1046dbdc0368SBen Langmuir unsigned ModuleLoadCapabilities = ASTReader::ARR_Missing; 10474382fe74SArgyrios Kyrtzidis llvm::LockFileManager Locked(ModuleFileName); 10484382fe74SArgyrios Kyrtzidis switch (Locked) { 10494382fe74SArgyrios Kyrtzidis case llvm::LockFileManager::LFS_Error: 1050d213aab7SBen Langmuir Diags.Report(ModuleNameLoc, diag::err_module_lock_failure) 1051d213aab7SBen Langmuir << Module->Name; 1052dbdc0368SBen Langmuir return false; 10534382fe74SArgyrios Kyrtzidis 10544382fe74SArgyrios Kyrtzidis case llvm::LockFileManager::LFS_Owned: 1055dbdc0368SBen Langmuir // We're responsible for building the module ourselves. 1056b797d59fSBen Langmuir if (!compileModuleImpl(ImportingInstance, ModuleNameLoc, Module, 1057b797d59fSBen Langmuir ModuleFileName)) { 1058b797d59fSBen Langmuir diagnoseBuildFailure(); 1059b797d59fSBen Langmuir return false; 1060b797d59fSBen Langmuir } 10614382fe74SArgyrios Kyrtzidis break; 10624382fe74SArgyrios Kyrtzidis 10634382fe74SArgyrios Kyrtzidis case llvm::LockFileManager::LFS_Shared: 10644382fe74SArgyrios Kyrtzidis // Someone else is responsible for building the module. Wait for them to 10654382fe74SArgyrios Kyrtzidis // finish. 10661daf4801SBen Langmuir switch (Locked.waitForUnlock()) { 10671daf4801SBen Langmuir case llvm::LockFileManager::Res_Success: 1068dbdc0368SBen Langmuir ModuleLoadCapabilities |= ASTReader::ARR_OutOfDate; 1069dbdc0368SBen Langmuir break; 10701daf4801SBen Langmuir case llvm::LockFileManager::Res_OwnerDied: 10711daf4801SBen Langmuir continue; // try again to get the lock. 10721daf4801SBen Langmuir case llvm::LockFileManager::Res_Timeout: 10731daf4801SBen Langmuir Diags.Report(ModuleNameLoc, diag::err_module_lock_timeout) 10741daf4801SBen Langmuir << Module->Name; 10751daf4801SBen Langmuir // Clear the lock file so that future invokations can make progress. 10761daf4801SBen Langmuir Locked.unsafeRemoveLockFile(); 10771daf4801SBen Langmuir return false; 10781daf4801SBen Langmuir } 10791daf4801SBen Langmuir break; 10804382fe74SArgyrios Kyrtzidis } 10814382fe74SArgyrios Kyrtzidis 1082dbdc0368SBen Langmuir // Try to read the module file, now that we've compiled it. 1083dbdc0368SBen Langmuir ASTReader::ASTReadResult ReadResult = 1084dbdc0368SBen Langmuir ImportingInstance.getModuleManager()->ReadAST( 1085e842a474SRichard Smith ModuleFileName, serialization::MK_ImplicitModule, ImportLoc, 1086dbdc0368SBen Langmuir ModuleLoadCapabilities); 1087dbdc0368SBen Langmuir 1088dbdc0368SBen Langmuir if (ReadResult == ASTReader::OutOfDate && 1089dbdc0368SBen Langmuir Locked == llvm::LockFileManager::LFS_Shared) { 1090dbdc0368SBen Langmuir // The module may be out of date in the presence of file system races, 1091dbdc0368SBen Langmuir // or if one of its imports depends on header search paths that are not 1092dbdc0368SBen Langmuir // consistent with this ImportingInstance. Try again... 1093dbdc0368SBen Langmuir continue; 1094dbdc0368SBen Langmuir } else if (ReadResult == ASTReader::Missing) { 1095b797d59fSBen Langmuir diagnoseBuildFailure(); 1096d213aab7SBen Langmuir } else if (ReadResult != ASTReader::Success && 1097d213aab7SBen Langmuir !Diags.hasErrorOccurred()) { 1098d213aab7SBen Langmuir // The ASTReader didn't diagnose the error, so conservatively report it. 1099d213aab7SBen Langmuir diagnoseBuildFailure(); 1100dbdc0368SBen Langmuir } 1101dbdc0368SBen Langmuir return ReadResult == ASTReader::Success; 11024382fe74SArgyrios Kyrtzidis } 11034382fe74SArgyrios Kyrtzidis } 11044382fe74SArgyrios Kyrtzidis 110535b13eceSDouglas Gregor /// \brief Diagnose differences between the current definition of the given 110635b13eceSDouglas Gregor /// configuration macro and the definition provided on the command line. 110735b13eceSDouglas Gregor static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro, 110835b13eceSDouglas Gregor Module *Mod, SourceLocation ImportLoc) { 110935b13eceSDouglas Gregor IdentifierInfo *Id = PP.getIdentifierInfo(ConfigMacro); 111035b13eceSDouglas Gregor SourceManager &SourceMgr = PP.getSourceManager(); 111135b13eceSDouglas Gregor 111235b13eceSDouglas Gregor // If this identifier has never had a macro definition, then it could 111335b13eceSDouglas Gregor // not have changed. 111435b13eceSDouglas Gregor if (!Id->hadMacroDefinition()) 111535b13eceSDouglas Gregor return; 111620e883e5SRichard Smith auto *LatestLocalMD = PP.getLocalMacroDirectiveHistory(Id); 111735b13eceSDouglas Gregor 111820e883e5SRichard Smith // Find the macro definition from the command line. 111920e883e5SRichard Smith MacroInfo *CmdLineDefinition = nullptr; 112020e883e5SRichard Smith for (auto *MD = LatestLocalMD; MD; MD = MD->getPrevious()) { 112135b13eceSDouglas Gregor // We only care about the predefines buffer. 112220e883e5SRichard Smith FileID FID = SourceMgr.getFileID(MD->getLocation()); 112320e883e5SRichard Smith if (FID.isInvalid() || FID != PP.getPredefinesFileID()) 112435b13eceSDouglas Gregor continue; 112520e883e5SRichard Smith if (auto *DMD = dyn_cast<DefMacroDirective>(MD)) 112620e883e5SRichard Smith CmdLineDefinition = DMD->getMacroInfo(); 112720e883e5SRichard Smith break; 112820e883e5SRichard Smith } 112935b13eceSDouglas Gregor 113020e883e5SRichard Smith auto *CurrentDefinition = PP.getMacroInfo(Id); 113120e883e5SRichard Smith if (CurrentDefinition == CmdLineDefinition) { 113220e883e5SRichard Smith // Macro matches. Nothing to do. 113320e883e5SRichard Smith } else if (!CurrentDefinition) { 113435b13eceSDouglas Gregor // This macro was defined on the command line, then #undef'd later. 113535b13eceSDouglas Gregor // Complain. 113635b13eceSDouglas Gregor PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 113735b13eceSDouglas Gregor << true << ConfigMacro << Mod->getFullModuleName(); 113820e883e5SRichard Smith auto LatestDef = LatestLocalMD->getDefinition(); 113920e883e5SRichard Smith assert(LatestDef.isUndefined() && 114020e883e5SRichard Smith "predefined macro went away with no #undef?"); 1141b6210dffSArgyrios Kyrtzidis PP.Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here) 114235b13eceSDouglas Gregor << true; 114335b13eceSDouglas Gregor return; 114420e883e5SRichard Smith } else if (!CmdLineDefinition) { 114520e883e5SRichard Smith // There was no definition for this macro in the predefines buffer, 114620e883e5SRichard Smith // but there was a local definition. Complain. 114735b13eceSDouglas Gregor PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 114835b13eceSDouglas Gregor << false << ConfigMacro << Mod->getFullModuleName(); 114920e883e5SRichard Smith PP.Diag(CurrentDefinition->getDefinitionLoc(), 115020e883e5SRichard Smith diag::note_module_def_undef_here) 115135b13eceSDouglas Gregor << false; 115220e883e5SRichard Smith } else if (!CurrentDefinition->isIdenticalTo(*CmdLineDefinition, PP, 115320e883e5SRichard Smith /*Syntactically=*/true)) { 115435b13eceSDouglas Gregor // The macro definitions differ. 115535b13eceSDouglas Gregor PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 115635b13eceSDouglas Gregor << false << ConfigMacro << Mod->getFullModuleName(); 115720e883e5SRichard Smith PP.Diag(CurrentDefinition->getDefinitionLoc(), 115820e883e5SRichard Smith diag::note_module_def_undef_here) 115935b13eceSDouglas Gregor << false; 116035b13eceSDouglas Gregor } 116120e883e5SRichard Smith } 116235b13eceSDouglas Gregor 1163527b1c95SDouglas Gregor /// \brief Write a new timestamp file with the given path. 1164527b1c95SDouglas Gregor static void writeTimestampFile(StringRef TimestampFile) { 1165dae941a6SRafael Espindola std::error_code EC; 1166dae941a6SRafael Espindola llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::F_None); 1167527b1c95SDouglas Gregor } 1168527b1c95SDouglas Gregor 1169527b1c95SDouglas Gregor /// \brief Prune the module cache of modules that haven't been accessed in 1170527b1c95SDouglas Gregor /// a long time. 1171527b1c95SDouglas Gregor static void pruneModuleCache(const HeaderSearchOptions &HSOpts) { 1172527b1c95SDouglas Gregor struct stat StatBuf; 1173527b1c95SDouglas Gregor llvm::SmallString<128> TimestampFile; 1174527b1c95SDouglas Gregor TimestampFile = HSOpts.ModuleCachePath; 11753938f0c7SRichard Smith assert(!TimestampFile.empty()); 1176527b1c95SDouglas Gregor llvm::sys::path::append(TimestampFile, "modules.timestamp"); 1177527b1c95SDouglas Gregor 1178527b1c95SDouglas Gregor // Try to stat() the timestamp file. 1179527b1c95SDouglas Gregor if (::stat(TimestampFile.c_str(), &StatBuf)) { 1180527b1c95SDouglas Gregor // If the timestamp file wasn't there, create one now. 1181527b1c95SDouglas Gregor if (errno == ENOENT) { 1182527b1c95SDouglas Gregor writeTimestampFile(TimestampFile); 1183527b1c95SDouglas Gregor } 1184527b1c95SDouglas Gregor return; 1185527b1c95SDouglas Gregor } 1186527b1c95SDouglas Gregor 1187527b1c95SDouglas Gregor // Check whether the time stamp is older than our pruning interval. 1188527b1c95SDouglas Gregor // If not, do nothing. 1189527b1c95SDouglas Gregor time_t TimeStampModTime = StatBuf.st_mtime; 119049a2790fSCraig Topper time_t CurrentTime = time(nullptr); 1191dbcf5037SBenjamin Kramer if (CurrentTime - TimeStampModTime <= time_t(HSOpts.ModuleCachePruneInterval)) 1192527b1c95SDouglas Gregor return; 1193527b1c95SDouglas Gregor 1194527b1c95SDouglas Gregor // Write a new timestamp file so that nobody else attempts to prune. 1195527b1c95SDouglas Gregor // There is a benign race condition here, if two Clang instances happen to 1196527b1c95SDouglas Gregor // notice at the same time that the timestamp is out-of-date. 1197527b1c95SDouglas Gregor writeTimestampFile(TimestampFile); 1198527b1c95SDouglas Gregor 1199527b1c95SDouglas Gregor // Walk the entire module cache, looking for unused module files and module 1200527b1c95SDouglas Gregor // indices. 1201c080917eSRafael Espindola std::error_code EC; 1202527b1c95SDouglas Gregor SmallString<128> ModuleCachePathNative; 1203527b1c95SDouglas Gregor llvm::sys::path::native(HSOpts.ModuleCachePath, ModuleCachePathNative); 120492e1b62dSYaron Keren for (llvm::sys::fs::directory_iterator Dir(ModuleCachePathNative, EC), DirEnd; 1205527b1c95SDouglas Gregor Dir != DirEnd && !EC; Dir.increment(EC)) { 1206527b1c95SDouglas Gregor // If we don't have a directory, there's nothing to look into. 1207a07f720aSRafael Espindola if (!llvm::sys::fs::is_directory(Dir->path())) 1208527b1c95SDouglas Gregor continue; 1209527b1c95SDouglas Gregor 1210527b1c95SDouglas Gregor // Walk all of the files within this directory. 1211527b1c95SDouglas Gregor for (llvm::sys::fs::directory_iterator File(Dir->path(), EC), FileEnd; 1212527b1c95SDouglas Gregor File != FileEnd && !EC; File.increment(EC)) { 1213527b1c95SDouglas Gregor // We only care about module and global module index files. 1214f430da4dSDmitri Gribenko StringRef Extension = llvm::sys::path::extension(File->path()); 1215f430da4dSDmitri Gribenko if (Extension != ".pcm" && Extension != ".timestamp" && 1216f430da4dSDmitri Gribenko llvm::sys::path::filename(File->path()) != "modules.idx") 1217527b1c95SDouglas Gregor continue; 1218527b1c95SDouglas Gregor 1219527b1c95SDouglas Gregor // Look at this file. If we can't stat it, there's nothing interesting 1220527b1c95SDouglas Gregor // there. 1221f430da4dSDmitri Gribenko if (::stat(File->path().c_str(), &StatBuf)) 1222527b1c95SDouglas Gregor continue; 1223527b1c95SDouglas Gregor 1224527b1c95SDouglas Gregor // If the file has been used recently enough, leave it there. 1225527b1c95SDouglas Gregor time_t FileAccessTime = StatBuf.st_atime; 1226dbcf5037SBenjamin Kramer if (CurrentTime - FileAccessTime <= 1227dbcf5037SBenjamin Kramer time_t(HSOpts.ModuleCachePruneAfter)) { 1228527b1c95SDouglas Gregor continue; 1229527b1c95SDouglas Gregor } 1230527b1c95SDouglas Gregor 1231527b1c95SDouglas Gregor // Remove the file. 1232f430da4dSDmitri Gribenko llvm::sys::fs::remove(File->path()); 1233f430da4dSDmitri Gribenko 1234f430da4dSDmitri Gribenko // Remove the timestamp file. 1235f430da4dSDmitri Gribenko std::string TimpestampFilename = File->path() + ".timestamp"; 1236f430da4dSDmitri Gribenko llvm::sys::fs::remove(TimpestampFilename); 1237527b1c95SDouglas Gregor } 1238527b1c95SDouglas Gregor 1239527b1c95SDouglas Gregor // If we removed all of the files in the directory, remove the directory 1240527b1c95SDouglas Gregor // itself. 1241f430da4dSDmitri Gribenko if (llvm::sys::fs::directory_iterator(Dir->path(), EC) == 1242f430da4dSDmitri Gribenko llvm::sys::fs::directory_iterator() && !EC) 12432a008784SRafael Espindola llvm::sys::fs::remove(Dir->path()); 1244527b1c95SDouglas Gregor } 1245527b1c95SDouglas Gregor } 1246527b1c95SDouglas Gregor 12472255f2ceSJohn Thompson void CompilerInstance::createModuleManager() { 12482255f2ceSJohn Thompson if (!ModuleManager) { 12492255f2ceSJohn Thompson if (!hasASTContext()) 12502255f2ceSJohn Thompson createASTContext(); 12512255f2ceSJohn Thompson 1252580dd296SChandler Carruth // If we're implicitly building modules but not currently recursively 1253580dd296SChandler Carruth // building a module, check whether we need to prune the module cache. 12543938f0c7SRichard Smith if (getSourceManager().getModuleBuildStack().empty() && 12553938f0c7SRichard Smith !getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty() && 12562255f2ceSJohn Thompson getHeaderSearchOpts().ModuleCachePruneInterval > 0 && 12572255f2ceSJohn Thompson getHeaderSearchOpts().ModuleCachePruneAfter > 0) { 12582255f2ceSJohn Thompson pruneModuleCache(getHeaderSearchOpts()); 12592255f2ceSJohn Thompson } 12602255f2ceSJohn Thompson 12612255f2ceSJohn Thompson HeaderSearchOptions &HSOpts = getHeaderSearchOpts(); 12622255f2ceSJohn Thompson std::string Sysroot = HSOpts.Sysroot; 12632255f2ceSJohn Thompson const PreprocessorOptions &PPOpts = getPreprocessorOpts(); 1264ce18a187SRichard Smith std::unique_ptr<llvm::Timer> ReadTimer; 1265ce18a187SRichard Smith if (FrontendTimerGroup) 1266ce18a187SRichard Smith ReadTimer = llvm::make_unique<llvm::Timer>("Reading modules", 1267ce18a187SRichard Smith *FrontendTimerGroup); 1268bb165fb0SAdrian Prantl ModuleManager = new ASTReader( 1269293534b1SRichard Smith getPreprocessor(), getASTContext(), getPCHContainerReader(), 1270bb165fb0SAdrian Prantl Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation, 12712255f2ceSJohn Thompson /*AllowASTWithCompilerErrors=*/false, 12722255f2ceSJohn Thompson /*AllowConfigurationMismatch=*/false, 12732255f2ceSJohn Thompson HSOpts.ModulesValidateSystemHeaders, 1274ce18a187SRichard Smith getFrontendOpts().UseGlobalModuleIndex, 1275ce18a187SRichard Smith std::move(ReadTimer)); 12762255f2ceSJohn Thompson if (hasASTConsumer()) { 12772255f2ceSJohn Thompson ModuleManager->setDeserializationListener( 12782255f2ceSJohn Thompson getASTConsumer().GetASTDeserializationListener()); 12792255f2ceSJohn Thompson getASTContext().setASTMutationListener( 12802255f2ceSJohn Thompson getASTConsumer().GetASTMutationListener()); 12812255f2ceSJohn Thompson } 12822255f2ceSJohn Thompson getASTContext().setExternalSource(ModuleManager); 12832255f2ceSJohn Thompson if (hasSema()) 12842255f2ceSJohn Thompson ModuleManager->InitializeSema(getSema()); 1285293534b1SRichard Smith if (hasASTConsumer()) 12862255f2ceSJohn Thompson ModuleManager->StartTranslationUnit(&getASTConsumer()); 128703f7e611SRichard Smith 128803f7e611SRichard Smith if (TheDependencyFileGenerator) 128903f7e611SRichard Smith TheDependencyFileGenerator->AttachToASTReader(*ModuleManager); 129003f7e611SRichard Smith if (ModuleDepCollector) 129103f7e611SRichard Smith ModuleDepCollector->attachToASTReader(*ModuleManager); 129203f7e611SRichard Smith for (auto &Listener : DependencyCollectors) 129303f7e611SRichard Smith Listener->attachToASTReader(*ModuleManager); 12942255f2ceSJohn Thompson } 12952255f2ceSJohn Thompson } 12962255f2ceSJohn Thompson 1297d4b230b3SRichard Smith bool CompilerInstance::loadModuleFile(StringRef FileName) { 1298ce18a187SRichard Smith llvm::Timer Timer; 1299ce18a187SRichard Smith if (FrontendTimerGroup) 1300ce18a187SRichard Smith Timer.init("Preloading " + FileName.str(), *FrontendTimerGroup); 1301ce18a187SRichard Smith llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr); 1302ce18a187SRichard Smith 1303d4b230b3SRichard Smith // Helper to recursively read the module names for all modules we're adding. 1304d4b230b3SRichard Smith // We mark these as known and redirect any attempt to load that module to 1305d4b230b3SRichard Smith // the files we were handed. 1306d4b230b3SRichard Smith struct ReadModuleNames : ASTReaderListener { 1307d4b230b3SRichard Smith CompilerInstance &CI; 13080f99d6a4SRichard Smith llvm::SmallVector<IdentifierInfo*, 8> LoadedModules; 1309e842a474SRichard Smith 13100f99d6a4SRichard Smith ReadModuleNames(CompilerInstance &CI) : CI(CI) {} 1311d4b230b3SRichard Smith 1312d4b230b3SRichard Smith void ReadModuleName(StringRef ModuleName) override { 13130f99d6a4SRichard Smith LoadedModules.push_back( 13140f99d6a4SRichard Smith CI.getPreprocessor().getIdentifierInfo(ModuleName)); 1315d4b230b3SRichard Smith } 13160f99d6a4SRichard Smith 13170f99d6a4SRichard Smith void registerAll() { 13180f99d6a4SRichard Smith for (auto *II : LoadedModules) { 13190f99d6a4SRichard Smith CI.KnownModules[II] = CI.getPreprocessor() 13200f99d6a4SRichard Smith .getHeaderSearchInfo() 13210f99d6a4SRichard Smith .getModuleMap() 13220f99d6a4SRichard Smith .findModule(II->getName()); 13230f99d6a4SRichard Smith } 13240f99d6a4SRichard Smith LoadedModules.clear(); 13250f99d6a4SRichard Smith } 13260f99d6a4SRichard Smith }; 1327d4b230b3SRichard Smith 13287f330cdbSRichard Smith // If we don't already have an ASTReader, create one now. 13297f330cdbSRichard Smith if (!ModuleManager) 13307f330cdbSRichard Smith createModuleManager(); 13317f330cdbSRichard Smith 13320f99d6a4SRichard Smith auto Listener = llvm::make_unique<ReadModuleNames>(*this); 13330f99d6a4SRichard Smith auto &ListenerRef = *Listener; 13340f99d6a4SRichard Smith ASTReader::ListenerScope ReadModuleNamesListener(*ModuleManager, 13350f99d6a4SRichard Smith std::move(Listener)); 13367f330cdbSRichard Smith 13370f99d6a4SRichard Smith // Try to load the module file. 13380f99d6a4SRichard Smith if (ModuleManager->ReadAST(FileName, serialization::MK_ExplicitModule, 13390f99d6a4SRichard Smith SourceLocation(), ASTReader::ARR_None) 13400f99d6a4SRichard Smith != ASTReader::Success) 1341d4b230b3SRichard Smith return false; 1342d4b230b3SRichard Smith 13430f99d6a4SRichard Smith // We successfully loaded the module file; remember the set of provided 13440f99d6a4SRichard Smith // modules so that we don't try to load implicit modules for them. 13450f99d6a4SRichard Smith ListenerRef.registerAll(); 1346d4b230b3SRichard Smith return true; 1347e842a474SRichard Smith } 1348e842a474SRichard Smith 1349e842a474SRichard Smith ModuleLoadResult 13507a626570SDouglas Gregor CompilerInstance::loadModule(SourceLocation ImportLoc, 1351ff2be53fSDouglas Gregor ModuleIdPath Path, 1352bcfc7d02SDouglas Gregor Module::NameVisibilityKind Visibility, 1353bcfc7d02SDouglas Gregor bool IsInclusionDirective) { 135492304e00SRichard Smith // Determine what file we're searching from. 135592304e00SRichard Smith StringRef ModuleName = Path[0].first->getName(); 135692304e00SRichard Smith SourceLocation ModuleNameLoc = Path[0].second; 135792304e00SRichard Smith 13581805b8a4SDouglas Gregor // If we've already handled this import, just return the cached result. 13591805b8a4SDouglas Gregor // This one-element cache is important to eliminate redundant diagnostics 13601805b8a4SDouglas Gregor // when both the preprocessor and parser see the same import declaration. 13618b563665SYaron Keren if (ImportLoc.isValid() && LastModuleImportLoc == ImportLoc) { 1362ff2be53fSDouglas Gregor // Make the named module visible. 1363b537a3a6SBen Langmuir if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule && 1364b537a3a6SBen Langmuir ModuleName != getLangOpts().ImplementationOfModule) 1365125df058SArgyrios Kyrtzidis ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility, 1366a7e2cc68SRichard Smith ImportLoc); 136769021974SDouglas Gregor return LastModuleImportResult; 1368ff2be53fSDouglas Gregor } 13691805b8a4SDouglas Gregor 137049a2790fSCraig Topper clang::Module *Module = nullptr; 13715196bc6bSDouglas Gregor 13725196bc6bSDouglas Gregor // If we don't already have information on this module, load the module now. 1373de3ef502SDouglas Gregor llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known 137469021974SDouglas Gregor = KnownModules.find(Path[0].first); 13752537a364SDouglas Gregor if (Known != KnownModules.end()) { 13762537a364SDouglas Gregor // Retrieve the cached top-level module. 13772537a364SDouglas Gregor Module = Known->second; 1378b537a3a6SBen Langmuir } else if (ModuleName == getLangOpts().CurrentModule || 1379b537a3a6SBen Langmuir ModuleName == getLangOpts().ImplementationOfModule) { 13802537a364SDouglas Gregor // This is the module we're building. 1381527040e0SBen Langmuir Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); 13822537a364SDouglas Gregor Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; 13832537a364SDouglas Gregor } else { 13845196bc6bSDouglas Gregor // Search for a module with the given name. 1385279a6c37SDouglas Gregor Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); 13869eb229bfSBen Langmuir if (!Module) { 13879eb229bfSBen Langmuir getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found) 13889eb229bfSBen Langmuir << ModuleName 13899eb229bfSBen Langmuir << SourceRange(ImportLoc, ModuleNameLoc); 13909eb229bfSBen Langmuir ModuleBuildFailed = true; 13919eb229bfSBen Langmuir return ModuleLoadResult(); 13929eb229bfSBen Langmuir } 13939eb229bfSBen Langmuir 1394d520a250SRichard Smith std::string ModuleFileName = 139586cc8290SRichard Smith PP->getHeaderSearchInfo().getModuleFileName(Module); 1396d520a250SRichard Smith if (ModuleFileName.empty()) { 1397d2e8b04dSManuel Klimek getDiagnostics().Report(ModuleNameLoc, diag::err_module_build_disabled) 1398d2e8b04dSManuel Klimek << ModuleName; 1399d2e8b04dSManuel Klimek ModuleBuildFailed = true; 1400d2e8b04dSManuel Klimek return ModuleLoadResult(); 1401d2e8b04dSManuel Klimek } 1402d4b230b3SRichard Smith 140308142534SDouglas Gregor // If we don't already have an ASTReader, create one now. 14042255f2ceSJohn Thompson if (!ModuleManager) 14052255f2ceSJohn Thompson createModuleManager(); 140608142534SDouglas Gregor 1407ce18a187SRichard Smith llvm::Timer Timer; 1408ce18a187SRichard Smith if (FrontendTimerGroup) 1409ce18a187SRichard Smith Timer.init("Loading " + ModuleFileName, *FrontendTimerGroup); 1410ce18a187SRichard Smith llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr); 1411ce18a187SRichard Smith 14127029ce1aSDouglas Gregor // Try to load the module file. 141386cc8290SRichard Smith unsigned ARRFlags = ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing; 1414e842a474SRichard Smith switch (ModuleManager->ReadAST(ModuleFileName, 141586cc8290SRichard Smith serialization::MK_ImplicitModule, 1416d4b230b3SRichard Smith ImportLoc, ARRFlags)) { 141708142534SDouglas Gregor case ASTReader::Success: 141808142534SDouglas Gregor break; 141908142534SDouglas Gregor 1420963ff2c3SEli Friedman case ASTReader::OutOfDate: 14217029ce1aSDouglas Gregor case ASTReader::Missing: { 1422963ff2c3SEli Friedman // The module file is missing or out-of-date. Build it. 14239eb229bfSBen Langmuir assert(Module && "missing module file"); 14247029ce1aSDouglas Gregor // Check whether there is a cycle in the module graph. 14257029ce1aSDouglas Gregor ModuleBuildStack ModPath = getSourceManager().getModuleBuildStack(); 14267029ce1aSDouglas Gregor ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end(); 14277029ce1aSDouglas Gregor for (; Pos != PosEnd; ++Pos) { 14287029ce1aSDouglas Gregor if (Pos->first == ModuleName) 14297029ce1aSDouglas Gregor break; 14307029ce1aSDouglas Gregor } 14317029ce1aSDouglas Gregor 14327029ce1aSDouglas Gregor if (Pos != PosEnd) { 14337029ce1aSDouglas Gregor SmallString<256> CyclePath; 14347029ce1aSDouglas Gregor for (; Pos != PosEnd; ++Pos) { 14357029ce1aSDouglas Gregor CyclePath += Pos->first; 14367029ce1aSDouglas Gregor CyclePath += " -> "; 14377029ce1aSDouglas Gregor } 14387029ce1aSDouglas Gregor CyclePath += ModuleName; 14397029ce1aSDouglas Gregor 14407029ce1aSDouglas Gregor getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle) 14417029ce1aSDouglas Gregor << ModuleName << CyclePath; 14427029ce1aSDouglas Gregor return ModuleLoadResult(); 14437029ce1aSDouglas Gregor } 14447a626570SDouglas Gregor 14457a626570SDouglas Gregor // Check whether we have already attempted to build this module (but 14467a626570SDouglas Gregor // failed). 14477a626570SDouglas Gregor if (getPreprocessorOpts().FailedModules && 14487a626570SDouglas Gregor getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) { 14497a626570SDouglas Gregor getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built) 14507a626570SDouglas Gregor << ModuleName 14517a626570SDouglas Gregor << SourceRange(ImportLoc, ModuleNameLoc); 1452c1bbec85SDouglas Gregor ModuleBuildFailed = true; 14537a626570SDouglas Gregor return ModuleLoadResult(); 14547a626570SDouglas Gregor } 14557a626570SDouglas Gregor 1456dbdc0368SBen Langmuir // Try to compile and then load the module. 1457dbdc0368SBen Langmuir if (!compileAndLoadModule(*this, ImportLoc, ModuleNameLoc, Module, 1458dbdc0368SBen Langmuir ModuleFileName)) { 1459d213aab7SBen Langmuir assert(getDiagnostics().hasErrorOccurred() && 1460d213aab7SBen Langmuir "undiagnosed error in compileAndLoadModule"); 14610f2b4635SDouglas Gregor if (getPreprocessorOpts().FailedModules) 14627a626570SDouglas Gregor getPreprocessorOpts().FailedModules->addFailed(ModuleName); 146349a2790fSCraig Topper KnownModules[Path[0].first] = nullptr; 1464c1bbec85SDouglas Gregor ModuleBuildFailed = true; 14657a626570SDouglas Gregor return ModuleLoadResult(); 1466188dbef2SDouglas Gregor } 1467188dbef2SDouglas Gregor 1468188dbef2SDouglas Gregor // Okay, we've rebuilt and now loaded the module. 1469188dbef2SDouglas Gregor break; 1470188dbef2SDouglas Gregor } 1471188dbef2SDouglas Gregor 1472c9ad5fb6SDouglas Gregor case ASTReader::VersionMismatch: 1473c9ad5fb6SDouglas Gregor case ASTReader::ConfigurationMismatch: 1474c9ad5fb6SDouglas Gregor case ASTReader::HadErrors: 1475dc9fdaf2SArgyrios Kyrtzidis ModuleLoader::HadFatalFailure = true; 14760f99d6a4SRichard Smith // FIXME: The ASTReader will already have complained, but can we shoehorn 147708142534SDouglas Gregor // that diagnostic information into a more useful form? 147849a2790fSCraig Topper KnownModules[Path[0].first] = nullptr; 14797a626570SDouglas Gregor return ModuleLoadResult(); 148008142534SDouglas Gregor 148108142534SDouglas Gregor case ASTReader::Failure: 1482dc9fdaf2SArgyrios Kyrtzidis ModuleLoader::HadFatalFailure = true; 148369021974SDouglas Gregor // Already complained, but note now that we failed. 148449a2790fSCraig Topper KnownModules[Path[0].first] = nullptr; 1485c1bbec85SDouglas Gregor ModuleBuildFailed = true; 14867a626570SDouglas Gregor return ModuleLoadResult(); 148708142534SDouglas Gregor } 148808142534SDouglas Gregor 148969021974SDouglas Gregor // Cache the result of this top-level module lookup for later. 149069021974SDouglas Gregor Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; 149169021974SDouglas Gregor } 149269021974SDouglas Gregor 149369021974SDouglas Gregor // If we never found the module, fail. 149469021974SDouglas Gregor if (!Module) 14957a626570SDouglas Gregor return ModuleLoadResult(); 149669021974SDouglas Gregor 14975196bc6bSDouglas Gregor // Verify that the rest of the module path actually corresponds to 14985196bc6bSDouglas Gregor // a submodule. 149969021974SDouglas Gregor if (Path.size() > 1) { 15005196bc6bSDouglas Gregor for (unsigned I = 1, N = Path.size(); I != N; ++I) { 15015196bc6bSDouglas Gregor StringRef Name = Path[I].first->getName(); 1502eb90e830SDouglas Gregor clang::Module *Sub = Module->findSubmodule(Name); 15035196bc6bSDouglas Gregor 1504eb90e830SDouglas Gregor if (!Sub) { 15055196bc6bSDouglas Gregor // Attempt to perform typo correction to find a module name that works. 1506f857950dSDmitri Gribenko SmallVector<StringRef, 2> Best; 15075196bc6bSDouglas Gregor unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)(); 15085196bc6bSDouglas Gregor 1509eb90e830SDouglas Gregor for (clang::Module::submodule_iterator J = Module->submodule_begin(), 1510eb90e830SDouglas Gregor JEnd = Module->submodule_end(); 1511eb44edadSMatt Beaumont-Gay J != JEnd; ++J) { 1512eb90e830SDouglas Gregor unsigned ED = Name.edit_distance((*J)->Name, 15135196bc6bSDouglas Gregor /*AllowReplacements=*/true, 15145196bc6bSDouglas Gregor BestEditDistance); 15155196bc6bSDouglas Gregor if (ED <= BestEditDistance) { 1516eb90e830SDouglas Gregor if (ED < BestEditDistance) { 15175196bc6bSDouglas Gregor Best.clear(); 1518eb90e830SDouglas Gregor BestEditDistance = ED; 1519eb90e830SDouglas Gregor } 1520eb90e830SDouglas Gregor 1521eb90e830SDouglas Gregor Best.push_back((*J)->Name); 15225196bc6bSDouglas Gregor } 15235196bc6bSDouglas Gregor } 15245196bc6bSDouglas Gregor 15255196bc6bSDouglas Gregor // If there was a clear winner, user it. 15265196bc6bSDouglas Gregor if (Best.size() == 1) { 15275196bc6bSDouglas Gregor getDiagnostics().Report(Path[I].second, 15285196bc6bSDouglas Gregor diag::err_no_submodule_suggest) 152969021974SDouglas Gregor << Path[I].first << Module->getFullModuleName() << Best[0] 15305196bc6bSDouglas Gregor << SourceRange(Path[0].second, Path[I-1].second) 15315196bc6bSDouglas Gregor << FixItHint::CreateReplacement(SourceRange(Path[I].second), 15325196bc6bSDouglas Gregor Best[0]); 1533eb90e830SDouglas Gregor 1534eb90e830SDouglas Gregor Sub = Module->findSubmodule(Best[0]); 15355196bc6bSDouglas Gregor } 15365196bc6bSDouglas Gregor } 15375196bc6bSDouglas Gregor 1538eb90e830SDouglas Gregor if (!Sub) { 15395196bc6bSDouglas Gregor // No submodule by this name. Complain, and don't look for further 15405196bc6bSDouglas Gregor // submodules. 15415196bc6bSDouglas Gregor getDiagnostics().Report(Path[I].second, diag::err_no_submodule) 154269021974SDouglas Gregor << Path[I].first << Module->getFullModuleName() 15435196bc6bSDouglas Gregor << SourceRange(Path[0].second, Path[I-1].second); 15445196bc6bSDouglas Gregor break; 15455196bc6bSDouglas Gregor } 15465196bc6bSDouglas Gregor 1547eb90e830SDouglas Gregor Module = Sub; 15485196bc6bSDouglas Gregor } 15495196bc6bSDouglas Gregor } 15505196bc6bSDouglas Gregor 1551b537a3a6SBen Langmuir // Don't make the module visible if we are in the implementation. 1552b537a3a6SBen Langmuir if (ModuleName == getLangOpts().ImplementationOfModule) 1553b537a3a6SBen Langmuir return ModuleLoadResult(Module, false); 1554b537a3a6SBen Langmuir 15552537a364SDouglas Gregor // Make the named module visible, if it's not already part of the module 15562537a364SDouglas Gregor // we are parsing. 155798a52db8SDouglas Gregor if (ModuleName != getLangOpts().CurrentModule) { 155898a52db8SDouglas Gregor if (!Module->IsFromModuleFile) { 155998a52db8SDouglas Gregor // We have an umbrella header or directory that doesn't actually include 156098a52db8SDouglas Gregor // all of the headers within the directory it covers. Complain about 156198a52db8SDouglas Gregor // this missing submodule and recover by forgetting that we ever saw 156298a52db8SDouglas Gregor // this submodule. 156398a52db8SDouglas Gregor // FIXME: Should we detect this at module load time? It seems fairly 156498a52db8SDouglas Gregor // expensive (and rare). 156598a52db8SDouglas Gregor getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule) 156698a52db8SDouglas Gregor << Module->getFullModuleName() 156798a52db8SDouglas Gregor << SourceRange(Path.front().second, Path.back().second); 156898a52db8SDouglas Gregor 156949a2790fSCraig Topper return ModuleLoadResult(nullptr, true); 157098a52db8SDouglas Gregor } 15711fb5c3a6SDouglas Gregor 15721fb5c3a6SDouglas Gregor // Check whether this module is available. 1573a3feee2aSRichard Smith clang::Module::Requirement Requirement; 15743c1a41adSRichard Smith clang::Module::UnresolvedHeaderDirective MissingHeader; 15750761a8a0SDaniel Jasper if (!Module->isAvailable(getLangOpts(), getTarget(), Requirement, 15760761a8a0SDaniel Jasper MissingHeader)) { 15770761a8a0SDaniel Jasper if (MissingHeader.FileNameLoc.isValid()) { 15780761a8a0SDaniel Jasper getDiagnostics().Report(MissingHeader.FileNameLoc, 15790761a8a0SDaniel Jasper diag::err_module_header_missing) 15800761a8a0SDaniel Jasper << MissingHeader.IsUmbrella << MissingHeader.FileName; 15810761a8a0SDaniel Jasper } else { 15821fb5c3a6SDouglas Gregor getDiagnostics().Report(ImportLoc, diag::err_module_unavailable) 15831fb5c3a6SDouglas Gregor << Module->getFullModuleName() 1584a3feee2aSRichard Smith << Requirement.second << Requirement.first 15851fb5c3a6SDouglas Gregor << SourceRange(Path.front().second, Path.back().second); 15860761a8a0SDaniel Jasper } 15871fb5c3a6SDouglas Gregor LastModuleImportLoc = ImportLoc; 15887a626570SDouglas Gregor LastModuleImportResult = ModuleLoadResult(); 15897a626570SDouglas Gregor return ModuleLoadResult(); 15901fb5c3a6SDouglas Gregor } 15911fb5c3a6SDouglas Gregor 1592a7e2cc68SRichard Smith ModuleManager->makeModuleVisible(Module, Visibility, ImportLoc); 159398a52db8SDouglas Gregor } 15945196bc6bSDouglas Gregor 159535b13eceSDouglas Gregor // Check for any configuration macros that have changed. 159635b13eceSDouglas Gregor clang::Module *TopModule = Module->getTopLevelModule(); 159735b13eceSDouglas Gregor for (unsigned I = 0, N = TopModule->ConfigMacros.size(); I != N; ++I) { 159835b13eceSDouglas Gregor checkConfigMacro(getPreprocessor(), TopModule->ConfigMacros[I], 159935b13eceSDouglas Gregor Module, ImportLoc); 160035b13eceSDouglas Gregor } 160135b13eceSDouglas Gregor 16021805b8a4SDouglas Gregor LastModuleImportLoc = ImportLoc; 16037a626570SDouglas Gregor LastModuleImportResult = ModuleLoadResult(Module, false); 16047a626570SDouglas Gregor return LastModuleImportResult; 160508142534SDouglas Gregor } 1606c147b0bcSDouglas Gregor 1607c147b0bcSDouglas Gregor void CompilerInstance::makeModuleVisible(Module *Mod, 1608125df058SArgyrios Kyrtzidis Module::NameVisibilityKind Visibility, 1609a7e2cc68SRichard Smith SourceLocation ImportLoc) { 161042413141SRichard Smith if (!ModuleManager) 161142413141SRichard Smith createModuleManager(); 161242413141SRichard Smith if (!ModuleManager) 161342413141SRichard Smith return; 161442413141SRichard Smith 1615a7e2cc68SRichard Smith ModuleManager->makeModuleVisible(Mod, Visibility, ImportLoc); 1616c147b0bcSDouglas Gregor } 1617c147b0bcSDouglas Gregor 16182255f2ceSJohn Thompson GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex( 16192255f2ceSJohn Thompson SourceLocation TriggerLoc) { 16203938f0c7SRichard Smith if (getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty()) 16213938f0c7SRichard Smith return nullptr; 16222255f2ceSJohn Thompson if (!ModuleManager) 16232255f2ceSJohn Thompson createModuleManager(); 16242255f2ceSJohn Thompson // Can't do anything if we don't have the module manager. 16252255f2ceSJohn Thompson if (!ModuleManager) 162649a2790fSCraig Topper return nullptr; 16272255f2ceSJohn Thompson // Get an existing global index. This loads it if not already 16282255f2ceSJohn Thompson // loaded. 16292255f2ceSJohn Thompson ModuleManager->loadGlobalIndex(); 16302255f2ceSJohn Thompson GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex(); 16312255f2ceSJohn Thompson // If the global index doesn't exist, create it. 16322255f2ceSJohn Thompson if (!GlobalIndex && shouldBuildGlobalModuleIndex() && hasFileManager() && 16332255f2ceSJohn Thompson hasPreprocessor()) { 16342255f2ceSJohn Thompson llvm::sys::fs::create_directories( 16352255f2ceSJohn Thompson getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); 16362255f2ceSJohn Thompson GlobalModuleIndex::writeIndex( 1637fb2398d0SAdrian Prantl getFileManager(), getPCHContainerReader(), 16382255f2ceSJohn Thompson getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); 16392255f2ceSJohn Thompson ModuleManager->resetForReload(); 16402255f2ceSJohn Thompson ModuleManager->loadGlobalIndex(); 16412255f2ceSJohn Thompson GlobalIndex = ModuleManager->getGlobalIndex(); 16422255f2ceSJohn Thompson } 16432255f2ceSJohn Thompson // For finding modules needing to be imported for fixit messages, 16442255f2ceSJohn Thompson // we need to make the global index cover all modules, so we do that here. 16452255f2ceSJohn Thompson if (!HaveFullGlobalModuleIndex && GlobalIndex && !buildingModule()) { 16462255f2ceSJohn Thompson ModuleMap &MMap = getPreprocessor().getHeaderSearchInfo().getModuleMap(); 16472255f2ceSJohn Thompson bool RecreateIndex = false; 16482255f2ceSJohn Thompson for (ModuleMap::module_iterator I = MMap.module_begin(), 16492255f2ceSJohn Thompson E = MMap.module_end(); I != E; ++I) { 16502255f2ceSJohn Thompson Module *TheModule = I->second; 16512255f2ceSJohn Thompson const FileEntry *Entry = TheModule->getASTFile(); 16522255f2ceSJohn Thompson if (!Entry) { 16532255f2ceSJohn Thompson SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path; 16542255f2ceSJohn Thompson Path.push_back(std::make_pair( 16552255f2ceSJohn Thompson getPreprocessor().getIdentifierInfo(TheModule->Name), TriggerLoc)); 16562255f2ceSJohn Thompson std::reverse(Path.begin(), Path.end()); 16572255f2ceSJohn Thompson // Load a module as hidden. This also adds it to the global index. 1658629d8e6fSRichard Smith loadModule(TheModule->DefinitionLoc, Path, Module::Hidden, false); 16592255f2ceSJohn Thompson RecreateIndex = true; 16602255f2ceSJohn Thompson } 16612255f2ceSJohn Thompson } 16622255f2ceSJohn Thompson if (RecreateIndex) { 16632255f2ceSJohn Thompson GlobalModuleIndex::writeIndex( 1664fb2398d0SAdrian Prantl getFileManager(), getPCHContainerReader(), 16652255f2ceSJohn Thompson getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); 16662255f2ceSJohn Thompson ModuleManager->resetForReload(); 16672255f2ceSJohn Thompson ModuleManager->loadGlobalIndex(); 16682255f2ceSJohn Thompson GlobalIndex = ModuleManager->getGlobalIndex(); 16692255f2ceSJohn Thompson } 16702255f2ceSJohn Thompson HaveFullGlobalModuleIndex = true; 16712255f2ceSJohn Thompson } 16722255f2ceSJohn Thompson return GlobalIndex; 16732255f2ceSJohn Thompson } 16742d94bbb0SJohn Thompson 16752d94bbb0SJohn Thompson // Check global module index for missing imports. 16762d94bbb0SJohn Thompson bool 16772d94bbb0SJohn Thompson CompilerInstance::lookupMissingImports(StringRef Name, 16782d94bbb0SJohn Thompson SourceLocation TriggerLoc) { 16792d94bbb0SJohn Thompson // Look for the symbol in non-imported modules, but only if an error 16802d94bbb0SJohn Thompson // actually occurred. 16812d94bbb0SJohn Thompson if (!buildingModule()) { 16822d94bbb0SJohn Thompson // Load global module index, or retrieve a previously loaded one. 16832d94bbb0SJohn Thompson GlobalModuleIndex *GlobalIndex = loadGlobalModuleIndex( 16842d94bbb0SJohn Thompson TriggerLoc); 16852d94bbb0SJohn Thompson 16862d94bbb0SJohn Thompson // Only if we have a global index. 16872d94bbb0SJohn Thompson if (GlobalIndex) { 16882d94bbb0SJohn Thompson GlobalModuleIndex::HitSet FoundModules; 16892d94bbb0SJohn Thompson 16902d94bbb0SJohn Thompson // Find the modules that reference the identifier. 16912d94bbb0SJohn Thompson // Note that this only finds top-level modules. 16922d94bbb0SJohn Thompson // We'll let diagnoseTypo find the actual declaration module. 16932d94bbb0SJohn Thompson if (GlobalIndex->lookupIdentifier(Name, FoundModules)) 16942d94bbb0SJohn Thompson return true; 16952d94bbb0SJohn Thompson } 16962d94bbb0SJohn Thompson } 16972d94bbb0SJohn Thompson 16982d94bbb0SJohn Thompson return false; 16992d94bbb0SJohn Thompson } 1700a97eaa1bSDavid Blaikie void CompilerInstance::resetAndLeakSema() { BuryPointer(takeSema()); } 1701