1636404a3SDaniel Dunbar //===--- CompilerInstance.cpp ---------------------------------------------===// 2636404a3SDaniel Dunbar // 3636404a3SDaniel Dunbar // The LLVM Compiler Infrastructure 4636404a3SDaniel Dunbar // 5636404a3SDaniel Dunbar // This file is distributed under the University of Illinois Open Source 6636404a3SDaniel Dunbar // License. See LICENSE.TXT for details. 7636404a3SDaniel Dunbar // 8636404a3SDaniel Dunbar //===----------------------------------------------------------------------===// 9636404a3SDaniel Dunbar 10636404a3SDaniel Dunbar #include "clang/Frontend/CompilerInstance.h" 1156d9c293SDaniel Dunbar #include "clang/AST/ASTConsumer.h" 12df3e30c4SDaniel Dunbar #include "clang/AST/ASTContext.h" 13bcfc7d02SDouglas Gregor #include "clang/AST/Decl.h" 14636404a3SDaniel Dunbar #include "clang/Basic/Diagnostic.h" 15546a676aSDaniel Dunbar #include "clang/Basic/FileManager.h" 16546a676aSDaniel Dunbar #include "clang/Basic/SourceManager.h" 17636404a3SDaniel Dunbar #include "clang/Basic/TargetInfo.h" 184f2bc55dSDaniel Dunbar #include "clang/Basic/Version.h" 19f988d006SAlp Toker #include "clang/Config/config.h" 208b00dcb0SDavid Blaikie #include "clang/Frontend/ChainedDiagnosticConsumer.h" 214f2bc55dSDaniel Dunbar #include "clang/Frontend/FrontendAction.h" 22faeb1d46SDouglas Gregor #include "clang/Frontend/FrontendActions.h" 23f7093b5aSDaniel Dunbar #include "clang/Frontend/FrontendDiagnostic.h" 242083c32fSDaniel Dunbar #include "clang/Frontend/LogDiagnosticPrinter.h" 254610ea2bSTed Kremenek #include "clang/Frontend/SerializedDiagnosticPrinter.h" 267d75afc5SDaniel Dunbar #include "clang/Frontend/TextDiagnosticPrinter.h" 27aaa148fdSDaniel Dunbar #include "clang/Frontend/Utils.h" 283a02247dSChandler Carruth #include "clang/Frontend/VerifyDiagnosticConsumer.h" 293a02247dSChandler Carruth #include "clang/Lex/HeaderSearch.h" 303a02247dSChandler Carruth #include "clang/Lex/PTHManager.h" 313a02247dSChandler Carruth #include "clang/Lex/Preprocessor.h" 32f7093b5aSDaniel Dunbar #include "clang/Sema/CodeCompleteConsumer.h" 333a02247dSChandler Carruth #include "clang/Sema/Sema.h" 343a02247dSChandler Carruth #include "clang/Serialization/ASTReader.h" 352255f2ceSJohn Thompson #include "clang/Serialization/GlobalModuleIndex.h" 36171b780cSDouglas Gregor #include "llvm/ADT/Statistic.h" 373a02247dSChandler Carruth #include "llvm/Support/CrashRecoveryContext.h" 3871de0b61SRafael Espindola #include "llvm/Support/Errc.h" 393a02247dSChandler Carruth #include "llvm/Support/FileSystem.h" 408aaf4995SMichael J. Spencer #include "llvm/Support/Host.h" 41e212489fSDouglas Gregor #include "llvm/Support/LockFileManager.h" 423a02247dSChandler Carruth #include "llvm/Support/MemoryBuffer.h" 438aaf4995SMichael J. Spencer #include "llvm/Support/Path.h" 448aaf4995SMichael J. Spencer #include "llvm/Support/Program.h" 458aaf4995SMichael J. Spencer #include "llvm/Support/Signals.h" 463a02247dSChandler Carruth #include "llvm/Support/Timer.h" 473a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h" 48527b1c95SDouglas Gregor #include <sys/stat.h> 498a8e554aSRafael Espindola #include <system_error> 5037da327cSDouglas Gregor #include <time.h> 5154a88810SDouglas Gregor 52636404a3SDaniel Dunbar using namespace clang; 53636404a3SDaniel Dunbar 542255f2ceSJohn Thompson CompilerInstance::CompilerInstance(bool BuildingModule) 552255f2ceSJohn Thompson : ModuleLoader(BuildingModule), 5649a2790fSCraig Topper Invocation(new CompilerInvocation()), ModuleManager(nullptr), 572255f2ceSJohn Thompson BuildGlobalModuleIndex(false), HaveFullGlobalModuleIndex(false), 582255f2ceSJohn Thompson ModuleBuildFailed(false) { 59636404a3SDaniel Dunbar } 60636404a3SDaniel Dunbar 61636404a3SDaniel Dunbar CompilerInstance::~CompilerInstance() { 623c717b45SBenjamin Kramer assert(OutputFiles.empty() && "Still output files in flight?"); 63e922d9bdSDaniel Dunbar } 64e922d9bdSDaniel Dunbar 6568242254SDaniel Dunbar void CompilerInstance::setInvocation(CompilerInvocation *Value) { 665e14d39aSTed Kremenek Invocation = Value; 6768242254SDaniel Dunbar } 6868242254SDaniel Dunbar 69c1bbec85SDouglas Gregor bool CompilerInstance::shouldBuildGlobalModuleIndex() const { 70e060e57bSDouglas Gregor return (BuildGlobalModuleIndex || 7111ef0b77SDouglas Gregor (ModuleManager && ModuleManager->isGlobalIndexUnavailable() && 7211ef0b77SDouglas Gregor getFrontendOpts().GenerateGlobalModuleIndex)) && 73e060e57bSDouglas Gregor !ModuleBuildFailed; 74c1bbec85SDouglas Gregor } 75c1bbec85SDouglas Gregor 769c902b55SDavid Blaikie void CompilerInstance::setDiagnostics(DiagnosticsEngine *Value) { 777f95d26eSDouglas Gregor Diagnostics = Value; 78e01dc86dSDaniel Dunbar } 79e01dc86dSDaniel Dunbar 80e01dc86dSDaniel Dunbar void CompilerInstance::setTarget(TargetInfo *Value) { 815e14d39aSTed Kremenek Target = Value; 82e01dc86dSDaniel Dunbar } 83e01dc86dSDaniel Dunbar 84e01dc86dSDaniel Dunbar void CompilerInstance::setFileManager(FileManager *Value) { 855e14d39aSTed Kremenek FileMgr = Value; 86c8130a74SBen Langmuir if (Value) 87c8130a74SBen Langmuir VirtualFileSystem = Value->getVirtualFileSystem(); 88c8130a74SBen Langmuir else 89c8130a74SBen Langmuir VirtualFileSystem.reset(); 90e01dc86dSDaniel Dunbar } 91e01dc86dSDaniel Dunbar 92e01dc86dSDaniel Dunbar void CompilerInstance::setSourceManager(SourceManager *Value) { 935e14d39aSTed Kremenek SourceMgr = Value; 94e01dc86dSDaniel Dunbar } 95e01dc86dSDaniel Dunbar 965e14d39aSTed Kremenek void CompilerInstance::setPreprocessor(Preprocessor *Value) { PP = Value; } 97e01dc86dSDaniel Dunbar 985e14d39aSTed Kremenek void CompilerInstance::setASTContext(ASTContext *Value) { Context = Value; } 99e01dc86dSDaniel Dunbar 1000e93f017SDouglas Gregor void CompilerInstance::setSema(Sema *S) { 1010e93f017SDouglas Gregor TheSema.reset(S); 1020e93f017SDouglas Gregor } 1030e93f017SDouglas Gregor 1046beb6aa8SDavid Blaikie void CompilerInstance::setASTConsumer(std::unique_ptr<ASTConsumer> Value) { 1056beb6aa8SDavid Blaikie Consumer = std::move(Value); 10656d9c293SDaniel Dunbar } 10756d9c293SDaniel Dunbar 108e01dc86dSDaniel Dunbar void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) { 109e01dc86dSDaniel Dunbar CompletionConsumer.reset(Value); 110e01dc86dSDaniel Dunbar } 111e01dc86dSDaniel Dunbar 1126153581aSDavid Blaikie std::unique_ptr<Sema> CompilerInstance::takeSema() { 1136153581aSDavid Blaikie return std::move(TheSema); 1146153581aSDavid Blaikie } 1156153581aSDavid Blaikie 1161b7ed91eSArgyrios Kyrtzidis IntrusiveRefCntPtr<ASTReader> CompilerInstance::getModuleManager() const { 1171b7ed91eSArgyrios Kyrtzidis return ModuleManager; 1181b7ed91eSArgyrios Kyrtzidis } 1191b7ed91eSArgyrios Kyrtzidis void CompilerInstance::setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader) { 1201b7ed91eSArgyrios Kyrtzidis ModuleManager = Reader; 1211b7ed91eSArgyrios Kyrtzidis } 1221b7ed91eSArgyrios Kyrtzidis 12386d1259cSJustin Bogner std::shared_ptr<ModuleDependencyCollector> 12486d1259cSJustin Bogner CompilerInstance::getModuleDepCollector() const { 12586d1259cSJustin Bogner return ModuleDepCollector; 12686d1259cSJustin Bogner } 12786d1259cSJustin Bogner 12886d1259cSJustin Bogner void CompilerInstance::setModuleDepCollector( 12986d1259cSJustin Bogner std::shared_ptr<ModuleDependencyCollector> Collector) { 13086d1259cSJustin Bogner ModuleDepCollector = Collector; 13186d1259cSJustin Bogner } 13286d1259cSJustin Bogner 1337d75afc5SDaniel Dunbar // Diagnostics 134811db4eaSDouglas Gregor static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts, 1357b83306dSDaniel Dunbar const CodeGenOptions *CodeGenOpts, 1369c902b55SDavid Blaikie DiagnosticsEngine &Diags) { 137dae941a6SRafael Espindola std::error_code EC; 13811f8a943SDavid Blaikie std::unique_ptr<raw_ostream> StreamOwner; 1390e62c1ccSChris Lattner raw_ostream *OS = &llvm::errs(); 140811db4eaSDouglas Gregor if (DiagOpts->DiagnosticLogFile != "-") { 1412083c32fSDaniel Dunbar // Create the output stream. 14211f8a943SDavid Blaikie auto FileOS = llvm::make_unique<llvm::raw_fd_ostream>( 143dae941a6SRafael Espindola DiagOpts->DiagnosticLogFile, EC, 14411f8a943SDavid Blaikie llvm::sys::fs::F_Append | llvm::sys::fs::F_Text); 145dae941a6SRafael Espindola if (EC) { 1462083c32fSDaniel Dunbar Diags.Report(diag::warn_fe_cc_log_diagnostics_failure) 147dae941a6SRafael Espindola << DiagOpts->DiagnosticLogFile << EC.message(); 1482083c32fSDaniel Dunbar } else { 1492083c32fSDaniel Dunbar FileOS->SetUnbuffered(); 1502083c32fSDaniel Dunbar FileOS->SetUseAtomicWrites(true); 15111f8a943SDavid Blaikie OS = FileOS.get(); 15211f8a943SDavid Blaikie StreamOwner = std::move(FileOS); 1532083c32fSDaniel Dunbar } 1542083c32fSDaniel Dunbar } 1552083c32fSDaniel Dunbar 1562083c32fSDaniel Dunbar // Chain in the diagnostic client which will log the diagnostics. 1577ee25502SDavid Blaikie auto Logger = llvm::make_unique<LogDiagnosticPrinter>(*OS, DiagOpts, 1587ee25502SDavid Blaikie std::move(StreamOwner)); 1597b83306dSDaniel Dunbar if (CodeGenOpts) 1607b83306dSDaniel Dunbar Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags); 1617ee25502SDavid Blaikie assert(Diags.ownsClient()); 16241c247a6SAlexander Kornienko Diags.setClient( 16341c247a6SAlexander Kornienko new ChainedDiagnosticConsumer(Diags.takeClient(), std::move(Logger))); 1642083c32fSDaniel Dunbar } 1652083c32fSDaniel Dunbar 166811db4eaSDouglas Gregor static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts, 1674610ea2bSTed Kremenek DiagnosticsEngine &Diags, 1684610ea2bSTed Kremenek StringRef OutputFile) { 1697ee25502SDavid Blaikie auto SerializedConsumer = 1705a6a2fcdSJustin Bogner clang::serialized_diags::create(OutputFile, DiagOpts); 1714610ea2bSTed Kremenek 172254b7dbaSAlexander Kornienko if (Diags.ownsClient()) { 1737ee25502SDavid Blaikie Diags.setClient(new ChainedDiagnosticConsumer( 17441c247a6SAlexander Kornienko Diags.takeClient(), std::move(SerializedConsumer))); 175254b7dbaSAlexander Kornienko } else { 176254b7dbaSAlexander Kornienko Diags.setClient(new ChainedDiagnosticConsumer( 1774c0ef379SAlexander Kornienko Diags.getClient(), std::move(SerializedConsumer))); 178254b7dbaSAlexander Kornienko } 1794610ea2bSTed Kremenek } 1804610ea2bSTed Kremenek 181f1b49e23SSean Silva void CompilerInstance::createDiagnostics(DiagnosticConsumer *Client, 18230071ceaSDouglas Gregor bool ShouldOwnClient) { 183f1b49e23SSean Silva Diagnostics = createDiagnostics(&getDiagnosticOpts(), Client, 18430071ceaSDouglas Gregor ShouldOwnClient, &getCodeGenOpts()); 1857d75afc5SDaniel Dunbar } 1867d75afc5SDaniel Dunbar 187c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> 188811db4eaSDouglas Gregor CompilerInstance::createDiagnostics(DiagnosticOptions *Opts, 189e2eefaecSDavid Blaikie DiagnosticConsumer *Client, 1902b9b4642SDouglas Gregor bool ShouldOwnClient, 1917b83306dSDaniel Dunbar const CodeGenOptions *CodeGenOpts) { 192c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 193c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> 194811db4eaSDouglas Gregor Diags(new DiagnosticsEngine(DiagID, Opts)); 1951b39a2edSDaniel Dunbar 1967d75afc5SDaniel Dunbar // Create the diagnostic client for reporting errors or for 1977d75afc5SDaniel Dunbar // implementing -verify. 198d0e9e3a6SDouglas Gregor if (Client) { 199d0e9e3a6SDouglas Gregor Diags->setClient(Client, ShouldOwnClient); 200d0e9e3a6SDouglas Gregor } else 2012dd19f1dSDouglas Gregor Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts)); 20250ec0da0SDaniel Dunbar 20350ec0da0SDaniel Dunbar // Chain in -verify checker, if requested. 204811db4eaSDouglas Gregor if (Opts->VerifyDiagnostics) 20569609dceSDavid Blaikie Diags->setClient(new VerifyDiagnosticConsumer(*Diags)); 2067d75afc5SDaniel Dunbar 2072083c32fSDaniel Dunbar // Chain in -diagnostic-log-file dumper, if requested. 208811db4eaSDouglas Gregor if (!Opts->DiagnosticLogFile.empty()) 2097b83306dSDaniel Dunbar SetUpDiagnosticLog(Opts, CodeGenOpts, *Diags); 2102083c32fSDaniel Dunbar 211811db4eaSDouglas Gregor if (!Opts->DiagnosticSerializationFile.empty()) 2124610ea2bSTed Kremenek SetupSerializedDiagnostics(Opts, *Diags, 213811db4eaSDouglas Gregor Opts->DiagnosticSerializationFile); 2144610ea2bSTed Kremenek 2157d75afc5SDaniel Dunbar // Configure our handling of diagnostics. 216811db4eaSDouglas Gregor ProcessWarningOptions(*Diags, *Opts); 2177d75afc5SDaniel Dunbar 2187f95d26eSDouglas Gregor return Diags; 2197d75afc5SDaniel Dunbar } 2207d75afc5SDaniel Dunbar 2217d75afc5SDaniel Dunbar // File Manager 2227d75afc5SDaniel Dunbar 223546a676aSDaniel Dunbar void CompilerInstance::createFileManager() { 224c8130a74SBen Langmuir if (!hasVirtualFileSystem()) { 225c8130a74SBen Langmuir // TODO: choose the virtual file system based on the CompilerInvocation. 226c8130a74SBen Langmuir setVirtualFileSystem(vfs::getRealFileSystem()); 227c8130a74SBen Langmuir } 228c8130a74SBen Langmuir FileMgr = new FileManager(getFileSystemOpts(), VirtualFileSystem); 229546a676aSDaniel Dunbar } 230546a676aSDaniel Dunbar 2317d75afc5SDaniel Dunbar // Source Manager 2327d75afc5SDaniel Dunbar 2335159f616SChris Lattner void CompilerInstance::createSourceManager(FileManager &FileMgr) { 2345e14d39aSTed Kremenek SourceMgr = new SourceManager(getDiagnostics(), FileMgr); 235546a676aSDaniel Dunbar } 236aaa148fdSDaniel Dunbar 237c358000eSAlp Toker // Initialize the remapping of files to alternative contents, e.g., 238c358000eSAlp Toker // those specified through other files. 239c358000eSAlp Toker static void InitializeFileRemapping(DiagnosticsEngine &Diags, 240c358000eSAlp Toker SourceManager &SourceMgr, 241c358000eSAlp Toker FileManager &FileMgr, 242c358000eSAlp Toker const PreprocessorOptions &InitOpts) { 243c358000eSAlp Toker // Remap files in the source manager (with buffers). 2441b070d25SAlp Toker for (const auto &RB : InitOpts.RemappedFileBuffers) { 245c358000eSAlp Toker // Create the file entry for the file that we're mapping from. 246c358000eSAlp Toker const FileEntry *FromFile = 2471b070d25SAlp Toker FileMgr.getVirtualFile(RB.first, RB.second->getBufferSize(), 0); 248c358000eSAlp Toker if (!FromFile) { 2491b070d25SAlp Toker Diags.Report(diag::err_fe_remap_missing_from_file) << RB.first; 250c358000eSAlp Toker if (!InitOpts.RetainRemappedFileBuffers) 2511b070d25SAlp Toker delete RB.second; 252c358000eSAlp Toker continue; 253c358000eSAlp Toker } 254c358000eSAlp Toker 255c358000eSAlp Toker // Override the contents of the "from" file with the contents of 256c358000eSAlp Toker // the "to" file. 2571b070d25SAlp Toker SourceMgr.overrideFileContents(FromFile, RB.second, 258c358000eSAlp Toker InitOpts.RetainRemappedFileBuffers); 259c358000eSAlp Toker } 260c358000eSAlp Toker 261c358000eSAlp Toker // Remap files in the source manager (with other files). 2621b070d25SAlp Toker for (const auto &RF : InitOpts.RemappedFiles) { 263c358000eSAlp Toker // Find the file that we're mapping to. 2641b070d25SAlp Toker const FileEntry *ToFile = FileMgr.getFile(RF.second); 265c358000eSAlp Toker if (!ToFile) { 2661b070d25SAlp Toker Diags.Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second; 267c358000eSAlp Toker continue; 268c358000eSAlp Toker } 269c358000eSAlp Toker 270c358000eSAlp Toker // Create the file entry for the file that we're mapping from. 271c358000eSAlp Toker const FileEntry *FromFile = 2721b070d25SAlp Toker FileMgr.getVirtualFile(RF.first, ToFile->getSize(), 0); 273c358000eSAlp Toker if (!FromFile) { 2741b070d25SAlp Toker Diags.Report(diag::err_fe_remap_missing_from_file) << RF.first; 275c358000eSAlp Toker continue; 276c358000eSAlp Toker } 277c358000eSAlp Toker 278c358000eSAlp Toker // Override the contents of the "from" file with the contents of 279c358000eSAlp Toker // the "to" file. 280c358000eSAlp Toker SourceMgr.overrideFileContents(FromFile, ToFile); 281c358000eSAlp Toker } 282c358000eSAlp Toker 283c358000eSAlp Toker SourceMgr.setOverridenFilesKeepOriginalName( 284c358000eSAlp Toker InitOpts.RemappedFilesKeepOriginalName); 285c358000eSAlp Toker } 286c358000eSAlp Toker 2877d75afc5SDaniel Dunbar // Preprocessor 2887d75afc5SDaniel Dunbar 289e1974dcdSArgyrios Kyrtzidis void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) { 29008142534SDouglas Gregor const PreprocessorOptions &PPOpts = getPreprocessorOpts(); 291aaa148fdSDaniel Dunbar 292aaa148fdSDaniel Dunbar // Create a PTH manager if we are using some form of a token cache. 29349a2790fSCraig Topper PTHManager *PTHMgr = nullptr; 294d6ea9028SDaniel Dunbar if (!PPOpts.TokenCache.empty()) 29508142534SDouglas Gregor PTHMgr = PTHManager::Create(PPOpts.TokenCache, getDiagnostics()); 296aaa148fdSDaniel Dunbar 297aaa148fdSDaniel Dunbar // Create the Preprocessor. 298b85b9ccbSDouglas Gregor HeaderSearch *HeaderInfo = new HeaderSearch(&getHeaderSearchOpts(), 2991f76c4e8SManuel Klimek getSourceManager(), 3001fb5c3a6SDouglas Gregor getDiagnostics(), 30189929282SDouglas Gregor getLangOpts(), 30289929282SDouglas Gregor &getTarget()); 3039663780eSAlp Toker PP = new Preprocessor(&getPreprocessorOpts(), getDiagnostics(), getLangOpts(), 30408142534SDouglas Gregor getSourceManager(), *HeaderInfo, *this, PTHMgr, 3059663780eSAlp Toker /*OwnsHeaderSearch=*/true, TUKind); 3061ae02f68SAlp Toker PP->Initialize(getTarget()); 307aaa148fdSDaniel Dunbar 308aaa148fdSDaniel Dunbar // Note that this is different then passing PTHMgr to Preprocessor's ctor. 309aaa148fdSDaniel Dunbar // That argument is used as the IdentifierInfoLookup argument to 310aaa148fdSDaniel Dunbar // IdentifierTable's ctor. 311aaa148fdSDaniel Dunbar if (PTHMgr) { 31208142534SDouglas Gregor PTHMgr->setPreprocessor(&*PP); 313aaa148fdSDaniel Dunbar PP->setPTHManager(PTHMgr); 314aaa148fdSDaniel Dunbar } 315aaa148fdSDaniel Dunbar 3167f6d60dcSDouglas Gregor if (PPOpts.DetailedRecord) 317f3d587eaSArgyrios Kyrtzidis PP->createPreprocessingRecord(); 3187f6d60dcSDouglas Gregor 319c358000eSAlp Toker // Apply remappings to the source manager. 320c358000eSAlp Toker InitializeFileRemapping(PP->getDiagnostics(), PP->getSourceManager(), 321c358000eSAlp Toker PP->getFileManager(), PPOpts); 322c358000eSAlp Toker 323c358000eSAlp Toker // Predefine macros and configure the preprocessor. 324c358000eSAlp Toker InitializePreprocessor(*PP, PPOpts, getFrontendOpts()); 325c358000eSAlp Toker 326c358000eSAlp Toker // Initialize the header search object. 327c358000eSAlp Toker ApplyHeaderSearchOptions(PP->getHeaderSearchInfo(), getHeaderSearchOpts(), 328c358000eSAlp Toker PP->getLangOpts(), PP->getTargetInfo().getTriple()); 329aaa148fdSDaniel Dunbar 33017441589SJordan Rose PP->setPreprocessedOutput(getPreprocessorOutputOpts().ShowCPP); 33117441589SJordan Rose 332bd0b651bSArgyrios Kyrtzidis PP->getHeaderSearchInfo().setModuleCachePath(getSpecificModuleCachePath()); 3331735f4e7SDouglas Gregor 334aaa148fdSDaniel Dunbar // Handle generating dependencies, if requested. 33508142534SDouglas Gregor const DependencyOutputOptions &DepOpts = getDependencyOutputOpts(); 336aaa148fdSDaniel Dunbar if (!DepOpts.OutputFile.empty()) 337cb69b57bSBen Langmuir TheDependencyFileGenerator.reset( 338cb69b57bSBen Langmuir DependencyFileGenerator::CreateAndAttachToPreprocessor(*PP, DepOpts)); 3392e129659SDouglas Gregor if (!DepOpts.DOTOutputFile.empty()) 3402e129659SDouglas Gregor AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile, 34183d46be3SDouglas Gregor getHeaderSearchOpts().Sysroot); 34283d46be3SDouglas Gregor 34333c8090aSBen Langmuir for (auto &Listener : DependencyCollectors) 34433c8090aSBen Langmuir Listener->attachToPreprocessor(*PP); 34533c8090aSBen Langmuir 34686d1259cSJustin Bogner // If we don't have a collector, but we are collecting module dependencies, 34786d1259cSJustin Bogner // then we're the top level compiler instance and need to create one. 34886d1259cSJustin Bogner if (!ModuleDepCollector && !DepOpts.ModuleDependencyOutputDir.empty()) 34986d1259cSJustin Bogner ModuleDepCollector = std::make_shared<ModuleDependencyCollector>( 35086d1259cSJustin Bogner DepOpts.ModuleDependencyOutputDir); 351aaa148fdSDaniel Dunbar 35227734fdbSDaniel Dunbar // Handle generating header include information, if requested. 35327734fdbSDaniel Dunbar if (DepOpts.ShowHeaderIncludes) 35427734fdbSDaniel Dunbar AttachHeaderIncludeGen(*PP); 3551af1d275SDaniel Dunbar if (!DepOpts.HeaderIncludeOutputFile.empty()) { 3560e62c1ccSChris Lattner StringRef OutputPath = DepOpts.HeaderIncludeOutputFile; 3571af1d275SDaniel Dunbar if (OutputPath == "-") 3581af1d275SDaniel Dunbar OutputPath = ""; 359fe908a80SDaniel Dunbar AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/true, OutputPath, 360fe908a80SDaniel Dunbar /*ShowDepth=*/false); 3610fd6207dSHans Wennborg } 3620fd6207dSHans Wennborg 3630fd6207dSHans Wennborg if (DepOpts.PrintShowIncludes) { 3640fd6207dSHans Wennborg AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/false, /*OutputPath=*/"", 3650fd6207dSHans Wennborg /*ShowDepth=*/true, /*MSStyle=*/true); 3661af1d275SDaniel Dunbar } 367aaa148fdSDaniel Dunbar } 368df3e30c4SDaniel Dunbar 369bd0b651bSArgyrios Kyrtzidis std::string CompilerInstance::getSpecificModuleCachePath() { 370bd0b651bSArgyrios Kyrtzidis // Set up the module path, including the hash for the 371bd0b651bSArgyrios Kyrtzidis // module-creation options. 372bd0b651bSArgyrios Kyrtzidis SmallString<256> SpecificModuleCache( 373bd0b651bSArgyrios Kyrtzidis getHeaderSearchOpts().ModuleCachePath); 374bd0b651bSArgyrios Kyrtzidis if (!getHeaderSearchOpts().DisableModuleHash) 375bd0b651bSArgyrios Kyrtzidis llvm::sys::path::append(SpecificModuleCache, 376bd0b651bSArgyrios Kyrtzidis getInvocation().getModuleHash()); 377bd0b651bSArgyrios Kyrtzidis return SpecificModuleCache.str(); 378bd0b651bSArgyrios Kyrtzidis } 379bd0b651bSArgyrios Kyrtzidis 380df3e30c4SDaniel Dunbar // ASTContext 381df3e30c4SDaniel Dunbar 382df3e30c4SDaniel Dunbar void CompilerInstance::createASTContext() { 383df3e30c4SDaniel Dunbar Preprocessor &PP = getPreprocessor(); 3845e14d39aSTed Kremenek Context = new ASTContext(getLangOpts(), PP.getSourceManager(), 38508043437SAlp Toker PP.getIdentifierTable(), PP.getSelectorTable(), 38608043437SAlp Toker PP.getBuiltinInfo()); 38708043437SAlp Toker Context->InitBuiltinTypes(getTarget()); 388df3e30c4SDaniel Dunbar } 389599313efSDaniel Dunbar 390599313efSDaniel Dunbar // ExternalASTSource 391599313efSDaniel Dunbar 392824285ecSNico Weber void CompilerInstance::createPCHExternalASTSource( 393824285ecSNico Weber StringRef Path, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors, 394824285ecSNico Weber void *DeserializationListener, bool OwnDeserializationListener) { 395009e7f20SSebastian Redl bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0; 3964eca9b93SRichard Smith ModuleManager = createPCHExternalASTSource( 397824285ecSNico Weber Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation, 398824285ecSNico Weber AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(), 399824285ecSNico Weber DeserializationListener, OwnDeserializationListener, Preamble, 4001b7ed91eSArgyrios Kyrtzidis getFrontendOpts().UseGlobalModuleIndex); 401599313efSDaniel Dunbar } 402599313efSDaniel Dunbar 4034eca9b93SRichard Smith IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource( 404824285ecSNico Weber StringRef Path, const std::string &Sysroot, bool DisablePCHValidation, 405824285ecSNico Weber bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context, 406824285ecSNico Weber void *DeserializationListener, bool OwnDeserializationListener, 407824285ecSNico Weber bool Preamble, bool UseGlobalModuleIndex) { 408dcf73861SBen Langmuir HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts(); 409dcf73861SBen Langmuir 4104eca9b93SRichard Smith IntrusiveRefCntPtr<ASTReader> Reader( 4114eca9b93SRichard Smith new ASTReader(PP, Context, Sysroot.empty() ? "" : Sysroot.c_str(), 4124eca9b93SRichard Smith DisablePCHValidation, AllowPCHWithCompilerErrors, 4133d4417c7SBen Langmuir /*AllowConfigurationMismatch*/ false, 4144eca9b93SRichard Smith HSOpts.ModulesValidateSystemHeaders, UseGlobalModuleIndex)); 4154eca9b93SRichard Smith 4164eca9b93SRichard Smith // We need the external source to be set up before we read the AST, because 4174eca9b93SRichard Smith // eagerly-deserialized declarations may use it. 4184eca9b93SRichard Smith Context.setExternalSource(Reader.get()); 419599313efSDaniel Dunbar 42007a89a83SSebastian Redl Reader->setDeserializationListener( 421824285ecSNico Weber static_cast<ASTDeserializationListener *>(DeserializationListener), 422824285ecSNico Weber /*TakeOwnership=*/OwnDeserializationListener); 423009e7f20SSebastian Redl switch (Reader->ReadAST(Path, 424a6895d8aSDouglas Gregor Preamble ? serialization::MK_Preamble 4254b29c16eSDouglas Gregor : serialization::MK_PCH, 4262ec29367SArgyrios Kyrtzidis SourceLocation(), 4273d4417c7SBen Langmuir ASTReader::ARR_None)) { 4282c499f65SSebastian Redl case ASTReader::Success: 429599313efSDaniel Dunbar // Set the predefines buffer as suggested by the PCH reader. Typically, the 430599313efSDaniel Dunbar // predefines buffer will be empty. 431599313efSDaniel Dunbar PP.setPredefines(Reader->getSuggestedPredefines()); 4324eca9b93SRichard Smith return Reader; 433599313efSDaniel Dunbar 4342c499f65SSebastian Redl case ASTReader::Failure: 435599313efSDaniel Dunbar // Unrecoverable failure: don't even try to process the input file. 436599313efSDaniel Dunbar break; 437599313efSDaniel Dunbar 4387029ce1aSDouglas Gregor case ASTReader::Missing: 439c9ad5fb6SDouglas Gregor case ASTReader::OutOfDate: 440c9ad5fb6SDouglas Gregor case ASTReader::VersionMismatch: 441c9ad5fb6SDouglas Gregor case ASTReader::ConfigurationMismatch: 442c9ad5fb6SDouglas Gregor case ASTReader::HadErrors: 443599313efSDaniel Dunbar // No suitable PCH file could be found. Return an error. 444599313efSDaniel Dunbar break; 445599313efSDaniel Dunbar } 446599313efSDaniel Dunbar 4474eca9b93SRichard Smith Context.setExternalSource(nullptr); 44849a2790fSCraig Topper return nullptr; 449599313efSDaniel Dunbar } 450f7093b5aSDaniel Dunbar 451f7093b5aSDaniel Dunbar // Code Completion 452f7093b5aSDaniel Dunbar 4538e984da8SDouglas Gregor static bool EnableCodeCompletion(Preprocessor &PP, 4548e984da8SDouglas Gregor const std::string &Filename, 4558e984da8SDouglas Gregor unsigned Line, 4568e984da8SDouglas Gregor unsigned Column) { 4578e984da8SDouglas Gregor // Tell the source manager to chop off the given file at a specific 4588e984da8SDouglas Gregor // line and column. 4595159f616SChris Lattner const FileEntry *Entry = PP.getFileManager().getFile(Filename); 4608e984da8SDouglas Gregor if (!Entry) { 4618e984da8SDouglas Gregor PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file) 4628e984da8SDouglas Gregor << Filename; 4638e984da8SDouglas Gregor return true; 4648e984da8SDouglas Gregor } 4658e984da8SDouglas Gregor 4668e984da8SDouglas Gregor // Truncate the named file at the given line/column. 4678e984da8SDouglas Gregor PP.SetCodeCompletionPoint(Entry, Line, Column); 4688e984da8SDouglas Gregor return false; 4698e984da8SDouglas Gregor } 4708e984da8SDouglas Gregor 471f7093b5aSDaniel Dunbar void CompilerInstance::createCodeCompletionConsumer() { 472f7093b5aSDaniel Dunbar const ParsedSourceLocation &Loc = getFrontendOpts().CodeCompletionAt; 4738e984da8SDouglas Gregor if (!CompletionConsumer) { 4742fca3c2cSErik Verbruggen setCodeCompletionConsumer( 475f7093b5aSDaniel Dunbar createCodeCompletionConsumer(getPreprocessor(), 476f7093b5aSDaniel Dunbar Loc.FileName, Loc.Line, Loc.Column, 4773292d06aSDmitri Gribenko getFrontendOpts().CodeCompleteOpts, 478f7093b5aSDaniel Dunbar llvm::outs())); 47900a0cf70SDouglas Gregor if (!CompletionConsumer) 48000a0cf70SDouglas Gregor return; 4818e984da8SDouglas Gregor } else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName, 4828e984da8SDouglas Gregor Loc.Line, Loc.Column)) { 48349a2790fSCraig Topper setCodeCompletionConsumer(nullptr); 4848e984da8SDouglas Gregor return; 4858e984da8SDouglas Gregor } 486f09935f1SDouglas Gregor 487f09935f1SDouglas Gregor if (CompletionConsumer->isOutputBinary() && 488a3346d87SRafael Espindola llvm::sys::ChangeStdoutToBinary()) { 489f09935f1SDouglas Gregor getPreprocessor().getDiagnostics().Report(diag::err_fe_stdout_binary); 49049a2790fSCraig Topper setCodeCompletionConsumer(nullptr); 491f09935f1SDouglas Gregor } 492f7093b5aSDaniel Dunbar } 493f7093b5aSDaniel Dunbar 4945505dff8SKovarththanan Rajaratnam void CompilerInstance::createFrontendTimer() { 4955505dff8SKovarththanan Rajaratnam FrontendTimer.reset(new llvm::Timer("Clang front-end timer")); 4965505dff8SKovarththanan Rajaratnam } 4975505dff8SKovarththanan Rajaratnam 498f7093b5aSDaniel Dunbar CodeCompleteConsumer * 499f7093b5aSDaniel Dunbar CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP, 500f7093b5aSDaniel Dunbar const std::string &Filename, 501f7093b5aSDaniel Dunbar unsigned Line, 502f7093b5aSDaniel Dunbar unsigned Column, 5033292d06aSDmitri Gribenko const CodeCompleteOptions &Opts, 5040e62c1ccSChris Lattner raw_ostream &OS) { 5058e984da8SDouglas Gregor if (EnableCodeCompletion(PP, Filename, Line, Column)) 50649a2790fSCraig Topper return nullptr; 507f7093b5aSDaniel Dunbar 508f7093b5aSDaniel Dunbar // Set up the creation routine for code-completion. 5093292d06aSDmitri Gribenko return new PrintingCodeCompleteConsumer(Opts, OS); 510f7093b5aSDaniel Dunbar } 511566eeb2dSDaniel Dunbar 51269f74f80SDouglas Gregor void CompilerInstance::createSema(TranslationUnitKind TUKind, 5130e93f017SDouglas Gregor CodeCompleteConsumer *CompletionConsumer) { 5140e93f017SDouglas Gregor TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(), 51569f74f80SDouglas Gregor TUKind, CompletionConsumer)); 5160e93f017SDouglas Gregor } 5170e93f017SDouglas Gregor 518566eeb2dSDaniel Dunbar // Output Files 519566eeb2dSDaniel Dunbar 52069f3528cSNAKAMURA Takumi void CompilerInstance::addOutputFile(const OutputFile &OutFile) { 521d0599970SArgyrios Kyrtzidis assert(OutFile.OS && "Attempt to add empty stream to output list!"); 52269f3528cSNAKAMURA Takumi OutputFiles.push_back(OutFile); 523566eeb2dSDaniel Dunbar } 524566eeb2dSDaniel Dunbar 5251c558cd7SKovarththanan Rajaratnam void CompilerInstance::clearOutputFiles(bool EraseFiles) { 526d0599970SArgyrios Kyrtzidis for (std::list<OutputFile>::iterator 527566eeb2dSDaniel Dunbar it = OutputFiles.begin(), ie = OutputFiles.end(); it != ie; ++it) { 52869f3528cSNAKAMURA Takumi delete it->OS; 529d0599970SArgyrios Kyrtzidis if (!it->TempFilename.empty()) { 530b5c356a4SAnders Carlsson if (EraseFiles) { 5312a008784SRafael Espindola llvm::sys::fs::remove(it->TempFilename); 532b5c356a4SAnders Carlsson } else { 5332c1dd271SDylan Noblesmith SmallString<128> NewOutFile(it->Filename); 534b5c356a4SAnders Carlsson 53571731d6bSArgyrios Kyrtzidis // If '-working-directory' was passed, the output filename should be 53671731d6bSArgyrios Kyrtzidis // relative to that. 5379ba8fb1eSAnders Carlsson FileMgr->FixupRelativePath(NewOutFile); 538c080917eSRafael Espindola if (std::error_code ec = 539c080917eSRafael Espindola llvm::sys::fs::rename(it->TempFilename, NewOutFile.str())) { 5403ef9c447SManuel Klimek getDiagnostics().Report(diag::err_unable_to_rename_temp) 541b5c356a4SAnders Carlsson << it->TempFilename << it->Filename << ec.message(); 542b5c356a4SAnders Carlsson 5432a008784SRafael Espindola llvm::sys::fs::remove(it->TempFilename); 544d0599970SArgyrios Kyrtzidis } 545d0599970SArgyrios Kyrtzidis } 546d0599970SArgyrios Kyrtzidis } else if (!it->Filename.empty() && EraseFiles) 547399ab33aSRafael Espindola llvm::sys::fs::remove(it->Filename); 548d0599970SArgyrios Kyrtzidis 549566eeb2dSDaniel Dunbar } 550566eeb2dSDaniel Dunbar OutputFiles.clear(); 551566eeb2dSDaniel Dunbar } 552566eeb2dSDaniel Dunbar 553420b0f1bSDaniel Dunbar llvm::raw_fd_ostream * 554420b0f1bSDaniel Dunbar CompilerInstance::createDefaultOutputFile(bool Binary, 5550e62c1ccSChris Lattner StringRef InFile, 5560e62c1ccSChris Lattner StringRef Extension) { 557420b0f1bSDaniel Dunbar return createOutputFile(getFrontendOpts().OutputFile, Binary, 558ae77b3dfSDaniel Dunbar /*RemoveFileOnSignal=*/true, InFile, Extension, 559ae77b3dfSDaniel Dunbar /*UseTemporary=*/true); 560420b0f1bSDaniel Dunbar } 561420b0f1bSDaniel Dunbar 562ea04672cSAlp Toker llvm::raw_null_ostream *CompilerInstance::createNullOutputFile() { 56369f3528cSNAKAMURA Takumi llvm::raw_null_ostream *OS = new llvm::raw_null_ostream(); 56469f3528cSNAKAMURA Takumi addOutputFile(OutputFile("", "", OS)); 56569f3528cSNAKAMURA Takumi return OS; 566ea04672cSAlp Toker } 567ea04672cSAlp Toker 568420b0f1bSDaniel Dunbar llvm::raw_fd_ostream * 5690e62c1ccSChris Lattner CompilerInstance::createOutputFile(StringRef OutputPath, 570e326f9bbSDaniel Dunbar bool Binary, bool RemoveFileOnSignal, 5710e62c1ccSChris Lattner StringRef InFile, 57208a2bfd2SArgyrios Kyrtzidis StringRef Extension, 573b9c62c07SDaniel Dunbar bool UseTemporary, 574b9c62c07SDaniel Dunbar bool CreateMissingDirectories) { 575dae941a6SRafael Espindola std::string OutputPathName, TempPathName; 576dae941a6SRafael Espindola std::error_code EC; 577dae941a6SRafael Espindola llvm::raw_fd_ostream *OS = createOutputFile( 578dae941a6SRafael Espindola OutputPath, EC, Binary, RemoveFileOnSignal, InFile, Extension, 579dae941a6SRafael Espindola UseTemporary, CreateMissingDirectories, &OutputPathName, &TempPathName); 580420b0f1bSDaniel Dunbar if (!OS) { 581dae941a6SRafael Espindola getDiagnostics().Report(diag::err_fe_unable_to_open_output) << OutputPath 582dae941a6SRafael Espindola << EC.message(); 58349a2790fSCraig Topper return nullptr; 584420b0f1bSDaniel Dunbar } 585420b0f1bSDaniel Dunbar 586420b0f1bSDaniel Dunbar // Add the output file -- but don't try to remove "-", since this means we are 587420b0f1bSDaniel Dunbar // using stdin. 588d0599970SArgyrios Kyrtzidis addOutputFile(OutputFile((OutputPathName != "-") ? OutputPathName : "", 58969f3528cSNAKAMURA Takumi TempPathName, OS)); 590420b0f1bSDaniel Dunbar 59169f3528cSNAKAMURA Takumi return OS; 592420b0f1bSDaniel Dunbar } 593420b0f1bSDaniel Dunbar 594dae941a6SRafael Espindola llvm::raw_fd_ostream *CompilerInstance::createOutputFile( 595dae941a6SRafael Espindola StringRef OutputPath, std::error_code &Error, bool Binary, 596dae941a6SRafael Espindola bool RemoveFileOnSignal, StringRef InFile, StringRef Extension, 597dae941a6SRafael Espindola bool UseTemporary, bool CreateMissingDirectories, 598dae941a6SRafael Espindola std::string *ResultPathName, std::string *TempPathName) { 599b9c62c07SDaniel Dunbar assert((!CreateMissingDirectories || UseTemporary) && 600b9c62c07SDaniel Dunbar "CreateMissingDirectories is only allowed when using temporary files"); 601b9c62c07SDaniel Dunbar 602d0599970SArgyrios Kyrtzidis std::string OutFile, TempFile; 603420b0f1bSDaniel Dunbar if (!OutputPath.empty()) { 604420b0f1bSDaniel Dunbar OutFile = OutputPath; 605420b0f1bSDaniel Dunbar } else if (InFile == "-") { 606420b0f1bSDaniel Dunbar OutFile = "-"; 607420b0f1bSDaniel Dunbar } else if (!Extension.empty()) { 608399ab33aSRafael Espindola SmallString<128> Path(InFile); 609399ab33aSRafael Espindola llvm::sys::path::replace_extension(Path, Extension); 610420b0f1bSDaniel Dunbar OutFile = Path.str(); 611420b0f1bSDaniel Dunbar } else { 612420b0f1bSDaniel Dunbar OutFile = "-"; 613420b0f1bSDaniel Dunbar } 614420b0f1bSDaniel Dunbar 615b8984329SAhmed Charles std::unique_ptr<llvm::raw_fd_ostream> OS; 61608a2bfd2SArgyrios Kyrtzidis std::string OSFile; 61708a2bfd2SArgyrios Kyrtzidis 61873c23a71SRafael Espindola if (UseTemporary) { 61973c23a71SRafael Espindola if (OutFile == "-") 62073c23a71SRafael Espindola UseTemporary = false; 62173c23a71SRafael Espindola else { 62273c23a71SRafael Espindola llvm::sys::fs::file_status Status; 62373c23a71SRafael Espindola llvm::sys::fs::status(OutputPath, Status); 62473c23a71SRafael Espindola if (llvm::sys::fs::exists(Status)) { 62573c23a71SRafael Espindola // Fail early if we can't write to the final destination. 62673c23a71SRafael Espindola if (!llvm::sys::fs::can_write(OutputPath)) 62749a2790fSCraig Topper return nullptr; 62873c23a71SRafael Espindola 62973c23a71SRafael Espindola // Don't use a temporary if the output is a special file. This handles 63073c23a71SRafael Espindola // things like '-o /dev/null' 63173c23a71SRafael Espindola if (!llvm::sys::fs::is_regular_file(Status)) 63273c23a71SRafael Espindola UseTemporary = false; 63373c23a71SRafael Espindola } 63473c23a71SRafael Espindola } 63573c23a71SRafael Espindola } 63673c23a71SRafael Espindola 63773c23a71SRafael Espindola if (UseTemporary) { 638d0599970SArgyrios Kyrtzidis // Create a temporary file. 6392c1dd271SDylan Noblesmith SmallString<128> TempPath; 64008a2bfd2SArgyrios Kyrtzidis TempPath = OutFile; 64108a2bfd2SArgyrios Kyrtzidis TempPath += "-%%%%%%%%"; 64208a2bfd2SArgyrios Kyrtzidis int fd; 643c080917eSRafael Espindola std::error_code EC = 64418627115SRafael Espindola llvm::sys::fs::createUniqueFile(TempPath.str(), fd, TempPath); 645157f34bdSRafael Espindola 646157f34bdSRafael Espindola if (CreateMissingDirectories && 64771de0b61SRafael Espindola EC == llvm::errc::no_such_file_or_directory) { 648157f34bdSRafael Espindola StringRef Parent = llvm::sys::path::parent_path(OutputPath); 649157f34bdSRafael Espindola EC = llvm::sys::fs::create_directories(Parent); 650157f34bdSRafael Espindola if (!EC) { 65118627115SRafael Espindola EC = llvm::sys::fs::createUniqueFile(TempPath.str(), fd, TempPath); 652157f34bdSRafael Espindola } 653157f34bdSRafael Espindola } 654157f34bdSRafael Espindola 655157f34bdSRafael Espindola if (!EC) { 65669f3528cSNAKAMURA Takumi OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true)); 65708a2bfd2SArgyrios Kyrtzidis OSFile = TempFile = TempPath.str(); 65808a2bfd2SArgyrios Kyrtzidis } 65973c23a71SRafael Espindola // If we failed to create the temporary, fallback to writing to the file 66073c23a71SRafael Espindola // directly. This handles the corner case where we cannot write to the 66173c23a71SRafael Espindola // directory, but can write to the file. 662d0599970SArgyrios Kyrtzidis } 663d0599970SArgyrios Kyrtzidis 66408a2bfd2SArgyrios Kyrtzidis if (!OS) { 66508a2bfd2SArgyrios Kyrtzidis OSFile = OutFile; 66669f3528cSNAKAMURA Takumi OS.reset(new llvm::raw_fd_ostream( 667dae941a6SRafael Espindola OSFile, Error, 66869f3528cSNAKAMURA Takumi (Binary ? llvm::sys::fs::F_None : llvm::sys::fs::F_Text))); 669dae941a6SRafael Espindola if (Error) 67049a2790fSCraig Topper return nullptr; 67108a2bfd2SArgyrios Kyrtzidis } 672420b0f1bSDaniel Dunbar 673d0599970SArgyrios Kyrtzidis // Make sure the out stream file gets removed if we crash. 674e326f9bbSDaniel Dunbar if (RemoveFileOnSignal) 67518556de3SRafael Espindola llvm::sys::RemoveFileOnSignal(OSFile); 676d0599970SArgyrios Kyrtzidis 677420b0f1bSDaniel Dunbar if (ResultPathName) 678420b0f1bSDaniel Dunbar *ResultPathName = OutFile; 679d0599970SArgyrios Kyrtzidis if (TempPathName) 680d0599970SArgyrios Kyrtzidis *TempPathName = TempFile; 681420b0f1bSDaniel Dunbar 68269f3528cSNAKAMURA Takumi return OS.release(); 683420b0f1bSDaniel Dunbar } 684409e890fSDaniel Dunbar 685409e890fSDaniel Dunbar // Initialization Utilities 686409e890fSDaniel Dunbar 6871b3240b0SArgyrios Kyrtzidis bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input){ 6881b3240b0SArgyrios Kyrtzidis return InitializeSourceManager(Input, getDiagnostics(), 689a686e1b0SDouglas Gregor getFileManager(), getSourceManager(), 690a686e1b0SDouglas Gregor getFrontendOpts()); 691409e890fSDaniel Dunbar } 692409e890fSDaniel Dunbar 6931b3240b0SArgyrios Kyrtzidis bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input, 6949c902b55SDavid Blaikie DiagnosticsEngine &Diags, 695409e890fSDaniel Dunbar FileManager &FileMgr, 696409e890fSDaniel Dunbar SourceManager &SourceMgr, 697409e890fSDaniel Dunbar const FrontendOptions &Opts) { 6981b3240b0SArgyrios Kyrtzidis SrcMgr::CharacteristicKind 699873c8583SArgyrios Kyrtzidis Kind = Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User; 7001b3240b0SArgyrios Kyrtzidis 7016566e23eSArgyrios Kyrtzidis if (Input.isBuffer()) { 70250a5f97eSDavid Blaikie SourceMgr.setMainFileID(SourceMgr.createFileID( 70350a5f97eSDavid Blaikie std::unique_ptr<llvm::MemoryBuffer>(Input.getBuffer()), Kind)); 7046566e23eSArgyrios Kyrtzidis assert(!SourceMgr.getMainFileID().isInvalid() && 7056566e23eSArgyrios Kyrtzidis "Couldn't establish MainFileID!"); 7066566e23eSArgyrios Kyrtzidis return true; 7076566e23eSArgyrios Kyrtzidis } 7086566e23eSArgyrios Kyrtzidis 7096566e23eSArgyrios Kyrtzidis StringRef InputFile = Input.getFile(); 7106566e23eSArgyrios Kyrtzidis 7117c06d866SArgyrios Kyrtzidis // Figure out where to get and map in the main file. 7127c06d866SArgyrios Kyrtzidis if (InputFile != "-") { 7133841fa38SBenjamin Kramer const FileEntry *File = FileMgr.getFile(InputFile, /*OpenFile=*/true); 71452765215SDan Gohman if (!File) { 715409e890fSDaniel Dunbar Diags.Report(diag::err_fe_error_reading) << InputFile; 716409e890fSDaniel Dunbar return false; 717409e890fSDaniel Dunbar } 718e2951f48SDaniel Dunbar 719e2951f48SDaniel Dunbar // The natural SourceManager infrastructure can't currently handle named 720e2951f48SDaniel Dunbar // pipes, but we would at least like to accept them for the main 7213841fa38SBenjamin Kramer // file. Detect them here, read them with the volatile flag so FileMgr will 7223841fa38SBenjamin Kramer // pick up the correct size, and simply override their contents as we do for 7233841fa38SBenjamin Kramer // STDIN. 724e2951f48SDaniel Dunbar if (File->isNamedPipe()) { 725a885796dSBenjamin Kramer auto MB = FileMgr.getBufferForFile(File, /*isVolatile=*/true); 726a885796dSBenjamin Kramer if (MB) { 727db0745abSDaniel Dunbar // Create a new virtual file that will have the correct size. 728a885796dSBenjamin Kramer File = FileMgr.getVirtualFile(InputFile, (*MB)->getBufferSize(), 0); 729a885796dSBenjamin Kramer SourceMgr.overrideFileContents(File, std::move(*MB)); 7303841fa38SBenjamin Kramer } else { 731a885796dSBenjamin Kramer Diags.Report(diag::err_cannot_open_file) << InputFile 732a885796dSBenjamin Kramer << MB.getError().message(); 7333841fa38SBenjamin Kramer return false; 7343841fa38SBenjamin Kramer } 735e2951f48SDaniel Dunbar } 736db0745abSDaniel Dunbar 737b671e34cSAlp Toker SourceMgr.setMainFileID( 738b671e34cSAlp Toker SourceMgr.createFileID(File, SourceLocation(), Kind)); 739409e890fSDaniel Dunbar } else { 7402d2b420aSRafael Espindola llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> SBOrErr = 7412d2b420aSRafael Espindola llvm::MemoryBuffer::getSTDIN(); 7422d2b420aSRafael Espindola if (std::error_code EC = SBOrErr.getError()) { 7432d2b420aSRafael Espindola Diags.Report(diag::err_fe_error_reading_stdin) << EC.message(); 744409e890fSDaniel Dunbar return false; 745409e890fSDaniel Dunbar } 7462d2b420aSRafael Espindola std::unique_ptr<llvm::MemoryBuffer> SB = std::move(SBOrErr.get()); 7472d2b420aSRafael Espindola 7482f76cd75SDan Gohman const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(), 7495159f616SChris Lattner SB->getBufferSize(), 0); 750b671e34cSAlp Toker SourceMgr.setMainFileID( 751b671e34cSAlp Toker SourceMgr.createFileID(File, SourceLocation(), Kind)); 75249cc3181SDavid Blaikie SourceMgr.overrideFileContents(File, std::move(SB)); 753409e890fSDaniel Dunbar } 754409e890fSDaniel Dunbar 75552765215SDan Gohman assert(!SourceMgr.getMainFileID().isInvalid() && 75652765215SDan Gohman "Couldn't establish MainFileID!"); 757409e890fSDaniel Dunbar return true; 758409e890fSDaniel Dunbar } 7594f2bc55dSDaniel Dunbar 7604f2bc55dSDaniel Dunbar // High-Level Operations 7614f2bc55dSDaniel Dunbar 7624f2bc55dSDaniel Dunbar bool CompilerInstance::ExecuteAction(FrontendAction &Act) { 7634f2bc55dSDaniel Dunbar assert(hasDiagnostics() && "Diagnostics engine is not initialized!"); 7644f2bc55dSDaniel Dunbar assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!"); 7654f2bc55dSDaniel Dunbar assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!"); 7664f2bc55dSDaniel Dunbar 7674f2bc55dSDaniel Dunbar // FIXME: Take this as an argument, once all the APIs we used have moved to 7684f2bc55dSDaniel Dunbar // taking it as an input instead of hard-coding llvm::errs. 7690e62c1ccSChris Lattner raw_ostream &OS = llvm::errs(); 7704f2bc55dSDaniel Dunbar 7714f2bc55dSDaniel Dunbar // Create the target instance. 77280758084SAlp Toker setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), 77380758084SAlp Toker getInvocation().TargetOpts)); 7744f2bc55dSDaniel Dunbar if (!hasTarget()) 7754f2bc55dSDaniel Dunbar return false; 7764f2bc55dSDaniel Dunbar 7774f2bc55dSDaniel Dunbar // Inform the target of the language options. 7784f2bc55dSDaniel Dunbar // 7794f2bc55dSDaniel Dunbar // FIXME: We shouldn't need to do this, the target should be immutable once 7804f2bc55dSDaniel Dunbar // created. This complexity should be lifted elsewhere. 78174437975SAlp Toker getTarget().adjust(getLangOpts()); 7824f2bc55dSDaniel Dunbar 78329898f45SFariborz Jahanian // rewriter project will change target built-in bool type from its default. 78429898f45SFariborz Jahanian if (getFrontendOpts().ProgramAction == frontend::RewriteObjC) 78529898f45SFariborz Jahanian getTarget().noSignedCharForObjCBool(); 78629898f45SFariborz Jahanian 7874f2bc55dSDaniel Dunbar // Validate/process some options. 7884f2bc55dSDaniel Dunbar if (getHeaderSearchOpts().Verbose) 7894f2bc55dSDaniel Dunbar OS << "clang -cc1 version " CLANG_VERSION_STRING 790f988d006SAlp Toker << " based upon " << BACKEND_PACKAGE_STRING 7918188c8a1SSebastian Pop << " default target " << llvm::sys::getDefaultTargetTriple() << "\n"; 7924f2bc55dSDaniel Dunbar 7934f2bc55dSDaniel Dunbar if (getFrontendOpts().ShowTimers) 7944f2bc55dSDaniel Dunbar createFrontendTimer(); 7954f2bc55dSDaniel Dunbar 796171b780cSDouglas Gregor if (getFrontendOpts().ShowStats) 797171b780cSDouglas Gregor llvm::EnableStatistics(); 798171b780cSDouglas Gregor 7994f2bc55dSDaniel Dunbar for (unsigned i = 0, e = getFrontendOpts().Inputs.size(); i != e; ++i) { 800eeccb30bSTed Kremenek // Reset the ID tables if we are reusing the SourceManager and parsing 801eeccb30bSTed Kremenek // regular files. 802eeccb30bSTed Kremenek if (hasSourceManager() && !Act.isModelParsingAction()) 8034f2bc55dSDaniel Dunbar getSourceManager().clearIDTables(); 8044f2bc55dSDaniel Dunbar 80532fbe312SDouglas Gregor if (Act.BeginSourceFile(*this, getFrontendOpts().Inputs[i])) { 8064f2bc55dSDaniel Dunbar Act.Execute(); 8074f2bc55dSDaniel Dunbar Act.EndSourceFile(); 8084f2bc55dSDaniel Dunbar } 8094f2bc55dSDaniel Dunbar } 8104f2bc55dSDaniel Dunbar 8117910d7b7SArgyrios Kyrtzidis // Notify the diagnostic client that all files were processed. 8127910d7b7SArgyrios Kyrtzidis getDiagnostics().getClient()->finish(); 8137910d7b7SArgyrios Kyrtzidis 814198cb4dfSChris Lattner if (getDiagnosticOpts().ShowCarets) { 815c79346a5SArgyrios Kyrtzidis // We can have multiple diagnostics sharing one diagnostic client. 816c79346a5SArgyrios Kyrtzidis // Get the total number of warnings/errors from the client. 817c79346a5SArgyrios Kyrtzidis unsigned NumWarnings = getDiagnostics().getClient()->getNumWarnings(); 818c79346a5SArgyrios Kyrtzidis unsigned NumErrors = getDiagnostics().getClient()->getNumErrors(); 819198cb4dfSChris Lattner 820198cb4dfSChris Lattner if (NumWarnings) 821198cb4dfSChris Lattner OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s"); 822198cb4dfSChris Lattner if (NumWarnings && NumErrors) 823198cb4dfSChris Lattner OS << " and "; 824198cb4dfSChris Lattner if (NumErrors) 825198cb4dfSChris Lattner OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s"); 826198cb4dfSChris Lattner if (NumWarnings || NumErrors) 827198cb4dfSChris Lattner OS << " generated.\n"; 828198cb4dfSChris Lattner } 8294f2bc55dSDaniel Dunbar 830aed46fcbSDaniel Dunbar if (getFrontendOpts().ShowStats && hasFileManager()) { 8314f2bc55dSDaniel Dunbar getFileManager().PrintStats(); 8324f2bc55dSDaniel Dunbar OS << "\n"; 8334f2bc55dSDaniel Dunbar } 8344f2bc55dSDaniel Dunbar 835bc467933SArgyrios Kyrtzidis return !getDiagnostics().getClient()->getNumErrors(); 8364f2bc55dSDaniel Dunbar } 8374f2bc55dSDaniel Dunbar 838faeb1d46SDouglas Gregor /// \brief Determine the appropriate source input kind based on language 839faeb1d46SDouglas Gregor /// options. 840faeb1d46SDouglas Gregor static InputKind getSourceInputKindFromOptions(const LangOptions &LangOpts) { 841faeb1d46SDouglas Gregor if (LangOpts.OpenCL) 842faeb1d46SDouglas Gregor return IK_OpenCL; 843faeb1d46SDouglas Gregor if (LangOpts.CUDA) 844faeb1d46SDouglas Gregor return IK_CUDA; 845faeb1d46SDouglas Gregor if (LangOpts.ObjC1) 846faeb1d46SDouglas Gregor return LangOpts.CPlusPlus? IK_ObjCXX : IK_ObjC; 847faeb1d46SDouglas Gregor return LangOpts.CPlusPlus? IK_CXX : IK_C; 848faeb1d46SDouglas Gregor } 849faeb1d46SDouglas Gregor 850514b636aSDouglas Gregor /// \brief Compile a module file for the given module, using the options 851b797d59fSBen Langmuir /// provided by the importing compiler instance. Returns true if the module 852b797d59fSBen Langmuir /// was built without errors. 853b797d59fSBen Langmuir static bool compileModuleImpl(CompilerInstance &ImportingInstance, 854af8f0263SDouglas Gregor SourceLocation ImportLoc, 855de3ef502SDouglas Gregor Module *Module, 8566dc57927SDouglas Gregor StringRef ModuleFileName) { 857514b636aSDouglas Gregor ModuleMap &ModMap 858514b636aSDouglas Gregor = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap(); 859514b636aSDouglas Gregor 860faeb1d46SDouglas Gregor // Construct a compiler invocation for creating this module. 861c95d8192SDylan Noblesmith IntrusiveRefCntPtr<CompilerInvocation> Invocation 862faeb1d46SDouglas Gregor (new CompilerInvocation(ImportingInstance.getInvocation())); 86344bf68d8SDouglas Gregor 864f545f67dSDouglas Gregor PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 865f545f67dSDouglas Gregor 86644bf68d8SDouglas Gregor // For any options that aren't intended to affect how a module is built, 86744bf68d8SDouglas Gregor // reset them to their default values. 8688cf47df7STed Kremenek Invocation->getLangOpts()->resetNonModularOptions(); 869f545f67dSDouglas Gregor PPOpts.resetNonModularOptions(); 87044bf68d8SDouglas Gregor 8715dc3899cSDouglas Gregor // Remove any macro definitions that are explicitly ignored by the module. 8725dc3899cSDouglas Gregor // They aren't supposed to affect how the module is built anyway. 8735dc3899cSDouglas Gregor const HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts(); 874bbdd7640SBenjamin Kramer PPOpts.Macros.erase( 875bbdd7640SBenjamin Kramer std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(), 876bbdd7640SBenjamin Kramer [&HSOpts](const std::pair<std::string, bool> &def) { 877bbdd7640SBenjamin Kramer StringRef MacroDef = def.first; 878bbdd7640SBenjamin Kramer return HSOpts.ModulesIgnoreMacros.count(MacroDef.split('=').first) > 0; 879bbdd7640SBenjamin Kramer }), 8805dc3899cSDouglas Gregor PPOpts.Macros.end()); 8815dc3899cSDouglas Gregor 8827d106e42SDouglas Gregor // Note the name of the module we're building. 8836dc57927SDouglas Gregor Invocation->getLangOpts()->CurrentModule = Module->getTopLevelModuleName(); 8847d106e42SDouglas Gregor 8857a626570SDouglas Gregor // Make sure that the failed-module structure has been allocated in 8867a626570SDouglas Gregor // the importing instance, and propagate the pointer to the newly-created 8877a626570SDouglas Gregor // instance. 8887a626570SDouglas Gregor PreprocessorOptions &ImportingPPOpts 8897a626570SDouglas Gregor = ImportingInstance.getInvocation().getPreprocessorOpts(); 8907a626570SDouglas Gregor if (!ImportingPPOpts.FailedModules) 8917a626570SDouglas Gregor ImportingPPOpts.FailedModules = new PreprocessorOptions::FailedModulesSet; 8927a626570SDouglas Gregor PPOpts.FailedModules = ImportingPPOpts.FailedModules; 8937a626570SDouglas Gregor 894514b636aSDouglas Gregor // If there is a module map file, build the module using the module map. 895514b636aSDouglas Gregor // Set up the inputs/outputs so that we build the module from its umbrella 896514b636aSDouglas Gregor // header. 897514b636aSDouglas Gregor FrontendOptions &FrontendOpts = Invocation->getFrontendOpts(); 898514b636aSDouglas Gregor FrontendOpts.OutputFile = ModuleFileName.str(); 899514b636aSDouglas Gregor FrontendOpts.DisableFree = false; 900c1bbec85SDouglas Gregor FrontendOpts.GenerateGlobalModuleIndex = false; 901514b636aSDouglas Gregor FrontendOpts.Inputs.clear(); 902f545f67dSDouglas Gregor InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts()); 903f545f67dSDouglas Gregor 904f545f67dSDouglas Gregor // Don't free the remapped file buffers; they are owned by our caller. 905f545f67dSDouglas Gregor PPOpts.RetainRemappedFileBuffers = true; 906514b636aSDouglas Gregor 907514b636aSDouglas Gregor Invocation->getDiagnosticOpts().VerifyDiagnostics = 0; 908514b636aSDouglas Gregor assert(ImportingInstance.getInvocation().getModuleHash() == 909514b636aSDouglas Gregor Invocation->getModuleHash() && "Module hash mismatch!"); 910514b636aSDouglas Gregor 911514b636aSDouglas Gregor // Construct a compiler instance that will be used to actually create the 912514b636aSDouglas Gregor // module. 9132255f2ceSJohn Thompson CompilerInstance Instance(/*BuildingModule=*/true); 914514b636aSDouglas Gregor Instance.setInvocation(&*Invocation); 9156b930967SDouglas Gregor 9166b930967SDouglas Gregor Instance.createDiagnostics(new ForwardingDiagnosticConsumer( 9176b930967SDouglas Gregor ImportingInstance.getDiagnosticClient()), 91830071ceaSDouglas Gregor /*ShouldOwnClient=*/true); 919514b636aSDouglas Gregor 920c8130a74SBen Langmuir Instance.setVirtualFileSystem(&ImportingInstance.getVirtualFileSystem()); 921c8130a74SBen Langmuir 92263365431SDouglas Gregor // Note that this module is part of the module build stack, so that we 923af8f0263SDouglas Gregor // can detect cycles in the module graph. 924d066d4c8SBen Langmuir Instance.setFileManager(&ImportingInstance.getFileManager()); 925af8f0263SDouglas Gregor Instance.createSourceManager(Instance.getFileManager()); 926af8f0263SDouglas Gregor SourceManager &SourceMgr = Instance.getSourceManager(); 92763365431SDouglas Gregor SourceMgr.setModuleBuildStack( 92863365431SDouglas Gregor ImportingInstance.getSourceManager().getModuleBuildStack()); 92963365431SDouglas Gregor SourceMgr.pushModuleBuildStack(Module->getTopLevelModuleName(), 930af8f0263SDouglas Gregor FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager())); 931af8f0263SDouglas Gregor 93286d1259cSJustin Bogner // If we're collecting module dependencies, we need to share a collector 93386d1259cSJustin Bogner // between all of the module CompilerInstances. 93486d1259cSJustin Bogner Instance.setModuleDepCollector(ImportingInstance.getModuleDepCollector()); 93586d1259cSJustin Bogner 9361f76c4e8SManuel Klimek // Get or create the module map that we'll use to build this module. 9371f76c4e8SManuel Klimek std::string InferredModuleMapContent; 9381f76c4e8SManuel Klimek if (const FileEntry *ModuleMapFile = 9391f76c4e8SManuel Klimek ModMap.getContainingModuleMapFile(Module)) { 9401f76c4e8SManuel Klimek // Use the module map where this module resides. 9411f76c4e8SManuel Klimek FrontendOpts.Inputs.push_back( 9421f76c4e8SManuel Klimek FrontendInputFile(ModuleMapFile->getName(), IK)); 9431f76c4e8SManuel Klimek } else { 9441f76c4e8SManuel Klimek llvm::raw_string_ostream OS(InferredModuleMapContent); 9451f76c4e8SManuel Klimek Module->print(OS); 9461f76c4e8SManuel Klimek OS.flush(); 9471f76c4e8SManuel Klimek FrontendOpts.Inputs.push_back( 9481f76c4e8SManuel Klimek FrontendInputFile("__inferred_module.map", IK)); 9491f76c4e8SManuel Klimek 950d87f8d76SRafael Espindola std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer = 9511f76c4e8SManuel Klimek llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent); 9521f76c4e8SManuel Klimek ModuleMapFile = Instance.getFileManager().getVirtualFile( 9531f76c4e8SManuel Klimek "__inferred_module.map", InferredModuleMapContent.size(), 0); 95449cc3181SDavid Blaikie SourceMgr.overrideFileContents(ModuleMapFile, std::move(ModuleMapBuffer)); 9551f76c4e8SManuel Klimek } 956af8f0263SDouglas Gregor 9579d6448b1SBen Langmuir // Construct a module-generating action. Passing through the module map is 958beee15e7SBen Langmuir // safe because the FileManager is shared between the compiler instances. 9599d6448b1SBen Langmuir GenerateModuleAction CreateModuleAction( 9609d6448b1SBen Langmuir ModMap.getModuleMapFileForUniquing(Module), Module->IsSystem); 961514b636aSDouglas Gregor 96299891da7SRichard Smith ImportingInstance.getDiagnostics().Report(ImportLoc, 96399891da7SRichard Smith diag::remark_module_build) 96499891da7SRichard Smith << Module->Name << ModuleFileName; 96599891da7SRichard Smith 966514b636aSDouglas Gregor // Execute the action to actually build the module in-place. Use a separate 967514b636aSDouglas Gregor // thread so that we get a stack large enough. 968514b636aSDouglas Gregor const unsigned ThreadStackSize = 8 << 20; 969514b636aSDouglas Gregor llvm::CrashRecoveryContext CRC; 970841f1c78SRichard Smith CRC.RunSafelyOnThread([&]() { Instance.ExecuteAction(CreateModuleAction); }, 971841f1c78SRichard Smith ThreadStackSize); 9726b930967SDouglas Gregor 97399891da7SRichard Smith ImportingInstance.getDiagnostics().Report(ImportLoc, 97499891da7SRichard Smith diag::remark_module_build_done) 97599891da7SRichard Smith << Module->Name; 97699891da7SRichard Smith 977f545f67dSDouglas Gregor // Delete the temporary module map file. 978f545f67dSDouglas Gregor // FIXME: Even though we're executing under crash protection, it would still 979f545f67dSDouglas Gregor // be nice to do this with RemoveFileOnSignal when we can. However, that 980f545f67dSDouglas Gregor // doesn't make sense for all clients, so clean this up manually. 98113afbf42SBenjamin Kramer Instance.clearOutputFiles(/*EraseFiles=*/true); 9825e306b12SDouglas Gregor 9835e306b12SDouglas Gregor // We've rebuilt a module. If we're allowed to generate or update the global 9845e306b12SDouglas Gregor // module index, record that fact in the importing compiler instance. 985c1bbec85SDouglas Gregor if (ImportingInstance.getFrontendOpts().GenerateGlobalModuleIndex) { 9865e306b12SDouglas Gregor ImportingInstance.setBuildGlobalModuleIndex(true); 9875e306b12SDouglas Gregor } 988b797d59fSBen Langmuir 989b797d59fSBen Langmuir return !Instance.getDiagnostics().hasErrorOccurred(); 990faeb1d46SDouglas Gregor } 991faeb1d46SDouglas Gregor 992dbdc0368SBen Langmuir static bool compileAndLoadModule(CompilerInstance &ImportingInstance, 9934382fe74SArgyrios Kyrtzidis SourceLocation ImportLoc, 994b797d59fSBen Langmuir SourceLocation ModuleNameLoc, Module *Module, 9954382fe74SArgyrios Kyrtzidis StringRef ModuleFileName) { 996d213aab7SBen Langmuir DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics(); 997d213aab7SBen Langmuir 998b797d59fSBen Langmuir auto diagnoseBuildFailure = [&] { 999d213aab7SBen Langmuir Diags.Report(ModuleNameLoc, diag::err_module_not_built) 1000b797d59fSBen Langmuir << Module->Name << SourceRange(ImportLoc, ModuleNameLoc); 1001b797d59fSBen Langmuir }; 1002b797d59fSBen Langmuir 10034382fe74SArgyrios Kyrtzidis // FIXME: have LockFileManager return an error_code so that we can 10044382fe74SArgyrios Kyrtzidis // avoid the mkdir when the directory already exists. 10054382fe74SArgyrios Kyrtzidis StringRef Dir = llvm::sys::path::parent_path(ModuleFileName); 10064382fe74SArgyrios Kyrtzidis llvm::sys::fs::create_directories(Dir); 10074382fe74SArgyrios Kyrtzidis 10084382fe74SArgyrios Kyrtzidis while (1) { 1009dbdc0368SBen Langmuir unsigned ModuleLoadCapabilities = ASTReader::ARR_Missing; 10104382fe74SArgyrios Kyrtzidis llvm::LockFileManager Locked(ModuleFileName); 10114382fe74SArgyrios Kyrtzidis switch (Locked) { 10124382fe74SArgyrios Kyrtzidis case llvm::LockFileManager::LFS_Error: 1013d213aab7SBen Langmuir Diags.Report(ModuleNameLoc, diag::err_module_lock_failure) 1014d213aab7SBen Langmuir << Module->Name; 1015dbdc0368SBen Langmuir return false; 10164382fe74SArgyrios Kyrtzidis 10174382fe74SArgyrios Kyrtzidis case llvm::LockFileManager::LFS_Owned: 1018dbdc0368SBen Langmuir // We're responsible for building the module ourselves. 1019b797d59fSBen Langmuir if (!compileModuleImpl(ImportingInstance, ModuleNameLoc, Module, 1020b797d59fSBen Langmuir ModuleFileName)) { 1021b797d59fSBen Langmuir diagnoseBuildFailure(); 1022b797d59fSBen Langmuir return false; 1023b797d59fSBen Langmuir } 10244382fe74SArgyrios Kyrtzidis break; 10254382fe74SArgyrios Kyrtzidis 10264382fe74SArgyrios Kyrtzidis case llvm::LockFileManager::LFS_Shared: 10274382fe74SArgyrios Kyrtzidis // Someone else is responsible for building the module. Wait for them to 10284382fe74SArgyrios Kyrtzidis // finish. 10291daf4801SBen Langmuir switch (Locked.waitForUnlock()) { 10301daf4801SBen Langmuir case llvm::LockFileManager::Res_Success: 1031dbdc0368SBen Langmuir ModuleLoadCapabilities |= ASTReader::ARR_OutOfDate; 1032dbdc0368SBen Langmuir break; 10331daf4801SBen Langmuir case llvm::LockFileManager::Res_OwnerDied: 10341daf4801SBen Langmuir continue; // try again to get the lock. 10351daf4801SBen Langmuir case llvm::LockFileManager::Res_Timeout: 10361daf4801SBen Langmuir Diags.Report(ModuleNameLoc, diag::err_module_lock_timeout) 10371daf4801SBen Langmuir << Module->Name; 10381daf4801SBen Langmuir // Clear the lock file so that future invokations can make progress. 10391daf4801SBen Langmuir Locked.unsafeRemoveLockFile(); 10401daf4801SBen Langmuir return false; 10411daf4801SBen Langmuir } 10421daf4801SBen Langmuir break; 10434382fe74SArgyrios Kyrtzidis } 10444382fe74SArgyrios Kyrtzidis 1045dbdc0368SBen Langmuir // Try to read the module file, now that we've compiled it. 1046dbdc0368SBen Langmuir ASTReader::ASTReadResult ReadResult = 1047dbdc0368SBen Langmuir ImportingInstance.getModuleManager()->ReadAST( 1048e842a474SRichard Smith ModuleFileName, serialization::MK_ImplicitModule, ImportLoc, 1049dbdc0368SBen Langmuir ModuleLoadCapabilities); 1050dbdc0368SBen Langmuir 1051dbdc0368SBen Langmuir if (ReadResult == ASTReader::OutOfDate && 1052dbdc0368SBen Langmuir Locked == llvm::LockFileManager::LFS_Shared) { 1053dbdc0368SBen Langmuir // The module may be out of date in the presence of file system races, 1054dbdc0368SBen Langmuir // or if one of its imports depends on header search paths that are not 1055dbdc0368SBen Langmuir // consistent with this ImportingInstance. Try again... 1056dbdc0368SBen Langmuir continue; 1057dbdc0368SBen Langmuir } else if (ReadResult == ASTReader::Missing) { 1058b797d59fSBen Langmuir diagnoseBuildFailure(); 1059d213aab7SBen Langmuir } else if (ReadResult != ASTReader::Success && 1060d213aab7SBen Langmuir !Diags.hasErrorOccurred()) { 1061d213aab7SBen Langmuir // The ASTReader didn't diagnose the error, so conservatively report it. 1062d213aab7SBen Langmuir diagnoseBuildFailure(); 1063dbdc0368SBen Langmuir } 1064dbdc0368SBen Langmuir return ReadResult == ASTReader::Success; 10654382fe74SArgyrios Kyrtzidis } 10664382fe74SArgyrios Kyrtzidis } 10674382fe74SArgyrios Kyrtzidis 106835b13eceSDouglas Gregor /// \brief Diagnose differences between the current definition of the given 106935b13eceSDouglas Gregor /// configuration macro and the definition provided on the command line. 107035b13eceSDouglas Gregor static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro, 107135b13eceSDouglas Gregor Module *Mod, SourceLocation ImportLoc) { 107235b13eceSDouglas Gregor IdentifierInfo *Id = PP.getIdentifierInfo(ConfigMacro); 107335b13eceSDouglas Gregor SourceManager &SourceMgr = PP.getSourceManager(); 107435b13eceSDouglas Gregor 107535b13eceSDouglas Gregor // If this identifier has never had a macro definition, then it could 107635b13eceSDouglas Gregor // not have changed. 107735b13eceSDouglas Gregor if (!Id->hadMacroDefinition()) 107835b13eceSDouglas Gregor return; 107935b13eceSDouglas Gregor 108035b13eceSDouglas Gregor // If this identifier does not currently have a macro definition, 108135b13eceSDouglas Gregor // check whether it had one on the command line. 108235b13eceSDouglas Gregor if (!Id->hasMacroDefinition()) { 1083b6210dffSArgyrios Kyrtzidis MacroDirective::DefInfo LatestDef = 1084b6210dffSArgyrios Kyrtzidis PP.getMacroDirectiveHistory(Id)->getDefinition(); 1085b6210dffSArgyrios Kyrtzidis for (MacroDirective::DefInfo Def = LatestDef; Def; 1086b6210dffSArgyrios Kyrtzidis Def = Def.getPreviousDefinition()) { 1087b6210dffSArgyrios Kyrtzidis FileID FID = SourceMgr.getFileID(Def.getLocation()); 108835b13eceSDouglas Gregor if (FID.isInvalid()) 108935b13eceSDouglas Gregor continue; 109035b13eceSDouglas Gregor 109135b13eceSDouglas Gregor // We only care about the predefines buffer. 109205ba2a05SDouglas Gregor if (FID != PP.getPredefinesFileID()) 109335b13eceSDouglas Gregor continue; 109435b13eceSDouglas Gregor 109535b13eceSDouglas Gregor // This macro was defined on the command line, then #undef'd later. 109635b13eceSDouglas Gregor // Complain. 109735b13eceSDouglas Gregor PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 109835b13eceSDouglas Gregor << true << ConfigMacro << Mod->getFullModuleName(); 1099b6210dffSArgyrios Kyrtzidis if (LatestDef.isUndefined()) 1100b6210dffSArgyrios Kyrtzidis PP.Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here) 110135b13eceSDouglas Gregor << true; 110235b13eceSDouglas Gregor return; 110335b13eceSDouglas Gregor } 110435b13eceSDouglas Gregor 110535b13eceSDouglas Gregor // Okay: no definition in the predefines buffer. 110635b13eceSDouglas Gregor return; 110735b13eceSDouglas Gregor } 110835b13eceSDouglas Gregor 110935b13eceSDouglas Gregor // This identifier has a macro definition. Check whether we had a definition 111035b13eceSDouglas Gregor // on the command line. 1111b6210dffSArgyrios Kyrtzidis MacroDirective::DefInfo LatestDef = 1112b6210dffSArgyrios Kyrtzidis PP.getMacroDirectiveHistory(Id)->getDefinition(); 1113b6210dffSArgyrios Kyrtzidis MacroDirective::DefInfo PredefinedDef; 1114b6210dffSArgyrios Kyrtzidis for (MacroDirective::DefInfo Def = LatestDef; Def; 1115b6210dffSArgyrios Kyrtzidis Def = Def.getPreviousDefinition()) { 1116b6210dffSArgyrios Kyrtzidis FileID FID = SourceMgr.getFileID(Def.getLocation()); 111735b13eceSDouglas Gregor if (FID.isInvalid()) 111835b13eceSDouglas Gregor continue; 111935b13eceSDouglas Gregor 112035b13eceSDouglas Gregor // We only care about the predefines buffer. 112105ba2a05SDouglas Gregor if (FID != PP.getPredefinesFileID()) 112235b13eceSDouglas Gregor continue; 112335b13eceSDouglas Gregor 1124b6210dffSArgyrios Kyrtzidis PredefinedDef = Def; 112535b13eceSDouglas Gregor break; 112635b13eceSDouglas Gregor } 112735b13eceSDouglas Gregor 112835b13eceSDouglas Gregor // If there was no definition for this macro in the predefines buffer, 112935b13eceSDouglas Gregor // complain. 1130b6210dffSArgyrios Kyrtzidis if (!PredefinedDef || 1131b6210dffSArgyrios Kyrtzidis (!PredefinedDef.getLocation().isValid() && 1132b6210dffSArgyrios Kyrtzidis PredefinedDef.getUndefLocation().isValid())) { 113335b13eceSDouglas Gregor PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 113435b13eceSDouglas Gregor << false << ConfigMacro << Mod->getFullModuleName(); 1135b6210dffSArgyrios Kyrtzidis PP.Diag(LatestDef.getLocation(), diag::note_module_def_undef_here) 113635b13eceSDouglas Gregor << false; 113735b13eceSDouglas Gregor return; 113835b13eceSDouglas Gregor } 113935b13eceSDouglas Gregor 114035b13eceSDouglas Gregor // If the current macro definition is the same as the predefined macro 114135b13eceSDouglas Gregor // definition, it's okay. 1142b6210dffSArgyrios Kyrtzidis if (LatestDef.getMacroInfo() == PredefinedDef.getMacroInfo() || 11430c2f30b9SArgyrios Kyrtzidis LatestDef.getMacroInfo()->isIdenticalTo(*PredefinedDef.getMacroInfo(),PP, 11440c2f30b9SArgyrios Kyrtzidis /*Syntactically=*/true)) 114535b13eceSDouglas Gregor return; 114635b13eceSDouglas Gregor 114735b13eceSDouglas Gregor // The macro definitions differ. 114835b13eceSDouglas Gregor PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 114935b13eceSDouglas Gregor << false << ConfigMacro << Mod->getFullModuleName(); 1150b6210dffSArgyrios Kyrtzidis PP.Diag(LatestDef.getLocation(), diag::note_module_def_undef_here) 115135b13eceSDouglas Gregor << false; 115235b13eceSDouglas Gregor } 115335b13eceSDouglas Gregor 1154527b1c95SDouglas Gregor /// \brief Write a new timestamp file with the given path. 1155527b1c95SDouglas Gregor static void writeTimestampFile(StringRef TimestampFile) { 1156dae941a6SRafael Espindola std::error_code EC; 1157dae941a6SRafael Espindola llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::F_None); 1158527b1c95SDouglas Gregor } 1159527b1c95SDouglas Gregor 1160527b1c95SDouglas Gregor /// \brief Prune the module cache of modules that haven't been accessed in 1161527b1c95SDouglas Gregor /// a long time. 1162527b1c95SDouglas Gregor static void pruneModuleCache(const HeaderSearchOptions &HSOpts) { 1163527b1c95SDouglas Gregor struct stat StatBuf; 1164527b1c95SDouglas Gregor llvm::SmallString<128> TimestampFile; 1165527b1c95SDouglas Gregor TimestampFile = HSOpts.ModuleCachePath; 1166527b1c95SDouglas Gregor llvm::sys::path::append(TimestampFile, "modules.timestamp"); 1167527b1c95SDouglas Gregor 1168527b1c95SDouglas Gregor // Try to stat() the timestamp file. 1169527b1c95SDouglas Gregor if (::stat(TimestampFile.c_str(), &StatBuf)) { 1170527b1c95SDouglas Gregor // If the timestamp file wasn't there, create one now. 1171527b1c95SDouglas Gregor if (errno == ENOENT) { 1172527b1c95SDouglas Gregor writeTimestampFile(TimestampFile); 1173527b1c95SDouglas Gregor } 1174527b1c95SDouglas Gregor return; 1175527b1c95SDouglas Gregor } 1176527b1c95SDouglas Gregor 1177527b1c95SDouglas Gregor // Check whether the time stamp is older than our pruning interval. 1178527b1c95SDouglas Gregor // If not, do nothing. 1179527b1c95SDouglas Gregor time_t TimeStampModTime = StatBuf.st_mtime; 118049a2790fSCraig Topper time_t CurrentTime = time(nullptr); 1181dbcf5037SBenjamin Kramer if (CurrentTime - TimeStampModTime <= time_t(HSOpts.ModuleCachePruneInterval)) 1182527b1c95SDouglas Gregor return; 1183527b1c95SDouglas Gregor 1184527b1c95SDouglas Gregor // Write a new timestamp file so that nobody else attempts to prune. 1185527b1c95SDouglas Gregor // There is a benign race condition here, if two Clang instances happen to 1186527b1c95SDouglas Gregor // notice at the same time that the timestamp is out-of-date. 1187527b1c95SDouglas Gregor writeTimestampFile(TimestampFile); 1188527b1c95SDouglas Gregor 1189527b1c95SDouglas Gregor // Walk the entire module cache, looking for unused module files and module 1190527b1c95SDouglas Gregor // indices. 1191c080917eSRafael Espindola std::error_code EC; 1192527b1c95SDouglas Gregor SmallString<128> ModuleCachePathNative; 1193527b1c95SDouglas Gregor llvm::sys::path::native(HSOpts.ModuleCachePath, ModuleCachePathNative); 1194527b1c95SDouglas Gregor for (llvm::sys::fs::directory_iterator 1195527b1c95SDouglas Gregor Dir(ModuleCachePathNative.str(), EC), DirEnd; 1196527b1c95SDouglas Gregor Dir != DirEnd && !EC; Dir.increment(EC)) { 1197527b1c95SDouglas Gregor // If we don't have a directory, there's nothing to look into. 1198a07f720aSRafael Espindola if (!llvm::sys::fs::is_directory(Dir->path())) 1199527b1c95SDouglas Gregor continue; 1200527b1c95SDouglas Gregor 1201527b1c95SDouglas Gregor // Walk all of the files within this directory. 1202527b1c95SDouglas Gregor for (llvm::sys::fs::directory_iterator File(Dir->path(), EC), FileEnd; 1203527b1c95SDouglas Gregor File != FileEnd && !EC; File.increment(EC)) { 1204527b1c95SDouglas Gregor // We only care about module and global module index files. 1205f430da4dSDmitri Gribenko StringRef Extension = llvm::sys::path::extension(File->path()); 1206f430da4dSDmitri Gribenko if (Extension != ".pcm" && Extension != ".timestamp" && 1207f430da4dSDmitri Gribenko llvm::sys::path::filename(File->path()) != "modules.idx") 1208527b1c95SDouglas Gregor continue; 1209527b1c95SDouglas Gregor 1210527b1c95SDouglas Gregor // Look at this file. If we can't stat it, there's nothing interesting 1211527b1c95SDouglas Gregor // there. 1212f430da4dSDmitri Gribenko if (::stat(File->path().c_str(), &StatBuf)) 1213527b1c95SDouglas Gregor continue; 1214527b1c95SDouglas Gregor 1215527b1c95SDouglas Gregor // If the file has been used recently enough, leave it there. 1216527b1c95SDouglas Gregor time_t FileAccessTime = StatBuf.st_atime; 1217dbcf5037SBenjamin Kramer if (CurrentTime - FileAccessTime <= 1218dbcf5037SBenjamin Kramer time_t(HSOpts.ModuleCachePruneAfter)) { 1219527b1c95SDouglas Gregor continue; 1220527b1c95SDouglas Gregor } 1221527b1c95SDouglas Gregor 1222527b1c95SDouglas Gregor // Remove the file. 1223f430da4dSDmitri Gribenko llvm::sys::fs::remove(File->path()); 1224f430da4dSDmitri Gribenko 1225f430da4dSDmitri Gribenko // Remove the timestamp file. 1226f430da4dSDmitri Gribenko std::string TimpestampFilename = File->path() + ".timestamp"; 1227f430da4dSDmitri Gribenko llvm::sys::fs::remove(TimpestampFilename); 1228527b1c95SDouglas Gregor } 1229527b1c95SDouglas Gregor 1230527b1c95SDouglas Gregor // If we removed all of the files in the directory, remove the directory 1231527b1c95SDouglas Gregor // itself. 1232f430da4dSDmitri Gribenko if (llvm::sys::fs::directory_iterator(Dir->path(), EC) == 1233f430da4dSDmitri Gribenko llvm::sys::fs::directory_iterator() && !EC) 12342a008784SRafael Espindola llvm::sys::fs::remove(Dir->path()); 1235527b1c95SDouglas Gregor } 1236527b1c95SDouglas Gregor } 1237527b1c95SDouglas Gregor 12382255f2ceSJohn Thompson void CompilerInstance::createModuleManager() { 12392255f2ceSJohn Thompson if (!ModuleManager) { 12402255f2ceSJohn Thompson if (!hasASTContext()) 12412255f2ceSJohn Thompson createASTContext(); 12422255f2ceSJohn Thompson 12432255f2ceSJohn Thompson // If we're not recursively building a module, check whether we 12442255f2ceSJohn Thompson // need to prune the module cache. 12452255f2ceSJohn Thompson if (getSourceManager().getModuleBuildStack().empty() && 12462255f2ceSJohn Thompson getHeaderSearchOpts().ModuleCachePruneInterval > 0 && 12472255f2ceSJohn Thompson getHeaderSearchOpts().ModuleCachePruneAfter > 0) { 12482255f2ceSJohn Thompson pruneModuleCache(getHeaderSearchOpts()); 12492255f2ceSJohn Thompson } 12502255f2ceSJohn Thompson 12512255f2ceSJohn Thompson HeaderSearchOptions &HSOpts = getHeaderSearchOpts(); 12522255f2ceSJohn Thompson std::string Sysroot = HSOpts.Sysroot; 12532255f2ceSJohn Thompson const PreprocessorOptions &PPOpts = getPreprocessorOpts(); 12542255f2ceSJohn Thompson ModuleManager = new ASTReader(getPreprocessor(), *Context, 12552255f2ceSJohn Thompson Sysroot.empty() ? "" : Sysroot.c_str(), 12562255f2ceSJohn Thompson PPOpts.DisablePCHValidation, 12572255f2ceSJohn Thompson /*AllowASTWithCompilerErrors=*/false, 12582255f2ceSJohn Thompson /*AllowConfigurationMismatch=*/false, 12592255f2ceSJohn Thompson HSOpts.ModulesValidateSystemHeaders, 12602255f2ceSJohn Thompson getFrontendOpts().UseGlobalModuleIndex); 12612255f2ceSJohn Thompson if (hasASTConsumer()) { 12622255f2ceSJohn Thompson ModuleManager->setDeserializationListener( 12632255f2ceSJohn Thompson getASTConsumer().GetASTDeserializationListener()); 12642255f2ceSJohn Thompson getASTContext().setASTMutationListener( 12652255f2ceSJohn Thompson getASTConsumer().GetASTMutationListener()); 12662255f2ceSJohn Thompson } 12672255f2ceSJohn Thompson getASTContext().setExternalSource(ModuleManager); 12682255f2ceSJohn Thompson if (hasSema()) 12692255f2ceSJohn Thompson ModuleManager->InitializeSema(getSema()); 12702255f2ceSJohn Thompson if (hasASTConsumer()) 12712255f2ceSJohn Thompson ModuleManager->StartTranslationUnit(&getASTConsumer()); 12722255f2ceSJohn Thompson } 12732255f2ceSJohn Thompson } 12742255f2ceSJohn Thompson 1275d4b230b3SRichard Smith bool CompilerInstance::loadModuleFile(StringRef FileName) { 1276d4b230b3SRichard Smith // Helper to recursively read the module names for all modules we're adding. 1277d4b230b3SRichard Smith // We mark these as known and redirect any attempt to load that module to 1278d4b230b3SRichard Smith // the files we were handed. 1279d4b230b3SRichard Smith struct ReadModuleNames : ASTReaderListener { 1280d4b230b3SRichard Smith CompilerInstance &CI; 1281d4b230b3SRichard Smith std::vector<StringRef> ModuleFileStack; 128237bd29a5SRichard Smith std::vector<StringRef> ModuleNameStack; 1283d4b230b3SRichard Smith bool Failed; 1284d4b230b3SRichard Smith bool TopFileIsModule; 1285e842a474SRichard Smith 1286d4b230b3SRichard Smith ReadModuleNames(CompilerInstance &CI) 1287d4b230b3SRichard Smith : CI(CI), Failed(false), TopFileIsModule(false) {} 1288e842a474SRichard Smith 1289d4b230b3SRichard Smith bool needsImportVisitation() const override { return true; } 1290e842a474SRichard Smith 1291d4b230b3SRichard Smith void visitImport(StringRef FileName) override { 12928cebe37fSRichard Smith if (!CI.ExplicitlyLoadedModuleFiles.insert(FileName).second) { 12938cebe37fSRichard Smith if (ModuleFileStack.size() == 0) 12948cebe37fSRichard Smith TopFileIsModule = true; 12955638c114SRichard Smith return; 12968cebe37fSRichard Smith } 12975638c114SRichard Smith 1298d4b230b3SRichard Smith ModuleFileStack.push_back(FileName); 129937bd29a5SRichard Smith ModuleNameStack.push_back(StringRef()); 1300d4b230b3SRichard Smith if (ASTReader::readASTFileControlBlock(FileName, CI.getFileManager(), 1301d4b230b3SRichard Smith *this)) { 130237bd29a5SRichard Smith CI.getDiagnostics().Report( 130337bd29a5SRichard Smith SourceLocation(), CI.getFileManager().getBufferForFile(FileName) 130437bd29a5SRichard Smith ? diag::err_module_file_invalid 130537bd29a5SRichard Smith : diag::err_module_file_not_found) 1306e842a474SRichard Smith << FileName; 130737bd29a5SRichard Smith for (int I = ModuleFileStack.size() - 2; I >= 0; --I) 130837bd29a5SRichard Smith CI.getDiagnostics().Report(SourceLocation(), 130937bd29a5SRichard Smith diag::note_module_file_imported_by) 131037bd29a5SRichard Smith << ModuleFileStack[I] 131137bd29a5SRichard Smith << !ModuleNameStack[I].empty() << ModuleNameStack[I]; 1312d4b230b3SRichard Smith Failed = true; 1313e842a474SRichard Smith } 131437bd29a5SRichard Smith ModuleNameStack.pop_back(); 1315d4b230b3SRichard Smith ModuleFileStack.pop_back(); 1316d4b230b3SRichard Smith } 1317d4b230b3SRichard Smith 1318d4b230b3SRichard Smith void ReadModuleName(StringRef ModuleName) override { 1319d4b230b3SRichard Smith if (ModuleFileStack.size() == 1) 1320d4b230b3SRichard Smith TopFileIsModule = true; 132137bd29a5SRichard Smith ModuleNameStack.back() = ModuleName; 1322d4b230b3SRichard Smith 1323d4b230b3SRichard Smith auto &ModuleFile = CI.ModuleFileOverrides[ModuleName]; 13240c6387f7SRichard Smith if (!ModuleFile.empty() && 13250c6387f7SRichard Smith CI.getFileManager().getFile(ModuleFile) != 13260c6387f7SRichard Smith CI.getFileManager().getFile(ModuleFileStack.back())) 1327d4b230b3SRichard Smith CI.getDiagnostics().Report(SourceLocation(), 1328d4b230b3SRichard Smith diag::err_conflicting_module_files) 1329d4b230b3SRichard Smith << ModuleName << ModuleFile << ModuleFileStack.back(); 1330d4b230b3SRichard Smith ModuleFile = ModuleFileStack.back(); 1331d4b230b3SRichard Smith } 1332d4b230b3SRichard Smith } RMN(*this); 1333d4b230b3SRichard Smith 1334*7f330cdbSRichard Smith // If we don't already have an ASTReader, create one now. 1335*7f330cdbSRichard Smith if (!ModuleManager) 1336*7f330cdbSRichard Smith createModuleManager(); 1337*7f330cdbSRichard Smith 1338*7f330cdbSRichard Smith // Tell the module manager about this module file. 1339*7f330cdbSRichard Smith if (getModuleManager()->getModuleManager().addKnownModuleFile(FileName)) { 1340*7f330cdbSRichard Smith getDiagnostics().Report(SourceLocation(), diag::err_module_file_not_found) 1341*7f330cdbSRichard Smith << FileName; 1342*7f330cdbSRichard Smith return false; 1343*7f330cdbSRichard Smith } 1344*7f330cdbSRichard Smith 1345*7f330cdbSRichard Smith // Build our mapping of module names to module files from this file 1346*7f330cdbSRichard Smith // and its imports. 1347d4b230b3SRichard Smith RMN.visitImport(FileName); 1348d4b230b3SRichard Smith 1349d4b230b3SRichard Smith if (RMN.Failed) 1350d4b230b3SRichard Smith return false; 1351d4b230b3SRichard Smith 1352d4b230b3SRichard Smith // If we never found a module name for the top file, then it's not a module, 1353d4b230b3SRichard Smith // it's a PCH or preamble or something. 1354d4b230b3SRichard Smith if (!RMN.TopFileIsModule) { 1355d4b230b3SRichard Smith getDiagnostics().Report(SourceLocation(), diag::err_module_file_not_module) 1356d4b230b3SRichard Smith << FileName; 1357d4b230b3SRichard Smith return false; 1358d4b230b3SRichard Smith } 1359d4b230b3SRichard Smith 1360d4b230b3SRichard Smith return true; 1361e842a474SRichard Smith } 1362e842a474SRichard Smith 1363e842a474SRichard Smith ModuleLoadResult 13647a626570SDouglas Gregor CompilerInstance::loadModule(SourceLocation ImportLoc, 1365ff2be53fSDouglas Gregor ModuleIdPath Path, 1366bcfc7d02SDouglas Gregor Module::NameVisibilityKind Visibility, 1367bcfc7d02SDouglas Gregor bool IsInclusionDirective) { 136892304e00SRichard Smith // Determine what file we're searching from. 136992304e00SRichard Smith StringRef ModuleName = Path[0].first->getName(); 137092304e00SRichard Smith SourceLocation ModuleNameLoc = Path[0].second; 137192304e00SRichard Smith 13721805b8a4SDouglas Gregor // If we've already handled this import, just return the cached result. 13731805b8a4SDouglas Gregor // This one-element cache is important to eliminate redundant diagnostics 13741805b8a4SDouglas Gregor // when both the preprocessor and parser see the same import declaration. 1375ff2be53fSDouglas Gregor if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc) { 1376ff2be53fSDouglas Gregor // Make the named module visible. 1377b537a3a6SBen Langmuir if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule && 1378b537a3a6SBen Langmuir ModuleName != getLangOpts().ImplementationOfModule) 1379125df058SArgyrios Kyrtzidis ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility, 1380fb912657SDouglas Gregor ImportLoc, /*Complain=*/false); 138169021974SDouglas Gregor return LastModuleImportResult; 1382ff2be53fSDouglas Gregor } 13831805b8a4SDouglas Gregor 138449a2790fSCraig Topper clang::Module *Module = nullptr; 13855196bc6bSDouglas Gregor 13865196bc6bSDouglas Gregor // If we don't already have information on this module, load the module now. 1387de3ef502SDouglas Gregor llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known 138869021974SDouglas Gregor = KnownModules.find(Path[0].first); 13892537a364SDouglas Gregor if (Known != KnownModules.end()) { 13902537a364SDouglas Gregor // Retrieve the cached top-level module. 13912537a364SDouglas Gregor Module = Known->second; 1392b537a3a6SBen Langmuir } else if (ModuleName == getLangOpts().CurrentModule || 1393b537a3a6SBen Langmuir ModuleName == getLangOpts().ImplementationOfModule) { 13942537a364SDouglas Gregor // This is the module we're building. 1395527040e0SBen Langmuir Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); 13962537a364SDouglas Gregor Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; 13972537a364SDouglas Gregor } else { 13985196bc6bSDouglas Gregor // Search for a module with the given name. 1399279a6c37SDouglas Gregor Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); 14009eb229bfSBen Langmuir if (!Module) { 14019eb229bfSBen Langmuir getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found) 14029eb229bfSBen Langmuir << ModuleName 14039eb229bfSBen Langmuir << SourceRange(ImportLoc, ModuleNameLoc); 14049eb229bfSBen Langmuir ModuleBuildFailed = true; 14059eb229bfSBen Langmuir return ModuleLoadResult(); 14069eb229bfSBen Langmuir } 14079eb229bfSBen Langmuir 1408d4b230b3SRichard Smith auto Override = ModuleFileOverrides.find(ModuleName); 1409d4b230b3SRichard Smith bool Explicit = Override != ModuleFileOverrides.end(); 1410d2e8b04dSManuel Klimek if (!Explicit && !getLangOpts().ImplicitModules) { 1411d2e8b04dSManuel Klimek getDiagnostics().Report(ModuleNameLoc, diag::err_module_build_disabled) 1412d2e8b04dSManuel Klimek << ModuleName; 1413d2e8b04dSManuel Klimek ModuleBuildFailed = true; 1414d2e8b04dSManuel Klimek return ModuleLoadResult(); 1415d2e8b04dSManuel Klimek } 1416d4b230b3SRichard Smith 1417f24d9c91SJustin Bogner std::string ModuleFileName = 1418d4b230b3SRichard Smith Explicit ? Override->second 1419d4b230b3SRichard Smith : PP->getHeaderSearchInfo().getModuleFileName(Module); 1420faeb1d46SDouglas Gregor 142108142534SDouglas Gregor // If we don't already have an ASTReader, create one now. 14222255f2ceSJohn Thompson if (!ModuleManager) 14232255f2ceSJohn Thompson createModuleManager(); 142408142534SDouglas Gregor 1425cb69b57bSBen Langmuir if (TheDependencyFileGenerator) 1426cb69b57bSBen Langmuir TheDependencyFileGenerator->AttachToASTReader(*ModuleManager); 1427cb69b57bSBen Langmuir 142886d1259cSJustin Bogner if (ModuleDepCollector) 142986d1259cSJustin Bogner ModuleDepCollector->attachToASTReader(*ModuleManager); 143086d1259cSJustin Bogner 143133c8090aSBen Langmuir for (auto &Listener : DependencyCollectors) 143233c8090aSBen Langmuir Listener->attachToASTReader(*ModuleManager); 143333c8090aSBen Langmuir 14347029ce1aSDouglas Gregor // Try to load the module file. 1435d4b230b3SRichard Smith unsigned ARRFlags = 1436d4b230b3SRichard Smith Explicit ? 0 : ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing; 1437e842a474SRichard Smith switch (ModuleManager->ReadAST(ModuleFileName, 1438d4b230b3SRichard Smith Explicit ? serialization::MK_ExplicitModule 1439d4b230b3SRichard Smith : serialization::MK_ImplicitModule, 1440d4b230b3SRichard Smith ImportLoc, ARRFlags)) { 144108142534SDouglas Gregor case ASTReader::Success: 144208142534SDouglas Gregor break; 144308142534SDouglas Gregor 1444963ff2c3SEli Friedman case ASTReader::OutOfDate: 14457029ce1aSDouglas Gregor case ASTReader::Missing: { 1446d4b230b3SRichard Smith if (Explicit) { 1447d4b230b3SRichard Smith // ReadAST has already complained for us. 1448d4b230b3SRichard Smith ModuleLoader::HadFatalFailure = true; 1449d4b230b3SRichard Smith KnownModules[Path[0].first] = nullptr; 1450d4b230b3SRichard Smith return ModuleLoadResult(); 1451d4b230b3SRichard Smith } 1452d4b230b3SRichard Smith 1453963ff2c3SEli Friedman // The module file is missing or out-of-date. Build it. 14549eb229bfSBen Langmuir assert(Module && "missing module file"); 14557029ce1aSDouglas Gregor // Check whether there is a cycle in the module graph. 14567029ce1aSDouglas Gregor ModuleBuildStack ModPath = getSourceManager().getModuleBuildStack(); 14577029ce1aSDouglas Gregor ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end(); 14587029ce1aSDouglas Gregor for (; Pos != PosEnd; ++Pos) { 14597029ce1aSDouglas Gregor if (Pos->first == ModuleName) 14607029ce1aSDouglas Gregor break; 14617029ce1aSDouglas Gregor } 14627029ce1aSDouglas Gregor 14637029ce1aSDouglas Gregor if (Pos != PosEnd) { 14647029ce1aSDouglas Gregor SmallString<256> CyclePath; 14657029ce1aSDouglas Gregor for (; Pos != PosEnd; ++Pos) { 14667029ce1aSDouglas Gregor CyclePath += Pos->first; 14677029ce1aSDouglas Gregor CyclePath += " -> "; 14687029ce1aSDouglas Gregor } 14697029ce1aSDouglas Gregor CyclePath += ModuleName; 14707029ce1aSDouglas Gregor 14717029ce1aSDouglas Gregor getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle) 14727029ce1aSDouglas Gregor << ModuleName << CyclePath; 14737029ce1aSDouglas Gregor return ModuleLoadResult(); 14747029ce1aSDouglas Gregor } 14757a626570SDouglas Gregor 14767a626570SDouglas Gregor // Check whether we have already attempted to build this module (but 14777a626570SDouglas Gregor // failed). 14787a626570SDouglas Gregor if (getPreprocessorOpts().FailedModules && 14797a626570SDouglas Gregor getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) { 14807a626570SDouglas Gregor getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built) 14817a626570SDouglas Gregor << ModuleName 14827a626570SDouglas Gregor << SourceRange(ImportLoc, ModuleNameLoc); 1483c1bbec85SDouglas Gregor ModuleBuildFailed = true; 14847a626570SDouglas Gregor return ModuleLoadResult(); 14857a626570SDouglas Gregor } 14867a626570SDouglas Gregor 1487dbdc0368SBen Langmuir // Try to compile and then load the module. 1488dbdc0368SBen Langmuir if (!compileAndLoadModule(*this, ImportLoc, ModuleNameLoc, Module, 1489dbdc0368SBen Langmuir ModuleFileName)) { 1490d213aab7SBen Langmuir assert(getDiagnostics().hasErrorOccurred() && 1491d213aab7SBen Langmuir "undiagnosed error in compileAndLoadModule"); 14920f2b4635SDouglas Gregor if (getPreprocessorOpts().FailedModules) 14937a626570SDouglas Gregor getPreprocessorOpts().FailedModules->addFailed(ModuleName); 149449a2790fSCraig Topper KnownModules[Path[0].first] = nullptr; 1495c1bbec85SDouglas Gregor ModuleBuildFailed = true; 14967a626570SDouglas Gregor return ModuleLoadResult(); 1497188dbef2SDouglas Gregor } 1498188dbef2SDouglas Gregor 1499188dbef2SDouglas Gregor // Okay, we've rebuilt and now loaded the module. 1500188dbef2SDouglas Gregor break; 1501188dbef2SDouglas Gregor } 1502188dbef2SDouglas Gregor 1503c9ad5fb6SDouglas Gregor case ASTReader::VersionMismatch: 1504c9ad5fb6SDouglas Gregor case ASTReader::ConfigurationMismatch: 1505c9ad5fb6SDouglas Gregor case ASTReader::HadErrors: 1506dc9fdaf2SArgyrios Kyrtzidis ModuleLoader::HadFatalFailure = true; 150708142534SDouglas Gregor // FIXME: The ASTReader will already have complained, but can we showhorn 150808142534SDouglas Gregor // that diagnostic information into a more useful form? 150949a2790fSCraig Topper KnownModules[Path[0].first] = nullptr; 15107a626570SDouglas Gregor return ModuleLoadResult(); 151108142534SDouglas Gregor 151208142534SDouglas Gregor case ASTReader::Failure: 1513dc9fdaf2SArgyrios Kyrtzidis ModuleLoader::HadFatalFailure = true; 151469021974SDouglas Gregor // Already complained, but note now that we failed. 151549a2790fSCraig Topper KnownModules[Path[0].first] = nullptr; 1516c1bbec85SDouglas Gregor ModuleBuildFailed = true; 15177a626570SDouglas Gregor return ModuleLoadResult(); 151808142534SDouglas Gregor } 151908142534SDouglas Gregor 152069021974SDouglas Gregor // Cache the result of this top-level module lookup for later. 152169021974SDouglas Gregor Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; 152269021974SDouglas Gregor } 152369021974SDouglas Gregor 152469021974SDouglas Gregor // If we never found the module, fail. 152569021974SDouglas Gregor if (!Module) 15267a626570SDouglas Gregor return ModuleLoadResult(); 152769021974SDouglas Gregor 15285196bc6bSDouglas Gregor // Verify that the rest of the module path actually corresponds to 15295196bc6bSDouglas Gregor // a submodule. 153069021974SDouglas Gregor if (Path.size() > 1) { 15315196bc6bSDouglas Gregor for (unsigned I = 1, N = Path.size(); I != N; ++I) { 15325196bc6bSDouglas Gregor StringRef Name = Path[I].first->getName(); 1533eb90e830SDouglas Gregor clang::Module *Sub = Module->findSubmodule(Name); 15345196bc6bSDouglas Gregor 1535eb90e830SDouglas Gregor if (!Sub) { 15365196bc6bSDouglas Gregor // Attempt to perform typo correction to find a module name that works. 1537f857950dSDmitri Gribenko SmallVector<StringRef, 2> Best; 15385196bc6bSDouglas Gregor unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)(); 15395196bc6bSDouglas Gregor 1540eb90e830SDouglas Gregor for (clang::Module::submodule_iterator J = Module->submodule_begin(), 1541eb90e830SDouglas Gregor JEnd = Module->submodule_end(); 1542eb44edadSMatt Beaumont-Gay J != JEnd; ++J) { 1543eb90e830SDouglas Gregor unsigned ED = Name.edit_distance((*J)->Name, 15445196bc6bSDouglas Gregor /*AllowReplacements=*/true, 15455196bc6bSDouglas Gregor BestEditDistance); 15465196bc6bSDouglas Gregor if (ED <= BestEditDistance) { 1547eb90e830SDouglas Gregor if (ED < BestEditDistance) { 15485196bc6bSDouglas Gregor Best.clear(); 1549eb90e830SDouglas Gregor BestEditDistance = ED; 1550eb90e830SDouglas Gregor } 1551eb90e830SDouglas Gregor 1552eb90e830SDouglas Gregor Best.push_back((*J)->Name); 15535196bc6bSDouglas Gregor } 15545196bc6bSDouglas Gregor } 15555196bc6bSDouglas Gregor 15565196bc6bSDouglas Gregor // If there was a clear winner, user it. 15575196bc6bSDouglas Gregor if (Best.size() == 1) { 15585196bc6bSDouglas Gregor getDiagnostics().Report(Path[I].second, 15595196bc6bSDouglas Gregor diag::err_no_submodule_suggest) 156069021974SDouglas Gregor << Path[I].first << Module->getFullModuleName() << Best[0] 15615196bc6bSDouglas Gregor << SourceRange(Path[0].second, Path[I-1].second) 15625196bc6bSDouglas Gregor << FixItHint::CreateReplacement(SourceRange(Path[I].second), 15635196bc6bSDouglas Gregor Best[0]); 1564eb90e830SDouglas Gregor 1565eb90e830SDouglas Gregor Sub = Module->findSubmodule(Best[0]); 15665196bc6bSDouglas Gregor } 15675196bc6bSDouglas Gregor } 15685196bc6bSDouglas Gregor 1569eb90e830SDouglas Gregor if (!Sub) { 15705196bc6bSDouglas Gregor // No submodule by this name. Complain, and don't look for further 15715196bc6bSDouglas Gregor // submodules. 15725196bc6bSDouglas Gregor getDiagnostics().Report(Path[I].second, diag::err_no_submodule) 157369021974SDouglas Gregor << Path[I].first << Module->getFullModuleName() 15745196bc6bSDouglas Gregor << SourceRange(Path[0].second, Path[I-1].second); 15755196bc6bSDouglas Gregor break; 15765196bc6bSDouglas Gregor } 15775196bc6bSDouglas Gregor 1578eb90e830SDouglas Gregor Module = Sub; 15795196bc6bSDouglas Gregor } 15805196bc6bSDouglas Gregor } 15815196bc6bSDouglas Gregor 1582b537a3a6SBen Langmuir // Don't make the module visible if we are in the implementation. 1583b537a3a6SBen Langmuir if (ModuleName == getLangOpts().ImplementationOfModule) 1584b537a3a6SBen Langmuir return ModuleLoadResult(Module, false); 1585b537a3a6SBen Langmuir 15862537a364SDouglas Gregor // Make the named module visible, if it's not already part of the module 15872537a364SDouglas Gregor // we are parsing. 158898a52db8SDouglas Gregor if (ModuleName != getLangOpts().CurrentModule) { 158998a52db8SDouglas Gregor if (!Module->IsFromModuleFile) { 159098a52db8SDouglas Gregor // We have an umbrella header or directory that doesn't actually include 159198a52db8SDouglas Gregor // all of the headers within the directory it covers. Complain about 159298a52db8SDouglas Gregor // this missing submodule and recover by forgetting that we ever saw 159398a52db8SDouglas Gregor // this submodule. 159498a52db8SDouglas Gregor // FIXME: Should we detect this at module load time? It seems fairly 159598a52db8SDouglas Gregor // expensive (and rare). 159698a52db8SDouglas Gregor getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule) 159798a52db8SDouglas Gregor << Module->getFullModuleName() 159898a52db8SDouglas Gregor << SourceRange(Path.front().second, Path.back().second); 159998a52db8SDouglas Gregor 160049a2790fSCraig Topper return ModuleLoadResult(nullptr, true); 160198a52db8SDouglas Gregor } 16021fb5c3a6SDouglas Gregor 16031fb5c3a6SDouglas Gregor // Check whether this module is available. 1604a3feee2aSRichard Smith clang::Module::Requirement Requirement; 16053c1a41adSRichard Smith clang::Module::UnresolvedHeaderDirective MissingHeader; 16060761a8a0SDaniel Jasper if (!Module->isAvailable(getLangOpts(), getTarget(), Requirement, 16070761a8a0SDaniel Jasper MissingHeader)) { 16080761a8a0SDaniel Jasper if (MissingHeader.FileNameLoc.isValid()) { 16090761a8a0SDaniel Jasper getDiagnostics().Report(MissingHeader.FileNameLoc, 16100761a8a0SDaniel Jasper diag::err_module_header_missing) 16110761a8a0SDaniel Jasper << MissingHeader.IsUmbrella << MissingHeader.FileName; 16120761a8a0SDaniel Jasper } else { 16131fb5c3a6SDouglas Gregor getDiagnostics().Report(ImportLoc, diag::err_module_unavailable) 16141fb5c3a6SDouglas Gregor << Module->getFullModuleName() 1615a3feee2aSRichard Smith << Requirement.second << Requirement.first 16161fb5c3a6SDouglas Gregor << SourceRange(Path.front().second, Path.back().second); 16170761a8a0SDaniel Jasper } 16181fb5c3a6SDouglas Gregor LastModuleImportLoc = ImportLoc; 16197a626570SDouglas Gregor LastModuleImportResult = ModuleLoadResult(); 16207a626570SDouglas Gregor return ModuleLoadResult(); 16211fb5c3a6SDouglas Gregor } 16221fb5c3a6SDouglas Gregor 1623fb912657SDouglas Gregor ModuleManager->makeModuleVisible(Module, Visibility, ImportLoc, 1624fb912657SDouglas Gregor /*Complain=*/true); 162598a52db8SDouglas Gregor } 16265196bc6bSDouglas Gregor 162735b13eceSDouglas Gregor // Check for any configuration macros that have changed. 162835b13eceSDouglas Gregor clang::Module *TopModule = Module->getTopLevelModule(); 162935b13eceSDouglas Gregor for (unsigned I = 0, N = TopModule->ConfigMacros.size(); I != N; ++I) { 163035b13eceSDouglas Gregor checkConfigMacro(getPreprocessor(), TopModule->ConfigMacros[I], 163135b13eceSDouglas Gregor Module, ImportLoc); 163235b13eceSDouglas Gregor } 163335b13eceSDouglas Gregor 16343c1a41adSRichard Smith // Determine whether we're in the #include buffer for a module. The #includes 16353c1a41adSRichard Smith // in that buffer do not qualify as module imports; they're just an 16363c1a41adSRichard Smith // implementation detail of us building the module. 16373c1a41adSRichard Smith bool IsInModuleIncludes = !getLangOpts().CurrentModule.empty() && 16383c1a41adSRichard Smith getSourceManager().getFileID(ImportLoc) == 16393c1a41adSRichard Smith getSourceManager().getMainFileID(); 16403c1a41adSRichard Smith 1641bcfc7d02SDouglas Gregor // If this module import was due to an inclusion directive, create an 1642bcfc7d02SDouglas Gregor // implicit import declaration to capture it in the AST. 16433c1a41adSRichard Smith if (IsInclusionDirective && hasASTContext() && !IsInModuleIncludes) { 1644bcfc7d02SDouglas Gregor TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl(); 164572d1aa3cSArgyrios Kyrtzidis ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU, 1646bcfc7d02SDouglas Gregor ImportLoc, Module, 164772d1aa3cSArgyrios Kyrtzidis Path.back().second); 164872d1aa3cSArgyrios Kyrtzidis TU->addDecl(ImportD); 164972d1aa3cSArgyrios Kyrtzidis if (Consumer) 165072d1aa3cSArgyrios Kyrtzidis Consumer->HandleImplicitImportDecl(ImportD); 1651bcfc7d02SDouglas Gregor } 1652bcfc7d02SDouglas Gregor 16531805b8a4SDouglas Gregor LastModuleImportLoc = ImportLoc; 16547a626570SDouglas Gregor LastModuleImportResult = ModuleLoadResult(Module, false); 16557a626570SDouglas Gregor return LastModuleImportResult; 165608142534SDouglas Gregor } 1657c147b0bcSDouglas Gregor 1658c147b0bcSDouglas Gregor void CompilerInstance::makeModuleVisible(Module *Mod, 1659125df058SArgyrios Kyrtzidis Module::NameVisibilityKind Visibility, 1660fb912657SDouglas Gregor SourceLocation ImportLoc, 1661fb912657SDouglas Gregor bool Complain){ 1662fb912657SDouglas Gregor ModuleManager->makeModuleVisible(Mod, Visibility, ImportLoc, Complain); 1663c147b0bcSDouglas Gregor } 1664c147b0bcSDouglas Gregor 16652255f2ceSJohn Thompson GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex( 16662255f2ceSJohn Thompson SourceLocation TriggerLoc) { 16672255f2ceSJohn Thompson if (!ModuleManager) 16682255f2ceSJohn Thompson createModuleManager(); 16692255f2ceSJohn Thompson // Can't do anything if we don't have the module manager. 16702255f2ceSJohn Thompson if (!ModuleManager) 167149a2790fSCraig Topper return nullptr; 16722255f2ceSJohn Thompson // Get an existing global index. This loads it if not already 16732255f2ceSJohn Thompson // loaded. 16742255f2ceSJohn Thompson ModuleManager->loadGlobalIndex(); 16752255f2ceSJohn Thompson GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex(); 16762255f2ceSJohn Thompson // If the global index doesn't exist, create it. 16772255f2ceSJohn Thompson if (!GlobalIndex && shouldBuildGlobalModuleIndex() && hasFileManager() && 16782255f2ceSJohn Thompson hasPreprocessor()) { 16792255f2ceSJohn Thompson llvm::sys::fs::create_directories( 16802255f2ceSJohn Thompson getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); 16812255f2ceSJohn Thompson GlobalModuleIndex::writeIndex( 16822255f2ceSJohn Thompson getFileManager(), 16832255f2ceSJohn Thompson getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); 16842255f2ceSJohn Thompson ModuleManager->resetForReload(); 16852255f2ceSJohn Thompson ModuleManager->loadGlobalIndex(); 16862255f2ceSJohn Thompson GlobalIndex = ModuleManager->getGlobalIndex(); 16872255f2ceSJohn Thompson } 16882255f2ceSJohn Thompson // For finding modules needing to be imported for fixit messages, 16892255f2ceSJohn Thompson // we need to make the global index cover all modules, so we do that here. 16902255f2ceSJohn Thompson if (!HaveFullGlobalModuleIndex && GlobalIndex && !buildingModule()) { 16912255f2ceSJohn Thompson ModuleMap &MMap = getPreprocessor().getHeaderSearchInfo().getModuleMap(); 16922255f2ceSJohn Thompson bool RecreateIndex = false; 16932255f2ceSJohn Thompson for (ModuleMap::module_iterator I = MMap.module_begin(), 16942255f2ceSJohn Thompson E = MMap.module_end(); I != E; ++I) { 16952255f2ceSJohn Thompson Module *TheModule = I->second; 16962255f2ceSJohn Thompson const FileEntry *Entry = TheModule->getASTFile(); 16972255f2ceSJohn Thompson if (!Entry) { 16982255f2ceSJohn Thompson SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path; 16992255f2ceSJohn Thompson Path.push_back(std::make_pair( 17002255f2ceSJohn Thompson getPreprocessor().getIdentifierInfo(TheModule->Name), TriggerLoc)); 17012255f2ceSJohn Thompson std::reverse(Path.begin(), Path.end()); 17022255f2ceSJohn Thompson // Load a module as hidden. This also adds it to the global index. 1703e0a5afe8SJohn Thompson loadModule(TheModule->DefinitionLoc, Path, 17042255f2ceSJohn Thompson Module::Hidden, false); 17052255f2ceSJohn Thompson RecreateIndex = true; 17062255f2ceSJohn Thompson } 17072255f2ceSJohn Thompson } 17082255f2ceSJohn Thompson if (RecreateIndex) { 17092255f2ceSJohn Thompson GlobalModuleIndex::writeIndex( 17102255f2ceSJohn Thompson getFileManager(), 17112255f2ceSJohn Thompson getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); 17122255f2ceSJohn Thompson ModuleManager->resetForReload(); 17132255f2ceSJohn Thompson ModuleManager->loadGlobalIndex(); 17142255f2ceSJohn Thompson GlobalIndex = ModuleManager->getGlobalIndex(); 17152255f2ceSJohn Thompson } 17162255f2ceSJohn Thompson HaveFullGlobalModuleIndex = true; 17172255f2ceSJohn Thompson } 17182255f2ceSJohn Thompson return GlobalIndex; 17192255f2ceSJohn Thompson } 17202d94bbb0SJohn Thompson 17212d94bbb0SJohn Thompson // Check global module index for missing imports. 17222d94bbb0SJohn Thompson bool 17232d94bbb0SJohn Thompson CompilerInstance::lookupMissingImports(StringRef Name, 17242d94bbb0SJohn Thompson SourceLocation TriggerLoc) { 17252d94bbb0SJohn Thompson // Look for the symbol in non-imported modules, but only if an error 17262d94bbb0SJohn Thompson // actually occurred. 17272d94bbb0SJohn Thompson if (!buildingModule()) { 17282d94bbb0SJohn Thompson // Load global module index, or retrieve a previously loaded one. 17292d94bbb0SJohn Thompson GlobalModuleIndex *GlobalIndex = loadGlobalModuleIndex( 17302d94bbb0SJohn Thompson TriggerLoc); 17312d94bbb0SJohn Thompson 17322d94bbb0SJohn Thompson // Only if we have a global index. 17332d94bbb0SJohn Thompson if (GlobalIndex) { 17342d94bbb0SJohn Thompson GlobalModuleIndex::HitSet FoundModules; 17352d94bbb0SJohn Thompson 17362d94bbb0SJohn Thompson // Find the modules that reference the identifier. 17372d94bbb0SJohn Thompson // Note that this only finds top-level modules. 17382d94bbb0SJohn Thompson // We'll let diagnoseTypo find the actual declaration module. 17392d94bbb0SJohn Thompson if (GlobalIndex->lookupIdentifier(Name, FoundModules)) 17402d94bbb0SJohn Thompson return true; 17412d94bbb0SJohn Thompson } 17422d94bbb0SJohn Thompson } 17432d94bbb0SJohn Thompson 17442d94bbb0SJohn Thompson return false; 17452d94bbb0SJohn Thompson } 1746a97eaa1bSDavid Blaikie void CompilerInstance::resetAndLeakSema() { BuryPointer(takeSema()); } 1747