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" 16*030d7d6dSDuncan P. N. Exon Smith #include "clang/Basic/MemoryBufferCache.h" 17546a676aSDaniel Dunbar #include "clang/Basic/SourceManager.h" 18636404a3SDaniel Dunbar #include "clang/Basic/TargetInfo.h" 194f2bc55dSDaniel Dunbar #include "clang/Basic/Version.h" 20f988d006SAlp Toker #include "clang/Config/config.h" 218b00dcb0SDavid Blaikie #include "clang/Frontend/ChainedDiagnosticConsumer.h" 224f2bc55dSDaniel Dunbar #include "clang/Frontend/FrontendAction.h" 23faeb1d46SDouglas Gregor #include "clang/Frontend/FrontendActions.h" 24f7093b5aSDaniel Dunbar #include "clang/Frontend/FrontendDiagnostic.h" 252083c32fSDaniel Dunbar #include "clang/Frontend/LogDiagnosticPrinter.h" 264610ea2bSTed Kremenek #include "clang/Frontend/SerializedDiagnosticPrinter.h" 277d75afc5SDaniel Dunbar #include "clang/Frontend/TextDiagnosticPrinter.h" 28aaa148fdSDaniel Dunbar #include "clang/Frontend/Utils.h" 293a02247dSChandler Carruth #include "clang/Frontend/VerifyDiagnosticConsumer.h" 303a02247dSChandler Carruth #include "clang/Lex/HeaderSearch.h" 313a02247dSChandler Carruth #include "clang/Lex/PTHManager.h" 323a02247dSChandler Carruth #include "clang/Lex/Preprocessor.h" 339670f847SMehdi Amini #include "clang/Lex/PreprocessorOptions.h" 34f7093b5aSDaniel Dunbar #include "clang/Sema/CodeCompleteConsumer.h" 353a02247dSChandler Carruth #include "clang/Sema/Sema.h" 363a02247dSChandler Carruth #include "clang/Serialization/ASTReader.h" 372255f2ceSJohn Thompson #include "clang/Serialization/GlobalModuleIndex.h" 38171b780cSDouglas Gregor #include "llvm/ADT/Statistic.h" 393a02247dSChandler Carruth #include "llvm/Support/CrashRecoveryContext.h" 4071de0b61SRafael Espindola #include "llvm/Support/Errc.h" 413a02247dSChandler Carruth #include "llvm/Support/FileSystem.h" 428aaf4995SMichael J. Spencer #include "llvm/Support/Host.h" 43e212489fSDouglas Gregor #include "llvm/Support/LockFileManager.h" 443a02247dSChandler Carruth #include "llvm/Support/MemoryBuffer.h" 458aaf4995SMichael J. Spencer #include "llvm/Support/Path.h" 468aaf4995SMichael J. Spencer #include "llvm/Support/Program.h" 478aaf4995SMichael J. Spencer #include "llvm/Support/Signals.h" 483a02247dSChandler Carruth #include "llvm/Support/Timer.h" 493a02247dSChandler Carruth #include "llvm/Support/raw_ostream.h" 50527b1c95SDouglas Gregor #include <sys/stat.h> 518a8e554aSRafael Espindola #include <system_error> 5237da327cSDouglas Gregor #include <time.h> 53cfeacf56SBenjamin Kramer #include <utility> 5454a88810SDouglas Gregor 55636404a3SDaniel Dunbar using namespace clang; 56636404a3SDaniel Dunbar 57bb165fb0SAdrian Prantl CompilerInstance::CompilerInstance( 58bb165fb0SAdrian Prantl std::shared_ptr<PCHContainerOperations> PCHContainerOps, 59*030d7d6dSDuncan P. N. Exon Smith MemoryBufferCache *SharedPCMCache) 60*030d7d6dSDuncan P. N. Exon Smith : ModuleLoader(/* BuildingModule = */ SharedPCMCache), 61*030d7d6dSDuncan P. N. Exon Smith Invocation(new CompilerInvocation()), 62*030d7d6dSDuncan P. N. Exon Smith PCMCache(SharedPCMCache ? SharedPCMCache : new MemoryBufferCache), 63*030d7d6dSDuncan P. N. Exon Smith ThePCHContainerOperations(std::move(PCHContainerOps)) { 64*030d7d6dSDuncan P. N. Exon Smith // Don't allow this to invalidate buffers in use by others. 65*030d7d6dSDuncan P. N. Exon Smith if (SharedPCMCache) 66*030d7d6dSDuncan P. N. Exon Smith getPCMCache().finalizeCurrentBuffers(); 67*030d7d6dSDuncan P. N. Exon Smith } 68636404a3SDaniel Dunbar 69636404a3SDaniel Dunbar CompilerInstance::~CompilerInstance() { 703c717b45SBenjamin Kramer assert(OutputFiles.empty() && "Still output files in flight?"); 71e922d9bdSDaniel Dunbar } 72e922d9bdSDaniel Dunbar 73ea4395ebSDavid Blaikie void CompilerInstance::setInvocation( 74ea4395ebSDavid Blaikie std::shared_ptr<CompilerInvocation> Value) { 75ea4395ebSDavid Blaikie Invocation = std::move(Value); 7668242254SDaniel Dunbar } 7768242254SDaniel Dunbar 78c1bbec85SDouglas Gregor bool CompilerInstance::shouldBuildGlobalModuleIndex() const { 79e060e57bSDouglas Gregor return (BuildGlobalModuleIndex || 8011ef0b77SDouglas Gregor (ModuleManager && ModuleManager->isGlobalIndexUnavailable() && 8111ef0b77SDouglas Gregor getFrontendOpts().GenerateGlobalModuleIndex)) && 82e060e57bSDouglas Gregor !ModuleBuildFailed; 83c1bbec85SDouglas Gregor } 84c1bbec85SDouglas Gregor 859c902b55SDavid Blaikie void CompilerInstance::setDiagnostics(DiagnosticsEngine *Value) { 867f95d26eSDouglas Gregor Diagnostics = Value; 87e01dc86dSDaniel Dunbar } 88e01dc86dSDaniel Dunbar 89b5bc923aSArtem Belevich void CompilerInstance::setTarget(TargetInfo *Value) { Target = Value; } 90b5bc923aSArtem Belevich void CompilerInstance::setAuxTarget(TargetInfo *Value) { AuxTarget = Value; } 91e01dc86dSDaniel Dunbar 92e01dc86dSDaniel Dunbar void CompilerInstance::setFileManager(FileManager *Value) { 935e14d39aSTed Kremenek FileMgr = Value; 94c8130a74SBen Langmuir if (Value) 95c8130a74SBen Langmuir VirtualFileSystem = Value->getVirtualFileSystem(); 96c8130a74SBen Langmuir else 97c8130a74SBen Langmuir VirtualFileSystem.reset(); 98e01dc86dSDaniel Dunbar } 99e01dc86dSDaniel Dunbar 100e01dc86dSDaniel Dunbar void CompilerInstance::setSourceManager(SourceManager *Value) { 1015e14d39aSTed Kremenek SourceMgr = Value; 102e01dc86dSDaniel Dunbar } 103e01dc86dSDaniel Dunbar 10441565463SDavid Blaikie void CompilerInstance::setPreprocessor(std::shared_ptr<Preprocessor> Value) { 10541565463SDavid Blaikie PP = std::move(Value); 10641565463SDavid Blaikie } 107e01dc86dSDaniel Dunbar 108293534b1SRichard Smith void CompilerInstance::setASTContext(ASTContext *Value) { 109293534b1SRichard Smith Context = Value; 110293534b1SRichard Smith 111293534b1SRichard Smith if (Context && Consumer) 112293534b1SRichard Smith getASTConsumer().Initialize(getASTContext()); 113293534b1SRichard Smith } 114e01dc86dSDaniel Dunbar 1150e93f017SDouglas Gregor void CompilerInstance::setSema(Sema *S) { 1160e93f017SDouglas Gregor TheSema.reset(S); 1170e93f017SDouglas Gregor } 1180e93f017SDouglas Gregor 1196beb6aa8SDavid Blaikie void CompilerInstance::setASTConsumer(std::unique_ptr<ASTConsumer> Value) { 1206beb6aa8SDavid Blaikie Consumer = std::move(Value); 121293534b1SRichard Smith 122293534b1SRichard Smith if (Context && Consumer) 123293534b1SRichard Smith getASTConsumer().Initialize(getASTContext()); 12456d9c293SDaniel Dunbar } 12556d9c293SDaniel Dunbar 126e01dc86dSDaniel Dunbar void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) { 127e01dc86dSDaniel Dunbar CompletionConsumer.reset(Value); 128e01dc86dSDaniel Dunbar } 129e01dc86dSDaniel Dunbar 1306153581aSDavid Blaikie std::unique_ptr<Sema> CompilerInstance::takeSema() { 1316153581aSDavid Blaikie return std::move(TheSema); 1326153581aSDavid Blaikie } 1336153581aSDavid Blaikie 1341b7ed91eSArgyrios Kyrtzidis IntrusiveRefCntPtr<ASTReader> CompilerInstance::getModuleManager() const { 1351b7ed91eSArgyrios Kyrtzidis return ModuleManager; 1361b7ed91eSArgyrios Kyrtzidis } 1371b7ed91eSArgyrios Kyrtzidis void CompilerInstance::setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader) { 138*030d7d6dSDuncan P. N. Exon Smith assert(PCMCache.get() == &Reader->getModuleManager().getPCMCache() && 139*030d7d6dSDuncan P. N. Exon Smith "Expected ASTReader to use the same PCM cache"); 140d6da1a09SBenjamin Kramer ModuleManager = std::move(Reader); 1411b7ed91eSArgyrios Kyrtzidis } 1421b7ed91eSArgyrios Kyrtzidis 14386d1259cSJustin Bogner std::shared_ptr<ModuleDependencyCollector> 14486d1259cSJustin Bogner CompilerInstance::getModuleDepCollector() const { 14586d1259cSJustin Bogner return ModuleDepCollector; 14686d1259cSJustin Bogner } 14786d1259cSJustin Bogner 14886d1259cSJustin Bogner void CompilerInstance::setModuleDepCollector( 14986d1259cSJustin Bogner std::shared_ptr<ModuleDependencyCollector> Collector) { 150d6da1a09SBenjamin Kramer ModuleDepCollector = std::move(Collector); 15186d1259cSJustin Bogner } 15286d1259cSJustin Bogner 153181225b8SBruno Cardoso Lopes static void collectHeaderMaps(const HeaderSearch &HS, 154181225b8SBruno Cardoso Lopes std::shared_ptr<ModuleDependencyCollector> MDC) { 155181225b8SBruno Cardoso Lopes SmallVector<std::string, 4> HeaderMapFileNames; 156181225b8SBruno Cardoso Lopes HS.getHeaderMapFileNames(HeaderMapFileNames); 157181225b8SBruno Cardoso Lopes for (auto &Name : HeaderMapFileNames) 158181225b8SBruno Cardoso Lopes MDC->addFile(Name); 159181225b8SBruno Cardoso Lopes } 160181225b8SBruno Cardoso Lopes 1617aff2bb3SBruno Cardoso Lopes static void collectIncludePCH(CompilerInstance &CI, 1627aff2bb3SBruno Cardoso Lopes std::shared_ptr<ModuleDependencyCollector> MDC) { 1637aff2bb3SBruno Cardoso Lopes const PreprocessorOptions &PPOpts = CI.getPreprocessorOpts(); 1647aff2bb3SBruno Cardoso Lopes if (PPOpts.ImplicitPCHInclude.empty()) 1657aff2bb3SBruno Cardoso Lopes return; 1667aff2bb3SBruno Cardoso Lopes 1677aff2bb3SBruno Cardoso Lopes StringRef PCHInclude = PPOpts.ImplicitPCHInclude; 1687aff2bb3SBruno Cardoso Lopes FileManager &FileMgr = CI.getFileManager(); 1697aff2bb3SBruno Cardoso Lopes const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude); 1707aff2bb3SBruno Cardoso Lopes if (!PCHDir) { 1717aff2bb3SBruno Cardoso Lopes MDC->addFile(PCHInclude); 1727aff2bb3SBruno Cardoso Lopes return; 1737aff2bb3SBruno Cardoso Lopes } 1747aff2bb3SBruno Cardoso Lopes 1757aff2bb3SBruno Cardoso Lopes std::error_code EC; 1767aff2bb3SBruno Cardoso Lopes SmallString<128> DirNative; 1777aff2bb3SBruno Cardoso Lopes llvm::sys::path::native(PCHDir->getName(), DirNative); 1787aff2bb3SBruno Cardoso Lopes vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem(); 1797aff2bb3SBruno Cardoso Lopes SimpleASTReaderListener Validator(CI.getPreprocessor()); 1807aff2bb3SBruno Cardoso Lopes for (vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd; 1817aff2bb3SBruno Cardoso Lopes Dir != DirEnd && !EC; Dir.increment(EC)) { 1827aff2bb3SBruno Cardoso Lopes // Check whether this is an AST file. ASTReader::isAcceptableASTFile is not 1837aff2bb3SBruno Cardoso Lopes // used here since we're not interested in validating the PCH at this time, 1847aff2bb3SBruno Cardoso Lopes // but only to check whether this is a file containing an AST. 1857aff2bb3SBruno Cardoso Lopes if (!ASTReader::readASTFileControlBlock( 1867aff2bb3SBruno Cardoso Lopes Dir->getName(), FileMgr, CI.getPCHContainerReader(), 1877aff2bb3SBruno Cardoso Lopes /*FindModuleFileExtensions=*/false, Validator, 1887aff2bb3SBruno Cardoso Lopes /*ValidateDiagnosticOptions=*/false)) 1897aff2bb3SBruno Cardoso Lopes MDC->addFile(Dir->getName()); 1907aff2bb3SBruno Cardoso Lopes } 1917aff2bb3SBruno Cardoso Lopes } 1927aff2bb3SBruno Cardoso Lopes 19382ec4fdeSBruno Cardoso Lopes static void collectVFSEntries(CompilerInstance &CI, 19482ec4fdeSBruno Cardoso Lopes std::shared_ptr<ModuleDependencyCollector> MDC) { 19582ec4fdeSBruno Cardoso Lopes if (CI.getHeaderSearchOpts().VFSOverlayFiles.empty()) 19682ec4fdeSBruno Cardoso Lopes return; 19782ec4fdeSBruno Cardoso Lopes 19882ec4fdeSBruno Cardoso Lopes // Collect all VFS found. 19982ec4fdeSBruno Cardoso Lopes SmallVector<vfs::YAMLVFSEntry, 16> VFSEntries; 20082ec4fdeSBruno Cardoso Lopes for (const std::string &VFSFile : CI.getHeaderSearchOpts().VFSOverlayFiles) { 20182ec4fdeSBruno Cardoso Lopes llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer = 20282ec4fdeSBruno Cardoso Lopes llvm::MemoryBuffer::getFile(VFSFile); 20382ec4fdeSBruno Cardoso Lopes if (!Buffer) 20482ec4fdeSBruno Cardoso Lopes return; 20582ec4fdeSBruno Cardoso Lopes vfs::collectVFSFromYAML(std::move(Buffer.get()), /*DiagHandler*/ nullptr, 20682ec4fdeSBruno Cardoso Lopes VFSFile, VFSEntries); 20782ec4fdeSBruno Cardoso Lopes } 20882ec4fdeSBruno Cardoso Lopes 20982ec4fdeSBruno Cardoso Lopes for (auto &E : VFSEntries) 21082ec4fdeSBruno Cardoso Lopes MDC->addFile(E.VPath, E.RPath); 21182ec4fdeSBruno Cardoso Lopes } 21282ec4fdeSBruno Cardoso Lopes 2137d75afc5SDaniel Dunbar // Diagnostics 214811db4eaSDouglas Gregor static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts, 2157b83306dSDaniel Dunbar const CodeGenOptions *CodeGenOpts, 2169c902b55SDavid Blaikie DiagnosticsEngine &Diags) { 217dae941a6SRafael Espindola std::error_code EC; 21811f8a943SDavid Blaikie std::unique_ptr<raw_ostream> StreamOwner; 2190e62c1ccSChris Lattner raw_ostream *OS = &llvm::errs(); 220811db4eaSDouglas Gregor if (DiagOpts->DiagnosticLogFile != "-") { 2212083c32fSDaniel Dunbar // Create the output stream. 22211f8a943SDavid Blaikie auto FileOS = llvm::make_unique<llvm::raw_fd_ostream>( 223dae941a6SRafael Espindola DiagOpts->DiagnosticLogFile, EC, 22411f8a943SDavid Blaikie llvm::sys::fs::F_Append | llvm::sys::fs::F_Text); 225dae941a6SRafael Espindola if (EC) { 2262083c32fSDaniel Dunbar Diags.Report(diag::warn_fe_cc_log_diagnostics_failure) 227dae941a6SRafael Espindola << DiagOpts->DiagnosticLogFile << EC.message(); 2282083c32fSDaniel Dunbar } else { 2292083c32fSDaniel Dunbar FileOS->SetUnbuffered(); 23011f8a943SDavid Blaikie OS = FileOS.get(); 23111f8a943SDavid Blaikie StreamOwner = std::move(FileOS); 2322083c32fSDaniel Dunbar } 2332083c32fSDaniel Dunbar } 2342083c32fSDaniel Dunbar 2352083c32fSDaniel Dunbar // Chain in the diagnostic client which will log the diagnostics. 2367ee25502SDavid Blaikie auto Logger = llvm::make_unique<LogDiagnosticPrinter>(*OS, DiagOpts, 2377ee25502SDavid Blaikie std::move(StreamOwner)); 2387b83306dSDaniel Dunbar if (CodeGenOpts) 2397b83306dSDaniel Dunbar Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags); 2407ee25502SDavid Blaikie assert(Diags.ownsClient()); 24141c247a6SAlexander Kornienko Diags.setClient( 24241c247a6SAlexander Kornienko new ChainedDiagnosticConsumer(Diags.takeClient(), std::move(Logger))); 2432083c32fSDaniel Dunbar } 2442083c32fSDaniel Dunbar 245811db4eaSDouglas Gregor static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts, 2464610ea2bSTed Kremenek DiagnosticsEngine &Diags, 2474610ea2bSTed Kremenek StringRef OutputFile) { 2487ee25502SDavid Blaikie auto SerializedConsumer = 2495a6a2fcdSJustin Bogner clang::serialized_diags::create(OutputFile, DiagOpts); 2504610ea2bSTed Kremenek 251254b7dbaSAlexander Kornienko if (Diags.ownsClient()) { 2527ee25502SDavid Blaikie Diags.setClient(new ChainedDiagnosticConsumer( 25341c247a6SAlexander Kornienko Diags.takeClient(), std::move(SerializedConsumer))); 254254b7dbaSAlexander Kornienko } else { 255254b7dbaSAlexander Kornienko Diags.setClient(new ChainedDiagnosticConsumer( 2564c0ef379SAlexander Kornienko Diags.getClient(), std::move(SerializedConsumer))); 257254b7dbaSAlexander Kornienko } 2584610ea2bSTed Kremenek } 2594610ea2bSTed Kremenek 260f1b49e23SSean Silva void CompilerInstance::createDiagnostics(DiagnosticConsumer *Client, 26130071ceaSDouglas Gregor bool ShouldOwnClient) { 262f1b49e23SSean Silva Diagnostics = createDiagnostics(&getDiagnosticOpts(), Client, 26330071ceaSDouglas Gregor ShouldOwnClient, &getCodeGenOpts()); 2647d75afc5SDaniel Dunbar } 2657d75afc5SDaniel Dunbar 266c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> 267811db4eaSDouglas Gregor CompilerInstance::createDiagnostics(DiagnosticOptions *Opts, 268e2eefaecSDavid Blaikie DiagnosticConsumer *Client, 2692b9b4642SDouglas Gregor bool ShouldOwnClient, 2707b83306dSDaniel Dunbar const CodeGenOptions *CodeGenOpts) { 271c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 272c95d8192SDylan Noblesmith IntrusiveRefCntPtr<DiagnosticsEngine> 273811db4eaSDouglas Gregor Diags(new DiagnosticsEngine(DiagID, Opts)); 2741b39a2edSDaniel Dunbar 2757d75afc5SDaniel Dunbar // Create the diagnostic client for reporting errors or for 2767d75afc5SDaniel Dunbar // implementing -verify. 277d0e9e3a6SDouglas Gregor if (Client) { 278d0e9e3a6SDouglas Gregor Diags->setClient(Client, ShouldOwnClient); 279d0e9e3a6SDouglas Gregor } else 2802dd19f1dSDouglas Gregor Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts)); 28150ec0da0SDaniel Dunbar 28250ec0da0SDaniel Dunbar // Chain in -verify checker, if requested. 283811db4eaSDouglas Gregor if (Opts->VerifyDiagnostics) 28469609dceSDavid Blaikie Diags->setClient(new VerifyDiagnosticConsumer(*Diags)); 2857d75afc5SDaniel Dunbar 2862083c32fSDaniel Dunbar // Chain in -diagnostic-log-file dumper, if requested. 287811db4eaSDouglas Gregor if (!Opts->DiagnosticLogFile.empty()) 2887b83306dSDaniel Dunbar SetUpDiagnosticLog(Opts, CodeGenOpts, *Diags); 2892083c32fSDaniel Dunbar 290811db4eaSDouglas Gregor if (!Opts->DiagnosticSerializationFile.empty()) 2914610ea2bSTed Kremenek SetupSerializedDiagnostics(Opts, *Diags, 292811db4eaSDouglas Gregor Opts->DiagnosticSerializationFile); 2934610ea2bSTed Kremenek 2947d75afc5SDaniel Dunbar // Configure our handling of diagnostics. 295811db4eaSDouglas Gregor ProcessWarningOptions(*Diags, *Opts); 2967d75afc5SDaniel Dunbar 2977f95d26eSDouglas Gregor return Diags; 2987d75afc5SDaniel Dunbar } 2997d75afc5SDaniel Dunbar 3007d75afc5SDaniel Dunbar // File Manager 3017d75afc5SDaniel Dunbar 302546a676aSDaniel Dunbar void CompilerInstance::createFileManager() { 303c8130a74SBen Langmuir if (!hasVirtualFileSystem()) { 304c8130a74SBen Langmuir // TODO: choose the virtual file system based on the CompilerInvocation. 305c8130a74SBen Langmuir setVirtualFileSystem(vfs::getRealFileSystem()); 306c8130a74SBen Langmuir } 307c8130a74SBen Langmuir FileMgr = new FileManager(getFileSystemOpts(), VirtualFileSystem); 308546a676aSDaniel Dunbar } 309546a676aSDaniel Dunbar 3107d75afc5SDaniel Dunbar // Source Manager 3117d75afc5SDaniel Dunbar 3125159f616SChris Lattner void CompilerInstance::createSourceManager(FileManager &FileMgr) { 3135e14d39aSTed Kremenek SourceMgr = new SourceManager(getDiagnostics(), FileMgr); 314546a676aSDaniel Dunbar } 315aaa148fdSDaniel Dunbar 316c358000eSAlp Toker // Initialize the remapping of files to alternative contents, e.g., 317c358000eSAlp Toker // those specified through other files. 318c358000eSAlp Toker static void InitializeFileRemapping(DiagnosticsEngine &Diags, 319c358000eSAlp Toker SourceManager &SourceMgr, 320c358000eSAlp Toker FileManager &FileMgr, 321c358000eSAlp Toker const PreprocessorOptions &InitOpts) { 322c358000eSAlp Toker // Remap files in the source manager (with buffers). 3231b070d25SAlp Toker for (const auto &RB : InitOpts.RemappedFileBuffers) { 324c358000eSAlp Toker // Create the file entry for the file that we're mapping from. 325c358000eSAlp Toker const FileEntry *FromFile = 3261b070d25SAlp Toker FileMgr.getVirtualFile(RB.first, RB.second->getBufferSize(), 0); 327c358000eSAlp Toker if (!FromFile) { 3281b070d25SAlp Toker Diags.Report(diag::err_fe_remap_missing_from_file) << RB.first; 329c358000eSAlp Toker if (!InitOpts.RetainRemappedFileBuffers) 3301b070d25SAlp Toker delete RB.second; 331c358000eSAlp Toker continue; 332c358000eSAlp Toker } 333c358000eSAlp Toker 334c358000eSAlp Toker // Override the contents of the "from" file with the contents of 335c358000eSAlp Toker // the "to" file. 3361b070d25SAlp Toker SourceMgr.overrideFileContents(FromFile, RB.second, 337c358000eSAlp Toker InitOpts.RetainRemappedFileBuffers); 338c358000eSAlp Toker } 339c358000eSAlp Toker 340c358000eSAlp Toker // Remap files in the source manager (with other files). 3411b070d25SAlp Toker for (const auto &RF : InitOpts.RemappedFiles) { 342c358000eSAlp Toker // Find the file that we're mapping to. 3431b070d25SAlp Toker const FileEntry *ToFile = FileMgr.getFile(RF.second); 344c358000eSAlp Toker if (!ToFile) { 3451b070d25SAlp Toker Diags.Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second; 346c358000eSAlp Toker continue; 347c358000eSAlp Toker } 348c358000eSAlp Toker 349c358000eSAlp Toker // Create the file entry for the file that we're mapping from. 350c358000eSAlp Toker const FileEntry *FromFile = 3511b070d25SAlp Toker FileMgr.getVirtualFile(RF.first, ToFile->getSize(), 0); 352c358000eSAlp Toker if (!FromFile) { 3531b070d25SAlp Toker Diags.Report(diag::err_fe_remap_missing_from_file) << RF.first; 354c358000eSAlp Toker continue; 355c358000eSAlp Toker } 356c358000eSAlp Toker 357c358000eSAlp Toker // Override the contents of the "from" file with the contents of 358c358000eSAlp Toker // the "to" file. 359c358000eSAlp Toker SourceMgr.overrideFileContents(FromFile, ToFile); 360c358000eSAlp Toker } 361c358000eSAlp Toker 362c358000eSAlp Toker SourceMgr.setOverridenFilesKeepOriginalName( 363c358000eSAlp Toker InitOpts.RemappedFilesKeepOriginalName); 364c358000eSAlp Toker } 365c358000eSAlp Toker 3667d75afc5SDaniel Dunbar // Preprocessor 3677d75afc5SDaniel Dunbar 368e1974dcdSArgyrios Kyrtzidis void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) { 36908142534SDouglas Gregor const PreprocessorOptions &PPOpts = getPreprocessorOpts(); 370aaa148fdSDaniel Dunbar 371aaa148fdSDaniel Dunbar // Create a PTH manager if we are using some form of a token cache. 37249a2790fSCraig Topper PTHManager *PTHMgr = nullptr; 373d6ea9028SDaniel Dunbar if (!PPOpts.TokenCache.empty()) 37408142534SDouglas Gregor PTHMgr = PTHManager::Create(PPOpts.TokenCache, getDiagnostics()); 375aaa148fdSDaniel Dunbar 376aaa148fdSDaniel Dunbar // Create the Preprocessor. 3779c28cb3fSDavid Blaikie HeaderSearch *HeaderInfo = 3789c28cb3fSDavid Blaikie new HeaderSearch(getHeaderSearchOptsPtr(), getSourceManager(), 3799c28cb3fSDavid Blaikie getDiagnostics(), getLangOpts(), &getTarget()); 38041565463SDavid Blaikie PP = std::make_shared<Preprocessor>( 38141565463SDavid Blaikie Invocation->getPreprocessorOptsPtr(), getDiagnostics(), getLangOpts(), 382*030d7d6dSDuncan P. N. Exon Smith getSourceManager(), getPCMCache(), *HeaderInfo, *this, PTHMgr, 3839663780eSAlp Toker /*OwnsHeaderSearch=*/true, TUKind); 384b5bc923aSArtem Belevich PP->Initialize(getTarget(), getAuxTarget()); 385aaa148fdSDaniel Dunbar 386aaa148fdSDaniel Dunbar // Note that this is different then passing PTHMgr to Preprocessor's ctor. 387aaa148fdSDaniel Dunbar // That argument is used as the IdentifierInfoLookup argument to 388aaa148fdSDaniel Dunbar // IdentifierTable's ctor. 389aaa148fdSDaniel Dunbar if (PTHMgr) { 39008142534SDouglas Gregor PTHMgr->setPreprocessor(&*PP); 391aaa148fdSDaniel Dunbar PP->setPTHManager(PTHMgr); 392aaa148fdSDaniel Dunbar } 393aaa148fdSDaniel Dunbar 3947f6d60dcSDouglas Gregor if (PPOpts.DetailedRecord) 395f3d587eaSArgyrios Kyrtzidis PP->createPreprocessingRecord(); 3967f6d60dcSDouglas Gregor 397c358000eSAlp Toker // Apply remappings to the source manager. 398c358000eSAlp Toker InitializeFileRemapping(PP->getDiagnostics(), PP->getSourceManager(), 399c358000eSAlp Toker PP->getFileManager(), PPOpts); 400c358000eSAlp Toker 401c358000eSAlp Toker // Predefine macros and configure the preprocessor. 402fb2398d0SAdrian Prantl InitializePreprocessor(*PP, PPOpts, getPCHContainerReader(), 403bb165fb0SAdrian Prantl getFrontendOpts()); 404c358000eSAlp Toker 405f91086b0SJustin Lebar // Initialize the header search object. In CUDA compilations, we use the aux 406f91086b0SJustin Lebar // triple (the host triple) to initialize our header search, since we need to 407f91086b0SJustin Lebar // find the host headers in order to compile the CUDA code. 408f91086b0SJustin Lebar const llvm::Triple *HeaderSearchTriple = &PP->getTargetInfo().getTriple(); 409f91086b0SJustin Lebar if (PP->getTargetInfo().getTriple().getOS() == llvm::Triple::CUDA && 410f91086b0SJustin Lebar PP->getAuxTargetInfo()) 411f91086b0SJustin Lebar HeaderSearchTriple = &PP->getAuxTargetInfo()->getTriple(); 412f91086b0SJustin Lebar 413c358000eSAlp Toker ApplyHeaderSearchOptions(PP->getHeaderSearchInfo(), getHeaderSearchOpts(), 414f91086b0SJustin Lebar PP->getLangOpts(), *HeaderSearchTriple); 415aaa148fdSDaniel Dunbar 41617441589SJordan Rose PP->setPreprocessedOutput(getPreprocessorOutputOpts().ShowCPP); 41717441589SJordan Rose 4183938f0c7SRichard Smith if (PP->getLangOpts().Modules && PP->getLangOpts().ImplicitModules) 419bd0b651bSArgyrios Kyrtzidis PP->getHeaderSearchInfo().setModuleCachePath(getSpecificModuleCachePath()); 4201735f4e7SDouglas Gregor 421aaa148fdSDaniel Dunbar // Handle generating dependencies, if requested. 42208142534SDouglas Gregor const DependencyOutputOptions &DepOpts = getDependencyOutputOpts(); 423aaa148fdSDaniel Dunbar if (!DepOpts.OutputFile.empty()) 424cb69b57bSBen Langmuir TheDependencyFileGenerator.reset( 425cb69b57bSBen Langmuir DependencyFileGenerator::CreateAndAttachToPreprocessor(*PP, DepOpts)); 4262e129659SDouglas Gregor if (!DepOpts.DOTOutputFile.empty()) 4272e129659SDouglas Gregor AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile, 42883d46be3SDouglas Gregor getHeaderSearchOpts().Sysroot); 42983d46be3SDouglas Gregor 43086d1259cSJustin Bogner // If we don't have a collector, but we are collecting module dependencies, 43186d1259cSJustin Bogner // then we're the top level compiler instance and need to create one. 432b1631d91SBruno Cardoso Lopes if (!ModuleDepCollector && !DepOpts.ModuleDependencyOutputDir.empty()) { 43386d1259cSJustin Bogner ModuleDepCollector = std::make_shared<ModuleDependencyCollector>( 43486d1259cSJustin Bogner DepOpts.ModuleDependencyOutputDir); 435b1631d91SBruno Cardoso Lopes } 436b1631d91SBruno Cardoso Lopes 437181225b8SBruno Cardoso Lopes // If there is a module dep collector, register with other dep collectors 438181225b8SBruno Cardoso Lopes // and also (a) collect header maps and (b) TODO: input vfs overlay files. 439181225b8SBruno Cardoso Lopes if (ModuleDepCollector) { 440b1631d91SBruno Cardoso Lopes addDependencyCollector(ModuleDepCollector); 441181225b8SBruno Cardoso Lopes collectHeaderMaps(PP->getHeaderSearchInfo(), ModuleDepCollector); 4427aff2bb3SBruno Cardoso Lopes collectIncludePCH(*this, ModuleDepCollector); 44382ec4fdeSBruno Cardoso Lopes collectVFSEntries(*this, ModuleDepCollector); 444181225b8SBruno Cardoso Lopes } 445b1631d91SBruno Cardoso Lopes 446b1631d91SBruno Cardoso Lopes for (auto &Listener : DependencyCollectors) 447b1631d91SBruno Cardoso Lopes Listener->attachToPreprocessor(*PP); 448aaa148fdSDaniel Dunbar 44927734fdbSDaniel Dunbar // Handle generating header include information, if requested. 45027734fdbSDaniel Dunbar if (DepOpts.ShowHeaderIncludes) 451f54146c1SNico Weber AttachHeaderIncludeGen(*PP, DepOpts); 4521af1d275SDaniel Dunbar if (!DepOpts.HeaderIncludeOutputFile.empty()) { 4530e62c1ccSChris Lattner StringRef OutputPath = DepOpts.HeaderIncludeOutputFile; 4541af1d275SDaniel Dunbar if (OutputPath == "-") 4551af1d275SDaniel Dunbar OutputPath = ""; 456f54146c1SNico Weber AttachHeaderIncludeGen(*PP, DepOpts, 4571193f2cbSIvan Krasin /*ShowAllHeaders=*/true, OutputPath, 458fe908a80SDaniel Dunbar /*ShowDepth=*/false); 4590fd6207dSHans Wennborg } 4600fd6207dSHans Wennborg 4610fd6207dSHans Wennborg if (DepOpts.PrintShowIncludes) { 462f54146c1SNico Weber AttachHeaderIncludeGen(*PP, DepOpts, 463149d9522SNico Weber /*ShowAllHeaders=*/true, /*OutputPath=*/"", 4640fd6207dSHans Wennborg /*ShowDepth=*/true, /*MSStyle=*/true); 4651af1d275SDaniel Dunbar } 466aaa148fdSDaniel Dunbar } 467df3e30c4SDaniel Dunbar 468bd0b651bSArgyrios Kyrtzidis std::string CompilerInstance::getSpecificModuleCachePath() { 469bd0b651bSArgyrios Kyrtzidis // Set up the module path, including the hash for the 470bd0b651bSArgyrios Kyrtzidis // module-creation options. 471d520a250SRichard Smith SmallString<256> SpecificModuleCache(getHeaderSearchOpts().ModuleCachePath); 472d520a250SRichard Smith if (!SpecificModuleCache.empty() && !getHeaderSearchOpts().DisableModuleHash) 473bd0b651bSArgyrios Kyrtzidis llvm::sys::path::append(SpecificModuleCache, 474bd0b651bSArgyrios Kyrtzidis getInvocation().getModuleHash()); 475bd0b651bSArgyrios Kyrtzidis return SpecificModuleCache.str(); 476bd0b651bSArgyrios Kyrtzidis } 477bd0b651bSArgyrios Kyrtzidis 478df3e30c4SDaniel Dunbar // ASTContext 479df3e30c4SDaniel Dunbar 480df3e30c4SDaniel Dunbar void CompilerInstance::createASTContext() { 481df3e30c4SDaniel Dunbar Preprocessor &PP = getPreprocessor(); 482293534b1SRichard Smith auto *Context = new ASTContext(getLangOpts(), PP.getSourceManager(), 48308043437SAlp Toker PP.getIdentifierTable(), PP.getSelectorTable(), 48408043437SAlp Toker PP.getBuiltinInfo()); 485b5bc923aSArtem Belevich Context->InitBuiltinTypes(getTarget(), getAuxTarget()); 486293534b1SRichard Smith setASTContext(Context); 487df3e30c4SDaniel Dunbar } 488599313efSDaniel Dunbar 489599313efSDaniel Dunbar // ExternalASTSource 490599313efSDaniel Dunbar 491824285ecSNico Weber void CompilerInstance::createPCHExternalASTSource( 492824285ecSNico Weber StringRef Path, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors, 493824285ecSNico Weber void *DeserializationListener, bool OwnDeserializationListener) { 494009e7f20SSebastian Redl bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0; 4954eca9b93SRichard Smith ModuleManager = createPCHExternalASTSource( 496824285ecSNico Weber Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation, 497824285ecSNico Weber AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(), 4986623e1f1SDouglas Gregor getPCHContainerReader(), 4996623e1f1SDouglas Gregor getFrontendOpts().ModuleFileExtensions, 5006623e1f1SDouglas Gregor DeserializationListener, 501bb165fb0SAdrian Prantl OwnDeserializationListener, Preamble, 5021b7ed91eSArgyrios Kyrtzidis getFrontendOpts().UseGlobalModuleIndex); 503599313efSDaniel Dunbar } 504599313efSDaniel Dunbar 5054eca9b93SRichard Smith IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource( 5065b816061SYaron Keren StringRef Path, StringRef Sysroot, bool DisablePCHValidation, 507824285ecSNico Weber bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context, 508fb2398d0SAdrian Prantl const PCHContainerReader &PCHContainerRdr, 50961137e1aSDavid Blaikie ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, 510824285ecSNico Weber void *DeserializationListener, bool OwnDeserializationListener, 511824285ecSNico Weber bool Preamble, bool UseGlobalModuleIndex) { 512dcf73861SBen Langmuir HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts(); 513dcf73861SBen Langmuir 514bb165fb0SAdrian Prantl IntrusiveRefCntPtr<ASTReader> Reader(new ASTReader( 5156623e1f1SDouglas Gregor PP, Context, PCHContainerRdr, Extensions, 5166623e1f1SDouglas Gregor Sysroot.empty() ? "" : Sysroot.data(), DisablePCHValidation, 5176623e1f1SDouglas Gregor AllowPCHWithCompilerErrors, /*AllowConfigurationMismatch*/ false, 5186623e1f1SDouglas Gregor HSOpts.ModulesValidateSystemHeaders, UseGlobalModuleIndex)); 5194eca9b93SRichard Smith 5204eca9b93SRichard Smith // We need the external source to be set up before we read the AST, because 5214eca9b93SRichard Smith // eagerly-deserialized declarations may use it. 5224eca9b93SRichard Smith Context.setExternalSource(Reader.get()); 523599313efSDaniel Dunbar 52407a89a83SSebastian Redl Reader->setDeserializationListener( 525824285ecSNico Weber static_cast<ASTDeserializationListener *>(DeserializationListener), 526824285ecSNico Weber /*TakeOwnership=*/OwnDeserializationListener); 527009e7f20SSebastian Redl switch (Reader->ReadAST(Path, 528a6895d8aSDouglas Gregor Preamble ? serialization::MK_Preamble 5294b29c16eSDouglas Gregor : serialization::MK_PCH, 5302ec29367SArgyrios Kyrtzidis SourceLocation(), 5313d4417c7SBen Langmuir ASTReader::ARR_None)) { 5322c499f65SSebastian Redl case ASTReader::Success: 533599313efSDaniel Dunbar // Set the predefines buffer as suggested by the PCH reader. Typically, the 534599313efSDaniel Dunbar // predefines buffer will be empty. 535599313efSDaniel Dunbar PP.setPredefines(Reader->getSuggestedPredefines()); 5364eca9b93SRichard Smith return Reader; 537599313efSDaniel Dunbar 5382c499f65SSebastian Redl case ASTReader::Failure: 539599313efSDaniel Dunbar // Unrecoverable failure: don't even try to process the input file. 540599313efSDaniel Dunbar break; 541599313efSDaniel Dunbar 5427029ce1aSDouglas Gregor case ASTReader::Missing: 543c9ad5fb6SDouglas Gregor case ASTReader::OutOfDate: 544c9ad5fb6SDouglas Gregor case ASTReader::VersionMismatch: 545c9ad5fb6SDouglas Gregor case ASTReader::ConfigurationMismatch: 546c9ad5fb6SDouglas Gregor case ASTReader::HadErrors: 547599313efSDaniel Dunbar // No suitable PCH file could be found. Return an error. 548599313efSDaniel Dunbar break; 549599313efSDaniel Dunbar } 550599313efSDaniel Dunbar 5514eca9b93SRichard Smith Context.setExternalSource(nullptr); 55249a2790fSCraig Topper return nullptr; 553599313efSDaniel Dunbar } 554f7093b5aSDaniel Dunbar 555f7093b5aSDaniel Dunbar // Code Completion 556f7093b5aSDaniel Dunbar 5578e984da8SDouglas Gregor static bool EnableCodeCompletion(Preprocessor &PP, 5580772c423SBenjamin Kramer StringRef Filename, 5598e984da8SDouglas Gregor unsigned Line, 5608e984da8SDouglas Gregor unsigned Column) { 5618e984da8SDouglas Gregor // Tell the source manager to chop off the given file at a specific 5628e984da8SDouglas Gregor // line and column. 5635159f616SChris Lattner const FileEntry *Entry = PP.getFileManager().getFile(Filename); 5648e984da8SDouglas Gregor if (!Entry) { 5658e984da8SDouglas Gregor PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file) 5668e984da8SDouglas Gregor << Filename; 5678e984da8SDouglas Gregor return true; 5688e984da8SDouglas Gregor } 5698e984da8SDouglas Gregor 5708e984da8SDouglas Gregor // Truncate the named file at the given line/column. 5718e984da8SDouglas Gregor PP.SetCodeCompletionPoint(Entry, Line, Column); 5728e984da8SDouglas Gregor return false; 5738e984da8SDouglas Gregor } 5748e984da8SDouglas Gregor 575f7093b5aSDaniel Dunbar void CompilerInstance::createCodeCompletionConsumer() { 576f7093b5aSDaniel Dunbar const ParsedSourceLocation &Loc = getFrontendOpts().CodeCompletionAt; 5778e984da8SDouglas Gregor if (!CompletionConsumer) { 5782fca3c2cSErik Verbruggen setCodeCompletionConsumer( 579f7093b5aSDaniel Dunbar createCodeCompletionConsumer(getPreprocessor(), 580f7093b5aSDaniel Dunbar Loc.FileName, Loc.Line, Loc.Column, 5813292d06aSDmitri Gribenko getFrontendOpts().CodeCompleteOpts, 582f7093b5aSDaniel Dunbar llvm::outs())); 58300a0cf70SDouglas Gregor if (!CompletionConsumer) 58400a0cf70SDouglas Gregor return; 5858e984da8SDouglas Gregor } else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName, 5868e984da8SDouglas Gregor Loc.Line, Loc.Column)) { 58749a2790fSCraig Topper setCodeCompletionConsumer(nullptr); 5888e984da8SDouglas Gregor return; 5898e984da8SDouglas Gregor } 590f09935f1SDouglas Gregor 591f09935f1SDouglas Gregor if (CompletionConsumer->isOutputBinary() && 592a3346d87SRafael Espindola llvm::sys::ChangeStdoutToBinary()) { 593f09935f1SDouglas Gregor getPreprocessor().getDiagnostics().Report(diag::err_fe_stdout_binary); 59449a2790fSCraig Topper setCodeCompletionConsumer(nullptr); 595f09935f1SDouglas Gregor } 596f7093b5aSDaniel Dunbar } 597f7093b5aSDaniel Dunbar 5985505dff8SKovarththanan Rajaratnam void CompilerInstance::createFrontendTimer() { 599ae032b6cSMatthias Braun FrontendTimerGroup.reset( 600ae032b6cSMatthias Braun new llvm::TimerGroup("frontend", "Clang front-end time report")); 601ce18a187SRichard Smith FrontendTimer.reset( 602ae032b6cSMatthias Braun new llvm::Timer("frontend", "Clang front-end timer", 603ae032b6cSMatthias Braun *FrontendTimerGroup)); 6045505dff8SKovarththanan Rajaratnam } 6055505dff8SKovarththanan Rajaratnam 606f7093b5aSDaniel Dunbar CodeCompleteConsumer * 607f7093b5aSDaniel Dunbar CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP, 6085b816061SYaron Keren StringRef Filename, 609f7093b5aSDaniel Dunbar unsigned Line, 610f7093b5aSDaniel Dunbar unsigned Column, 6113292d06aSDmitri Gribenko const CodeCompleteOptions &Opts, 6120e62c1ccSChris Lattner raw_ostream &OS) { 6138e984da8SDouglas Gregor if (EnableCodeCompletion(PP, Filename, Line, Column)) 61449a2790fSCraig Topper return nullptr; 615f7093b5aSDaniel Dunbar 616f7093b5aSDaniel Dunbar // Set up the creation routine for code-completion. 6173292d06aSDmitri Gribenko return new PrintingCodeCompleteConsumer(Opts, OS); 618f7093b5aSDaniel Dunbar } 619566eeb2dSDaniel Dunbar 62069f74f80SDouglas Gregor void CompilerInstance::createSema(TranslationUnitKind TUKind, 6210e93f017SDouglas Gregor CodeCompleteConsumer *CompletionConsumer) { 6220e93f017SDouglas Gregor TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(), 62369f74f80SDouglas Gregor TUKind, CompletionConsumer)); 6247de9969bSBenjamin Kramer // Attach the external sema source if there is any. 6257de9969bSBenjamin Kramer if (ExternalSemaSrc) { 6267de9969bSBenjamin Kramer TheSema->addExternalSource(ExternalSemaSrc.get()); 6277de9969bSBenjamin Kramer ExternalSemaSrc->InitializeSema(*TheSema); 6287de9969bSBenjamin Kramer } 6290e93f017SDouglas Gregor } 6300e93f017SDouglas Gregor 631566eeb2dSDaniel Dunbar // Output Files 632566eeb2dSDaniel Dunbar 633269ec0f4SRafael Espindola void CompilerInstance::addOutputFile(OutputFile &&OutFile) { 634269ec0f4SRafael Espindola OutputFiles.push_back(std::move(OutFile)); 635566eeb2dSDaniel Dunbar } 636566eeb2dSDaniel Dunbar 6371c558cd7SKovarththanan Rajaratnam void CompilerInstance::clearOutputFiles(bool EraseFiles) { 6380aa128e2SReid Kleckner for (OutputFile &OF : OutputFiles) { 6390aa128e2SReid Kleckner if (!OF.TempFilename.empty()) { 640b5c356a4SAnders Carlsson if (EraseFiles) { 6410aa128e2SReid Kleckner llvm::sys::fs::remove(OF.TempFilename); 642b5c356a4SAnders Carlsson } else { 6430aa128e2SReid Kleckner SmallString<128> NewOutFile(OF.Filename); 644b5c356a4SAnders Carlsson 64571731d6bSArgyrios Kyrtzidis // If '-working-directory' was passed, the output filename should be 64671731d6bSArgyrios Kyrtzidis // relative to that. 6479ba8fb1eSAnders Carlsson FileMgr->FixupRelativePath(NewOutFile); 648c080917eSRafael Espindola if (std::error_code ec = 6490aa128e2SReid Kleckner llvm::sys::fs::rename(OF.TempFilename, NewOutFile)) { 6503ef9c447SManuel Klimek getDiagnostics().Report(diag::err_unable_to_rename_temp) 6510aa128e2SReid Kleckner << OF.TempFilename << OF.Filename << ec.message(); 652b5c356a4SAnders Carlsson 6530aa128e2SReid Kleckner llvm::sys::fs::remove(OF.TempFilename); 654d0599970SArgyrios Kyrtzidis } 655d0599970SArgyrios Kyrtzidis } 6560aa128e2SReid Kleckner } else if (!OF.Filename.empty() && EraseFiles) 6570aa128e2SReid Kleckner llvm::sys::fs::remove(OF.Filename); 658566eeb2dSDaniel Dunbar } 659566eeb2dSDaniel Dunbar OutputFiles.clear(); 6602f16bc10SRafael Espindola NonSeekStream.reset(); 661566eeb2dSDaniel Dunbar } 662566eeb2dSDaniel Dunbar 66303f8907fSPeter Collingbourne std::unique_ptr<raw_pwrite_stream> 6642f16bc10SRafael Espindola CompilerInstance::createDefaultOutputFile(bool Binary, StringRef InFile, 6650e62c1ccSChris Lattner StringRef Extension) { 666420b0f1bSDaniel Dunbar return createOutputFile(getFrontendOpts().OutputFile, Binary, 667ae77b3dfSDaniel Dunbar /*RemoveFileOnSignal=*/true, InFile, Extension, 668ae77b3dfSDaniel Dunbar /*UseTemporary=*/true); 669420b0f1bSDaniel Dunbar } 670420b0f1bSDaniel Dunbar 67103f8907fSPeter Collingbourne std::unique_ptr<raw_pwrite_stream> CompilerInstance::createNullOutputFile() { 67203f8907fSPeter Collingbourne return llvm::make_unique<llvm::raw_null_ostream>(); 673ea04672cSAlp Toker } 674ea04672cSAlp Toker 67503f8907fSPeter Collingbourne std::unique_ptr<raw_pwrite_stream> 6762f16bc10SRafael Espindola CompilerInstance::createOutputFile(StringRef OutputPath, bool Binary, 6772f16bc10SRafael Espindola bool RemoveFileOnSignal, StringRef InFile, 6782f16bc10SRafael Espindola StringRef Extension, bool UseTemporary, 679b9c62c07SDaniel Dunbar bool CreateMissingDirectories) { 680dae941a6SRafael Espindola std::string OutputPathName, TempPathName; 681dae941a6SRafael Espindola std::error_code EC; 6822f16bc10SRafael Espindola std::unique_ptr<raw_pwrite_stream> OS = createOutputFile( 683dae941a6SRafael Espindola OutputPath, EC, Binary, RemoveFileOnSignal, InFile, Extension, 684c80a4066SRafael Espindola UseTemporary, CreateMissingDirectories, &OutputPathName, &TempPathName); 685420b0f1bSDaniel Dunbar if (!OS) { 686dae941a6SRafael Espindola getDiagnostics().Report(diag::err_fe_unable_to_open_output) << OutputPath 687dae941a6SRafael Espindola << EC.message(); 68849a2790fSCraig Topper return nullptr; 689420b0f1bSDaniel Dunbar } 690420b0f1bSDaniel Dunbar 691420b0f1bSDaniel Dunbar // Add the output file -- but don't try to remove "-", since this means we are 692420b0f1bSDaniel Dunbar // using stdin. 69303f8907fSPeter Collingbourne addOutputFile( 69403f8907fSPeter Collingbourne OutputFile((OutputPathName != "-") ? OutputPathName : "", TempPathName)); 695420b0f1bSDaniel Dunbar 69603f8907fSPeter Collingbourne return OS; 697420b0f1bSDaniel Dunbar } 698420b0f1bSDaniel Dunbar 6992f16bc10SRafael Espindola std::unique_ptr<llvm::raw_pwrite_stream> CompilerInstance::createOutputFile( 700dae941a6SRafael Espindola StringRef OutputPath, std::error_code &Error, bool Binary, 701dae941a6SRafael Espindola bool RemoveFileOnSignal, StringRef InFile, StringRef Extension, 702dae941a6SRafael Espindola bool UseTemporary, bool CreateMissingDirectories, 703dae941a6SRafael Espindola std::string *ResultPathName, std::string *TempPathName) { 704b9c62c07SDaniel Dunbar assert((!CreateMissingDirectories || UseTemporary) && 705b9c62c07SDaniel Dunbar "CreateMissingDirectories is only allowed when using temporary files"); 706b9c62c07SDaniel Dunbar 707d0599970SArgyrios Kyrtzidis std::string OutFile, TempFile; 708420b0f1bSDaniel Dunbar if (!OutputPath.empty()) { 709420b0f1bSDaniel Dunbar OutFile = OutputPath; 710420b0f1bSDaniel Dunbar } else if (InFile == "-") { 711420b0f1bSDaniel Dunbar OutFile = "-"; 712420b0f1bSDaniel Dunbar } else if (!Extension.empty()) { 713399ab33aSRafael Espindola SmallString<128> Path(InFile); 714399ab33aSRafael Espindola llvm::sys::path::replace_extension(Path, Extension); 715420b0f1bSDaniel Dunbar OutFile = Path.str(); 716420b0f1bSDaniel Dunbar } else { 717420b0f1bSDaniel Dunbar OutFile = "-"; 718420b0f1bSDaniel Dunbar } 719420b0f1bSDaniel Dunbar 720b8984329SAhmed Charles std::unique_ptr<llvm::raw_fd_ostream> OS; 72108a2bfd2SArgyrios Kyrtzidis std::string OSFile; 72208a2bfd2SArgyrios Kyrtzidis 72373c23a71SRafael Espindola if (UseTemporary) { 72473c23a71SRafael Espindola if (OutFile == "-") 72573c23a71SRafael Espindola UseTemporary = false; 72673c23a71SRafael Espindola else { 72773c23a71SRafael Espindola llvm::sys::fs::file_status Status; 72873c23a71SRafael Espindola llvm::sys::fs::status(OutputPath, Status); 72973c23a71SRafael Espindola if (llvm::sys::fs::exists(Status)) { 73073c23a71SRafael Espindola // Fail early if we can't write to the final destination. 7318bfac2c5SDouglas Katzman if (!llvm::sys::fs::can_write(OutputPath)) { 732ee4e08baSRafael Espindola Error = make_error_code(llvm::errc::operation_not_permitted); 73349a2790fSCraig Topper return nullptr; 7348bfac2c5SDouglas Katzman } 73573c23a71SRafael Espindola 73673c23a71SRafael Espindola // Don't use a temporary if the output is a special file. This handles 73773c23a71SRafael Espindola // things like '-o /dev/null' 73873c23a71SRafael Espindola if (!llvm::sys::fs::is_regular_file(Status)) 73973c23a71SRafael Espindola UseTemporary = false; 74073c23a71SRafael Espindola } 74173c23a71SRafael Espindola } 74273c23a71SRafael Espindola } 74373c23a71SRafael Espindola 74473c23a71SRafael Espindola if (UseTemporary) { 745d0599970SArgyrios Kyrtzidis // Create a temporary file. 7462c1dd271SDylan Noblesmith SmallString<128> TempPath; 74708a2bfd2SArgyrios Kyrtzidis TempPath = OutFile; 74808a2bfd2SArgyrios Kyrtzidis TempPath += "-%%%%%%%%"; 74908a2bfd2SArgyrios Kyrtzidis int fd; 750c080917eSRafael Espindola std::error_code EC = 75192e1b62dSYaron Keren llvm::sys::fs::createUniqueFile(TempPath, fd, TempPath); 752157f34bdSRafael Espindola 753157f34bdSRafael Espindola if (CreateMissingDirectories && 75471de0b61SRafael Espindola EC == llvm::errc::no_such_file_or_directory) { 755157f34bdSRafael Espindola StringRef Parent = llvm::sys::path::parent_path(OutputPath); 756157f34bdSRafael Espindola EC = llvm::sys::fs::create_directories(Parent); 757157f34bdSRafael Espindola if (!EC) { 75892e1b62dSYaron Keren EC = llvm::sys::fs::createUniqueFile(TempPath, fd, TempPath); 759157f34bdSRafael Espindola } 760157f34bdSRafael Espindola } 761157f34bdSRafael Espindola 762157f34bdSRafael Espindola if (!EC) { 76369f3528cSNAKAMURA Takumi OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true)); 76408a2bfd2SArgyrios Kyrtzidis OSFile = TempFile = TempPath.str(); 76508a2bfd2SArgyrios Kyrtzidis } 76673c23a71SRafael Espindola // If we failed to create the temporary, fallback to writing to the file 76773c23a71SRafael Espindola // directly. This handles the corner case where we cannot write to the 76873c23a71SRafael Espindola // directory, but can write to the file. 769d0599970SArgyrios Kyrtzidis } 770d0599970SArgyrios Kyrtzidis 77108a2bfd2SArgyrios Kyrtzidis if (!OS) { 77208a2bfd2SArgyrios Kyrtzidis OSFile = OutFile; 77369f3528cSNAKAMURA Takumi OS.reset(new llvm::raw_fd_ostream( 774dae941a6SRafael Espindola OSFile, Error, 77569f3528cSNAKAMURA Takumi (Binary ? llvm::sys::fs::F_None : llvm::sys::fs::F_Text))); 776dae941a6SRafael Espindola if (Error) 77749a2790fSCraig Topper return nullptr; 77808a2bfd2SArgyrios Kyrtzidis } 779420b0f1bSDaniel Dunbar 780d0599970SArgyrios Kyrtzidis // Make sure the out stream file gets removed if we crash. 781e326f9bbSDaniel Dunbar if (RemoveFileOnSignal) 78218556de3SRafael Espindola llvm::sys::RemoveFileOnSignal(OSFile); 783d0599970SArgyrios Kyrtzidis 784420b0f1bSDaniel Dunbar if (ResultPathName) 785420b0f1bSDaniel Dunbar *ResultPathName = OutFile; 786d0599970SArgyrios Kyrtzidis if (TempPathName) 787d0599970SArgyrios Kyrtzidis *TempPathName = TempFile; 788420b0f1bSDaniel Dunbar 7892f16bc10SRafael Espindola if (!Binary || OS->supportsSeeking()) 7902f16bc10SRafael Espindola return std::move(OS); 7912f16bc10SRafael Espindola 7922f16bc10SRafael Espindola auto B = llvm::make_unique<llvm::buffer_ostream>(*OS); 7932f16bc10SRafael Espindola assert(!NonSeekStream); 7942f16bc10SRafael Espindola NonSeekStream = std::move(OS); 7952f16bc10SRafael Espindola return std::move(B); 796420b0f1bSDaniel Dunbar } 797409e890fSDaniel Dunbar 798409e890fSDaniel Dunbar // Initialization Utilities 799409e890fSDaniel Dunbar 8001b3240b0SArgyrios Kyrtzidis bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input){ 8012ca4be97SNico Weber return InitializeSourceManager( 8022ca4be97SNico Weber Input, getDiagnostics(), getFileManager(), getSourceManager(), 8032ca4be97SNico Weber hasPreprocessor() ? &getPreprocessor().getHeaderSearchInfo() : nullptr, 8044b5aedefSNico Weber getDependencyOutputOpts(), getFrontendOpts()); 805409e890fSDaniel Dunbar } 806409e890fSDaniel Dunbar 8072ca4be97SNico Weber // static 8084b5aedefSNico Weber bool CompilerInstance::InitializeSourceManager( 8094b5aedefSNico Weber const FrontendInputFile &Input, DiagnosticsEngine &Diags, 8104b5aedefSNico Weber FileManager &FileMgr, SourceManager &SourceMgr, HeaderSearch *HS, 8114b5aedefSNico Weber DependencyOutputOptions &DepOpts, const FrontendOptions &Opts) { 8121b3240b0SArgyrios Kyrtzidis SrcMgr::CharacteristicKind 813873c8583SArgyrios Kyrtzidis Kind = Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User; 8141b3240b0SArgyrios Kyrtzidis 8156566e23eSArgyrios Kyrtzidis if (Input.isBuffer()) { 81650a5f97eSDavid Blaikie SourceMgr.setMainFileID(SourceMgr.createFileID( 81750a5f97eSDavid Blaikie std::unique_ptr<llvm::MemoryBuffer>(Input.getBuffer()), Kind)); 8188b563665SYaron Keren assert(SourceMgr.getMainFileID().isValid() && 8196566e23eSArgyrios Kyrtzidis "Couldn't establish MainFileID!"); 8206566e23eSArgyrios Kyrtzidis return true; 8216566e23eSArgyrios Kyrtzidis } 8226566e23eSArgyrios Kyrtzidis 8236566e23eSArgyrios Kyrtzidis StringRef InputFile = Input.getFile(); 8246566e23eSArgyrios Kyrtzidis 8257c06d866SArgyrios Kyrtzidis // Figure out where to get and map in the main file. 8267c06d866SArgyrios Kyrtzidis if (InputFile != "-") { 8272ca4be97SNico Weber const FileEntry *File; 8282ca4be97SNico Weber if (Opts.FindPchSource.empty()) { 8292ca4be97SNico Weber File = FileMgr.getFile(InputFile, /*OpenFile=*/true); 8302ca4be97SNico Weber } else { 8312ca4be97SNico Weber // When building a pch file in clang-cl mode, the .h file is built as if 8322ca4be97SNico Weber // it was included by a cc file. Since the driver doesn't know about 8332ca4be97SNico Weber // all include search directories, the frontend must search the input 8342ca4be97SNico Weber // file through HeaderSearch here, as if it had been included by the 8352ca4be97SNico Weber // cc file at Opts.FindPchSource. 8362ca4be97SNico Weber const FileEntry *FindFile = FileMgr.getFile(Opts.FindPchSource); 8372ca4be97SNico Weber if (!FindFile) { 8382ca4be97SNico Weber Diags.Report(diag::err_fe_error_reading) << Opts.FindPchSource; 8392ca4be97SNico Weber return false; 8402ca4be97SNico Weber } 8412ca4be97SNico Weber const DirectoryLookup *UnusedCurDir; 8422ca4be97SNico Weber SmallVector<std::pair<const FileEntry *, const DirectoryEntry *>, 16> 8432ca4be97SNico Weber Includers; 8442ca4be97SNico Weber Includers.push_back(std::make_pair(FindFile, FindFile->getDir())); 8452ca4be97SNico Weber File = HS->LookupFile(InputFile, SourceLocation(), /*isAngled=*/false, 8462ca4be97SNico Weber /*FromDir=*/nullptr, 8472ca4be97SNico Weber /*CurDir=*/UnusedCurDir, Includers, 8482ca4be97SNico Weber /*SearchPath=*/nullptr, 8492ca4be97SNico Weber /*RelativePath=*/nullptr, 8502ca4be97SNico Weber /*RequestingModule=*/nullptr, 8512ca4be97SNico Weber /*SuggestedModule=*/nullptr, /*SkipCache=*/true); 8524b5aedefSNico Weber // Also add the header to /showIncludes output. 8534b5aedefSNico Weber if (File) 854f54146c1SNico Weber DepOpts.ShowIncludesPretendHeader = File->getName(); 8552ca4be97SNico Weber } 85652765215SDan Gohman if (!File) { 857409e890fSDaniel Dunbar Diags.Report(diag::err_fe_error_reading) << InputFile; 858409e890fSDaniel Dunbar return false; 859409e890fSDaniel Dunbar } 860e2951f48SDaniel Dunbar 861e2951f48SDaniel Dunbar // The natural SourceManager infrastructure can't currently handle named 862e2951f48SDaniel Dunbar // pipes, but we would at least like to accept them for the main 8633841fa38SBenjamin Kramer // file. Detect them here, read them with the volatile flag so FileMgr will 8643841fa38SBenjamin Kramer // pick up the correct size, and simply override their contents as we do for 8653841fa38SBenjamin Kramer // STDIN. 866e2951f48SDaniel Dunbar if (File->isNamedPipe()) { 867a885796dSBenjamin Kramer auto MB = FileMgr.getBufferForFile(File, /*isVolatile=*/true); 868a885796dSBenjamin Kramer if (MB) { 869db0745abSDaniel Dunbar // Create a new virtual file that will have the correct size. 870a885796dSBenjamin Kramer File = FileMgr.getVirtualFile(InputFile, (*MB)->getBufferSize(), 0); 871a885796dSBenjamin Kramer SourceMgr.overrideFileContents(File, std::move(*MB)); 8723841fa38SBenjamin Kramer } else { 873a885796dSBenjamin Kramer Diags.Report(diag::err_cannot_open_file) << InputFile 874a885796dSBenjamin Kramer << MB.getError().message(); 8753841fa38SBenjamin Kramer return false; 8763841fa38SBenjamin Kramer } 877e2951f48SDaniel Dunbar } 878db0745abSDaniel Dunbar 879b671e34cSAlp Toker SourceMgr.setMainFileID( 880b671e34cSAlp Toker SourceMgr.createFileID(File, SourceLocation(), Kind)); 881409e890fSDaniel Dunbar } else { 8822d2b420aSRafael Espindola llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> SBOrErr = 8832d2b420aSRafael Espindola llvm::MemoryBuffer::getSTDIN(); 8842d2b420aSRafael Espindola if (std::error_code EC = SBOrErr.getError()) { 8852d2b420aSRafael Espindola Diags.Report(diag::err_fe_error_reading_stdin) << EC.message(); 886409e890fSDaniel Dunbar return false; 887409e890fSDaniel Dunbar } 8882d2b420aSRafael Espindola std::unique_ptr<llvm::MemoryBuffer> SB = std::move(SBOrErr.get()); 8892d2b420aSRafael Espindola 8902f76cd75SDan Gohman const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(), 8915159f616SChris Lattner SB->getBufferSize(), 0); 892b671e34cSAlp Toker SourceMgr.setMainFileID( 893b671e34cSAlp Toker SourceMgr.createFileID(File, SourceLocation(), Kind)); 89449cc3181SDavid Blaikie SourceMgr.overrideFileContents(File, std::move(SB)); 895409e890fSDaniel Dunbar } 896409e890fSDaniel Dunbar 8978b563665SYaron Keren assert(SourceMgr.getMainFileID().isValid() && 89852765215SDan Gohman "Couldn't establish MainFileID!"); 899409e890fSDaniel Dunbar return true; 900409e890fSDaniel Dunbar } 9014f2bc55dSDaniel Dunbar 9024f2bc55dSDaniel Dunbar // High-Level Operations 9034f2bc55dSDaniel Dunbar 9044f2bc55dSDaniel Dunbar bool CompilerInstance::ExecuteAction(FrontendAction &Act) { 9054f2bc55dSDaniel Dunbar assert(hasDiagnostics() && "Diagnostics engine is not initialized!"); 9064f2bc55dSDaniel Dunbar assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!"); 9074f2bc55dSDaniel Dunbar assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!"); 9084f2bc55dSDaniel Dunbar 9094f2bc55dSDaniel Dunbar // FIXME: Take this as an argument, once all the APIs we used have moved to 9104f2bc55dSDaniel Dunbar // taking it as an input instead of hard-coding llvm::errs. 9110e62c1ccSChris Lattner raw_ostream &OS = llvm::errs(); 9124f2bc55dSDaniel Dunbar 9134f2bc55dSDaniel Dunbar // Create the target instance. 91480758084SAlp Toker setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), 91510a4972aSSaleem Abdulrasool getInvocation().TargetOpts)); 9164f2bc55dSDaniel Dunbar if (!hasTarget()) 9174f2bc55dSDaniel Dunbar return false; 9184f2bc55dSDaniel Dunbar 919b5bc923aSArtem Belevich // Create TargetInfo for the other side of CUDA compilation. 920b5bc923aSArtem Belevich if (getLangOpts().CUDA && !getFrontendOpts().AuxTriple.empty()) { 92176945b2fSJustin Lebar auto TO = std::make_shared<TargetOptions>(); 922b5bc923aSArtem Belevich TO->Triple = getFrontendOpts().AuxTriple; 92376945b2fSJustin Lebar TO->HostTriple = getTarget().getTriple().str(); 92410a4972aSSaleem Abdulrasool setAuxTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), TO)); 925b5bc923aSArtem Belevich } 926b5bc923aSArtem Belevich 9274f2bc55dSDaniel Dunbar // Inform the target of the language options. 9284f2bc55dSDaniel Dunbar // 9294f2bc55dSDaniel Dunbar // FIXME: We shouldn't need to do this, the target should be immutable once 9304f2bc55dSDaniel Dunbar // created. This complexity should be lifted elsewhere. 93174437975SAlp Toker getTarget().adjust(getLangOpts()); 9324f2bc55dSDaniel Dunbar 9332c17e82bSYaxun Liu // Adjust target options based on codegen options. 9342c17e82bSYaxun Liu getTarget().adjustTargetOptions(getCodeGenOpts(), getTargetOpts()); 9352c17e82bSYaxun Liu 93629898f45SFariborz Jahanian // rewriter project will change target built-in bool type from its default. 93729898f45SFariborz Jahanian if (getFrontendOpts().ProgramAction == frontend::RewriteObjC) 93829898f45SFariborz Jahanian getTarget().noSignedCharForObjCBool(); 93929898f45SFariborz Jahanian 9404f2bc55dSDaniel Dunbar // Validate/process some options. 9414f2bc55dSDaniel Dunbar if (getHeaderSearchOpts().Verbose) 9424f2bc55dSDaniel Dunbar OS << "clang -cc1 version " CLANG_VERSION_STRING 943f988d006SAlp Toker << " based upon " << BACKEND_PACKAGE_STRING 9448188c8a1SSebastian Pop << " default target " << llvm::sys::getDefaultTargetTriple() << "\n"; 9454f2bc55dSDaniel Dunbar 9464f2bc55dSDaniel Dunbar if (getFrontendOpts().ShowTimers) 9474f2bc55dSDaniel Dunbar createFrontendTimer(); 9484f2bc55dSDaniel Dunbar 949abb6eea1SMatthias Braun if (getFrontendOpts().ShowStats || !getFrontendOpts().StatsFile.empty()) 950ec1c5a20SMatthias Braun llvm::EnableStatistics(false); 951171b780cSDouglas Gregor 9525b60ad68SVedant Kumar for (const FrontendInputFile &FIF : getFrontendOpts().Inputs) { 953eeccb30bSTed Kremenek // Reset the ID tables if we are reusing the SourceManager and parsing 954eeccb30bSTed Kremenek // regular files. 955eeccb30bSTed Kremenek if (hasSourceManager() && !Act.isModelParsingAction()) 9564f2bc55dSDaniel Dunbar getSourceManager().clearIDTables(); 9574f2bc55dSDaniel Dunbar 9585b60ad68SVedant Kumar if (Act.BeginSourceFile(*this, FIF)) { 9594f2bc55dSDaniel Dunbar Act.Execute(); 9604f2bc55dSDaniel Dunbar Act.EndSourceFile(); 9614f2bc55dSDaniel Dunbar } 9624f2bc55dSDaniel Dunbar } 9634f2bc55dSDaniel Dunbar 9647910d7b7SArgyrios Kyrtzidis // Notify the diagnostic client that all files were processed. 9657910d7b7SArgyrios Kyrtzidis getDiagnostics().getClient()->finish(); 9667910d7b7SArgyrios Kyrtzidis 967198cb4dfSChris Lattner if (getDiagnosticOpts().ShowCarets) { 968c79346a5SArgyrios Kyrtzidis // We can have multiple diagnostics sharing one diagnostic client. 969c79346a5SArgyrios Kyrtzidis // Get the total number of warnings/errors from the client. 970c79346a5SArgyrios Kyrtzidis unsigned NumWarnings = getDiagnostics().getClient()->getNumWarnings(); 971c79346a5SArgyrios Kyrtzidis unsigned NumErrors = getDiagnostics().getClient()->getNumErrors(); 972198cb4dfSChris Lattner 973198cb4dfSChris Lattner if (NumWarnings) 974198cb4dfSChris Lattner OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s"); 975198cb4dfSChris Lattner if (NumWarnings && NumErrors) 976198cb4dfSChris Lattner OS << " and "; 977198cb4dfSChris Lattner if (NumErrors) 978198cb4dfSChris Lattner OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s"); 979198cb4dfSChris Lattner if (NumWarnings || NumErrors) 980198cb4dfSChris Lattner OS << " generated.\n"; 981198cb4dfSChris Lattner } 9824f2bc55dSDaniel Dunbar 983abb6eea1SMatthias Braun if (getFrontendOpts().ShowStats) { 984abb6eea1SMatthias Braun if (hasFileManager()) { 9854f2bc55dSDaniel Dunbar getFileManager().PrintStats(); 986abb6eea1SMatthias Braun OS << '\n'; 987abb6eea1SMatthias Braun } 988abb6eea1SMatthias Braun llvm::PrintStatistics(OS); 989abb6eea1SMatthias Braun } 990abb6eea1SMatthias Braun StringRef StatsFile = getFrontendOpts().StatsFile; 991abb6eea1SMatthias Braun if (!StatsFile.empty()) { 992abb6eea1SMatthias Braun std::error_code EC; 993abb6eea1SMatthias Braun auto StatS = llvm::make_unique<llvm::raw_fd_ostream>(StatsFile, EC, 994abb6eea1SMatthias Braun llvm::sys::fs::F_Text); 995abb6eea1SMatthias Braun if (EC) { 996abb6eea1SMatthias Braun getDiagnostics().Report(diag::warn_fe_unable_to_open_stats_file) 997abb6eea1SMatthias Braun << StatsFile << EC.message(); 998abb6eea1SMatthias Braun } else { 999abb6eea1SMatthias Braun llvm::PrintStatisticsJSON(*StatS); 1000abb6eea1SMatthias Braun } 10014f2bc55dSDaniel Dunbar } 10024f2bc55dSDaniel Dunbar 1003bc467933SArgyrios Kyrtzidis return !getDiagnostics().getClient()->getNumErrors(); 10044f2bc55dSDaniel Dunbar } 10054f2bc55dSDaniel Dunbar 1006faeb1d46SDouglas Gregor /// \brief Determine the appropriate source input kind based on language 1007faeb1d46SDouglas Gregor /// options. 1008faeb1d46SDouglas Gregor static InputKind getSourceInputKindFromOptions(const LangOptions &LangOpts) { 1009faeb1d46SDouglas Gregor if (LangOpts.OpenCL) 1010faeb1d46SDouglas Gregor return IK_OpenCL; 1011faeb1d46SDouglas Gregor if (LangOpts.CUDA) 1012faeb1d46SDouglas Gregor return IK_CUDA; 1013faeb1d46SDouglas Gregor if (LangOpts.ObjC1) 1014faeb1d46SDouglas Gregor return LangOpts.CPlusPlus? IK_ObjCXX : IK_ObjC; 1015faeb1d46SDouglas Gregor return LangOpts.CPlusPlus? IK_CXX : IK_C; 1016faeb1d46SDouglas Gregor } 1017faeb1d46SDouglas Gregor 1018514b636aSDouglas Gregor /// \brief Compile a module file for the given module, using the options 1019b797d59fSBen Langmuir /// provided by the importing compiler instance. Returns true if the module 1020b797d59fSBen Langmuir /// was built without errors. 1021b797d59fSBen Langmuir static bool compileModuleImpl(CompilerInstance &ImportingInstance, 1022af8f0263SDouglas Gregor SourceLocation ImportLoc, 1023de3ef502SDouglas Gregor Module *Module, 10246dc57927SDouglas Gregor StringRef ModuleFileName) { 1025514b636aSDouglas Gregor ModuleMap &ModMap 1026514b636aSDouglas Gregor = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap(); 1027514b636aSDouglas Gregor 1028faeb1d46SDouglas Gregor // Construct a compiler invocation for creating this module. 1029ea4395ebSDavid Blaikie auto Invocation = 1030ea4395ebSDavid Blaikie std::make_shared<CompilerInvocation>(ImportingInstance.getInvocation()); 103144bf68d8SDouglas Gregor 1032f545f67dSDouglas Gregor PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 1033f545f67dSDouglas Gregor 103444bf68d8SDouglas Gregor // For any options that aren't intended to affect how a module is built, 103544bf68d8SDouglas Gregor // reset them to their default values. 10368cf47df7STed Kremenek Invocation->getLangOpts()->resetNonModularOptions(); 1037f545f67dSDouglas Gregor PPOpts.resetNonModularOptions(); 103844bf68d8SDouglas Gregor 10395dc3899cSDouglas Gregor // Remove any macro definitions that are explicitly ignored by the module. 10405dc3899cSDouglas Gregor // They aren't supposed to affect how the module is built anyway. 104160fa2888SDuncan P. N. Exon Smith HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts(); 1042bbdd7640SBenjamin Kramer PPOpts.Macros.erase( 1043bbdd7640SBenjamin Kramer std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(), 1044bbdd7640SBenjamin Kramer [&HSOpts](const std::pair<std::string, bool> &def) { 1045bbdd7640SBenjamin Kramer StringRef MacroDef = def.first; 10465e83dfedSJustin Lebar return HSOpts.ModulesIgnoreMacros.count( 10475e83dfedSJustin Lebar llvm::CachedHashString(MacroDef.split('=').first)) > 0; 1048bbdd7640SBenjamin Kramer }), 10495dc3899cSDouglas Gregor PPOpts.Macros.end()); 10505dc3899cSDouglas Gregor 10517d106e42SDouglas Gregor // Note the name of the module we're building. 10526dc57927SDouglas Gregor Invocation->getLangOpts()->CurrentModule = Module->getTopLevelModuleName(); 10537d106e42SDouglas Gregor 10547a626570SDouglas Gregor // Make sure that the failed-module structure has been allocated in 10557a626570SDouglas Gregor // the importing instance, and propagate the pointer to the newly-created 10567a626570SDouglas Gregor // instance. 10577a626570SDouglas Gregor PreprocessorOptions &ImportingPPOpts 10587a626570SDouglas Gregor = ImportingInstance.getInvocation().getPreprocessorOpts(); 10597a626570SDouglas Gregor if (!ImportingPPOpts.FailedModules) 1060f95113daSDavid Blaikie ImportingPPOpts.FailedModules = 1061f95113daSDavid Blaikie std::make_shared<PreprocessorOptions::FailedModulesSet>(); 10627a626570SDouglas Gregor PPOpts.FailedModules = ImportingPPOpts.FailedModules; 10637a626570SDouglas Gregor 1064514b636aSDouglas Gregor // If there is a module map file, build the module using the module map. 1065514b636aSDouglas Gregor // Set up the inputs/outputs so that we build the module from its umbrella 1066514b636aSDouglas Gregor // header. 1067514b636aSDouglas Gregor FrontendOptions &FrontendOpts = Invocation->getFrontendOpts(); 1068514b636aSDouglas Gregor FrontendOpts.OutputFile = ModuleFileName.str(); 1069514b636aSDouglas Gregor FrontendOpts.DisableFree = false; 1070c1bbec85SDouglas Gregor FrontendOpts.GenerateGlobalModuleIndex = false; 1071e75ee0f0SRichard Smith FrontendOpts.BuildingImplicitModule = true; 107260fa2888SDuncan P. N. Exon Smith // Force implicitly-built modules to hash the content of the module file. 107360fa2888SDuncan P. N. Exon Smith HSOpts.ModulesHashContent = true; 1074514b636aSDouglas Gregor FrontendOpts.Inputs.clear(); 1075f545f67dSDouglas Gregor InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts()); 1076f545f67dSDouglas Gregor 1077f545f67dSDouglas Gregor // Don't free the remapped file buffers; they are owned by our caller. 1078f545f67dSDouglas Gregor PPOpts.RetainRemappedFileBuffers = true; 1079514b636aSDouglas Gregor 1080514b636aSDouglas Gregor Invocation->getDiagnosticOpts().VerifyDiagnostics = 0; 1081514b636aSDouglas Gregor assert(ImportingInstance.getInvocation().getModuleHash() == 1082514b636aSDouglas Gregor Invocation->getModuleHash() && "Module hash mismatch!"); 1083514b636aSDouglas Gregor 1084514b636aSDouglas Gregor // Construct a compiler instance that will be used to actually create the 1085*030d7d6dSDuncan P. N. Exon Smith // module. Since we're sharing a PCMCache, 1086*030d7d6dSDuncan P. N. Exon Smith // CompilerInstance::CompilerInstance is responsible for finalizing the 1087*030d7d6dSDuncan P. N. Exon Smith // buffers to prevent use-after-frees. 1088bb165fb0SAdrian Prantl CompilerInstance Instance(ImportingInstance.getPCHContainerOperations(), 1089*030d7d6dSDuncan P. N. Exon Smith &ImportingInstance.getPreprocessor().getPCMCache()); 1090ea4395ebSDavid Blaikie auto &Inv = *Invocation; 1091ea4395ebSDavid Blaikie Instance.setInvocation(std::move(Invocation)); 10926b930967SDouglas Gregor 10936b930967SDouglas Gregor Instance.createDiagnostics(new ForwardingDiagnosticConsumer( 10946b930967SDouglas Gregor ImportingInstance.getDiagnosticClient()), 109530071ceaSDouglas Gregor /*ShouldOwnClient=*/true); 1096514b636aSDouglas Gregor 1097c8130a74SBen Langmuir Instance.setVirtualFileSystem(&ImportingInstance.getVirtualFileSystem()); 1098c8130a74SBen Langmuir 109963365431SDouglas Gregor // Note that this module is part of the module build stack, so that we 1100af8f0263SDouglas Gregor // can detect cycles in the module graph. 1101d066d4c8SBen Langmuir Instance.setFileManager(&ImportingInstance.getFileManager()); 1102af8f0263SDouglas Gregor Instance.createSourceManager(Instance.getFileManager()); 1103af8f0263SDouglas Gregor SourceManager &SourceMgr = Instance.getSourceManager(); 110463365431SDouglas Gregor SourceMgr.setModuleBuildStack( 110563365431SDouglas Gregor ImportingInstance.getSourceManager().getModuleBuildStack()); 110663365431SDouglas Gregor SourceMgr.pushModuleBuildStack(Module->getTopLevelModuleName(), 1107af8f0263SDouglas Gregor FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager())); 1108af8f0263SDouglas Gregor 110986d1259cSJustin Bogner // If we're collecting module dependencies, we need to share a collector 111038c1e6d3SRichard Smith // between all of the module CompilerInstances. Other than that, we don't 111138c1e6d3SRichard Smith // want to produce any dependency output from the module build. 111286d1259cSJustin Bogner Instance.setModuleDepCollector(ImportingInstance.getModuleDepCollector()); 1113ea4395ebSDavid Blaikie Inv.getDependencyOutputOpts() = DependencyOutputOptions(); 111486d1259cSJustin Bogner 11151f76c4e8SManuel Klimek // Get or create the module map that we'll use to build this module. 11161f76c4e8SManuel Klimek std::string InferredModuleMapContent; 11171f76c4e8SManuel Klimek if (const FileEntry *ModuleMapFile = 11181f76c4e8SManuel Klimek ModMap.getContainingModuleMapFile(Module)) { 11191f76c4e8SManuel Klimek // Use the module map where this module resides. 11203204b152SBenjamin Kramer FrontendOpts.Inputs.emplace_back(ModuleMapFile->getName(), IK); 11211f76c4e8SManuel Klimek } else { 11222b63d15fSRichard Smith SmallString<128> FakeModuleMapFile(Module->Directory->getName()); 11232b63d15fSRichard Smith llvm::sys::path::append(FakeModuleMapFile, "__inferred_module.map"); 11243204b152SBenjamin Kramer FrontendOpts.Inputs.emplace_back(FakeModuleMapFile, IK); 11252b63d15fSRichard Smith 11261f76c4e8SManuel Klimek llvm::raw_string_ostream OS(InferredModuleMapContent); 11271f76c4e8SManuel Klimek Module->print(OS); 11281f76c4e8SManuel Klimek OS.flush(); 11291f76c4e8SManuel Klimek 1130d87f8d76SRafael Espindola std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer = 11311f76c4e8SManuel Klimek llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent); 11321f76c4e8SManuel Klimek ModuleMapFile = Instance.getFileManager().getVirtualFile( 11332b63d15fSRichard Smith FakeModuleMapFile, InferredModuleMapContent.size(), 0); 113449cc3181SDavid Blaikie SourceMgr.overrideFileContents(ModuleMapFile, std::move(ModuleMapBuffer)); 11351f76c4e8SManuel Klimek } 1136af8f0263SDouglas Gregor 11379d6448b1SBen Langmuir // Construct a module-generating action. Passing through the module map is 1138beee15e7SBen Langmuir // safe because the FileManager is shared between the compiler instances. 1139bbcc9f04SRichard Smith GenerateModuleFromModuleMapAction CreateModuleAction( 11409d6448b1SBen Langmuir ModMap.getModuleMapFileForUniquing(Module), Module->IsSystem); 1141514b636aSDouglas Gregor 114299891da7SRichard Smith ImportingInstance.getDiagnostics().Report(ImportLoc, 114399891da7SRichard Smith diag::remark_module_build) 114499891da7SRichard Smith << Module->Name << ModuleFileName; 114599891da7SRichard Smith 1146514b636aSDouglas Gregor // Execute the action to actually build the module in-place. Use a separate 1147514b636aSDouglas Gregor // thread so that we get a stack large enough. 1148514b636aSDouglas Gregor const unsigned ThreadStackSize = 8 << 20; 1149514b636aSDouglas Gregor llvm::CrashRecoveryContext CRC; 1150841f1c78SRichard Smith CRC.RunSafelyOnThread([&]() { Instance.ExecuteAction(CreateModuleAction); }, 1151841f1c78SRichard Smith ThreadStackSize); 11526b930967SDouglas Gregor 115399891da7SRichard Smith ImportingInstance.getDiagnostics().Report(ImportLoc, 115499891da7SRichard Smith diag::remark_module_build_done) 115599891da7SRichard Smith << Module->Name; 115699891da7SRichard Smith 1157f545f67dSDouglas Gregor // Delete the temporary module map file. 1158f545f67dSDouglas Gregor // FIXME: Even though we're executing under crash protection, it would still 1159f545f67dSDouglas Gregor // be nice to do this with RemoveFileOnSignal when we can. However, that 1160f545f67dSDouglas Gregor // doesn't make sense for all clients, so clean this up manually. 116113afbf42SBenjamin Kramer Instance.clearOutputFiles(/*EraseFiles=*/true); 11625e306b12SDouglas Gregor 11635e306b12SDouglas Gregor // We've rebuilt a module. If we're allowed to generate or update the global 11645e306b12SDouglas Gregor // module index, record that fact in the importing compiler instance. 1165c1bbec85SDouglas Gregor if (ImportingInstance.getFrontendOpts().GenerateGlobalModuleIndex) { 11665e306b12SDouglas Gregor ImportingInstance.setBuildGlobalModuleIndex(true); 11675e306b12SDouglas Gregor } 1168b797d59fSBen Langmuir 1169b797d59fSBen Langmuir return !Instance.getDiagnostics().hasErrorOccurred(); 1170faeb1d46SDouglas Gregor } 1171faeb1d46SDouglas Gregor 1172dbdc0368SBen Langmuir static bool compileAndLoadModule(CompilerInstance &ImportingInstance, 11734382fe74SArgyrios Kyrtzidis SourceLocation ImportLoc, 1174b797d59fSBen Langmuir SourceLocation ModuleNameLoc, Module *Module, 11754382fe74SArgyrios Kyrtzidis StringRef ModuleFileName) { 1176d213aab7SBen Langmuir DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics(); 1177d213aab7SBen Langmuir 1178b797d59fSBen Langmuir auto diagnoseBuildFailure = [&] { 1179d213aab7SBen Langmuir Diags.Report(ModuleNameLoc, diag::err_module_not_built) 1180b797d59fSBen Langmuir << Module->Name << SourceRange(ImportLoc, ModuleNameLoc); 1181b797d59fSBen Langmuir }; 1182b797d59fSBen Langmuir 11834382fe74SArgyrios Kyrtzidis // FIXME: have LockFileManager return an error_code so that we can 11844382fe74SArgyrios Kyrtzidis // avoid the mkdir when the directory already exists. 11854382fe74SArgyrios Kyrtzidis StringRef Dir = llvm::sys::path::parent_path(ModuleFileName); 11864382fe74SArgyrios Kyrtzidis llvm::sys::fs::create_directories(Dir); 11874382fe74SArgyrios Kyrtzidis 11884382fe74SArgyrios Kyrtzidis while (1) { 1189dbdc0368SBen Langmuir unsigned ModuleLoadCapabilities = ASTReader::ARR_Missing; 11904382fe74SArgyrios Kyrtzidis llvm::LockFileManager Locked(ModuleFileName); 11914382fe74SArgyrios Kyrtzidis switch (Locked) { 11924382fe74SArgyrios Kyrtzidis case llvm::LockFileManager::LFS_Error: 11935a0af1fcSBruno Cardoso Lopes // PCMCache takes care of correctness and locks are only necessary for 11945a0af1fcSBruno Cardoso Lopes // performance. Fallback to building the module in case of any lock 11955a0af1fcSBruno Cardoso Lopes // related errors. 11965a0af1fcSBruno Cardoso Lopes Diags.Report(ModuleNameLoc, diag::remark_module_lock_failure) 11974a52222cSBruno Cardoso Lopes << Module->Name << Locked.getErrorMessage(); 11985a0af1fcSBruno Cardoso Lopes // Clear out any potential leftover. 11995a0af1fcSBruno Cardoso Lopes Locked.unsafeRemoveLockFile(); 12005a0af1fcSBruno Cardoso Lopes // FALLTHROUGH 12014382fe74SArgyrios Kyrtzidis case llvm::LockFileManager::LFS_Owned: 1202dbdc0368SBen Langmuir // We're responsible for building the module ourselves. 1203b797d59fSBen Langmuir if (!compileModuleImpl(ImportingInstance, ModuleNameLoc, Module, 1204b797d59fSBen Langmuir ModuleFileName)) { 1205b797d59fSBen Langmuir diagnoseBuildFailure(); 1206b797d59fSBen Langmuir return false; 1207b797d59fSBen Langmuir } 12084382fe74SArgyrios Kyrtzidis break; 12094382fe74SArgyrios Kyrtzidis 12104382fe74SArgyrios Kyrtzidis case llvm::LockFileManager::LFS_Shared: 12114382fe74SArgyrios Kyrtzidis // Someone else is responsible for building the module. Wait for them to 12124382fe74SArgyrios Kyrtzidis // finish. 12131daf4801SBen Langmuir switch (Locked.waitForUnlock()) { 12141daf4801SBen Langmuir case llvm::LockFileManager::Res_Success: 1215dbdc0368SBen Langmuir ModuleLoadCapabilities |= ASTReader::ARR_OutOfDate; 1216dbdc0368SBen Langmuir break; 12171daf4801SBen Langmuir case llvm::LockFileManager::Res_OwnerDied: 12181daf4801SBen Langmuir continue; // try again to get the lock. 12191daf4801SBen Langmuir case llvm::LockFileManager::Res_Timeout: 12205a0af1fcSBruno Cardoso Lopes // Since PCMCache takes care of correctness, we try waiting for another 12215a0af1fcSBruno Cardoso Lopes // process to complete the build so clang does not do it done twice. If 12225a0af1fcSBruno Cardoso Lopes // case of timeout, build it ourselves. 12235a0af1fcSBruno Cardoso Lopes Diags.Report(ModuleNameLoc, diag::remark_module_lock_timeout) 12241daf4801SBen Langmuir << Module->Name; 12251daf4801SBen Langmuir // Clear the lock file so that future invokations can make progress. 12261daf4801SBen Langmuir Locked.unsafeRemoveLockFile(); 12275a0af1fcSBruno Cardoso Lopes continue; 12281daf4801SBen Langmuir } 12291daf4801SBen Langmuir break; 12304382fe74SArgyrios Kyrtzidis } 12314382fe74SArgyrios Kyrtzidis 1232dbdc0368SBen Langmuir // Try to read the module file, now that we've compiled it. 1233dbdc0368SBen Langmuir ASTReader::ASTReadResult ReadResult = 1234dbdc0368SBen Langmuir ImportingInstance.getModuleManager()->ReadAST( 1235e842a474SRichard Smith ModuleFileName, serialization::MK_ImplicitModule, ImportLoc, 1236dbdc0368SBen Langmuir ModuleLoadCapabilities); 1237dbdc0368SBen Langmuir 1238dbdc0368SBen Langmuir if (ReadResult == ASTReader::OutOfDate && 1239dbdc0368SBen Langmuir Locked == llvm::LockFileManager::LFS_Shared) { 1240dbdc0368SBen Langmuir // The module may be out of date in the presence of file system races, 1241dbdc0368SBen Langmuir // or if one of its imports depends on header search paths that are not 1242dbdc0368SBen Langmuir // consistent with this ImportingInstance. Try again... 1243dbdc0368SBen Langmuir continue; 1244dbdc0368SBen Langmuir } else if (ReadResult == ASTReader::Missing) { 1245b797d59fSBen Langmuir diagnoseBuildFailure(); 1246d213aab7SBen Langmuir } else if (ReadResult != ASTReader::Success && 1247d213aab7SBen Langmuir !Diags.hasErrorOccurred()) { 1248d213aab7SBen Langmuir // The ASTReader didn't diagnose the error, so conservatively report it. 1249d213aab7SBen Langmuir diagnoseBuildFailure(); 1250dbdc0368SBen Langmuir } 1251dbdc0368SBen Langmuir return ReadResult == ASTReader::Success; 12524382fe74SArgyrios Kyrtzidis } 12534382fe74SArgyrios Kyrtzidis } 12544382fe74SArgyrios Kyrtzidis 125535b13eceSDouglas Gregor /// \brief Diagnose differences between the current definition of the given 125635b13eceSDouglas Gregor /// configuration macro and the definition provided on the command line. 125735b13eceSDouglas Gregor static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro, 125835b13eceSDouglas Gregor Module *Mod, SourceLocation ImportLoc) { 125935b13eceSDouglas Gregor IdentifierInfo *Id = PP.getIdentifierInfo(ConfigMacro); 126035b13eceSDouglas Gregor SourceManager &SourceMgr = PP.getSourceManager(); 126135b13eceSDouglas Gregor 126235b13eceSDouglas Gregor // If this identifier has never had a macro definition, then it could 126335b13eceSDouglas Gregor // not have changed. 126435b13eceSDouglas Gregor if (!Id->hadMacroDefinition()) 126535b13eceSDouglas Gregor return; 126620e883e5SRichard Smith auto *LatestLocalMD = PP.getLocalMacroDirectiveHistory(Id); 126735b13eceSDouglas Gregor 126820e883e5SRichard Smith // Find the macro definition from the command line. 126920e883e5SRichard Smith MacroInfo *CmdLineDefinition = nullptr; 127020e883e5SRichard Smith for (auto *MD = LatestLocalMD; MD; MD = MD->getPrevious()) { 127135b13eceSDouglas Gregor // We only care about the predefines buffer. 127220e883e5SRichard Smith FileID FID = SourceMgr.getFileID(MD->getLocation()); 127320e883e5SRichard Smith if (FID.isInvalid() || FID != PP.getPredefinesFileID()) 127435b13eceSDouglas Gregor continue; 127520e883e5SRichard Smith if (auto *DMD = dyn_cast<DefMacroDirective>(MD)) 127620e883e5SRichard Smith CmdLineDefinition = DMD->getMacroInfo(); 127720e883e5SRichard Smith break; 127820e883e5SRichard Smith } 127935b13eceSDouglas Gregor 128020e883e5SRichard Smith auto *CurrentDefinition = PP.getMacroInfo(Id); 128120e883e5SRichard Smith if (CurrentDefinition == CmdLineDefinition) { 128220e883e5SRichard Smith // Macro matches. Nothing to do. 128320e883e5SRichard Smith } else if (!CurrentDefinition) { 128435b13eceSDouglas Gregor // This macro was defined on the command line, then #undef'd later. 128535b13eceSDouglas Gregor // Complain. 128635b13eceSDouglas Gregor PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 128735b13eceSDouglas Gregor << true << ConfigMacro << Mod->getFullModuleName(); 128820e883e5SRichard Smith auto LatestDef = LatestLocalMD->getDefinition(); 128920e883e5SRichard Smith assert(LatestDef.isUndefined() && 129020e883e5SRichard Smith "predefined macro went away with no #undef?"); 1291b6210dffSArgyrios Kyrtzidis PP.Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here) 129235b13eceSDouglas Gregor << true; 129335b13eceSDouglas Gregor return; 129420e883e5SRichard Smith } else if (!CmdLineDefinition) { 129520e883e5SRichard Smith // There was no definition for this macro in the predefines buffer, 129620e883e5SRichard Smith // but there was a local definition. Complain. 129735b13eceSDouglas Gregor PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 129835b13eceSDouglas Gregor << false << ConfigMacro << Mod->getFullModuleName(); 129920e883e5SRichard Smith PP.Diag(CurrentDefinition->getDefinitionLoc(), 130020e883e5SRichard Smith diag::note_module_def_undef_here) 130135b13eceSDouglas Gregor << false; 130220e883e5SRichard Smith } else if (!CurrentDefinition->isIdenticalTo(*CmdLineDefinition, PP, 130320e883e5SRichard Smith /*Syntactically=*/true)) { 130435b13eceSDouglas Gregor // The macro definitions differ. 130535b13eceSDouglas Gregor PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 130635b13eceSDouglas Gregor << false << ConfigMacro << Mod->getFullModuleName(); 130720e883e5SRichard Smith PP.Diag(CurrentDefinition->getDefinitionLoc(), 130820e883e5SRichard Smith diag::note_module_def_undef_here) 130935b13eceSDouglas Gregor << false; 131035b13eceSDouglas Gregor } 131120e883e5SRichard Smith } 131235b13eceSDouglas Gregor 1313527b1c95SDouglas Gregor /// \brief Write a new timestamp file with the given path. 1314527b1c95SDouglas Gregor static void writeTimestampFile(StringRef TimestampFile) { 1315dae941a6SRafael Espindola std::error_code EC; 1316dae941a6SRafael Espindola llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::F_None); 1317527b1c95SDouglas Gregor } 1318527b1c95SDouglas Gregor 1319527b1c95SDouglas Gregor /// \brief Prune the module cache of modules that haven't been accessed in 1320527b1c95SDouglas Gregor /// a long time. 1321527b1c95SDouglas Gregor static void pruneModuleCache(const HeaderSearchOptions &HSOpts) { 1322527b1c95SDouglas Gregor struct stat StatBuf; 1323527b1c95SDouglas Gregor llvm::SmallString<128> TimestampFile; 1324527b1c95SDouglas Gregor TimestampFile = HSOpts.ModuleCachePath; 13253938f0c7SRichard Smith assert(!TimestampFile.empty()); 1326527b1c95SDouglas Gregor llvm::sys::path::append(TimestampFile, "modules.timestamp"); 1327527b1c95SDouglas Gregor 1328527b1c95SDouglas Gregor // Try to stat() the timestamp file. 1329527b1c95SDouglas Gregor if (::stat(TimestampFile.c_str(), &StatBuf)) { 1330527b1c95SDouglas Gregor // If the timestamp file wasn't there, create one now. 1331527b1c95SDouglas Gregor if (errno == ENOENT) { 1332527b1c95SDouglas Gregor writeTimestampFile(TimestampFile); 1333527b1c95SDouglas Gregor } 1334527b1c95SDouglas Gregor return; 1335527b1c95SDouglas Gregor } 1336527b1c95SDouglas Gregor 1337527b1c95SDouglas Gregor // Check whether the time stamp is older than our pruning interval. 1338527b1c95SDouglas Gregor // If not, do nothing. 1339527b1c95SDouglas Gregor time_t TimeStampModTime = StatBuf.st_mtime; 134049a2790fSCraig Topper time_t CurrentTime = time(nullptr); 1341dbcf5037SBenjamin Kramer if (CurrentTime - TimeStampModTime <= time_t(HSOpts.ModuleCachePruneInterval)) 1342527b1c95SDouglas Gregor return; 1343527b1c95SDouglas Gregor 1344527b1c95SDouglas Gregor // Write a new timestamp file so that nobody else attempts to prune. 1345527b1c95SDouglas Gregor // There is a benign race condition here, if two Clang instances happen to 1346527b1c95SDouglas Gregor // notice at the same time that the timestamp is out-of-date. 1347527b1c95SDouglas Gregor writeTimestampFile(TimestampFile); 1348527b1c95SDouglas Gregor 1349527b1c95SDouglas Gregor // Walk the entire module cache, looking for unused module files and module 1350527b1c95SDouglas Gregor // indices. 1351c080917eSRafael Espindola std::error_code EC; 1352527b1c95SDouglas Gregor SmallString<128> ModuleCachePathNative; 1353527b1c95SDouglas Gregor llvm::sys::path::native(HSOpts.ModuleCachePath, ModuleCachePathNative); 135492e1b62dSYaron Keren for (llvm::sys::fs::directory_iterator Dir(ModuleCachePathNative, EC), DirEnd; 1355527b1c95SDouglas Gregor Dir != DirEnd && !EC; Dir.increment(EC)) { 1356527b1c95SDouglas Gregor // If we don't have a directory, there's nothing to look into. 1357a07f720aSRafael Espindola if (!llvm::sys::fs::is_directory(Dir->path())) 1358527b1c95SDouglas Gregor continue; 1359527b1c95SDouglas Gregor 1360527b1c95SDouglas Gregor // Walk all of the files within this directory. 1361527b1c95SDouglas Gregor for (llvm::sys::fs::directory_iterator File(Dir->path(), EC), FileEnd; 1362527b1c95SDouglas Gregor File != FileEnd && !EC; File.increment(EC)) { 1363527b1c95SDouglas Gregor // We only care about module and global module index files. 1364f430da4dSDmitri Gribenko StringRef Extension = llvm::sys::path::extension(File->path()); 1365f430da4dSDmitri Gribenko if (Extension != ".pcm" && Extension != ".timestamp" && 1366f430da4dSDmitri Gribenko llvm::sys::path::filename(File->path()) != "modules.idx") 1367527b1c95SDouglas Gregor continue; 1368527b1c95SDouglas Gregor 1369527b1c95SDouglas Gregor // Look at this file. If we can't stat it, there's nothing interesting 1370527b1c95SDouglas Gregor // there. 1371f430da4dSDmitri Gribenko if (::stat(File->path().c_str(), &StatBuf)) 1372527b1c95SDouglas Gregor continue; 1373527b1c95SDouglas Gregor 1374527b1c95SDouglas Gregor // If the file has been used recently enough, leave it there. 1375527b1c95SDouglas Gregor time_t FileAccessTime = StatBuf.st_atime; 1376dbcf5037SBenjamin Kramer if (CurrentTime - FileAccessTime <= 1377dbcf5037SBenjamin Kramer time_t(HSOpts.ModuleCachePruneAfter)) { 1378527b1c95SDouglas Gregor continue; 1379527b1c95SDouglas Gregor } 1380527b1c95SDouglas Gregor 1381527b1c95SDouglas Gregor // Remove the file. 1382f430da4dSDmitri Gribenko llvm::sys::fs::remove(File->path()); 1383f430da4dSDmitri Gribenko 1384f430da4dSDmitri Gribenko // Remove the timestamp file. 1385f430da4dSDmitri Gribenko std::string TimpestampFilename = File->path() + ".timestamp"; 1386f430da4dSDmitri Gribenko llvm::sys::fs::remove(TimpestampFilename); 1387527b1c95SDouglas Gregor } 1388527b1c95SDouglas Gregor 1389527b1c95SDouglas Gregor // If we removed all of the files in the directory, remove the directory 1390527b1c95SDouglas Gregor // itself. 1391f430da4dSDmitri Gribenko if (llvm::sys::fs::directory_iterator(Dir->path(), EC) == 1392f430da4dSDmitri Gribenko llvm::sys::fs::directory_iterator() && !EC) 13932a008784SRafael Espindola llvm::sys::fs::remove(Dir->path()); 1394527b1c95SDouglas Gregor } 1395527b1c95SDouglas Gregor } 1396527b1c95SDouglas Gregor 13972255f2ceSJohn Thompson void CompilerInstance::createModuleManager() { 13982255f2ceSJohn Thompson if (!ModuleManager) { 13992255f2ceSJohn Thompson if (!hasASTContext()) 14002255f2ceSJohn Thompson createASTContext(); 14012255f2ceSJohn Thompson 1402580dd296SChandler Carruth // If we're implicitly building modules but not currently recursively 1403580dd296SChandler Carruth // building a module, check whether we need to prune the module cache. 14043938f0c7SRichard Smith if (getSourceManager().getModuleBuildStack().empty() && 14053938f0c7SRichard Smith !getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty() && 14062255f2ceSJohn Thompson getHeaderSearchOpts().ModuleCachePruneInterval > 0 && 14072255f2ceSJohn Thompson getHeaderSearchOpts().ModuleCachePruneAfter > 0) { 14082255f2ceSJohn Thompson pruneModuleCache(getHeaderSearchOpts()); 14092255f2ceSJohn Thompson } 14102255f2ceSJohn Thompson 14112255f2ceSJohn Thompson HeaderSearchOptions &HSOpts = getHeaderSearchOpts(); 14122255f2ceSJohn Thompson std::string Sysroot = HSOpts.Sysroot; 14132255f2ceSJohn Thompson const PreprocessorOptions &PPOpts = getPreprocessorOpts(); 1414ce18a187SRichard Smith std::unique_ptr<llvm::Timer> ReadTimer; 1415ce18a187SRichard Smith if (FrontendTimerGroup) 1416ae032b6cSMatthias Braun ReadTimer = llvm::make_unique<llvm::Timer>("reading_modules", 1417ae032b6cSMatthias Braun "Reading modules", 1418ce18a187SRichard Smith *FrontendTimerGroup); 1419bb165fb0SAdrian Prantl ModuleManager = new ASTReader( 1420293534b1SRichard Smith getPreprocessor(), getASTContext(), getPCHContainerReader(), 14216623e1f1SDouglas Gregor getFrontendOpts().ModuleFileExtensions, 1422bb165fb0SAdrian Prantl Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation, 14232255f2ceSJohn Thompson /*AllowASTWithCompilerErrors=*/false, 14242255f2ceSJohn Thompson /*AllowConfigurationMismatch=*/false, 14252255f2ceSJohn Thompson HSOpts.ModulesValidateSystemHeaders, 1426ce18a187SRichard Smith getFrontendOpts().UseGlobalModuleIndex, 1427ce18a187SRichard Smith std::move(ReadTimer)); 14282255f2ceSJohn Thompson if (hasASTConsumer()) { 14292255f2ceSJohn Thompson ModuleManager->setDeserializationListener( 14302255f2ceSJohn Thompson getASTConsumer().GetASTDeserializationListener()); 14312255f2ceSJohn Thompson getASTContext().setASTMutationListener( 14322255f2ceSJohn Thompson getASTConsumer().GetASTMutationListener()); 14332255f2ceSJohn Thompson } 14342255f2ceSJohn Thompson getASTContext().setExternalSource(ModuleManager); 14352255f2ceSJohn Thompson if (hasSema()) 14362255f2ceSJohn Thompson ModuleManager->InitializeSema(getSema()); 1437293534b1SRichard Smith if (hasASTConsumer()) 14382255f2ceSJohn Thompson ModuleManager->StartTranslationUnit(&getASTConsumer()); 143903f7e611SRichard Smith 144003f7e611SRichard Smith if (TheDependencyFileGenerator) 144103f7e611SRichard Smith TheDependencyFileGenerator->AttachToASTReader(*ModuleManager); 144203f7e611SRichard Smith for (auto &Listener : DependencyCollectors) 144303f7e611SRichard Smith Listener->attachToASTReader(*ModuleManager); 14442255f2ceSJohn Thompson } 14452255f2ceSJohn Thompson } 14462255f2ceSJohn Thompson 1447d4b230b3SRichard Smith bool CompilerInstance::loadModuleFile(StringRef FileName) { 1448ce18a187SRichard Smith llvm::Timer Timer; 1449ce18a187SRichard Smith if (FrontendTimerGroup) 1450ae032b6cSMatthias Braun Timer.init("preloading." + FileName.str(), "Preloading " + FileName.str(), 1451ae032b6cSMatthias Braun *FrontendTimerGroup); 1452ce18a187SRichard Smith llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr); 1453ce18a187SRichard Smith 1454d4b230b3SRichard Smith // Helper to recursively read the module names for all modules we're adding. 1455d4b230b3SRichard Smith // We mark these as known and redirect any attempt to load that module to 1456d4b230b3SRichard Smith // the files we were handed. 1457d4b230b3SRichard Smith struct ReadModuleNames : ASTReaderListener { 1458d4b230b3SRichard Smith CompilerInstance &CI; 14590f99d6a4SRichard Smith llvm::SmallVector<IdentifierInfo*, 8> LoadedModules; 1460e842a474SRichard Smith 14610f99d6a4SRichard Smith ReadModuleNames(CompilerInstance &CI) : CI(CI) {} 1462d4b230b3SRichard Smith 1463d4b230b3SRichard Smith void ReadModuleName(StringRef ModuleName) override { 14640f99d6a4SRichard Smith LoadedModules.push_back( 14650f99d6a4SRichard Smith CI.getPreprocessor().getIdentifierInfo(ModuleName)); 1466d4b230b3SRichard Smith } 14670f99d6a4SRichard Smith 14680f99d6a4SRichard Smith void registerAll() { 14690f99d6a4SRichard Smith for (auto *II : LoadedModules) { 14700f99d6a4SRichard Smith CI.KnownModules[II] = CI.getPreprocessor() 14710f99d6a4SRichard Smith .getHeaderSearchInfo() 14720f99d6a4SRichard Smith .getModuleMap() 14730f99d6a4SRichard Smith .findModule(II->getName()); 14740f99d6a4SRichard Smith } 14750f99d6a4SRichard Smith LoadedModules.clear(); 14760f99d6a4SRichard Smith } 14778a308ec2SRichard Smith 14788a308ec2SRichard Smith void markAllUnavailable() { 14798a308ec2SRichard Smith for (auto *II : LoadedModules) { 14808a308ec2SRichard Smith if (Module *M = CI.getPreprocessor() 14818a308ec2SRichard Smith .getHeaderSearchInfo() 14828a308ec2SRichard Smith .getModuleMap() 1483a114c46eSRichard Smith .findModule(II->getName())) { 14848a308ec2SRichard Smith M->HasIncompatibleModuleFile = true; 1485a114c46eSRichard Smith 1486a114c46eSRichard Smith // Mark module as available if the only reason it was unavailable 1487a114c46eSRichard Smith // was missing headers. 1488a114c46eSRichard Smith SmallVector<Module *, 2> Stack; 1489a114c46eSRichard Smith Stack.push_back(M); 1490a114c46eSRichard Smith while (!Stack.empty()) { 1491a114c46eSRichard Smith Module *Current = Stack.pop_back_val(); 1492a114c46eSRichard Smith if (Current->IsMissingRequirement) continue; 1493a114c46eSRichard Smith Current->IsAvailable = true; 1494a114c46eSRichard Smith Stack.insert(Stack.end(), 1495a114c46eSRichard Smith Current->submodule_begin(), Current->submodule_end()); 1496a114c46eSRichard Smith } 1497a114c46eSRichard Smith } 14988a308ec2SRichard Smith } 14998a308ec2SRichard Smith LoadedModules.clear(); 15008a308ec2SRichard Smith } 15010f99d6a4SRichard Smith }; 1502d4b230b3SRichard Smith 15037f330cdbSRichard Smith // If we don't already have an ASTReader, create one now. 15047f330cdbSRichard Smith if (!ModuleManager) 15057f330cdbSRichard Smith createModuleManager(); 15067f330cdbSRichard Smith 15070f99d6a4SRichard Smith auto Listener = llvm::make_unique<ReadModuleNames>(*this); 15080f99d6a4SRichard Smith auto &ListenerRef = *Listener; 15090f99d6a4SRichard Smith ASTReader::ListenerScope ReadModuleNamesListener(*ModuleManager, 15100f99d6a4SRichard Smith std::move(Listener)); 15117f330cdbSRichard Smith 15120f99d6a4SRichard Smith // Try to load the module file. 151395dc57a6SRichard Smith switch (ModuleManager->ReadAST(FileName, serialization::MK_ExplicitModule, 151495dc57a6SRichard Smith SourceLocation(), 151595dc57a6SRichard Smith ASTReader::ARR_ConfigurationMismatch)) { 151695dc57a6SRichard Smith case ASTReader::Success: 15170f99d6a4SRichard Smith // We successfully loaded the module file; remember the set of provided 15180f99d6a4SRichard Smith // modules so that we don't try to load implicit modules for them. 15190f99d6a4SRichard Smith ListenerRef.registerAll(); 1520d4b230b3SRichard Smith return true; 152195dc57a6SRichard Smith 152295dc57a6SRichard Smith case ASTReader::ConfigurationMismatch: 152395dc57a6SRichard Smith // Ignore unusable module files. 152495dc57a6SRichard Smith getDiagnostics().Report(SourceLocation(), diag::warn_module_config_mismatch) 152595dc57a6SRichard Smith << FileName; 15268a308ec2SRichard Smith // All modules provided by any files we tried and failed to load are now 15278a308ec2SRichard Smith // unavailable; includes of those modules should now be handled textually. 15288a308ec2SRichard Smith ListenerRef.markAllUnavailable(); 152995dc57a6SRichard Smith return true; 153095dc57a6SRichard Smith 153195dc57a6SRichard Smith default: 153295dc57a6SRichard Smith return false; 153395dc57a6SRichard Smith } 1534e842a474SRichard Smith } 1535e842a474SRichard Smith 1536e842a474SRichard Smith ModuleLoadResult 15377a626570SDouglas Gregor CompilerInstance::loadModule(SourceLocation ImportLoc, 1538ff2be53fSDouglas Gregor ModuleIdPath Path, 1539bcfc7d02SDouglas Gregor Module::NameVisibilityKind Visibility, 1540bcfc7d02SDouglas Gregor bool IsInclusionDirective) { 154192304e00SRichard Smith // Determine what file we're searching from. 154292304e00SRichard Smith StringRef ModuleName = Path[0].first->getName(); 154392304e00SRichard Smith SourceLocation ModuleNameLoc = Path[0].second; 154492304e00SRichard Smith 15451805b8a4SDouglas Gregor // If we've already handled this import, just return the cached result. 15461805b8a4SDouglas Gregor // This one-element cache is important to eliminate redundant diagnostics 15471805b8a4SDouglas Gregor // when both the preprocessor and parser see the same import declaration. 15488b563665SYaron Keren if (ImportLoc.isValid() && LastModuleImportLoc == ImportLoc) { 1549ff2be53fSDouglas Gregor // Make the named module visible. 15507e82e019SRichard Smith if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule) 1551125df058SArgyrios Kyrtzidis ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility, 1552a7e2cc68SRichard Smith ImportLoc); 155369021974SDouglas Gregor return LastModuleImportResult; 1554ff2be53fSDouglas Gregor } 15551805b8a4SDouglas Gregor 155649a2790fSCraig Topper clang::Module *Module = nullptr; 15575196bc6bSDouglas Gregor 15585196bc6bSDouglas Gregor // If we don't already have information on this module, load the module now. 1559de3ef502SDouglas Gregor llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known 156069021974SDouglas Gregor = KnownModules.find(Path[0].first); 15612537a364SDouglas Gregor if (Known != KnownModules.end()) { 15622537a364SDouglas Gregor // Retrieve the cached top-level module. 15632537a364SDouglas Gregor Module = Known->second; 15647e82e019SRichard Smith } else if (ModuleName == getLangOpts().CurrentModule) { 15652537a364SDouglas Gregor // This is the module we're building. 1566527040e0SBen Langmuir Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); 15672537a364SDouglas Gregor Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; 15682537a364SDouglas Gregor } else { 15695196bc6bSDouglas Gregor // Search for a module with the given name. 1570279a6c37SDouglas Gregor Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); 157111f2a477SManman Ren HeaderSearchOptions &HSOpts = 157211f2a477SManman Ren PP->getHeaderSearchInfo().getHeaderSearchOpts(); 157311f2a477SManman Ren 157411f2a477SManman Ren std::string ModuleFileName; 157511f2a477SManman Ren bool LoadFromPrebuiltModulePath = false; 157611f2a477SManman Ren // We try to load the module from the prebuilt module paths. If not 157711f2a477SManman Ren // successful, we then try to find it in the module cache. 157811f2a477SManman Ren if (!HSOpts.PrebuiltModulePaths.empty()) { 157911f2a477SManman Ren // Load the module from the prebuilt module path. 158011f2a477SManman Ren ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName( 158111f2a477SManman Ren ModuleName, "", /*UsePrebuiltPath*/ true); 158211f2a477SManman Ren if (!ModuleFileName.empty()) 158311f2a477SManman Ren LoadFromPrebuiltModulePath = true; 158411f2a477SManman Ren } 158511f2a477SManman Ren if (!LoadFromPrebuiltModulePath && Module) { 158611f2a477SManman Ren // Load the module from the module cache. 158711f2a477SManman Ren ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module); 158811f2a477SManman Ren } else if (!LoadFromPrebuiltModulePath) { 158911f2a477SManman Ren // We can't find a module, error out here. 15909eb229bfSBen Langmuir getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found) 15919eb229bfSBen Langmuir << ModuleName 15929eb229bfSBen Langmuir << SourceRange(ImportLoc, ModuleNameLoc); 15939eb229bfSBen Langmuir ModuleBuildFailed = true; 15949eb229bfSBen Langmuir return ModuleLoadResult(); 15959eb229bfSBen Langmuir } 15969eb229bfSBen Langmuir 1597d520a250SRichard Smith if (ModuleFileName.empty()) { 159811f2a477SManman Ren if (Module && Module->HasIncompatibleModuleFile) { 15998a308ec2SRichard Smith // We tried and failed to load a module file for this module. Fall 16008a308ec2SRichard Smith // back to textual inclusion for its headers. 1601a114c46eSRichard Smith return ModuleLoadResult::ConfigMismatch; 16028a308ec2SRichard Smith } 16038a308ec2SRichard Smith 1604d2e8b04dSManuel Klimek getDiagnostics().Report(ModuleNameLoc, diag::err_module_build_disabled) 1605d2e8b04dSManuel Klimek << ModuleName; 1606d2e8b04dSManuel Klimek ModuleBuildFailed = true; 1607d2e8b04dSManuel Klimek return ModuleLoadResult(); 1608d2e8b04dSManuel Klimek } 1609d4b230b3SRichard Smith 161008142534SDouglas Gregor // If we don't already have an ASTReader, create one now. 16112255f2ceSJohn Thompson if (!ModuleManager) 16122255f2ceSJohn Thompson createModuleManager(); 161308142534SDouglas Gregor 1614ce18a187SRichard Smith llvm::Timer Timer; 1615ce18a187SRichard Smith if (FrontendTimerGroup) 1616ae032b6cSMatthias Braun Timer.init("loading." + ModuleFileName, "Loading " + ModuleFileName, 1617ae032b6cSMatthias Braun *FrontendTimerGroup); 1618ce18a187SRichard Smith llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr); 1619ce18a187SRichard Smith 162011f2a477SManman Ren // Try to load the module file. If we are trying to load from the prebuilt 162111f2a477SManman Ren // module path, we don't have the module map files and don't know how to 162211f2a477SManman Ren // rebuild modules. 162311f2a477SManman Ren unsigned ARRFlags = LoadFromPrebuiltModulePath ? 162411f2a477SManman Ren ASTReader::ARR_ConfigurationMismatch : 162511f2a477SManman Ren ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing; 1626e842a474SRichard Smith switch (ModuleManager->ReadAST(ModuleFileName, 162711f2a477SManman Ren LoadFromPrebuiltModulePath ? 162811f2a477SManman Ren serialization::MK_PrebuiltModule : 162986cc8290SRichard Smith serialization::MK_ImplicitModule, 163011f2a477SManman Ren ImportLoc, 163111f2a477SManman Ren ARRFlags)) { 163211f2a477SManman Ren case ASTReader::Success: { 163311f2a477SManman Ren if (LoadFromPrebuiltModulePath && !Module) { 163411f2a477SManman Ren Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); 163511f2a477SManman Ren if (!Module || !Module->getASTFile() || 163611f2a477SManman Ren FileMgr->getFile(ModuleFileName) != Module->getASTFile()) { 163711f2a477SManman Ren // Error out if Module does not refer to the file in the prebuilt 163811f2a477SManman Ren // module path. 163911f2a477SManman Ren getDiagnostics().Report(ModuleNameLoc, diag::err_module_prebuilt) 164011f2a477SManman Ren << ModuleName; 164111f2a477SManman Ren ModuleBuildFailed = true; 164211f2a477SManman Ren KnownModules[Path[0].first] = nullptr; 164311f2a477SManman Ren return ModuleLoadResult(); 164411f2a477SManman Ren } 164511f2a477SManman Ren } 164608142534SDouglas Gregor break; 164711f2a477SManman Ren } 164808142534SDouglas Gregor 1649963ff2c3SEli Friedman case ASTReader::OutOfDate: 16507029ce1aSDouglas Gregor case ASTReader::Missing: { 165111f2a477SManman Ren if (LoadFromPrebuiltModulePath) { 165211f2a477SManman Ren // We can't rebuild the module without a module map. Since ReadAST 165311f2a477SManman Ren // already produces diagnostics for these two cases, we simply 165411f2a477SManman Ren // error out here. 165511f2a477SManman Ren ModuleBuildFailed = true; 165611f2a477SManman Ren KnownModules[Path[0].first] = nullptr; 165711f2a477SManman Ren return ModuleLoadResult(); 165811f2a477SManman Ren } 165911f2a477SManman Ren 1660963ff2c3SEli Friedman // The module file is missing or out-of-date. Build it. 16619eb229bfSBen Langmuir assert(Module && "missing module file"); 16627029ce1aSDouglas Gregor // Check whether there is a cycle in the module graph. 16637029ce1aSDouglas Gregor ModuleBuildStack ModPath = getSourceManager().getModuleBuildStack(); 16647029ce1aSDouglas Gregor ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end(); 16657029ce1aSDouglas Gregor for (; Pos != PosEnd; ++Pos) { 16667029ce1aSDouglas Gregor if (Pos->first == ModuleName) 16677029ce1aSDouglas Gregor break; 16687029ce1aSDouglas Gregor } 16697029ce1aSDouglas Gregor 16707029ce1aSDouglas Gregor if (Pos != PosEnd) { 16717029ce1aSDouglas Gregor SmallString<256> CyclePath; 16727029ce1aSDouglas Gregor for (; Pos != PosEnd; ++Pos) { 16737029ce1aSDouglas Gregor CyclePath += Pos->first; 16747029ce1aSDouglas Gregor CyclePath += " -> "; 16757029ce1aSDouglas Gregor } 16767029ce1aSDouglas Gregor CyclePath += ModuleName; 16777029ce1aSDouglas Gregor 16787029ce1aSDouglas Gregor getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle) 16797029ce1aSDouglas Gregor << ModuleName << CyclePath; 16807029ce1aSDouglas Gregor return ModuleLoadResult(); 16817029ce1aSDouglas Gregor } 16827a626570SDouglas Gregor 16837a626570SDouglas Gregor // Check whether we have already attempted to build this module (but 16847a626570SDouglas Gregor // failed). 16857a626570SDouglas Gregor if (getPreprocessorOpts().FailedModules && 16867a626570SDouglas Gregor getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) { 16877a626570SDouglas Gregor getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built) 16887a626570SDouglas Gregor << ModuleName 16897a626570SDouglas Gregor << SourceRange(ImportLoc, ModuleNameLoc); 1690c1bbec85SDouglas Gregor ModuleBuildFailed = true; 16917a626570SDouglas Gregor return ModuleLoadResult(); 16927a626570SDouglas Gregor } 16937a626570SDouglas Gregor 1694dbdc0368SBen Langmuir // Try to compile and then load the module. 1695dbdc0368SBen Langmuir if (!compileAndLoadModule(*this, ImportLoc, ModuleNameLoc, Module, 1696dbdc0368SBen Langmuir ModuleFileName)) { 1697d213aab7SBen Langmuir assert(getDiagnostics().hasErrorOccurred() && 1698d213aab7SBen Langmuir "undiagnosed error in compileAndLoadModule"); 16990f2b4635SDouglas Gregor if (getPreprocessorOpts().FailedModules) 17007a626570SDouglas Gregor getPreprocessorOpts().FailedModules->addFailed(ModuleName); 170149a2790fSCraig Topper KnownModules[Path[0].first] = nullptr; 1702c1bbec85SDouglas Gregor ModuleBuildFailed = true; 17037a626570SDouglas Gregor return ModuleLoadResult(); 1704188dbef2SDouglas Gregor } 1705188dbef2SDouglas Gregor 1706188dbef2SDouglas Gregor // Okay, we've rebuilt and now loaded the module. 1707188dbef2SDouglas Gregor break; 1708188dbef2SDouglas Gregor } 1709188dbef2SDouglas Gregor 1710c9ad5fb6SDouglas Gregor case ASTReader::ConfigurationMismatch: 171111f2a477SManman Ren if (LoadFromPrebuiltModulePath) 171211f2a477SManman Ren getDiagnostics().Report(SourceLocation(), 171311f2a477SManman Ren diag::warn_module_config_mismatch) 171411f2a477SManman Ren << ModuleFileName; 171511f2a477SManman Ren // Fall through to error out. 171611f2a477SManman Ren case ASTReader::VersionMismatch: 1717c9ad5fb6SDouglas Gregor case ASTReader::HadErrors: 1718dc9fdaf2SArgyrios Kyrtzidis ModuleLoader::HadFatalFailure = true; 17190f99d6a4SRichard Smith // FIXME: The ASTReader will already have complained, but can we shoehorn 172008142534SDouglas Gregor // that diagnostic information into a more useful form? 172149a2790fSCraig Topper KnownModules[Path[0].first] = nullptr; 17227a626570SDouglas Gregor return ModuleLoadResult(); 172308142534SDouglas Gregor 172408142534SDouglas Gregor case ASTReader::Failure: 1725dc9fdaf2SArgyrios Kyrtzidis ModuleLoader::HadFatalFailure = true; 172669021974SDouglas Gregor // Already complained, but note now that we failed. 172749a2790fSCraig Topper KnownModules[Path[0].first] = nullptr; 1728c1bbec85SDouglas Gregor ModuleBuildFailed = true; 17297a626570SDouglas Gregor return ModuleLoadResult(); 173008142534SDouglas Gregor } 173108142534SDouglas Gregor 173269021974SDouglas Gregor // Cache the result of this top-level module lookup for later. 173369021974SDouglas Gregor Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; 173469021974SDouglas Gregor } 173569021974SDouglas Gregor 173669021974SDouglas Gregor // If we never found the module, fail. 173769021974SDouglas Gregor if (!Module) 17387a626570SDouglas Gregor return ModuleLoadResult(); 173969021974SDouglas Gregor 17405196bc6bSDouglas Gregor // Verify that the rest of the module path actually corresponds to 17415196bc6bSDouglas Gregor // a submodule. 174269021974SDouglas Gregor if (Path.size() > 1) { 17435196bc6bSDouglas Gregor for (unsigned I = 1, N = Path.size(); I != N; ++I) { 17445196bc6bSDouglas Gregor StringRef Name = Path[I].first->getName(); 1745eb90e830SDouglas Gregor clang::Module *Sub = Module->findSubmodule(Name); 17465196bc6bSDouglas Gregor 1747eb90e830SDouglas Gregor if (!Sub) { 17485196bc6bSDouglas Gregor // Attempt to perform typo correction to find a module name that works. 1749f857950dSDmitri Gribenko SmallVector<StringRef, 2> Best; 17505196bc6bSDouglas Gregor unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)(); 17515196bc6bSDouglas Gregor 1752eb90e830SDouglas Gregor for (clang::Module::submodule_iterator J = Module->submodule_begin(), 1753eb90e830SDouglas Gregor JEnd = Module->submodule_end(); 1754eb44edadSMatt Beaumont-Gay J != JEnd; ++J) { 1755eb90e830SDouglas Gregor unsigned ED = Name.edit_distance((*J)->Name, 17565196bc6bSDouglas Gregor /*AllowReplacements=*/true, 17575196bc6bSDouglas Gregor BestEditDistance); 17585196bc6bSDouglas Gregor if (ED <= BestEditDistance) { 1759eb90e830SDouglas Gregor if (ED < BestEditDistance) { 17605196bc6bSDouglas Gregor Best.clear(); 1761eb90e830SDouglas Gregor BestEditDistance = ED; 1762eb90e830SDouglas Gregor } 1763eb90e830SDouglas Gregor 1764eb90e830SDouglas Gregor Best.push_back((*J)->Name); 17655196bc6bSDouglas Gregor } 17665196bc6bSDouglas Gregor } 17675196bc6bSDouglas Gregor 17685196bc6bSDouglas Gregor // If there was a clear winner, user it. 17695196bc6bSDouglas Gregor if (Best.size() == 1) { 17705196bc6bSDouglas Gregor getDiagnostics().Report(Path[I].second, 17715196bc6bSDouglas Gregor diag::err_no_submodule_suggest) 177269021974SDouglas Gregor << Path[I].first << Module->getFullModuleName() << Best[0] 17735196bc6bSDouglas Gregor << SourceRange(Path[0].second, Path[I-1].second) 17745196bc6bSDouglas Gregor << FixItHint::CreateReplacement(SourceRange(Path[I].second), 17755196bc6bSDouglas Gregor Best[0]); 1776eb90e830SDouglas Gregor 1777eb90e830SDouglas Gregor Sub = Module->findSubmodule(Best[0]); 17785196bc6bSDouglas Gregor } 17795196bc6bSDouglas Gregor } 17805196bc6bSDouglas Gregor 1781eb90e830SDouglas Gregor if (!Sub) { 17825196bc6bSDouglas Gregor // No submodule by this name. Complain, and don't look for further 17835196bc6bSDouglas Gregor // submodules. 17845196bc6bSDouglas Gregor getDiagnostics().Report(Path[I].second, diag::err_no_submodule) 178569021974SDouglas Gregor << Path[I].first << Module->getFullModuleName() 17865196bc6bSDouglas Gregor << SourceRange(Path[0].second, Path[I-1].second); 17875196bc6bSDouglas Gregor break; 17885196bc6bSDouglas Gregor } 17895196bc6bSDouglas Gregor 1790eb90e830SDouglas Gregor Module = Sub; 17915196bc6bSDouglas Gregor } 17925196bc6bSDouglas Gregor } 17935196bc6bSDouglas Gregor 17942537a364SDouglas Gregor // Make the named module visible, if it's not already part of the module 17952537a364SDouglas Gregor // we are parsing. 179698a52db8SDouglas Gregor if (ModuleName != getLangOpts().CurrentModule) { 179798a52db8SDouglas Gregor if (!Module->IsFromModuleFile) { 179898a52db8SDouglas Gregor // We have an umbrella header or directory that doesn't actually include 179998a52db8SDouglas Gregor // all of the headers within the directory it covers. Complain about 180098a52db8SDouglas Gregor // this missing submodule and recover by forgetting that we ever saw 180198a52db8SDouglas Gregor // this submodule. 180298a52db8SDouglas Gregor // FIXME: Should we detect this at module load time? It seems fairly 180398a52db8SDouglas Gregor // expensive (and rare). 180498a52db8SDouglas Gregor getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule) 180598a52db8SDouglas Gregor << Module->getFullModuleName() 180698a52db8SDouglas Gregor << SourceRange(Path.front().second, Path.back().second); 180798a52db8SDouglas Gregor 1808a114c46eSRichard Smith return ModuleLoadResult::MissingExpected; 180998a52db8SDouglas Gregor } 18101fb5c3a6SDouglas Gregor 18111fb5c3a6SDouglas Gregor // Check whether this module is available. 1812a3feee2aSRichard Smith clang::Module::Requirement Requirement; 18133c1a41adSRichard Smith clang::Module::UnresolvedHeaderDirective MissingHeader; 18140761a8a0SDaniel Jasper if (!Module->isAvailable(getLangOpts(), getTarget(), Requirement, 18150761a8a0SDaniel Jasper MissingHeader)) { 18160761a8a0SDaniel Jasper if (MissingHeader.FileNameLoc.isValid()) { 18170761a8a0SDaniel Jasper getDiagnostics().Report(MissingHeader.FileNameLoc, 18180761a8a0SDaniel Jasper diag::err_module_header_missing) 18190761a8a0SDaniel Jasper << MissingHeader.IsUmbrella << MissingHeader.FileName; 18200761a8a0SDaniel Jasper } else { 18211fb5c3a6SDouglas Gregor getDiagnostics().Report(ImportLoc, diag::err_module_unavailable) 18221fb5c3a6SDouglas Gregor << Module->getFullModuleName() 1823a3feee2aSRichard Smith << Requirement.second << Requirement.first 18241fb5c3a6SDouglas Gregor << SourceRange(Path.front().second, Path.back().second); 18250761a8a0SDaniel Jasper } 18261fb5c3a6SDouglas Gregor LastModuleImportLoc = ImportLoc; 18277a626570SDouglas Gregor LastModuleImportResult = ModuleLoadResult(); 18287a626570SDouglas Gregor return ModuleLoadResult(); 18291fb5c3a6SDouglas Gregor } 18301fb5c3a6SDouglas Gregor 1831a7e2cc68SRichard Smith ModuleManager->makeModuleVisible(Module, Visibility, ImportLoc); 183298a52db8SDouglas Gregor } 18335196bc6bSDouglas Gregor 183435b13eceSDouglas Gregor // Check for any configuration macros that have changed. 183535b13eceSDouglas Gregor clang::Module *TopModule = Module->getTopLevelModule(); 183635b13eceSDouglas Gregor for (unsigned I = 0, N = TopModule->ConfigMacros.size(); I != N; ++I) { 183735b13eceSDouglas Gregor checkConfigMacro(getPreprocessor(), TopModule->ConfigMacros[I], 183835b13eceSDouglas Gregor Module, ImportLoc); 183935b13eceSDouglas Gregor } 184035b13eceSDouglas Gregor 18411805b8a4SDouglas Gregor LastModuleImportLoc = ImportLoc; 1842a114c46eSRichard Smith LastModuleImportResult = ModuleLoadResult(Module); 18437a626570SDouglas Gregor return LastModuleImportResult; 184408142534SDouglas Gregor } 1845c147b0bcSDouglas Gregor 1846c147b0bcSDouglas Gregor void CompilerInstance::makeModuleVisible(Module *Mod, 1847125df058SArgyrios Kyrtzidis Module::NameVisibilityKind Visibility, 1848a7e2cc68SRichard Smith SourceLocation ImportLoc) { 184942413141SRichard Smith if (!ModuleManager) 185042413141SRichard Smith createModuleManager(); 185142413141SRichard Smith if (!ModuleManager) 185242413141SRichard Smith return; 185342413141SRichard Smith 1854a7e2cc68SRichard Smith ModuleManager->makeModuleVisible(Mod, Visibility, ImportLoc); 1855c147b0bcSDouglas Gregor } 1856c147b0bcSDouglas Gregor 18572255f2ceSJohn Thompson GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex( 18582255f2ceSJohn Thompson SourceLocation TriggerLoc) { 18593938f0c7SRichard Smith if (getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty()) 18603938f0c7SRichard Smith return nullptr; 18612255f2ceSJohn Thompson if (!ModuleManager) 18622255f2ceSJohn Thompson createModuleManager(); 18632255f2ceSJohn Thompson // Can't do anything if we don't have the module manager. 18642255f2ceSJohn Thompson if (!ModuleManager) 186549a2790fSCraig Topper return nullptr; 18662255f2ceSJohn Thompson // Get an existing global index. This loads it if not already 18672255f2ceSJohn Thompson // loaded. 18682255f2ceSJohn Thompson ModuleManager->loadGlobalIndex(); 18692255f2ceSJohn Thompson GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex(); 18702255f2ceSJohn Thompson // If the global index doesn't exist, create it. 18712255f2ceSJohn Thompson if (!GlobalIndex && shouldBuildGlobalModuleIndex() && hasFileManager() && 18722255f2ceSJohn Thompson hasPreprocessor()) { 18732255f2ceSJohn Thompson llvm::sys::fs::create_directories( 18742255f2ceSJohn Thompson getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); 18752255f2ceSJohn Thompson GlobalModuleIndex::writeIndex( 1876fb2398d0SAdrian Prantl getFileManager(), getPCHContainerReader(), 18772255f2ceSJohn Thompson getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); 18782255f2ceSJohn Thompson ModuleManager->resetForReload(); 18792255f2ceSJohn Thompson ModuleManager->loadGlobalIndex(); 18802255f2ceSJohn Thompson GlobalIndex = ModuleManager->getGlobalIndex(); 18812255f2ceSJohn Thompson } 18822255f2ceSJohn Thompson // For finding modules needing to be imported for fixit messages, 18832255f2ceSJohn Thompson // we need to make the global index cover all modules, so we do that here. 18842255f2ceSJohn Thompson if (!HaveFullGlobalModuleIndex && GlobalIndex && !buildingModule()) { 18852255f2ceSJohn Thompson ModuleMap &MMap = getPreprocessor().getHeaderSearchInfo().getModuleMap(); 18862255f2ceSJohn Thompson bool RecreateIndex = false; 18872255f2ceSJohn Thompson for (ModuleMap::module_iterator I = MMap.module_begin(), 18882255f2ceSJohn Thompson E = MMap.module_end(); I != E; ++I) { 18892255f2ceSJohn Thompson Module *TheModule = I->second; 18902255f2ceSJohn Thompson const FileEntry *Entry = TheModule->getASTFile(); 18912255f2ceSJohn Thompson if (!Entry) { 18922255f2ceSJohn Thompson SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path; 18932255f2ceSJohn Thompson Path.push_back(std::make_pair( 18942255f2ceSJohn Thompson getPreprocessor().getIdentifierInfo(TheModule->Name), TriggerLoc)); 18952255f2ceSJohn Thompson std::reverse(Path.begin(), Path.end()); 18962255f2ceSJohn Thompson // Load a module as hidden. This also adds it to the global index. 1897629d8e6fSRichard Smith loadModule(TheModule->DefinitionLoc, Path, Module::Hidden, false); 18982255f2ceSJohn Thompson RecreateIndex = true; 18992255f2ceSJohn Thompson } 19002255f2ceSJohn Thompson } 19012255f2ceSJohn Thompson if (RecreateIndex) { 19022255f2ceSJohn Thompson GlobalModuleIndex::writeIndex( 1903fb2398d0SAdrian Prantl getFileManager(), getPCHContainerReader(), 19042255f2ceSJohn Thompson getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); 19052255f2ceSJohn Thompson ModuleManager->resetForReload(); 19062255f2ceSJohn Thompson ModuleManager->loadGlobalIndex(); 19072255f2ceSJohn Thompson GlobalIndex = ModuleManager->getGlobalIndex(); 19082255f2ceSJohn Thompson } 19092255f2ceSJohn Thompson HaveFullGlobalModuleIndex = true; 19102255f2ceSJohn Thompson } 19112255f2ceSJohn Thompson return GlobalIndex; 19122255f2ceSJohn Thompson } 19132d94bbb0SJohn Thompson 19142d94bbb0SJohn Thompson // Check global module index for missing imports. 19152d94bbb0SJohn Thompson bool 19162d94bbb0SJohn Thompson CompilerInstance::lookupMissingImports(StringRef Name, 19172d94bbb0SJohn Thompson SourceLocation TriggerLoc) { 19182d94bbb0SJohn Thompson // Look for the symbol in non-imported modules, but only if an error 19192d94bbb0SJohn Thompson // actually occurred. 19202d94bbb0SJohn Thompson if (!buildingModule()) { 19212d94bbb0SJohn Thompson // Load global module index, or retrieve a previously loaded one. 19222d94bbb0SJohn Thompson GlobalModuleIndex *GlobalIndex = loadGlobalModuleIndex( 19232d94bbb0SJohn Thompson TriggerLoc); 19242d94bbb0SJohn Thompson 19252d94bbb0SJohn Thompson // Only if we have a global index. 19262d94bbb0SJohn Thompson if (GlobalIndex) { 19272d94bbb0SJohn Thompson GlobalModuleIndex::HitSet FoundModules; 19282d94bbb0SJohn Thompson 19292d94bbb0SJohn Thompson // Find the modules that reference the identifier. 19302d94bbb0SJohn Thompson // Note that this only finds top-level modules. 19312d94bbb0SJohn Thompson // We'll let diagnoseTypo find the actual declaration module. 19322d94bbb0SJohn Thompson if (GlobalIndex->lookupIdentifier(Name, FoundModules)) 19332d94bbb0SJohn Thompson return true; 19342d94bbb0SJohn Thompson } 19352d94bbb0SJohn Thompson } 19362d94bbb0SJohn Thompson 19372d94bbb0SJohn Thompson return false; 19382d94bbb0SJohn Thompson } 1939a97eaa1bSDavid Blaikie void CompilerInstance::resetAndLeakSema() { BuryPointer(takeSema()); } 19407de9969bSBenjamin Kramer 19417de9969bSBenjamin Kramer void CompilerInstance::setExternalSemaSource( 19427de9969bSBenjamin Kramer IntrusiveRefCntPtr<ExternalSemaSource> ESS) { 19437de9969bSBenjamin Kramer ExternalSemaSrc = std::move(ESS); 19447de9969bSBenjamin Kramer } 1945