10b57cec5SDimitry Andric //===--- CompilerInstance.cpp ---------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "clang/Frontend/CompilerInstance.h" 100b57cec5SDimitry Andric #include "clang/AST/ASTConsumer.h" 110b57cec5SDimitry Andric #include "clang/AST/ASTContext.h" 120b57cec5SDimitry Andric #include "clang/AST/Decl.h" 130b57cec5SDimitry Andric #include "clang/Basic/CharInfo.h" 140b57cec5SDimitry Andric #include "clang/Basic/Diagnostic.h" 15bdd1243dSDimitry Andric #include "clang/Basic/DiagnosticOptions.h" 160b57cec5SDimitry Andric #include "clang/Basic/FileManager.h" 17a7dea167SDimitry Andric #include "clang/Basic/LangStandard.h" 180b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h" 190b57cec5SDimitry Andric #include "clang/Basic/Stack.h" 200b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h" 210b57cec5SDimitry Andric #include "clang/Basic/Version.h" 220b57cec5SDimitry Andric #include "clang/Config/config.h" 230b57cec5SDimitry Andric #include "clang/Frontend/ChainedDiagnosticConsumer.h" 240b57cec5SDimitry Andric #include "clang/Frontend/FrontendAction.h" 250b57cec5SDimitry Andric #include "clang/Frontend/FrontendActions.h" 260b57cec5SDimitry Andric #include "clang/Frontend/FrontendDiagnostic.h" 27349cc55cSDimitry Andric #include "clang/Frontend/FrontendPluginRegistry.h" 280b57cec5SDimitry Andric #include "clang/Frontend/LogDiagnosticPrinter.h" 29bdd1243dSDimitry Andric #include "clang/Frontend/SARIFDiagnosticPrinter.h" 300b57cec5SDimitry Andric #include "clang/Frontend/SerializedDiagnosticPrinter.h" 310b57cec5SDimitry Andric #include "clang/Frontend/TextDiagnosticPrinter.h" 320b57cec5SDimitry Andric #include "clang/Frontend/Utils.h" 330b57cec5SDimitry Andric #include "clang/Frontend/VerifyDiagnosticConsumer.h" 340b57cec5SDimitry Andric #include "clang/Lex/HeaderSearch.h" 350b57cec5SDimitry Andric #include "clang/Lex/Preprocessor.h" 360b57cec5SDimitry Andric #include "clang/Lex/PreprocessorOptions.h" 370b57cec5SDimitry Andric #include "clang/Sema/CodeCompleteConsumer.h" 380b57cec5SDimitry Andric #include "clang/Sema/Sema.h" 390b57cec5SDimitry Andric #include "clang/Serialization/ASTReader.h" 400b57cec5SDimitry Andric #include "clang/Serialization/GlobalModuleIndex.h" 410b57cec5SDimitry Andric #include "clang/Serialization/InMemoryModuleCache.h" 425f757f3fSDimitry Andric #include "llvm/ADT/STLExtras.h" 4304eeddc0SDimitry Andric #include "llvm/ADT/ScopeExit.h" 440b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h" 45bdd1243dSDimitry Andric #include "llvm/Config/llvm-config.h" 460b57cec5SDimitry Andric #include "llvm/Support/BuryPointer.h" 470b57cec5SDimitry Andric #include "llvm/Support/CrashRecoveryContext.h" 480b57cec5SDimitry Andric #include "llvm/Support/Errc.h" 490b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h" 500b57cec5SDimitry Andric #include "llvm/Support/LockFileManager.h" 510b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 520b57cec5SDimitry Andric #include "llvm/Support/Path.h" 530b57cec5SDimitry Andric #include "llvm/Support/Program.h" 540b57cec5SDimitry Andric #include "llvm/Support/Signals.h" 550b57cec5SDimitry Andric #include "llvm/Support/TimeProfiler.h" 560b57cec5SDimitry Andric #include "llvm/Support/Timer.h" 570b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 5806c3fb27SDimitry Andric #include "llvm/TargetParser/Host.h" 59bdd1243dSDimitry Andric #include <optional> 600b57cec5SDimitry Andric #include <time.h> 610b57cec5SDimitry Andric #include <utility> 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric using namespace clang; 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric CompilerInstance::CompilerInstance( 660b57cec5SDimitry Andric std::shared_ptr<PCHContainerOperations> PCHContainerOps, 670b57cec5SDimitry Andric InMemoryModuleCache *SharedModuleCache) 680b57cec5SDimitry Andric : ModuleLoader(/* BuildingModule = */ SharedModuleCache), 690b57cec5SDimitry Andric Invocation(new CompilerInvocation()), 700b57cec5SDimitry Andric ModuleCache(SharedModuleCache ? SharedModuleCache 710b57cec5SDimitry Andric : new InMemoryModuleCache), 720b57cec5SDimitry Andric ThePCHContainerOperations(std::move(PCHContainerOps)) {} 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric CompilerInstance::~CompilerInstance() { 750b57cec5SDimitry Andric assert(OutputFiles.empty() && "Still output files in flight?"); 760b57cec5SDimitry Andric } 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric void CompilerInstance::setInvocation( 790b57cec5SDimitry Andric std::shared_ptr<CompilerInvocation> Value) { 800b57cec5SDimitry Andric Invocation = std::move(Value); 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric bool CompilerInstance::shouldBuildGlobalModuleIndex() const { 840b57cec5SDimitry Andric return (BuildGlobalModuleIndex || 85480093f4SDimitry Andric (TheASTReader && TheASTReader->isGlobalIndexUnavailable() && 860b57cec5SDimitry Andric getFrontendOpts().GenerateGlobalModuleIndex)) && 87fe6060f1SDimitry Andric !DisableGeneratingGlobalModuleIndex; 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric void CompilerInstance::setDiagnostics(DiagnosticsEngine *Value) { 910b57cec5SDimitry Andric Diagnostics = Value; 920b57cec5SDimitry Andric } 930b57cec5SDimitry Andric 94a7dea167SDimitry Andric void CompilerInstance::setVerboseOutputStream(raw_ostream &Value) { 95e8d8bef9SDimitry Andric OwnedVerboseOutputStream.reset(); 96a7dea167SDimitry Andric VerboseOutputStream = &Value; 97a7dea167SDimitry Andric } 98a7dea167SDimitry Andric 99a7dea167SDimitry Andric void CompilerInstance::setVerboseOutputStream(std::unique_ptr<raw_ostream> Value) { 100a7dea167SDimitry Andric OwnedVerboseOutputStream.swap(Value); 101a7dea167SDimitry Andric VerboseOutputStream = OwnedVerboseOutputStream.get(); 102a7dea167SDimitry Andric } 103a7dea167SDimitry Andric 1040b57cec5SDimitry Andric void CompilerInstance::setTarget(TargetInfo *Value) { Target = Value; } 1050b57cec5SDimitry Andric void CompilerInstance::setAuxTarget(TargetInfo *Value) { AuxTarget = Value; } 1060b57cec5SDimitry Andric 107fe6060f1SDimitry Andric bool CompilerInstance::createTarget() { 108fe6060f1SDimitry Andric // Create the target instance. 109fe6060f1SDimitry Andric setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), 110fe6060f1SDimitry Andric getInvocation().TargetOpts)); 111fe6060f1SDimitry Andric if (!hasTarget()) 112fe6060f1SDimitry Andric return false; 113fe6060f1SDimitry Andric 114fe6060f1SDimitry Andric // Check whether AuxTarget exists, if not, then create TargetInfo for the 115fe6060f1SDimitry Andric // other side of CUDA/OpenMP/SYCL compilation. 116fe6060f1SDimitry Andric if (!getAuxTarget() && 11706c3fb27SDimitry Andric (getLangOpts().CUDA || getLangOpts().OpenMPIsTargetDevice || 118fe6060f1SDimitry Andric getLangOpts().SYCLIsDevice) && 119fe6060f1SDimitry Andric !getFrontendOpts().AuxTriple.empty()) { 120fe6060f1SDimitry Andric auto TO = std::make_shared<TargetOptions>(); 121fe6060f1SDimitry Andric TO->Triple = llvm::Triple::normalize(getFrontendOpts().AuxTriple); 122fe6060f1SDimitry Andric if (getFrontendOpts().AuxTargetCPU) 123bdd1243dSDimitry Andric TO->CPU = *getFrontendOpts().AuxTargetCPU; 124fe6060f1SDimitry Andric if (getFrontendOpts().AuxTargetFeatures) 125bdd1243dSDimitry Andric TO->FeaturesAsWritten = *getFrontendOpts().AuxTargetFeatures; 126fe6060f1SDimitry Andric TO->HostTriple = getTarget().getTriple().str(); 127fe6060f1SDimitry Andric setAuxTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), TO)); 128fe6060f1SDimitry Andric } 129fe6060f1SDimitry Andric 130fe6060f1SDimitry Andric if (!getTarget().hasStrictFP() && !getLangOpts().ExpStrictFP) { 13181ad6265SDimitry Andric if (getLangOpts().RoundingMath) { 132fe6060f1SDimitry Andric getDiagnostics().Report(diag::warn_fe_backend_unsupported_fp_rounding); 13381ad6265SDimitry Andric getLangOpts().RoundingMath = false; 134fe6060f1SDimitry Andric } 13581ad6265SDimitry Andric auto FPExc = getLangOpts().getFPExceptionMode(); 13681ad6265SDimitry Andric if (FPExc != LangOptions::FPE_Default && FPExc != LangOptions::FPE_Ignore) { 137fe6060f1SDimitry Andric getDiagnostics().Report(diag::warn_fe_backend_unsupported_fp_exceptions); 138fe6060f1SDimitry Andric getLangOpts().setFPExceptionMode(LangOptions::FPE_Ignore); 139fe6060f1SDimitry Andric } 140fe6060f1SDimitry Andric // FIXME: can we disable FEnvAccess? 141fe6060f1SDimitry Andric } 142fe6060f1SDimitry Andric 143fe6060f1SDimitry Andric // We should do it here because target knows nothing about 144fe6060f1SDimitry Andric // language options when it's being created. 145fe6060f1SDimitry Andric if (getLangOpts().OpenCL && 146fe6060f1SDimitry Andric !getTarget().validateOpenCLTarget(getLangOpts(), getDiagnostics())) 147fe6060f1SDimitry Andric return false; 148fe6060f1SDimitry Andric 149fe6060f1SDimitry Andric // Inform the target of the language options. 150fe6060f1SDimitry Andric // FIXME: We shouldn't need to do this, the target should be immutable once 151fe6060f1SDimitry Andric // created. This complexity should be lifted elsewhere. 152fe6060f1SDimitry Andric getTarget().adjust(getDiagnostics(), getLangOpts()); 153fe6060f1SDimitry Andric 154fe6060f1SDimitry Andric if (auto *Aux = getAuxTarget()) 155fe6060f1SDimitry Andric getTarget().setAuxTarget(Aux); 156fe6060f1SDimitry Andric 157fe6060f1SDimitry Andric return true; 158fe6060f1SDimitry Andric } 159fe6060f1SDimitry Andric 1605ffd83dbSDimitry Andric llvm::vfs::FileSystem &CompilerInstance::getVirtualFileSystem() const { 1615ffd83dbSDimitry Andric return getFileManager().getVirtualFileSystem(); 1625ffd83dbSDimitry Andric } 1635ffd83dbSDimitry Andric 1640b57cec5SDimitry Andric void CompilerInstance::setFileManager(FileManager *Value) { 1650b57cec5SDimitry Andric FileMgr = Value; 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric void CompilerInstance::setSourceManager(SourceManager *Value) { 1690b57cec5SDimitry Andric SourceMgr = Value; 1700b57cec5SDimitry Andric } 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric void CompilerInstance::setPreprocessor(std::shared_ptr<Preprocessor> Value) { 1730b57cec5SDimitry Andric PP = std::move(Value); 1740b57cec5SDimitry Andric } 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric void CompilerInstance::setASTContext(ASTContext *Value) { 1770b57cec5SDimitry Andric Context = Value; 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric if (Context && Consumer) 1800b57cec5SDimitry Andric getASTConsumer().Initialize(getASTContext()); 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric void CompilerInstance::setSema(Sema *S) { 1840b57cec5SDimitry Andric TheSema.reset(S); 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric void CompilerInstance::setASTConsumer(std::unique_ptr<ASTConsumer> Value) { 1880b57cec5SDimitry Andric Consumer = std::move(Value); 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric if (Context && Consumer) 1910b57cec5SDimitry Andric getASTConsumer().Initialize(getASTContext()); 1920b57cec5SDimitry Andric } 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) { 1950b57cec5SDimitry Andric CompletionConsumer.reset(Value); 1960b57cec5SDimitry Andric } 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric std::unique_ptr<Sema> CompilerInstance::takeSema() { 1990b57cec5SDimitry Andric return std::move(TheSema); 2000b57cec5SDimitry Andric } 2010b57cec5SDimitry Andric 202480093f4SDimitry Andric IntrusiveRefCntPtr<ASTReader> CompilerInstance::getASTReader() const { 203480093f4SDimitry Andric return TheASTReader; 2040b57cec5SDimitry Andric } 2055ffd83dbSDimitry Andric void CompilerInstance::setASTReader(IntrusiveRefCntPtr<ASTReader> Reader) { 2060b57cec5SDimitry Andric assert(ModuleCache.get() == &Reader->getModuleManager().getModuleCache() && 2070b57cec5SDimitry Andric "Expected ASTReader to use the same PCM cache"); 208480093f4SDimitry Andric TheASTReader = std::move(Reader); 2090b57cec5SDimitry Andric } 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric std::shared_ptr<ModuleDependencyCollector> 2120b57cec5SDimitry Andric CompilerInstance::getModuleDepCollector() const { 2130b57cec5SDimitry Andric return ModuleDepCollector; 2140b57cec5SDimitry Andric } 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andric void CompilerInstance::setModuleDepCollector( 2170b57cec5SDimitry Andric std::shared_ptr<ModuleDependencyCollector> Collector) { 2180b57cec5SDimitry Andric ModuleDepCollector = std::move(Collector); 2190b57cec5SDimitry Andric } 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric static void collectHeaderMaps(const HeaderSearch &HS, 2220b57cec5SDimitry Andric std::shared_ptr<ModuleDependencyCollector> MDC) { 2230b57cec5SDimitry Andric SmallVector<std::string, 4> HeaderMapFileNames; 2240b57cec5SDimitry Andric HS.getHeaderMapFileNames(HeaderMapFileNames); 2250b57cec5SDimitry Andric for (auto &Name : HeaderMapFileNames) 2260b57cec5SDimitry Andric MDC->addFile(Name); 2270b57cec5SDimitry Andric } 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric static void collectIncludePCH(CompilerInstance &CI, 2300b57cec5SDimitry Andric std::shared_ptr<ModuleDependencyCollector> MDC) { 2310b57cec5SDimitry Andric const PreprocessorOptions &PPOpts = CI.getPreprocessorOpts(); 2320b57cec5SDimitry Andric if (PPOpts.ImplicitPCHInclude.empty()) 2330b57cec5SDimitry Andric return; 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric StringRef PCHInclude = PPOpts.ImplicitPCHInclude; 2360b57cec5SDimitry Andric FileManager &FileMgr = CI.getFileManager(); 23781ad6265SDimitry Andric auto PCHDir = FileMgr.getOptionalDirectoryRef(PCHInclude); 2380b57cec5SDimitry Andric if (!PCHDir) { 2390b57cec5SDimitry Andric MDC->addFile(PCHInclude); 2400b57cec5SDimitry Andric return; 2410b57cec5SDimitry Andric } 2420b57cec5SDimitry Andric 2430b57cec5SDimitry Andric std::error_code EC; 2440b57cec5SDimitry Andric SmallString<128> DirNative; 24581ad6265SDimitry Andric llvm::sys::path::native(PCHDir->getName(), DirNative); 2460b57cec5SDimitry Andric llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem(); 2470b57cec5SDimitry Andric SimpleASTReaderListener Validator(CI.getPreprocessor()); 2480b57cec5SDimitry Andric for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd; 2490b57cec5SDimitry Andric Dir != DirEnd && !EC; Dir.increment(EC)) { 2500b57cec5SDimitry Andric // Check whether this is an AST file. ASTReader::isAcceptableASTFile is not 2510b57cec5SDimitry Andric // used here since we're not interested in validating the PCH at this time, 2520b57cec5SDimitry Andric // but only to check whether this is a file containing an AST. 2530b57cec5SDimitry Andric if (!ASTReader::readASTFileControlBlock( 254bdd1243dSDimitry Andric Dir->path(), FileMgr, CI.getModuleCache(), 255bdd1243dSDimitry Andric CI.getPCHContainerReader(), 2560b57cec5SDimitry Andric /*FindModuleFileExtensions=*/false, Validator, 2570b57cec5SDimitry Andric /*ValidateDiagnosticOptions=*/false)) 2580b57cec5SDimitry Andric MDC->addFile(Dir->path()); 2590b57cec5SDimitry Andric } 2600b57cec5SDimitry Andric } 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric static void collectVFSEntries(CompilerInstance &CI, 2630b57cec5SDimitry Andric std::shared_ptr<ModuleDependencyCollector> MDC) { 2640b57cec5SDimitry Andric if (CI.getHeaderSearchOpts().VFSOverlayFiles.empty()) 2650b57cec5SDimitry Andric return; 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric // Collect all VFS found. 2680b57cec5SDimitry Andric SmallVector<llvm::vfs::YAMLVFSEntry, 16> VFSEntries; 2690b57cec5SDimitry Andric for (const std::string &VFSFile : CI.getHeaderSearchOpts().VFSOverlayFiles) { 2700b57cec5SDimitry Andric llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer = 2710b57cec5SDimitry Andric llvm::MemoryBuffer::getFile(VFSFile); 2720b57cec5SDimitry Andric if (!Buffer) 2730b57cec5SDimitry Andric return; 2740b57cec5SDimitry Andric llvm::vfs::collectVFSFromYAML(std::move(Buffer.get()), 2750b57cec5SDimitry Andric /*DiagHandler*/ nullptr, VFSFile, VFSEntries); 2760b57cec5SDimitry Andric } 2770b57cec5SDimitry Andric 2780b57cec5SDimitry Andric for (auto &E : VFSEntries) 2790b57cec5SDimitry Andric MDC->addFile(E.VPath, E.RPath); 2800b57cec5SDimitry Andric } 2810b57cec5SDimitry Andric 2820b57cec5SDimitry Andric // Diagnostics 2830b57cec5SDimitry Andric static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts, 2840b57cec5SDimitry Andric const CodeGenOptions *CodeGenOpts, 2850b57cec5SDimitry Andric DiagnosticsEngine &Diags) { 2860b57cec5SDimitry Andric std::error_code EC; 2870b57cec5SDimitry Andric std::unique_ptr<raw_ostream> StreamOwner; 2880b57cec5SDimitry Andric raw_ostream *OS = &llvm::errs(); 2890b57cec5SDimitry Andric if (DiagOpts->DiagnosticLogFile != "-") { 2900b57cec5SDimitry Andric // Create the output stream. 291a7dea167SDimitry Andric auto FileOS = std::make_unique<llvm::raw_fd_ostream>( 2920b57cec5SDimitry Andric DiagOpts->DiagnosticLogFile, EC, 293fe6060f1SDimitry Andric llvm::sys::fs::OF_Append | llvm::sys::fs::OF_TextWithCRLF); 2940b57cec5SDimitry Andric if (EC) { 2950b57cec5SDimitry Andric Diags.Report(diag::warn_fe_cc_log_diagnostics_failure) 2960b57cec5SDimitry Andric << DiagOpts->DiagnosticLogFile << EC.message(); 2970b57cec5SDimitry Andric } else { 2980b57cec5SDimitry Andric FileOS->SetUnbuffered(); 2990b57cec5SDimitry Andric OS = FileOS.get(); 3000b57cec5SDimitry Andric StreamOwner = std::move(FileOS); 3010b57cec5SDimitry Andric } 3020b57cec5SDimitry Andric } 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric // Chain in the diagnostic client which will log the diagnostics. 305a7dea167SDimitry Andric auto Logger = std::make_unique<LogDiagnosticPrinter>(*OS, DiagOpts, 3060b57cec5SDimitry Andric std::move(StreamOwner)); 3070b57cec5SDimitry Andric if (CodeGenOpts) 3080b57cec5SDimitry Andric Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags); 3090b57cec5SDimitry Andric if (Diags.ownsClient()) { 3100b57cec5SDimitry Andric Diags.setClient( 3110b57cec5SDimitry Andric new ChainedDiagnosticConsumer(Diags.takeClient(), std::move(Logger))); 3120b57cec5SDimitry Andric } else { 3130b57cec5SDimitry Andric Diags.setClient( 3140b57cec5SDimitry Andric new ChainedDiagnosticConsumer(Diags.getClient(), std::move(Logger))); 3150b57cec5SDimitry Andric } 3160b57cec5SDimitry Andric } 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts, 3190b57cec5SDimitry Andric DiagnosticsEngine &Diags, 3200b57cec5SDimitry Andric StringRef OutputFile) { 3210b57cec5SDimitry Andric auto SerializedConsumer = 3220b57cec5SDimitry Andric clang::serialized_diags::create(OutputFile, DiagOpts); 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric if (Diags.ownsClient()) { 3250b57cec5SDimitry Andric Diags.setClient(new ChainedDiagnosticConsumer( 3260b57cec5SDimitry Andric Diags.takeClient(), std::move(SerializedConsumer))); 3270b57cec5SDimitry Andric } else { 3280b57cec5SDimitry Andric Diags.setClient(new ChainedDiagnosticConsumer( 3290b57cec5SDimitry Andric Diags.getClient(), std::move(SerializedConsumer))); 3300b57cec5SDimitry Andric } 3310b57cec5SDimitry Andric } 3320b57cec5SDimitry Andric 3330b57cec5SDimitry Andric void CompilerInstance::createDiagnostics(DiagnosticConsumer *Client, 3340b57cec5SDimitry Andric bool ShouldOwnClient) { 3350b57cec5SDimitry Andric Diagnostics = createDiagnostics(&getDiagnosticOpts(), Client, 3360b57cec5SDimitry Andric ShouldOwnClient, &getCodeGenOpts()); 3370b57cec5SDimitry Andric } 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric IntrusiveRefCntPtr<DiagnosticsEngine> 3400b57cec5SDimitry Andric CompilerInstance::createDiagnostics(DiagnosticOptions *Opts, 3410b57cec5SDimitry Andric DiagnosticConsumer *Client, 3420b57cec5SDimitry Andric bool ShouldOwnClient, 3430b57cec5SDimitry Andric const CodeGenOptions *CodeGenOpts) { 3440b57cec5SDimitry Andric IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); 3450b57cec5SDimitry Andric IntrusiveRefCntPtr<DiagnosticsEngine> 3460b57cec5SDimitry Andric Diags(new DiagnosticsEngine(DiagID, Opts)); 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric // Create the diagnostic client for reporting errors or for 3490b57cec5SDimitry Andric // implementing -verify. 3500b57cec5SDimitry Andric if (Client) { 3510b57cec5SDimitry Andric Diags->setClient(Client, ShouldOwnClient); 352bdd1243dSDimitry Andric } else if (Opts->getFormat() == DiagnosticOptions::SARIF) { 353bdd1243dSDimitry Andric Diags->setClient(new SARIFDiagnosticPrinter(llvm::errs(), Opts)); 3540b57cec5SDimitry Andric } else 3550b57cec5SDimitry Andric Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts)); 3560b57cec5SDimitry Andric 3570b57cec5SDimitry Andric // Chain in -verify checker, if requested. 3580b57cec5SDimitry Andric if (Opts->VerifyDiagnostics) 3590b57cec5SDimitry Andric Diags->setClient(new VerifyDiagnosticConsumer(*Diags)); 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andric // Chain in -diagnostic-log-file dumper, if requested. 3620b57cec5SDimitry Andric if (!Opts->DiagnosticLogFile.empty()) 3630b57cec5SDimitry Andric SetUpDiagnosticLog(Opts, CodeGenOpts, *Diags); 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric if (!Opts->DiagnosticSerializationFile.empty()) 3660b57cec5SDimitry Andric SetupSerializedDiagnostics(Opts, *Diags, 3670b57cec5SDimitry Andric Opts->DiagnosticSerializationFile); 3680b57cec5SDimitry Andric 3690b57cec5SDimitry Andric // Configure our handling of diagnostics. 3700b57cec5SDimitry Andric ProcessWarningOptions(*Diags, *Opts); 3710b57cec5SDimitry Andric 3720b57cec5SDimitry Andric return Diags; 3730b57cec5SDimitry Andric } 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric // File Manager 3760b57cec5SDimitry Andric 3770b57cec5SDimitry Andric FileManager *CompilerInstance::createFileManager( 3780b57cec5SDimitry Andric IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) { 3790b57cec5SDimitry Andric if (!VFS) 3800b57cec5SDimitry Andric VFS = FileMgr ? &FileMgr->getVirtualFileSystem() 3810b57cec5SDimitry Andric : createVFSFromCompilerInvocation(getInvocation(), 3820b57cec5SDimitry Andric getDiagnostics()); 3830b57cec5SDimitry Andric assert(VFS && "FileManager has no VFS?"); 3840b57cec5SDimitry Andric FileMgr = new FileManager(getFileSystemOpts(), std::move(VFS)); 3850b57cec5SDimitry Andric return FileMgr.get(); 3860b57cec5SDimitry Andric } 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric // Source Manager 3890b57cec5SDimitry Andric 3900b57cec5SDimitry Andric void CompilerInstance::createSourceManager(FileManager &FileMgr) { 3910b57cec5SDimitry Andric SourceMgr = new SourceManager(getDiagnostics(), FileMgr); 3920b57cec5SDimitry Andric } 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric // Initialize the remapping of files to alternative contents, e.g., 3950b57cec5SDimitry Andric // those specified through other files. 3960b57cec5SDimitry Andric static void InitializeFileRemapping(DiagnosticsEngine &Diags, 3970b57cec5SDimitry Andric SourceManager &SourceMgr, 3980b57cec5SDimitry Andric FileManager &FileMgr, 3990b57cec5SDimitry Andric const PreprocessorOptions &InitOpts) { 4000b57cec5SDimitry Andric // Remap files in the source manager (with buffers). 4010b57cec5SDimitry Andric for (const auto &RB : InitOpts.RemappedFileBuffers) { 4020b57cec5SDimitry Andric // Create the file entry for the file that we're mapping from. 4035f757f3fSDimitry Andric FileEntryRef FromFile = 4045f757f3fSDimitry Andric FileMgr.getVirtualFileRef(RB.first, RB.second->getBufferSize(), 0); 4050b57cec5SDimitry Andric 406e8d8bef9SDimitry Andric // Override the contents of the "from" file with the contents of the 407e8d8bef9SDimitry Andric // "to" file. If the caller owns the buffers, then pass a MemoryBufferRef; 408e8d8bef9SDimitry Andric // otherwise, pass as a std::unique_ptr<MemoryBuffer> to transfer ownership 409e8d8bef9SDimitry Andric // to the SourceManager. 410e8d8bef9SDimitry Andric if (InitOpts.RetainRemappedFileBuffers) 411e8d8bef9SDimitry Andric SourceMgr.overrideFileContents(FromFile, RB.second->getMemBufferRef()); 412e8d8bef9SDimitry Andric else 413e8d8bef9SDimitry Andric SourceMgr.overrideFileContents( 414*0fca6ea1SDimitry Andric FromFile, std::unique_ptr<llvm::MemoryBuffer>(RB.second)); 4150b57cec5SDimitry Andric } 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric // Remap files in the source manager (with other files). 4180b57cec5SDimitry Andric for (const auto &RF : InitOpts.RemappedFiles) { 4190b57cec5SDimitry Andric // Find the file that we're mapping to. 420bdd1243dSDimitry Andric OptionalFileEntryRef ToFile = FileMgr.getOptionalFileRef(RF.second); 4210b57cec5SDimitry Andric if (!ToFile) { 4220b57cec5SDimitry Andric Diags.Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second; 4230b57cec5SDimitry Andric continue; 4240b57cec5SDimitry Andric } 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric // Create the file entry for the file that we're mapping from. 4270b57cec5SDimitry Andric const FileEntry *FromFile = 428bdd1243dSDimitry Andric FileMgr.getVirtualFile(RF.first, ToFile->getSize(), 0); 4290b57cec5SDimitry Andric if (!FromFile) { 4300b57cec5SDimitry Andric Diags.Report(diag::err_fe_remap_missing_from_file) << RF.first; 4310b57cec5SDimitry Andric continue; 4320b57cec5SDimitry Andric } 4330b57cec5SDimitry Andric 4340b57cec5SDimitry Andric // Override the contents of the "from" file with the contents of 4350b57cec5SDimitry Andric // the "to" file. 436a7dea167SDimitry Andric SourceMgr.overrideFileContents(FromFile, *ToFile); 4370b57cec5SDimitry Andric } 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric SourceMgr.setOverridenFilesKeepOriginalName( 4400b57cec5SDimitry Andric InitOpts.RemappedFilesKeepOriginalName); 4410b57cec5SDimitry Andric } 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andric // Preprocessor 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andric void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) { 4460b57cec5SDimitry Andric const PreprocessorOptions &PPOpts = getPreprocessorOpts(); 4470b57cec5SDimitry Andric 4485ffd83dbSDimitry Andric // The AST reader holds a reference to the old preprocessor (if any). 449480093f4SDimitry Andric TheASTReader.reset(); 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric // Create the Preprocessor. 4520b57cec5SDimitry Andric HeaderSearch *HeaderInfo = 4530b57cec5SDimitry Andric new HeaderSearch(getHeaderSearchOptsPtr(), getSourceManager(), 4540b57cec5SDimitry Andric getDiagnostics(), getLangOpts(), &getTarget()); 4550b57cec5SDimitry Andric PP = std::make_shared<Preprocessor>(Invocation->getPreprocessorOptsPtr(), 4560b57cec5SDimitry Andric getDiagnostics(), getLangOpts(), 4570b57cec5SDimitry Andric getSourceManager(), *HeaderInfo, *this, 4580b57cec5SDimitry Andric /*IdentifierInfoLookup=*/nullptr, 4590b57cec5SDimitry Andric /*OwnsHeaderSearch=*/true, TUKind); 460fe6060f1SDimitry Andric getTarget().adjust(getDiagnostics(), getLangOpts()); 4610b57cec5SDimitry Andric PP->Initialize(getTarget(), getAuxTarget()); 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andric if (PPOpts.DetailedRecord) 4640b57cec5SDimitry Andric PP->createPreprocessingRecord(); 4650b57cec5SDimitry Andric 4660b57cec5SDimitry Andric // Apply remappings to the source manager. 4670b57cec5SDimitry Andric InitializeFileRemapping(PP->getDiagnostics(), PP->getSourceManager(), 4680b57cec5SDimitry Andric PP->getFileManager(), PPOpts); 4690b57cec5SDimitry Andric 4700b57cec5SDimitry Andric // Predefine macros and configure the preprocessor. 4710b57cec5SDimitry Andric InitializePreprocessor(*PP, PPOpts, getPCHContainerReader(), 4727a6dacacSDimitry Andric getFrontendOpts(), getCodeGenOpts()); 4730b57cec5SDimitry Andric 4740b57cec5SDimitry Andric // Initialize the header search object. In CUDA compilations, we use the aux 4750b57cec5SDimitry Andric // triple (the host triple) to initialize our header search, since we need to 4760b57cec5SDimitry Andric // find the host headers in order to compile the CUDA code. 4770b57cec5SDimitry Andric const llvm::Triple *HeaderSearchTriple = &PP->getTargetInfo().getTriple(); 4780b57cec5SDimitry Andric if (PP->getTargetInfo().getTriple().getOS() == llvm::Triple::CUDA && 4790b57cec5SDimitry Andric PP->getAuxTargetInfo()) 4800b57cec5SDimitry Andric HeaderSearchTriple = &PP->getAuxTargetInfo()->getTriple(); 4810b57cec5SDimitry Andric 4820b57cec5SDimitry Andric ApplyHeaderSearchOptions(PP->getHeaderSearchInfo(), getHeaderSearchOpts(), 4830b57cec5SDimitry Andric PP->getLangOpts(), *HeaderSearchTriple); 4840b57cec5SDimitry Andric 4850b57cec5SDimitry Andric PP->setPreprocessedOutput(getPreprocessorOutputOpts().ShowCPP); 4860b57cec5SDimitry Andric 487e8d8bef9SDimitry Andric if (PP->getLangOpts().Modules && PP->getLangOpts().ImplicitModules) { 488e8d8bef9SDimitry Andric std::string ModuleHash = getInvocation().getModuleHash(); 489e8d8bef9SDimitry Andric PP->getHeaderSearchInfo().setModuleHash(ModuleHash); 490e8d8bef9SDimitry Andric PP->getHeaderSearchInfo().setModuleCachePath( 491e8d8bef9SDimitry Andric getSpecificModuleCachePath(ModuleHash)); 492e8d8bef9SDimitry Andric } 4930b57cec5SDimitry Andric 4940b57cec5SDimitry Andric // Handle generating dependencies, if requested. 4950b57cec5SDimitry Andric const DependencyOutputOptions &DepOpts = getDependencyOutputOpts(); 4960b57cec5SDimitry Andric if (!DepOpts.OutputFile.empty()) 4970b57cec5SDimitry Andric addDependencyCollector(std::make_shared<DependencyFileGenerator>(DepOpts)); 4980b57cec5SDimitry Andric if (!DepOpts.DOTOutputFile.empty()) 4990b57cec5SDimitry Andric AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile, 5000b57cec5SDimitry Andric getHeaderSearchOpts().Sysroot); 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andric // If we don't have a collector, but we are collecting module dependencies, 5030b57cec5SDimitry Andric // then we're the top level compiler instance and need to create one. 5040b57cec5SDimitry Andric if (!ModuleDepCollector && !DepOpts.ModuleDependencyOutputDir.empty()) { 5050b57cec5SDimitry Andric ModuleDepCollector = std::make_shared<ModuleDependencyCollector>( 5060b57cec5SDimitry Andric DepOpts.ModuleDependencyOutputDir); 5070b57cec5SDimitry Andric } 5080b57cec5SDimitry Andric 5090b57cec5SDimitry Andric // If there is a module dep collector, register with other dep collectors 5100b57cec5SDimitry Andric // and also (a) collect header maps and (b) TODO: input vfs overlay files. 5110b57cec5SDimitry Andric if (ModuleDepCollector) { 5120b57cec5SDimitry Andric addDependencyCollector(ModuleDepCollector); 5130b57cec5SDimitry Andric collectHeaderMaps(PP->getHeaderSearchInfo(), ModuleDepCollector); 5140b57cec5SDimitry Andric collectIncludePCH(*this, ModuleDepCollector); 5150b57cec5SDimitry Andric collectVFSEntries(*this, ModuleDepCollector); 5160b57cec5SDimitry Andric } 5170b57cec5SDimitry Andric 5180b57cec5SDimitry Andric for (auto &Listener : DependencyCollectors) 5190b57cec5SDimitry Andric Listener->attachToPreprocessor(*PP); 5200b57cec5SDimitry Andric 5210b57cec5SDimitry Andric // Handle generating header include information, if requested. 5220b57cec5SDimitry Andric if (DepOpts.ShowHeaderIncludes) 5230b57cec5SDimitry Andric AttachHeaderIncludeGen(*PP, DepOpts); 5240b57cec5SDimitry Andric if (!DepOpts.HeaderIncludeOutputFile.empty()) { 5250b57cec5SDimitry Andric StringRef OutputPath = DepOpts.HeaderIncludeOutputFile; 5260b57cec5SDimitry Andric if (OutputPath == "-") 5270b57cec5SDimitry Andric OutputPath = ""; 5280b57cec5SDimitry Andric AttachHeaderIncludeGen(*PP, DepOpts, 5290b57cec5SDimitry Andric /*ShowAllHeaders=*/true, OutputPath, 5300b57cec5SDimitry Andric /*ShowDepth=*/false); 5310b57cec5SDimitry Andric } 5320b57cec5SDimitry Andric 5330b57cec5SDimitry Andric if (DepOpts.ShowIncludesDest != ShowIncludesDestination::None) { 5340b57cec5SDimitry Andric AttachHeaderIncludeGen(*PP, DepOpts, 5350b57cec5SDimitry Andric /*ShowAllHeaders=*/true, /*OutputPath=*/"", 5360b57cec5SDimitry Andric /*ShowDepth=*/true, /*MSStyle=*/true); 5370b57cec5SDimitry Andric } 5380b57cec5SDimitry Andric } 5390b57cec5SDimitry Andric 540e8d8bef9SDimitry Andric std::string CompilerInstance::getSpecificModuleCachePath(StringRef ModuleHash) { 541e8d8bef9SDimitry Andric // Set up the module path, including the hash for the module-creation options. 5420b57cec5SDimitry Andric SmallString<256> SpecificModuleCache(getHeaderSearchOpts().ModuleCachePath); 5430b57cec5SDimitry Andric if (!SpecificModuleCache.empty() && !getHeaderSearchOpts().DisableModuleHash) 544e8d8bef9SDimitry Andric llvm::sys::path::append(SpecificModuleCache, ModuleHash); 5457a6dacacSDimitry Andric return std::string(SpecificModuleCache); 5460b57cec5SDimitry Andric } 5470b57cec5SDimitry Andric 5480b57cec5SDimitry Andric // ASTContext 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric void CompilerInstance::createASTContext() { 5510b57cec5SDimitry Andric Preprocessor &PP = getPreprocessor(); 5520b57cec5SDimitry Andric auto *Context = new ASTContext(getLangOpts(), PP.getSourceManager(), 5530b57cec5SDimitry Andric PP.getIdentifierTable(), PP.getSelectorTable(), 554fe6060f1SDimitry Andric PP.getBuiltinInfo(), PP.TUKind); 5550b57cec5SDimitry Andric Context->InitBuiltinTypes(getTarget(), getAuxTarget()); 5560b57cec5SDimitry Andric setASTContext(Context); 5570b57cec5SDimitry Andric } 5580b57cec5SDimitry Andric 5590b57cec5SDimitry Andric // ExternalASTSource 5600b57cec5SDimitry Andric 561349cc55cSDimitry Andric namespace { 562349cc55cSDimitry Andric // Helper to recursively read the module names for all modules we're adding. 563349cc55cSDimitry Andric // We mark these as known and redirect any attempt to load that module to 564349cc55cSDimitry Andric // the files we were handed. 565349cc55cSDimitry Andric struct ReadModuleNames : ASTReaderListener { 566349cc55cSDimitry Andric Preprocessor &PP; 567349cc55cSDimitry Andric llvm::SmallVector<std::string, 8> LoadedModules; 568349cc55cSDimitry Andric 569349cc55cSDimitry Andric ReadModuleNames(Preprocessor &PP) : PP(PP) {} 570349cc55cSDimitry Andric 571349cc55cSDimitry Andric void ReadModuleName(StringRef ModuleName) override { 572349cc55cSDimitry Andric // Keep the module name as a string for now. It's not safe to create a new 573349cc55cSDimitry Andric // IdentifierInfo from an ASTReader callback. 574349cc55cSDimitry Andric LoadedModules.push_back(ModuleName.str()); 575349cc55cSDimitry Andric } 576349cc55cSDimitry Andric 577349cc55cSDimitry Andric void registerAll() { 578349cc55cSDimitry Andric ModuleMap &MM = PP.getHeaderSearchInfo().getModuleMap(); 579349cc55cSDimitry Andric for (const std::string &LoadedModule : LoadedModules) 580349cc55cSDimitry Andric MM.cacheModuleLoad(*PP.getIdentifierInfo(LoadedModule), 581349cc55cSDimitry Andric MM.findModule(LoadedModule)); 582349cc55cSDimitry Andric LoadedModules.clear(); 583349cc55cSDimitry Andric } 584349cc55cSDimitry Andric 585349cc55cSDimitry Andric void markAllUnavailable() { 586349cc55cSDimitry Andric for (const std::string &LoadedModule : LoadedModules) { 587349cc55cSDimitry Andric if (Module *M = PP.getHeaderSearchInfo().getModuleMap().findModule( 588349cc55cSDimitry Andric LoadedModule)) { 589349cc55cSDimitry Andric M->HasIncompatibleModuleFile = true; 590349cc55cSDimitry Andric 591349cc55cSDimitry Andric // Mark module as available if the only reason it was unavailable 592349cc55cSDimitry Andric // was missing headers. 593349cc55cSDimitry Andric SmallVector<Module *, 2> Stack; 594349cc55cSDimitry Andric Stack.push_back(M); 595349cc55cSDimitry Andric while (!Stack.empty()) { 596349cc55cSDimitry Andric Module *Current = Stack.pop_back_val(); 597349cc55cSDimitry Andric if (Current->IsUnimportable) continue; 598349cc55cSDimitry Andric Current->IsAvailable = true; 59906c3fb27SDimitry Andric auto SubmodulesRange = Current->submodules(); 60006c3fb27SDimitry Andric Stack.insert(Stack.end(), SubmodulesRange.begin(), 60106c3fb27SDimitry Andric SubmodulesRange.end()); 602349cc55cSDimitry Andric } 603349cc55cSDimitry Andric } 604349cc55cSDimitry Andric } 605349cc55cSDimitry Andric LoadedModules.clear(); 606349cc55cSDimitry Andric } 607349cc55cSDimitry Andric }; 608349cc55cSDimitry Andric } // namespace 609349cc55cSDimitry Andric 6100b57cec5SDimitry Andric void CompilerInstance::createPCHExternalASTSource( 611e8d8bef9SDimitry Andric StringRef Path, DisableValidationForModuleKind DisableValidation, 612e8d8bef9SDimitry Andric bool AllowPCHWithCompilerErrors, void *DeserializationListener, 613e8d8bef9SDimitry Andric bool OwnDeserializationListener) { 6140b57cec5SDimitry Andric bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0; 615480093f4SDimitry Andric TheASTReader = createPCHExternalASTSource( 616e8d8bef9SDimitry Andric Path, getHeaderSearchOpts().Sysroot, DisableValidation, 6170b57cec5SDimitry Andric AllowPCHWithCompilerErrors, getPreprocessor(), getModuleCache(), 6180b57cec5SDimitry Andric getASTContext(), getPCHContainerReader(), 6190b57cec5SDimitry Andric getFrontendOpts().ModuleFileExtensions, DependencyCollectors, 6200b57cec5SDimitry Andric DeserializationListener, OwnDeserializationListener, Preamble, 6210b57cec5SDimitry Andric getFrontendOpts().UseGlobalModuleIndex); 6220b57cec5SDimitry Andric } 6230b57cec5SDimitry Andric 6240b57cec5SDimitry Andric IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource( 625e8d8bef9SDimitry Andric StringRef Path, StringRef Sysroot, 626e8d8bef9SDimitry Andric DisableValidationForModuleKind DisableValidation, 6270b57cec5SDimitry Andric bool AllowPCHWithCompilerErrors, Preprocessor &PP, 6280b57cec5SDimitry Andric InMemoryModuleCache &ModuleCache, ASTContext &Context, 6290b57cec5SDimitry Andric const PCHContainerReader &PCHContainerRdr, 6300b57cec5SDimitry Andric ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions, 6310b57cec5SDimitry Andric ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors, 6320b57cec5SDimitry Andric void *DeserializationListener, bool OwnDeserializationListener, 6330b57cec5SDimitry Andric bool Preamble, bool UseGlobalModuleIndex) { 6340b57cec5SDimitry Andric HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts(); 6350b57cec5SDimitry Andric 6360b57cec5SDimitry Andric IntrusiveRefCntPtr<ASTReader> Reader(new ASTReader( 6370b57cec5SDimitry Andric PP, ModuleCache, &Context, PCHContainerRdr, Extensions, 638e8d8bef9SDimitry Andric Sysroot.empty() ? "" : Sysroot.data(), DisableValidation, 6390b57cec5SDimitry Andric AllowPCHWithCompilerErrors, /*AllowConfigurationMismatch*/ false, 640a7dea167SDimitry Andric HSOpts.ModulesValidateSystemHeaders, HSOpts.ValidateASTInputFilesContent, 641a7dea167SDimitry Andric UseGlobalModuleIndex)); 6420b57cec5SDimitry Andric 6430b57cec5SDimitry Andric // We need the external source to be set up before we read the AST, because 6440b57cec5SDimitry Andric // eagerly-deserialized declarations may use it. 6450b57cec5SDimitry Andric Context.setExternalSource(Reader.get()); 6460b57cec5SDimitry Andric 6470b57cec5SDimitry Andric Reader->setDeserializationListener( 6480b57cec5SDimitry Andric static_cast<ASTDeserializationListener *>(DeserializationListener), 6490b57cec5SDimitry Andric /*TakeOwnership=*/OwnDeserializationListener); 6500b57cec5SDimitry Andric 6510b57cec5SDimitry Andric for (auto &Listener : DependencyCollectors) 6520b57cec5SDimitry Andric Listener->attachToASTReader(*Reader); 6530b57cec5SDimitry Andric 654349cc55cSDimitry Andric auto Listener = std::make_unique<ReadModuleNames>(PP); 655349cc55cSDimitry Andric auto &ListenerRef = *Listener; 656349cc55cSDimitry Andric ASTReader::ListenerScope ReadModuleNamesListener(*Reader, 657349cc55cSDimitry Andric std::move(Listener)); 658349cc55cSDimitry Andric 6590b57cec5SDimitry Andric switch (Reader->ReadAST(Path, 6600b57cec5SDimitry Andric Preamble ? serialization::MK_Preamble 6610b57cec5SDimitry Andric : serialization::MK_PCH, 6620b57cec5SDimitry Andric SourceLocation(), 6630b57cec5SDimitry Andric ASTReader::ARR_None)) { 6640b57cec5SDimitry Andric case ASTReader::Success: 6650b57cec5SDimitry Andric // Set the predefines buffer as suggested by the PCH reader. Typically, the 6660b57cec5SDimitry Andric // predefines buffer will be empty. 6670b57cec5SDimitry Andric PP.setPredefines(Reader->getSuggestedPredefines()); 668349cc55cSDimitry Andric ListenerRef.registerAll(); 6690b57cec5SDimitry Andric return Reader; 6700b57cec5SDimitry Andric 6710b57cec5SDimitry Andric case ASTReader::Failure: 6720b57cec5SDimitry Andric // Unrecoverable failure: don't even try to process the input file. 6730b57cec5SDimitry Andric break; 6740b57cec5SDimitry Andric 6750b57cec5SDimitry Andric case ASTReader::Missing: 6760b57cec5SDimitry Andric case ASTReader::OutOfDate: 6770b57cec5SDimitry Andric case ASTReader::VersionMismatch: 6780b57cec5SDimitry Andric case ASTReader::ConfigurationMismatch: 6790b57cec5SDimitry Andric case ASTReader::HadErrors: 6800b57cec5SDimitry Andric // No suitable PCH file could be found. Return an error. 6810b57cec5SDimitry Andric break; 6820b57cec5SDimitry Andric } 6830b57cec5SDimitry Andric 684349cc55cSDimitry Andric ListenerRef.markAllUnavailable(); 6850b57cec5SDimitry Andric Context.setExternalSource(nullptr); 6860b57cec5SDimitry Andric return nullptr; 6870b57cec5SDimitry Andric } 6880b57cec5SDimitry Andric 6890b57cec5SDimitry Andric // Code Completion 6900b57cec5SDimitry Andric 6910b57cec5SDimitry Andric static bool EnableCodeCompletion(Preprocessor &PP, 6920b57cec5SDimitry Andric StringRef Filename, 6930b57cec5SDimitry Andric unsigned Line, 6940b57cec5SDimitry Andric unsigned Column) { 6950b57cec5SDimitry Andric // Tell the source manager to chop off the given file at a specific 6960b57cec5SDimitry Andric // line and column. 6975f757f3fSDimitry Andric auto Entry = PP.getFileManager().getOptionalFileRef(Filename); 6980b57cec5SDimitry Andric if (!Entry) { 6990b57cec5SDimitry Andric PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file) 7000b57cec5SDimitry Andric << Filename; 7010b57cec5SDimitry Andric return true; 7020b57cec5SDimitry Andric } 7030b57cec5SDimitry Andric 7040b57cec5SDimitry Andric // Truncate the named file at the given line/column. 705a7dea167SDimitry Andric PP.SetCodeCompletionPoint(*Entry, Line, Column); 7060b57cec5SDimitry Andric return false; 7070b57cec5SDimitry Andric } 7080b57cec5SDimitry Andric 7090b57cec5SDimitry Andric void CompilerInstance::createCodeCompletionConsumer() { 7100b57cec5SDimitry Andric const ParsedSourceLocation &Loc = getFrontendOpts().CodeCompletionAt; 7110b57cec5SDimitry Andric if (!CompletionConsumer) { 71281ad6265SDimitry Andric setCodeCompletionConsumer(createCodeCompletionConsumer( 71381ad6265SDimitry Andric getPreprocessor(), Loc.FileName, Loc.Line, Loc.Column, 71481ad6265SDimitry Andric getFrontendOpts().CodeCompleteOpts, llvm::outs())); 7150b57cec5SDimitry Andric return; 7160b57cec5SDimitry Andric } else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName, 7170b57cec5SDimitry Andric Loc.Line, Loc.Column)) { 7180b57cec5SDimitry Andric setCodeCompletionConsumer(nullptr); 7190b57cec5SDimitry Andric return; 7200b57cec5SDimitry Andric } 7210b57cec5SDimitry Andric } 7220b57cec5SDimitry Andric 7230b57cec5SDimitry Andric void CompilerInstance::createFrontendTimer() { 7240b57cec5SDimitry Andric FrontendTimerGroup.reset( 7250b57cec5SDimitry Andric new llvm::TimerGroup("frontend", "Clang front-end time report")); 7260b57cec5SDimitry Andric FrontendTimer.reset( 7270b57cec5SDimitry Andric new llvm::Timer("frontend", "Clang front-end timer", 7280b57cec5SDimitry Andric *FrontendTimerGroup)); 7290b57cec5SDimitry Andric } 7300b57cec5SDimitry Andric 7310b57cec5SDimitry Andric CodeCompleteConsumer * 7320b57cec5SDimitry Andric CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP, 7330b57cec5SDimitry Andric StringRef Filename, 7340b57cec5SDimitry Andric unsigned Line, 7350b57cec5SDimitry Andric unsigned Column, 7360b57cec5SDimitry Andric const CodeCompleteOptions &Opts, 7370b57cec5SDimitry Andric raw_ostream &OS) { 7380b57cec5SDimitry Andric if (EnableCodeCompletion(PP, Filename, Line, Column)) 7390b57cec5SDimitry Andric return nullptr; 7400b57cec5SDimitry Andric 7410b57cec5SDimitry Andric // Set up the creation routine for code-completion. 7420b57cec5SDimitry Andric return new PrintingCodeCompleteConsumer(Opts, OS); 7430b57cec5SDimitry Andric } 7440b57cec5SDimitry Andric 7450b57cec5SDimitry Andric void CompilerInstance::createSema(TranslationUnitKind TUKind, 7460b57cec5SDimitry Andric CodeCompleteConsumer *CompletionConsumer) { 7470b57cec5SDimitry Andric TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(), 7480b57cec5SDimitry Andric TUKind, CompletionConsumer)); 7495f757f3fSDimitry Andric 7505f757f3fSDimitry Andric // Set up API notes. 7515f757f3fSDimitry Andric TheSema->APINotes.setSwiftVersion(getAPINotesOpts().SwiftVersion); 7525f757f3fSDimitry Andric 7530b57cec5SDimitry Andric // Attach the external sema source if there is any. 7540b57cec5SDimitry Andric if (ExternalSemaSrc) { 7550b57cec5SDimitry Andric TheSema->addExternalSource(ExternalSemaSrc.get()); 7560b57cec5SDimitry Andric ExternalSemaSrc->InitializeSema(*TheSema); 7570b57cec5SDimitry Andric } 7585f757f3fSDimitry Andric 7595f757f3fSDimitry Andric // If we're building a module and are supposed to load API notes, 7605f757f3fSDimitry Andric // notify the API notes manager. 7615f757f3fSDimitry Andric if (auto *currentModule = getPreprocessor().getCurrentModule()) { 7625f757f3fSDimitry Andric (void)TheSema->APINotes.loadCurrentModuleAPINotes( 7635f757f3fSDimitry Andric currentModule, getLangOpts().APINotesModules, 7645f757f3fSDimitry Andric getAPINotesOpts().ModuleSearchPaths); 7655f757f3fSDimitry Andric } 7660b57cec5SDimitry Andric } 7670b57cec5SDimitry Andric 7680b57cec5SDimitry Andric // Output Files 7690b57cec5SDimitry Andric 7700b57cec5SDimitry Andric void CompilerInstance::clearOutputFiles(bool EraseFiles) { 771753f127fSDimitry Andric // The ASTConsumer can own streams that write to the output files. 772753f127fSDimitry Andric assert(!hasASTConsumer() && "ASTConsumer should be reset"); 773fe6060f1SDimitry Andric // Ignore errors that occur when trying to discard the temp file. 7740b57cec5SDimitry Andric for (OutputFile &OF : OutputFiles) { 7750b57cec5SDimitry Andric if (EraseFiles) { 776fe6060f1SDimitry Andric if (OF.File) 777fe6060f1SDimitry Andric consumeError(OF.File->discard()); 778e8d8bef9SDimitry Andric if (!OF.Filename.empty()) 779e8d8bef9SDimitry Andric llvm::sys::fs::remove(OF.Filename); 780e8d8bef9SDimitry Andric continue; 781e8d8bef9SDimitry Andric } 782e8d8bef9SDimitry Andric 783fe6060f1SDimitry Andric if (!OF.File) 784e8d8bef9SDimitry Andric continue; 7850b57cec5SDimitry Andric 786fe6060f1SDimitry Andric if (OF.File->TmpName.empty()) { 787fe6060f1SDimitry Andric consumeError(OF.File->discard()); 788fe6060f1SDimitry Andric continue; 789fe6060f1SDimitry Andric } 790fe6060f1SDimitry Andric 791bdd1243dSDimitry Andric llvm::Error E = OF.File->keep(OF.Filename); 792fe6060f1SDimitry Andric if (!E) 793fe6060f1SDimitry Andric continue; 794fe6060f1SDimitry Andric 795fe6060f1SDimitry Andric getDiagnostics().Report(diag::err_unable_to_rename_temp) 796fe6060f1SDimitry Andric << OF.File->TmpName << OF.Filename << std::move(E); 797fe6060f1SDimitry Andric 798fe6060f1SDimitry Andric llvm::sys::fs::remove(OF.File->TmpName); 7990b57cec5SDimitry Andric } 8000b57cec5SDimitry Andric OutputFiles.clear(); 8010b57cec5SDimitry Andric if (DeleteBuiltModules) { 8020b57cec5SDimitry Andric for (auto &Module : BuiltModules) 8030b57cec5SDimitry Andric llvm::sys::fs::remove(Module.second); 8040b57cec5SDimitry Andric BuiltModules.clear(); 8050b57cec5SDimitry Andric } 8060b57cec5SDimitry Andric } 8070b57cec5SDimitry Andric 808fe6060f1SDimitry Andric std::unique_ptr<raw_pwrite_stream> CompilerInstance::createDefaultOutputFile( 809fe6060f1SDimitry Andric bool Binary, StringRef InFile, StringRef Extension, bool RemoveFileOnSignal, 810fe6060f1SDimitry Andric bool CreateMissingDirectories, bool ForceUseTemporary) { 811e8d8bef9SDimitry Andric StringRef OutputPath = getFrontendOpts().OutputFile; 812bdd1243dSDimitry Andric std::optional<SmallString<128>> PathStorage; 813e8d8bef9SDimitry Andric if (OutputPath.empty()) { 814e8d8bef9SDimitry Andric if (InFile == "-" || Extension.empty()) { 815e8d8bef9SDimitry Andric OutputPath = "-"; 816e8d8bef9SDimitry Andric } else { 817e8d8bef9SDimitry Andric PathStorage.emplace(InFile); 818e8d8bef9SDimitry Andric llvm::sys::path::replace_extension(*PathStorage, Extension); 819e8d8bef9SDimitry Andric OutputPath = *PathStorage; 820e8d8bef9SDimitry Andric } 821e8d8bef9SDimitry Andric } 822e8d8bef9SDimitry Andric 823e8d8bef9SDimitry Andric return createOutputFile(OutputPath, Binary, RemoveFileOnSignal, 824fe6060f1SDimitry Andric getFrontendOpts().UseTemporary || ForceUseTemporary, 825e8d8bef9SDimitry Andric CreateMissingDirectories); 8260b57cec5SDimitry Andric } 8270b57cec5SDimitry Andric 8280b57cec5SDimitry Andric std::unique_ptr<raw_pwrite_stream> CompilerInstance::createNullOutputFile() { 829a7dea167SDimitry Andric return std::make_unique<llvm::raw_null_ostream>(); 8300b57cec5SDimitry Andric } 8310b57cec5SDimitry Andric 8320b57cec5SDimitry Andric std::unique_ptr<raw_pwrite_stream> 8330b57cec5SDimitry Andric CompilerInstance::createOutputFile(StringRef OutputPath, bool Binary, 834e8d8bef9SDimitry Andric bool RemoveFileOnSignal, bool UseTemporary, 8350b57cec5SDimitry Andric bool CreateMissingDirectories) { 836e8d8bef9SDimitry Andric Expected<std::unique_ptr<raw_pwrite_stream>> OS = 837e8d8bef9SDimitry Andric createOutputFileImpl(OutputPath, Binary, RemoveFileOnSignal, UseTemporary, 838e8d8bef9SDimitry Andric CreateMissingDirectories); 839e8d8bef9SDimitry Andric if (OS) 840e8d8bef9SDimitry Andric return std::move(*OS); 841e8d8bef9SDimitry Andric getDiagnostics().Report(diag::err_fe_unable_to_open_output) 842e8d8bef9SDimitry Andric << OutputPath << errorToErrorCode(OS.takeError()).message(); 8430b57cec5SDimitry Andric return nullptr; 8440b57cec5SDimitry Andric } 8450b57cec5SDimitry Andric 846e8d8bef9SDimitry Andric Expected<std::unique_ptr<llvm::raw_pwrite_stream>> 847e8d8bef9SDimitry Andric CompilerInstance::createOutputFileImpl(StringRef OutputPath, bool Binary, 848e8d8bef9SDimitry Andric bool RemoveFileOnSignal, 849e8d8bef9SDimitry Andric bool UseTemporary, 850e8d8bef9SDimitry Andric bool CreateMissingDirectories) { 8510b57cec5SDimitry Andric assert((!CreateMissingDirectories || UseTemporary) && 8520b57cec5SDimitry Andric "CreateMissingDirectories is only allowed when using temporary files"); 8530b57cec5SDimitry Andric 854bdd1243dSDimitry Andric // If '-working-directory' was passed, the output filename should be 855bdd1243dSDimitry Andric // relative to that. 856bdd1243dSDimitry Andric std::optional<SmallString<128>> AbsPath; 857bdd1243dSDimitry Andric if (OutputPath != "-" && !llvm::sys::path::is_absolute(OutputPath)) { 85806c3fb27SDimitry Andric assert(hasFileManager() && 85906c3fb27SDimitry Andric "File Manager is required to fix up relative path.\n"); 86006c3fb27SDimitry Andric 861bdd1243dSDimitry Andric AbsPath.emplace(OutputPath); 862bdd1243dSDimitry Andric FileMgr->FixupRelativePath(*AbsPath); 863bdd1243dSDimitry Andric OutputPath = *AbsPath; 864bdd1243dSDimitry Andric } 865bdd1243dSDimitry Andric 8660b57cec5SDimitry Andric std::unique_ptr<llvm::raw_fd_ostream> OS; 867bdd1243dSDimitry Andric std::optional<StringRef> OSFile; 8680b57cec5SDimitry Andric 8690b57cec5SDimitry Andric if (UseTemporary) { 870e8d8bef9SDimitry Andric if (OutputPath == "-") 8710b57cec5SDimitry Andric UseTemporary = false; 8720b57cec5SDimitry Andric else { 8730b57cec5SDimitry Andric llvm::sys::fs::file_status Status; 8740b57cec5SDimitry Andric llvm::sys::fs::status(OutputPath, Status); 8750b57cec5SDimitry Andric if (llvm::sys::fs::exists(Status)) { 8760b57cec5SDimitry Andric // Fail early if we can't write to the final destination. 877e8d8bef9SDimitry Andric if (!llvm::sys::fs::can_write(OutputPath)) 878e8d8bef9SDimitry Andric return llvm::errorCodeToError( 879e8d8bef9SDimitry Andric make_error_code(llvm::errc::operation_not_permitted)); 8800b57cec5SDimitry Andric 8810b57cec5SDimitry Andric // Don't use a temporary if the output is a special file. This handles 8820b57cec5SDimitry Andric // things like '-o /dev/null' 8830b57cec5SDimitry Andric if (!llvm::sys::fs::is_regular_file(Status)) 8840b57cec5SDimitry Andric UseTemporary = false; 8850b57cec5SDimitry Andric } 8860b57cec5SDimitry Andric } 8870b57cec5SDimitry Andric } 8880b57cec5SDimitry Andric 889bdd1243dSDimitry Andric std::optional<llvm::sys::fs::TempFile> Temp; 8900b57cec5SDimitry Andric if (UseTemporary) { 8910b57cec5SDimitry Andric // Create a temporary file. 8920b57cec5SDimitry Andric // Insert -%%%%%%%% before the extension (if any), and because some tools 8930b57cec5SDimitry Andric // (noticeable, clang's own GlobalModuleIndex.cpp) glob for build 8940b57cec5SDimitry Andric // artifacts, also append .tmp. 895e8d8bef9SDimitry Andric StringRef OutputExtension = llvm::sys::path::extension(OutputPath); 8960b57cec5SDimitry Andric SmallString<128> TempPath = 897e8d8bef9SDimitry Andric StringRef(OutputPath).drop_back(OutputExtension.size()); 8980b57cec5SDimitry Andric TempPath += "-%%%%%%%%"; 8990b57cec5SDimitry Andric TempPath += OutputExtension; 9000b57cec5SDimitry Andric TempPath += ".tmp"; 90106c3fb27SDimitry Andric llvm::sys::fs::OpenFlags BinaryFlags = 90206c3fb27SDimitry Andric Binary ? llvm::sys::fs::OF_None : llvm::sys::fs::OF_Text; 903fe6060f1SDimitry Andric Expected<llvm::sys::fs::TempFile> ExpectedFile = 904fe6060f1SDimitry Andric llvm::sys::fs::TempFile::create( 905fe6060f1SDimitry Andric TempPath, llvm::sys::fs::all_read | llvm::sys::fs::all_write, 90606c3fb27SDimitry Andric BinaryFlags); 9070b57cec5SDimitry Andric 908fe6060f1SDimitry Andric llvm::Error E = handleErrors( 909fe6060f1SDimitry Andric ExpectedFile.takeError(), [&](const llvm::ECError &E) -> llvm::Error { 910fe6060f1SDimitry Andric std::error_code EC = E.convertToErrorCode(); 9110b57cec5SDimitry Andric if (CreateMissingDirectories && 9120b57cec5SDimitry Andric EC == llvm::errc::no_such_file_or_directory) { 9130b57cec5SDimitry Andric StringRef Parent = llvm::sys::path::parent_path(OutputPath); 9140b57cec5SDimitry Andric EC = llvm::sys::fs::create_directories(Parent); 9150b57cec5SDimitry Andric if (!EC) { 91606c3fb27SDimitry Andric ExpectedFile = llvm::sys::fs::TempFile::create( 91706c3fb27SDimitry Andric TempPath, llvm::sys::fs::all_read | llvm::sys::fs::all_write, 91806c3fb27SDimitry Andric BinaryFlags); 919fe6060f1SDimitry Andric if (!ExpectedFile) 920fe6060f1SDimitry Andric return llvm::errorCodeToError( 921fe6060f1SDimitry Andric llvm::errc::no_such_file_or_directory); 9220b57cec5SDimitry Andric } 9230b57cec5SDimitry Andric } 924fe6060f1SDimitry Andric return llvm::errorCodeToError(EC); 925fe6060f1SDimitry Andric }); 9260b57cec5SDimitry Andric 927fe6060f1SDimitry Andric if (E) { 928fe6060f1SDimitry Andric consumeError(std::move(E)); 929fe6060f1SDimitry Andric } else { 930fe6060f1SDimitry Andric Temp = std::move(ExpectedFile.get()); 931fe6060f1SDimitry Andric OS.reset(new llvm::raw_fd_ostream(Temp->FD, /*shouldClose=*/false)); 932fe6060f1SDimitry Andric OSFile = Temp->TmpName; 9330b57cec5SDimitry Andric } 9340b57cec5SDimitry Andric // If we failed to create the temporary, fallback to writing to the file 9350b57cec5SDimitry Andric // directly. This handles the corner case where we cannot write to the 9360b57cec5SDimitry Andric // directory, but can write to the file. 9370b57cec5SDimitry Andric } 9380b57cec5SDimitry Andric 9390b57cec5SDimitry Andric if (!OS) { 940e8d8bef9SDimitry Andric OSFile = OutputPath; 941e8d8bef9SDimitry Andric std::error_code EC; 9420b57cec5SDimitry Andric OS.reset(new llvm::raw_fd_ostream( 943e8d8bef9SDimitry Andric *OSFile, EC, 944fe6060f1SDimitry Andric (Binary ? llvm::sys::fs::OF_None : llvm::sys::fs::OF_TextWithCRLF))); 945e8d8bef9SDimitry Andric if (EC) 946e8d8bef9SDimitry Andric return llvm::errorCodeToError(EC); 9470b57cec5SDimitry Andric } 9480b57cec5SDimitry Andric 949e8d8bef9SDimitry Andric // Add the output file -- but don't try to remove "-", since this means we are 950e8d8bef9SDimitry Andric // using stdin. 951e8d8bef9SDimitry Andric OutputFiles.emplace_back(((OutputPath != "-") ? OutputPath : "").str(), 952fe6060f1SDimitry Andric std::move(Temp)); 9530b57cec5SDimitry Andric 9540b57cec5SDimitry Andric if (!Binary || OS->supportsSeeking()) 9550b57cec5SDimitry Andric return std::move(OS); 9560b57cec5SDimitry Andric 957e8d8bef9SDimitry Andric return std::make_unique<llvm::buffer_unique_ostream>(std::move(OS)); 9580b57cec5SDimitry Andric } 9590b57cec5SDimitry Andric 9600b57cec5SDimitry Andric // Initialization Utilities 9610b57cec5SDimitry Andric 9620b57cec5SDimitry Andric bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input){ 9635ffd83dbSDimitry Andric return InitializeSourceManager(Input, getDiagnostics(), getFileManager(), 9645ffd83dbSDimitry Andric getSourceManager()); 9650b57cec5SDimitry Andric } 9660b57cec5SDimitry Andric 9670b57cec5SDimitry Andric // static 9685ffd83dbSDimitry Andric bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input, 9695ffd83dbSDimitry Andric DiagnosticsEngine &Diags, 9705ffd83dbSDimitry Andric FileManager &FileMgr, 9715ffd83dbSDimitry Andric SourceManager &SourceMgr) { 9720b57cec5SDimitry Andric SrcMgr::CharacteristicKind Kind = 9730b57cec5SDimitry Andric Input.getKind().getFormat() == InputKind::ModuleMap 9740b57cec5SDimitry Andric ? Input.isSystem() ? SrcMgr::C_System_ModuleMap 9750b57cec5SDimitry Andric : SrcMgr::C_User_ModuleMap 9760b57cec5SDimitry Andric : Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User; 9770b57cec5SDimitry Andric 9780b57cec5SDimitry Andric if (Input.isBuffer()) { 979e8d8bef9SDimitry Andric SourceMgr.setMainFileID(SourceMgr.createFileID(Input.getBuffer(), Kind)); 9800b57cec5SDimitry Andric assert(SourceMgr.getMainFileID().isValid() && 9810b57cec5SDimitry Andric "Couldn't establish MainFileID!"); 9820b57cec5SDimitry Andric return true; 9830b57cec5SDimitry Andric } 9840b57cec5SDimitry Andric 9850b57cec5SDimitry Andric StringRef InputFile = Input.getFile(); 9860b57cec5SDimitry Andric 9870b57cec5SDimitry Andric // Figure out where to get and map in the main file. 988e8d8bef9SDimitry Andric auto FileOrErr = InputFile == "-" 989e8d8bef9SDimitry Andric ? FileMgr.getSTDIN() 990e8d8bef9SDimitry Andric : FileMgr.getFileRef(InputFile, /*OpenFile=*/true); 991a7dea167SDimitry Andric if (!FileOrErr) { 992e8d8bef9SDimitry Andric auto EC = llvm::errorToErrorCode(FileOrErr.takeError()); 993e8d8bef9SDimitry Andric if (InputFile != "-") 99406c3fb27SDimitry Andric Diags.Report(diag::err_fe_error_reading) << InputFile << EC.message(); 995e8d8bef9SDimitry Andric else 9960b57cec5SDimitry Andric Diags.Report(diag::err_fe_error_reading_stdin) << EC.message(); 9970b57cec5SDimitry Andric return false; 9980b57cec5SDimitry Andric } 9990b57cec5SDimitry Andric 10000b57cec5SDimitry Andric SourceMgr.setMainFileID( 1001e8d8bef9SDimitry Andric SourceMgr.createFileID(*FileOrErr, SourceLocation(), Kind)); 10020b57cec5SDimitry Andric 10030b57cec5SDimitry Andric assert(SourceMgr.getMainFileID().isValid() && 10040b57cec5SDimitry Andric "Couldn't establish MainFileID!"); 10050b57cec5SDimitry Andric return true; 10060b57cec5SDimitry Andric } 10070b57cec5SDimitry Andric 10080b57cec5SDimitry Andric // High-Level Operations 10090b57cec5SDimitry Andric 10100b57cec5SDimitry Andric bool CompilerInstance::ExecuteAction(FrontendAction &Act) { 10110b57cec5SDimitry Andric assert(hasDiagnostics() && "Diagnostics engine is not initialized!"); 10120b57cec5SDimitry Andric assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!"); 10130b57cec5SDimitry Andric assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!"); 10140b57cec5SDimitry Andric 1015a7dea167SDimitry Andric // Mark this point as the bottom of the stack if we don't have somewhere 1016a7dea167SDimitry Andric // better. We generally expect frontend actions to be invoked with (nearly) 1017a7dea167SDimitry Andric // DesiredStackSpace available. 1018a7dea167SDimitry Andric noteBottomOfStack(); 1019a7dea167SDimitry Andric 102004eeddc0SDimitry Andric auto FinishDiagnosticClient = llvm::make_scope_exit([&]() { 102104eeddc0SDimitry Andric // Notify the diagnostic client that all files were processed. 102204eeddc0SDimitry Andric getDiagnosticClient().finish(); 102304eeddc0SDimitry Andric }); 102404eeddc0SDimitry Andric 1025a7dea167SDimitry Andric raw_ostream &OS = getVerboseOutputStream(); 10260b57cec5SDimitry Andric 10270b57cec5SDimitry Andric if (!Act.PrepareToExecute(*this)) 10280b57cec5SDimitry Andric return false; 10290b57cec5SDimitry Andric 1030fe6060f1SDimitry Andric if (!createTarget()) 10310b57cec5SDimitry Andric return false; 10320b57cec5SDimitry Andric 10330b57cec5SDimitry Andric // rewriter project will change target built-in bool type from its default. 10340b57cec5SDimitry Andric if (getFrontendOpts().ProgramAction == frontend::RewriteObjC) 10350b57cec5SDimitry Andric getTarget().noSignedCharForObjCBool(); 10360b57cec5SDimitry Andric 10370b57cec5SDimitry Andric // Validate/process some options. 10380b57cec5SDimitry Andric if (getHeaderSearchOpts().Verbose) 1039bdd1243dSDimitry Andric OS << "clang -cc1 version " CLANG_VERSION_STRING << " based upon LLVM " 1040bdd1243dSDimitry Andric << LLVM_VERSION_STRING << " default target " 1041bdd1243dSDimitry Andric << llvm::sys::getDefaultTargetTriple() << "\n"; 10420b57cec5SDimitry Andric 1043e8d8bef9SDimitry Andric if (getCodeGenOpts().TimePasses) 10440b57cec5SDimitry Andric createFrontendTimer(); 10450b57cec5SDimitry Andric 10460b57cec5SDimitry Andric if (getFrontendOpts().ShowStats || !getFrontendOpts().StatsFile.empty()) 10470b57cec5SDimitry Andric llvm::EnableStatistics(false); 10480b57cec5SDimitry Andric 1049*0fca6ea1SDimitry Andric // Sort vectors containing toc data and no toc data variables to facilitate 1050*0fca6ea1SDimitry Andric // binary search later. 1051*0fca6ea1SDimitry Andric llvm::sort(getCodeGenOpts().TocDataVarsUserSpecified); 1052*0fca6ea1SDimitry Andric llvm::sort(getCodeGenOpts().NoTocDataVars); 1053*0fca6ea1SDimitry Andric 10540b57cec5SDimitry Andric for (const FrontendInputFile &FIF : getFrontendOpts().Inputs) { 10550b57cec5SDimitry Andric // Reset the ID tables if we are reusing the SourceManager and parsing 10560b57cec5SDimitry Andric // regular files. 10570b57cec5SDimitry Andric if (hasSourceManager() && !Act.isModelParsingAction()) 10580b57cec5SDimitry Andric getSourceManager().clearIDTables(); 10590b57cec5SDimitry Andric 10600b57cec5SDimitry Andric if (Act.BeginSourceFile(*this, FIF)) { 10610b57cec5SDimitry Andric if (llvm::Error Err = Act.Execute()) { 10620b57cec5SDimitry Andric consumeError(std::move(Err)); // FIXME this drops errors on the floor. 10630b57cec5SDimitry Andric } 10640b57cec5SDimitry Andric Act.EndSourceFile(); 10650b57cec5SDimitry Andric } 10660b57cec5SDimitry Andric } 10670b57cec5SDimitry Andric 1068*0fca6ea1SDimitry Andric printDiagnosticStats(); 10690b57cec5SDimitry Andric 10700b57cec5SDimitry Andric if (getFrontendOpts().ShowStats) { 10710b57cec5SDimitry Andric if (hasFileManager()) { 10720b57cec5SDimitry Andric getFileManager().PrintStats(); 10730b57cec5SDimitry Andric OS << '\n'; 10740b57cec5SDimitry Andric } 10750b57cec5SDimitry Andric llvm::PrintStatistics(OS); 10760b57cec5SDimitry Andric } 10770b57cec5SDimitry Andric StringRef StatsFile = getFrontendOpts().StatsFile; 10780b57cec5SDimitry Andric if (!StatsFile.empty()) { 107906c3fb27SDimitry Andric llvm::sys::fs::OpenFlags FileFlags = llvm::sys::fs::OF_TextWithCRLF; 108006c3fb27SDimitry Andric if (getFrontendOpts().AppendStats) 108106c3fb27SDimitry Andric FileFlags |= llvm::sys::fs::OF_Append; 10820b57cec5SDimitry Andric std::error_code EC; 108306c3fb27SDimitry Andric auto StatS = 108406c3fb27SDimitry Andric std::make_unique<llvm::raw_fd_ostream>(StatsFile, EC, FileFlags); 10850b57cec5SDimitry Andric if (EC) { 10860b57cec5SDimitry Andric getDiagnostics().Report(diag::warn_fe_unable_to_open_stats_file) 10870b57cec5SDimitry Andric << StatsFile << EC.message(); 10880b57cec5SDimitry Andric } else { 10890b57cec5SDimitry Andric llvm::PrintStatisticsJSON(*StatS); 10900b57cec5SDimitry Andric } 10910b57cec5SDimitry Andric } 10920b57cec5SDimitry Andric 10930b57cec5SDimitry Andric return !getDiagnostics().getClient()->getNumErrors(); 10940b57cec5SDimitry Andric } 10950b57cec5SDimitry Andric 1096*0fca6ea1SDimitry Andric void CompilerInstance::printDiagnosticStats() { 1097*0fca6ea1SDimitry Andric if (!getDiagnosticOpts().ShowCarets) 1098*0fca6ea1SDimitry Andric return; 1099*0fca6ea1SDimitry Andric 1100*0fca6ea1SDimitry Andric raw_ostream &OS = getVerboseOutputStream(); 1101*0fca6ea1SDimitry Andric 1102*0fca6ea1SDimitry Andric // We can have multiple diagnostics sharing one diagnostic client. 1103*0fca6ea1SDimitry Andric // Get the total number of warnings/errors from the client. 1104*0fca6ea1SDimitry Andric unsigned NumWarnings = getDiagnostics().getClient()->getNumWarnings(); 1105*0fca6ea1SDimitry Andric unsigned NumErrors = getDiagnostics().getClient()->getNumErrors(); 1106*0fca6ea1SDimitry Andric 1107*0fca6ea1SDimitry Andric if (NumWarnings) 1108*0fca6ea1SDimitry Andric OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s"); 1109*0fca6ea1SDimitry Andric if (NumWarnings && NumErrors) 1110*0fca6ea1SDimitry Andric OS << " and "; 1111*0fca6ea1SDimitry Andric if (NumErrors) 1112*0fca6ea1SDimitry Andric OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s"); 1113*0fca6ea1SDimitry Andric if (NumWarnings || NumErrors) { 1114*0fca6ea1SDimitry Andric OS << " generated"; 1115*0fca6ea1SDimitry Andric if (getLangOpts().CUDA) { 1116*0fca6ea1SDimitry Andric if (!getLangOpts().CUDAIsDevice) { 1117*0fca6ea1SDimitry Andric OS << " when compiling for host"; 1118*0fca6ea1SDimitry Andric } else { 1119*0fca6ea1SDimitry Andric OS << " when compiling for " << getTargetOpts().CPU; 1120*0fca6ea1SDimitry Andric } 1121*0fca6ea1SDimitry Andric } 1122*0fca6ea1SDimitry Andric OS << ".\n"; 1123*0fca6ea1SDimitry Andric } 1124*0fca6ea1SDimitry Andric } 1125*0fca6ea1SDimitry Andric 1126349cc55cSDimitry Andric void CompilerInstance::LoadRequestedPlugins() { 1127349cc55cSDimitry Andric // Load any requested plugins. 1128349cc55cSDimitry Andric for (const std::string &Path : getFrontendOpts().Plugins) { 1129349cc55cSDimitry Andric std::string Error; 1130349cc55cSDimitry Andric if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error)) 1131349cc55cSDimitry Andric getDiagnostics().Report(diag::err_fe_unable_to_load_plugin) 1132349cc55cSDimitry Andric << Path << Error; 1133349cc55cSDimitry Andric } 1134349cc55cSDimitry Andric 1135349cc55cSDimitry Andric // Check if any of the loaded plugins replaces the main AST action 1136349cc55cSDimitry Andric for (const FrontendPluginRegistry::entry &Plugin : 1137349cc55cSDimitry Andric FrontendPluginRegistry::entries()) { 1138349cc55cSDimitry Andric std::unique_ptr<PluginASTAction> P(Plugin.instantiate()); 1139349cc55cSDimitry Andric if (P->getActionType() == PluginASTAction::ReplaceAction) { 1140349cc55cSDimitry Andric getFrontendOpts().ProgramAction = clang::frontend::PluginAction; 1141349cc55cSDimitry Andric getFrontendOpts().ActionName = Plugin.getName().str(); 1142349cc55cSDimitry Andric break; 1143349cc55cSDimitry Andric } 1144349cc55cSDimitry Andric } 1145349cc55cSDimitry Andric } 1146349cc55cSDimitry Andric 11470b57cec5SDimitry Andric /// Determine the appropriate source input kind based on language 11480b57cec5SDimitry Andric /// options. 1149a7dea167SDimitry Andric static Language getLanguageFromOptions(const LangOptions &LangOpts) { 11500b57cec5SDimitry Andric if (LangOpts.OpenCL) 1151a7dea167SDimitry Andric return Language::OpenCL; 11520b57cec5SDimitry Andric if (LangOpts.CUDA) 1153a7dea167SDimitry Andric return Language::CUDA; 11540b57cec5SDimitry Andric if (LangOpts.ObjC) 1155a7dea167SDimitry Andric return LangOpts.CPlusPlus ? Language::ObjCXX : Language::ObjC; 1156a7dea167SDimitry Andric return LangOpts.CPlusPlus ? Language::CXX : Language::C; 11570b57cec5SDimitry Andric } 11580b57cec5SDimitry Andric 11590b57cec5SDimitry Andric /// Compile a module file for the given module, using the options 11600b57cec5SDimitry Andric /// provided by the importing compiler instance. Returns true if the module 11610b57cec5SDimitry Andric /// was built without errors. 11620b57cec5SDimitry Andric static bool 11630b57cec5SDimitry Andric compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, 11640b57cec5SDimitry Andric StringRef ModuleName, FrontendInputFile Input, 11650b57cec5SDimitry Andric StringRef OriginalModuleMapFile, StringRef ModuleFileName, 11660b57cec5SDimitry Andric llvm::function_ref<void(CompilerInstance &)> PreBuildStep = 11670b57cec5SDimitry Andric [](CompilerInstance &) {}, 11680b57cec5SDimitry Andric llvm::function_ref<void(CompilerInstance &)> PostBuildStep = 11690b57cec5SDimitry Andric [](CompilerInstance &) {}) { 11700b57cec5SDimitry Andric llvm::TimeTraceScope TimeScope("Module Compile", ModuleName); 11710b57cec5SDimitry Andric 1172fe6060f1SDimitry Andric // Never compile a module that's already finalized - this would cause the 1173fe6060f1SDimitry Andric // existing module to be freed, causing crashes if it is later referenced 1174fe6060f1SDimitry Andric if (ImportingInstance.getModuleCache().isPCMFinal(ModuleFileName)) { 1175fe6060f1SDimitry Andric ImportingInstance.getDiagnostics().Report( 1176fe6060f1SDimitry Andric ImportLoc, diag::err_module_rebuild_finalized) 1177fe6060f1SDimitry Andric << ModuleName; 1178fe6060f1SDimitry Andric return false; 1179fe6060f1SDimitry Andric } 1180fe6060f1SDimitry Andric 11810b57cec5SDimitry Andric // Construct a compiler invocation for creating this module. 11820b57cec5SDimitry Andric auto Invocation = 11830b57cec5SDimitry Andric std::make_shared<CompilerInvocation>(ImportingInstance.getInvocation()); 11840b57cec5SDimitry Andric 11850b57cec5SDimitry Andric PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts(); 11860b57cec5SDimitry Andric 11870b57cec5SDimitry Andric // For any options that aren't intended to affect how a module is built, 11880b57cec5SDimitry Andric // reset them to their default values. 1189bdd1243dSDimitry Andric Invocation->resetNonModularOptions(); 11900b57cec5SDimitry Andric 11910b57cec5SDimitry Andric // Remove any macro definitions that are explicitly ignored by the module. 11920b57cec5SDimitry Andric // They aren't supposed to affect how the module is built anyway. 11930b57cec5SDimitry Andric HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts(); 11940eae32dcSDimitry Andric llvm::erase_if(PPOpts.Macros, 11950eae32dcSDimitry Andric [&HSOpts](const std::pair<std::string, bool> &def) { 11960b57cec5SDimitry Andric StringRef MacroDef = def.first; 11970eae32dcSDimitry Andric return HSOpts.ModulesIgnoreMacros.contains( 11980eae32dcSDimitry Andric llvm::CachedHashString(MacroDef.split('=').first)); 1199349cc55cSDimitry Andric }); 12000b57cec5SDimitry Andric 12010b57cec5SDimitry Andric // If the original compiler invocation had -fmodule-name, pass it through. 12025f757f3fSDimitry Andric Invocation->getLangOpts().ModuleName = 12035f757f3fSDimitry Andric ImportingInstance.getInvocation().getLangOpts().ModuleName; 12040b57cec5SDimitry Andric 12050b57cec5SDimitry Andric // Note the name of the module we're building. 12065f757f3fSDimitry Andric Invocation->getLangOpts().CurrentModule = std::string(ModuleName); 12070b57cec5SDimitry Andric 12080b57cec5SDimitry Andric // If there is a module map file, build the module using the module map. 12090b57cec5SDimitry Andric // Set up the inputs/outputs so that we build the module from its umbrella 12100b57cec5SDimitry Andric // header. 12110b57cec5SDimitry Andric FrontendOptions &FrontendOpts = Invocation->getFrontendOpts(); 12120b57cec5SDimitry Andric FrontendOpts.OutputFile = ModuleFileName.str(); 12130b57cec5SDimitry Andric FrontendOpts.DisableFree = false; 12140b57cec5SDimitry Andric FrontendOpts.GenerateGlobalModuleIndex = false; 12150b57cec5SDimitry Andric FrontendOpts.BuildingImplicitModule = true; 12165ffd83dbSDimitry Andric FrontendOpts.OriginalModuleMap = std::string(OriginalModuleMapFile); 12170b57cec5SDimitry Andric // Force implicitly-built modules to hash the content of the module file. 12180b57cec5SDimitry Andric HSOpts.ModulesHashContent = true; 12190b57cec5SDimitry Andric FrontendOpts.Inputs = {Input}; 12200b57cec5SDimitry Andric 12210b57cec5SDimitry Andric // Don't free the remapped file buffers; they are owned by our caller. 12220b57cec5SDimitry Andric PPOpts.RetainRemappedFileBuffers = true; 12230b57cec5SDimitry Andric 12245f757f3fSDimitry Andric DiagnosticOptions &DiagOpts = Invocation->getDiagnosticOpts(); 12255f757f3fSDimitry Andric 12265f757f3fSDimitry Andric DiagOpts.VerifyDiagnostics = 0; 12270b57cec5SDimitry Andric assert(ImportingInstance.getInvocation().getModuleHash() == 12280b57cec5SDimitry Andric Invocation->getModuleHash() && "Module hash mismatch!"); 12290b57cec5SDimitry Andric 12300b57cec5SDimitry Andric // Construct a compiler instance that will be used to actually create the 12310b57cec5SDimitry Andric // module. Since we're sharing an in-memory module cache, 12320b57cec5SDimitry Andric // CompilerInstance::CompilerInstance is responsible for finalizing the 12330b57cec5SDimitry Andric // buffers to prevent use-after-frees. 12340b57cec5SDimitry Andric CompilerInstance Instance(ImportingInstance.getPCHContainerOperations(), 12350b57cec5SDimitry Andric &ImportingInstance.getModuleCache()); 12360b57cec5SDimitry Andric auto &Inv = *Invocation; 12370b57cec5SDimitry Andric Instance.setInvocation(std::move(Invocation)); 12380b57cec5SDimitry Andric 12390b57cec5SDimitry Andric Instance.createDiagnostics(new ForwardingDiagnosticConsumer( 12400b57cec5SDimitry Andric ImportingInstance.getDiagnosticClient()), 12410b57cec5SDimitry Andric /*ShouldOwnClient=*/true); 12420b57cec5SDimitry Andric 12435f757f3fSDimitry Andric if (llvm::is_contained(DiagOpts.SystemHeaderWarningsModules, ModuleName)) 12445f757f3fSDimitry Andric Instance.getDiagnostics().setSuppressSystemWarnings(false); 12455f757f3fSDimitry Andric 1246bdd1243dSDimitry Andric if (FrontendOpts.ModulesShareFileManager) { 12470b57cec5SDimitry Andric Instance.setFileManager(&ImportingInstance.getFileManager()); 1248bdd1243dSDimitry Andric } else { 1249bdd1243dSDimitry Andric Instance.createFileManager(&ImportingInstance.getVirtualFileSystem()); 1250bdd1243dSDimitry Andric } 12510b57cec5SDimitry Andric Instance.createSourceManager(Instance.getFileManager()); 12520b57cec5SDimitry Andric SourceManager &SourceMgr = Instance.getSourceManager(); 1253bdd1243dSDimitry Andric 1254bdd1243dSDimitry Andric // Note that this module is part of the module build stack, so that we 1255bdd1243dSDimitry Andric // can detect cycles in the module graph. 12560b57cec5SDimitry Andric SourceMgr.setModuleBuildStack( 12570b57cec5SDimitry Andric ImportingInstance.getSourceManager().getModuleBuildStack()); 12580b57cec5SDimitry Andric SourceMgr.pushModuleBuildStack(ModuleName, 12590b57cec5SDimitry Andric FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager())); 12600b57cec5SDimitry Andric 1261*0fca6ea1SDimitry Andric // Make sure that the failed-module structure has been allocated in 1262*0fca6ea1SDimitry Andric // the importing instance, and propagate the pointer to the newly-created 1263*0fca6ea1SDimitry Andric // instance. 1264*0fca6ea1SDimitry Andric if (!ImportingInstance.hasFailedModulesSet()) 1265*0fca6ea1SDimitry Andric ImportingInstance.createFailedModulesSet(); 1266*0fca6ea1SDimitry Andric Instance.setFailedModulesSet(ImportingInstance.getFailedModulesSetPtr()); 1267*0fca6ea1SDimitry Andric 12680b57cec5SDimitry Andric // If we're collecting module dependencies, we need to share a collector 12690b57cec5SDimitry Andric // between all of the module CompilerInstances. Other than that, we don't 12700b57cec5SDimitry Andric // want to produce any dependency output from the module build. 12710b57cec5SDimitry Andric Instance.setModuleDepCollector(ImportingInstance.getModuleDepCollector()); 12720b57cec5SDimitry Andric Inv.getDependencyOutputOpts() = DependencyOutputOptions(); 12730b57cec5SDimitry Andric 12740b57cec5SDimitry Andric ImportingInstance.getDiagnostics().Report(ImportLoc, 12750b57cec5SDimitry Andric diag::remark_module_build) 12760b57cec5SDimitry Andric << ModuleName << ModuleFileName; 12770b57cec5SDimitry Andric 12780b57cec5SDimitry Andric PreBuildStep(Instance); 12790b57cec5SDimitry Andric 12800b57cec5SDimitry Andric // Execute the action to actually build the module in-place. Use a separate 12810b57cec5SDimitry Andric // thread so that we get a stack large enough. 1282753f127fSDimitry Andric bool Crashed = !llvm::CrashRecoveryContext().RunSafelyOnThread( 12830b57cec5SDimitry Andric [&]() { 12840b57cec5SDimitry Andric GenerateModuleFromModuleMapAction Action; 12850b57cec5SDimitry Andric Instance.ExecuteAction(Action); 12860b57cec5SDimitry Andric }, 12870b57cec5SDimitry Andric DesiredStackSize); 12880b57cec5SDimitry Andric 12890b57cec5SDimitry Andric PostBuildStep(Instance); 12900b57cec5SDimitry Andric 12910b57cec5SDimitry Andric ImportingInstance.getDiagnostics().Report(ImportLoc, 12920b57cec5SDimitry Andric diag::remark_module_build_done) 12930b57cec5SDimitry Andric << ModuleName; 12940b57cec5SDimitry Andric 1295*0fca6ea1SDimitry Andric // Propagate the statistics to the parent FileManager. 1296*0fca6ea1SDimitry Andric if (!FrontendOpts.ModulesShareFileManager) 1297*0fca6ea1SDimitry Andric ImportingInstance.getFileManager().AddStats(Instance.getFileManager()); 1298*0fca6ea1SDimitry Andric 1299753f127fSDimitry Andric if (Crashed) { 1300753f127fSDimitry Andric // Clear the ASTConsumer if it hasn't been already, in case it owns streams 1301753f127fSDimitry Andric // that must be closed before clearing output files. 1302753f127fSDimitry Andric Instance.setSema(nullptr); 1303753f127fSDimitry Andric Instance.setASTConsumer(nullptr); 1304753f127fSDimitry Andric 1305753f127fSDimitry Andric // Delete any remaining temporary files related to Instance. 13060b57cec5SDimitry Andric Instance.clearOutputFiles(/*EraseFiles=*/true); 1307753f127fSDimitry Andric } 13080b57cec5SDimitry Andric 1309fe6060f1SDimitry Andric // If \p AllowPCMWithCompilerErrors is set return 'success' even if errors 1310fe6060f1SDimitry Andric // occurred. 1311fe6060f1SDimitry Andric return !Instance.getDiagnostics().hasErrorOccurred() || 1312fe6060f1SDimitry Andric Instance.getFrontendOpts().AllowPCMWithCompilerErrors; 13130b57cec5SDimitry Andric } 13140b57cec5SDimitry Andric 1315bdd1243dSDimitry Andric static OptionalFileEntryRef getPublicModuleMap(FileEntryRef File, 13160b57cec5SDimitry Andric FileManager &FileMgr) { 1317bdd1243dSDimitry Andric StringRef Filename = llvm::sys::path::filename(File.getName()); 1318bdd1243dSDimitry Andric SmallString<128> PublicFilename(File.getDir().getName()); 13190b57cec5SDimitry Andric if (Filename == "module_private.map") 13200b57cec5SDimitry Andric llvm::sys::path::append(PublicFilename, "module.map"); 13210b57cec5SDimitry Andric else if (Filename == "module.private.modulemap") 13220b57cec5SDimitry Andric llvm::sys::path::append(PublicFilename, "module.modulemap"); 13230b57cec5SDimitry Andric else 1324bdd1243dSDimitry Andric return std::nullopt; 1325bdd1243dSDimitry Andric return FileMgr.getOptionalFileRef(PublicFilename); 13260b57cec5SDimitry Andric } 13270b57cec5SDimitry Andric 1328480093f4SDimitry Andric /// Compile a module file for the given module in a separate compiler instance, 1329480093f4SDimitry Andric /// using the options provided by the importing compiler instance. Returns true 1330480093f4SDimitry Andric /// if the module was built without errors. 1331480093f4SDimitry Andric static bool compileModule(CompilerInstance &ImportingInstance, 1332480093f4SDimitry Andric SourceLocation ImportLoc, Module *Module, 13330b57cec5SDimitry Andric StringRef ModuleFileName) { 13340b57cec5SDimitry Andric InputKind IK(getLanguageFromOptions(ImportingInstance.getLangOpts()), 13350b57cec5SDimitry Andric InputKind::ModuleMap); 13360b57cec5SDimitry Andric 13370b57cec5SDimitry Andric // Get or create the module map that we'll use to build this module. 13380b57cec5SDimitry Andric ModuleMap &ModMap 13390b57cec5SDimitry Andric = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap(); 1340*0fca6ea1SDimitry Andric SourceManager &SourceMgr = ImportingInstance.getSourceManager(); 13410b57cec5SDimitry Andric bool Result; 1342*0fca6ea1SDimitry Andric if (FileID ModuleMapFID = ModMap.getContainingModuleMapFileID(Module); 1343*0fca6ea1SDimitry Andric ModuleMapFID.isValid()) { 1344*0fca6ea1SDimitry Andric // We want to use the top-level module map. If we don't, the compiling 1345*0fca6ea1SDimitry Andric // instance may think the containing module map is a top-level one, while 1346*0fca6ea1SDimitry Andric // the importing instance knows it's included from a parent module map via 1347*0fca6ea1SDimitry Andric // the extern directive. This mismatch could bite us later. 1348*0fca6ea1SDimitry Andric SourceLocation Loc = SourceMgr.getIncludeLoc(ModuleMapFID); 1349*0fca6ea1SDimitry Andric while (Loc.isValid() && isModuleMap(SourceMgr.getFileCharacteristic(Loc))) { 1350*0fca6ea1SDimitry Andric ModuleMapFID = SourceMgr.getFileID(Loc); 1351*0fca6ea1SDimitry Andric Loc = SourceMgr.getIncludeLoc(ModuleMapFID); 1352*0fca6ea1SDimitry Andric } 1353*0fca6ea1SDimitry Andric 1354*0fca6ea1SDimitry Andric OptionalFileEntryRef ModuleMapFile = 1355*0fca6ea1SDimitry Andric SourceMgr.getFileEntryRefForID(ModuleMapFID); 1356*0fca6ea1SDimitry Andric assert(ModuleMapFile && "Top-level module map with no FileID"); 1357*0fca6ea1SDimitry Andric 13580b57cec5SDimitry Andric // Canonicalize compilation to start with the public module map. This is 13590b57cec5SDimitry Andric // vital for submodules declarations in the private module maps to be 13600b57cec5SDimitry Andric // correctly parsed when depending on a top level module in the public one. 1361bdd1243dSDimitry Andric if (OptionalFileEntryRef PublicMMFile = getPublicModuleMap( 1362bdd1243dSDimitry Andric *ModuleMapFile, ImportingInstance.getFileManager())) 13630b57cec5SDimitry Andric ModuleMapFile = PublicMMFile; 13640b57cec5SDimitry Andric 1365bdd1243dSDimitry Andric StringRef ModuleMapFilePath = ModuleMapFile->getNameAsRequested(); 1366bdd1243dSDimitry Andric 13670b57cec5SDimitry Andric // Use the module map where this module resides. 13680b57cec5SDimitry Andric Result = compileModuleImpl( 13690b57cec5SDimitry Andric ImportingInstance, ImportLoc, Module->getTopLevelModuleName(), 1370bdd1243dSDimitry Andric FrontendInputFile(ModuleMapFilePath, IK, +Module->IsSystem), 1371bdd1243dSDimitry Andric ModMap.getModuleMapFileForUniquing(Module)->getName(), ModuleFileName); 13720b57cec5SDimitry Andric } else { 13730b57cec5SDimitry Andric // FIXME: We only need to fake up an input file here as a way of 13740b57cec5SDimitry Andric // transporting the module's directory to the module map parser. We should 13750b57cec5SDimitry Andric // be able to do that more directly, and parse from a memory buffer without 13760b57cec5SDimitry Andric // inventing this file. 13770b57cec5SDimitry Andric SmallString<128> FakeModuleMapFile(Module->Directory->getName()); 13780b57cec5SDimitry Andric llvm::sys::path::append(FakeModuleMapFile, "__inferred_module.map"); 13790b57cec5SDimitry Andric 13800b57cec5SDimitry Andric std::string InferredModuleMapContent; 13810b57cec5SDimitry Andric llvm::raw_string_ostream OS(InferredModuleMapContent); 13820b57cec5SDimitry Andric Module->print(OS); 13830b57cec5SDimitry Andric OS.flush(); 13840b57cec5SDimitry Andric 13850b57cec5SDimitry Andric Result = compileModuleImpl( 13860b57cec5SDimitry Andric ImportingInstance, ImportLoc, Module->getTopLevelModuleName(), 13870b57cec5SDimitry Andric FrontendInputFile(FakeModuleMapFile, IK, +Module->IsSystem), 13880b57cec5SDimitry Andric ModMap.getModuleMapFileForUniquing(Module)->getName(), 13890b57cec5SDimitry Andric ModuleFileName, 13900b57cec5SDimitry Andric [&](CompilerInstance &Instance) { 13910b57cec5SDimitry Andric std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer = 13920b57cec5SDimitry Andric llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent); 13935f757f3fSDimitry Andric FileEntryRef ModuleMapFile = Instance.getFileManager().getVirtualFileRef( 13940b57cec5SDimitry Andric FakeModuleMapFile, InferredModuleMapContent.size(), 0); 13950b57cec5SDimitry Andric Instance.getSourceManager().overrideFileContents( 13960b57cec5SDimitry Andric ModuleMapFile, std::move(ModuleMapBuffer)); 13970b57cec5SDimitry Andric }); 13980b57cec5SDimitry Andric } 13990b57cec5SDimitry Andric 14000b57cec5SDimitry Andric // We've rebuilt a module. If we're allowed to generate or update the global 14010b57cec5SDimitry Andric // module index, record that fact in the importing compiler instance. 14020b57cec5SDimitry Andric if (ImportingInstance.getFrontendOpts().GenerateGlobalModuleIndex) { 14030b57cec5SDimitry Andric ImportingInstance.setBuildGlobalModuleIndex(true); 14040b57cec5SDimitry Andric } 14050b57cec5SDimitry Andric 14060b57cec5SDimitry Andric return Result; 14070b57cec5SDimitry Andric } 14080b57cec5SDimitry Andric 1409349cc55cSDimitry Andric /// Read the AST right after compiling the module. 1410349cc55cSDimitry Andric static bool readASTAfterCompileModule(CompilerInstance &ImportingInstance, 1411349cc55cSDimitry Andric SourceLocation ImportLoc, 1412349cc55cSDimitry Andric SourceLocation ModuleNameLoc, 1413349cc55cSDimitry Andric Module *Module, StringRef ModuleFileName, 1414349cc55cSDimitry Andric bool *OutOfDate) { 1415349cc55cSDimitry Andric DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics(); 1416349cc55cSDimitry Andric 1417349cc55cSDimitry Andric unsigned ModuleLoadCapabilities = ASTReader::ARR_Missing; 1418349cc55cSDimitry Andric if (OutOfDate) 1419349cc55cSDimitry Andric ModuleLoadCapabilities |= ASTReader::ARR_OutOfDate; 1420349cc55cSDimitry Andric 1421349cc55cSDimitry Andric // Try to read the module file, now that we've compiled it. 1422349cc55cSDimitry Andric ASTReader::ASTReadResult ReadResult = 1423349cc55cSDimitry Andric ImportingInstance.getASTReader()->ReadAST( 1424349cc55cSDimitry Andric ModuleFileName, serialization::MK_ImplicitModule, ImportLoc, 1425349cc55cSDimitry Andric ModuleLoadCapabilities); 1426349cc55cSDimitry Andric if (ReadResult == ASTReader::Success) 1427349cc55cSDimitry Andric return true; 1428349cc55cSDimitry Andric 1429349cc55cSDimitry Andric // The caller wants to handle out-of-date failures. 1430349cc55cSDimitry Andric if (OutOfDate && ReadResult == ASTReader::OutOfDate) { 1431349cc55cSDimitry Andric *OutOfDate = true; 1432349cc55cSDimitry Andric return false; 1433349cc55cSDimitry Andric } 1434349cc55cSDimitry Andric 1435349cc55cSDimitry Andric // The ASTReader didn't diagnose the error, so conservatively report it. 1436349cc55cSDimitry Andric if (ReadResult == ASTReader::Missing || !Diags.hasErrorOccurred()) 1437349cc55cSDimitry Andric Diags.Report(ModuleNameLoc, diag::err_module_not_built) 1438349cc55cSDimitry Andric << Module->Name << SourceRange(ImportLoc, ModuleNameLoc); 1439349cc55cSDimitry Andric 1440349cc55cSDimitry Andric return false; 1441349cc55cSDimitry Andric } 1442349cc55cSDimitry Andric 1443480093f4SDimitry Andric /// Compile a module in a separate compiler instance and read the AST, 1444480093f4SDimitry Andric /// returning true if the module compiles without errors. 1445349cc55cSDimitry Andric static bool compileModuleAndReadASTImpl(CompilerInstance &ImportingInstance, 1446349cc55cSDimitry Andric SourceLocation ImportLoc, 1447349cc55cSDimitry Andric SourceLocation ModuleNameLoc, 1448349cc55cSDimitry Andric Module *Module, 1449349cc55cSDimitry Andric StringRef ModuleFileName) { 1450349cc55cSDimitry Andric if (!compileModule(ImportingInstance, ModuleNameLoc, Module, 1451349cc55cSDimitry Andric ModuleFileName)) { 1452349cc55cSDimitry Andric ImportingInstance.getDiagnostics().Report(ModuleNameLoc, 1453349cc55cSDimitry Andric diag::err_module_not_built) 1454349cc55cSDimitry Andric << Module->Name << SourceRange(ImportLoc, ModuleNameLoc); 1455349cc55cSDimitry Andric return false; 1456349cc55cSDimitry Andric } 1457349cc55cSDimitry Andric 1458349cc55cSDimitry Andric return readASTAfterCompileModule(ImportingInstance, ImportLoc, ModuleNameLoc, 1459349cc55cSDimitry Andric Module, ModuleFileName, 1460349cc55cSDimitry Andric /*OutOfDate=*/nullptr); 1461349cc55cSDimitry Andric } 1462349cc55cSDimitry Andric 1463349cc55cSDimitry Andric /// Compile a module in a separate compiler instance and read the AST, 1464349cc55cSDimitry Andric /// returning true if the module compiles without errors, using a lock manager 1465349cc55cSDimitry Andric /// to avoid building the same module in multiple compiler instances. 1466480093f4SDimitry Andric /// 1467480093f4SDimitry Andric /// Uses a lock file manager and exponential backoff to reduce the chances that 1468480093f4SDimitry Andric /// multiple instances will compete to create the same module. On timeout, 1469480093f4SDimitry Andric /// deletes the lock file in order to avoid deadlock from crashing processes or 1470480093f4SDimitry Andric /// bugs in the lock file manager. 1471349cc55cSDimitry Andric static bool compileModuleAndReadASTBehindLock( 1472349cc55cSDimitry Andric CompilerInstance &ImportingInstance, SourceLocation ImportLoc, 1473349cc55cSDimitry Andric SourceLocation ModuleNameLoc, Module *Module, StringRef ModuleFileName) { 14740b57cec5SDimitry Andric DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics(); 14750b57cec5SDimitry Andric 1476349cc55cSDimitry Andric Diags.Report(ModuleNameLoc, diag::remark_module_lock) 1477349cc55cSDimitry Andric << ModuleFileName << Module->Name; 14780b57cec5SDimitry Andric 14790b57cec5SDimitry Andric // FIXME: have LockFileManager return an error_code so that we can 14800b57cec5SDimitry Andric // avoid the mkdir when the directory already exists. 14810b57cec5SDimitry Andric StringRef Dir = llvm::sys::path::parent_path(ModuleFileName); 14820b57cec5SDimitry Andric llvm::sys::fs::create_directories(Dir); 14830b57cec5SDimitry Andric 148404eeddc0SDimitry Andric while (true) { 14850b57cec5SDimitry Andric llvm::LockFileManager Locked(ModuleFileName); 14860b57cec5SDimitry Andric switch (Locked) { 14870b57cec5SDimitry Andric case llvm::LockFileManager::LFS_Error: 14880b57cec5SDimitry Andric // ModuleCache takes care of correctness and locks are only necessary for 14890b57cec5SDimitry Andric // performance. Fallback to building the module in case of any lock 14900b57cec5SDimitry Andric // related errors. 14910b57cec5SDimitry Andric Diags.Report(ModuleNameLoc, diag::remark_module_lock_failure) 14920b57cec5SDimitry Andric << Module->Name << Locked.getErrorMessage(); 14930b57cec5SDimitry Andric // Clear out any potential leftover. 14940b57cec5SDimitry Andric Locked.unsafeRemoveLockFile(); 1495bdd1243dSDimitry Andric [[fallthrough]]; 14960b57cec5SDimitry Andric case llvm::LockFileManager::LFS_Owned: 14970b57cec5SDimitry Andric // We're responsible for building the module ourselves. 1498349cc55cSDimitry Andric return compileModuleAndReadASTImpl(ImportingInstance, ImportLoc, 1499349cc55cSDimitry Andric ModuleNameLoc, Module, ModuleFileName); 15000b57cec5SDimitry Andric 15010b57cec5SDimitry Andric case llvm::LockFileManager::LFS_Shared: 1502349cc55cSDimitry Andric break; // The interesting case. 1503349cc55cSDimitry Andric } 1504349cc55cSDimitry Andric 15050b57cec5SDimitry Andric // Someone else is responsible for building the module. Wait for them to 15060b57cec5SDimitry Andric // finish. 15070b57cec5SDimitry Andric switch (Locked.waitForUnlock()) { 15080b57cec5SDimitry Andric case llvm::LockFileManager::Res_Success: 1509349cc55cSDimitry Andric break; // The interesting case. 15100b57cec5SDimitry Andric case llvm::LockFileManager::Res_OwnerDied: 15110b57cec5SDimitry Andric continue; // try again to get the lock. 15120b57cec5SDimitry Andric case llvm::LockFileManager::Res_Timeout: 15130b57cec5SDimitry Andric // Since ModuleCache takes care of correctness, we try waiting for 15140b57cec5SDimitry Andric // another process to complete the build so clang does not do it done 15150b57cec5SDimitry Andric // twice. If case of timeout, build it ourselves. 15160b57cec5SDimitry Andric Diags.Report(ModuleNameLoc, diag::remark_module_lock_timeout) 15170b57cec5SDimitry Andric << Module->Name; 15180b57cec5SDimitry Andric // Clear the lock file so that future invocations can make progress. 15190b57cec5SDimitry Andric Locked.unsafeRemoveLockFile(); 15200b57cec5SDimitry Andric continue; 15210b57cec5SDimitry Andric } 15220b57cec5SDimitry Andric 1523349cc55cSDimitry Andric // Read the module that was just written by someone else. 1524349cc55cSDimitry Andric bool OutOfDate = false; 1525349cc55cSDimitry Andric if (readASTAfterCompileModule(ImportingInstance, ImportLoc, ModuleNameLoc, 1526349cc55cSDimitry Andric Module, ModuleFileName, &OutOfDate)) 1527349cc55cSDimitry Andric return true; 1528349cc55cSDimitry Andric if (!OutOfDate) 1529349cc55cSDimitry Andric return false; 15300b57cec5SDimitry Andric 15310b57cec5SDimitry Andric // The module may be out of date in the presence of file system races, 15320b57cec5SDimitry Andric // or if one of its imports depends on header search paths that are not 15330b57cec5SDimitry Andric // consistent with this ImportingInstance. Try again... 15340b57cec5SDimitry Andric } 15350b57cec5SDimitry Andric } 1536349cc55cSDimitry Andric 1537349cc55cSDimitry Andric /// Compile a module in a separate compiler instance and read the AST, 1538349cc55cSDimitry Andric /// returning true if the module compiles without errors, potentially using a 1539349cc55cSDimitry Andric /// lock manager to avoid building the same module in multiple compiler 1540349cc55cSDimitry Andric /// instances. 1541349cc55cSDimitry Andric static bool compileModuleAndReadAST(CompilerInstance &ImportingInstance, 1542349cc55cSDimitry Andric SourceLocation ImportLoc, 1543349cc55cSDimitry Andric SourceLocation ModuleNameLoc, 1544349cc55cSDimitry Andric Module *Module, StringRef ModuleFileName) { 1545349cc55cSDimitry Andric return ImportingInstance.getInvocation() 1546349cc55cSDimitry Andric .getFrontendOpts() 1547349cc55cSDimitry Andric .BuildingImplicitModuleUsesLock 1548349cc55cSDimitry Andric ? compileModuleAndReadASTBehindLock(ImportingInstance, ImportLoc, 1549349cc55cSDimitry Andric ModuleNameLoc, Module, 1550349cc55cSDimitry Andric ModuleFileName) 1551349cc55cSDimitry Andric : compileModuleAndReadASTImpl(ImportingInstance, ImportLoc, 1552349cc55cSDimitry Andric ModuleNameLoc, Module, 1553349cc55cSDimitry Andric ModuleFileName); 15540b57cec5SDimitry Andric } 15550b57cec5SDimitry Andric 15560b57cec5SDimitry Andric /// Diagnose differences between the current definition of the given 15570b57cec5SDimitry Andric /// configuration macro and the definition provided on the command line. 15580b57cec5SDimitry Andric static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro, 15590b57cec5SDimitry Andric Module *Mod, SourceLocation ImportLoc) { 15600b57cec5SDimitry Andric IdentifierInfo *Id = PP.getIdentifierInfo(ConfigMacro); 15610b57cec5SDimitry Andric SourceManager &SourceMgr = PP.getSourceManager(); 15620b57cec5SDimitry Andric 15630b57cec5SDimitry Andric // If this identifier has never had a macro definition, then it could 15640b57cec5SDimitry Andric // not have changed. 15650b57cec5SDimitry Andric if (!Id->hadMacroDefinition()) 15660b57cec5SDimitry Andric return; 15670b57cec5SDimitry Andric auto *LatestLocalMD = PP.getLocalMacroDirectiveHistory(Id); 15680b57cec5SDimitry Andric 15690b57cec5SDimitry Andric // Find the macro definition from the command line. 15700b57cec5SDimitry Andric MacroInfo *CmdLineDefinition = nullptr; 15710b57cec5SDimitry Andric for (auto *MD = LatestLocalMD; MD; MD = MD->getPrevious()) { 15720b57cec5SDimitry Andric // We only care about the predefines buffer. 15730b57cec5SDimitry Andric FileID FID = SourceMgr.getFileID(MD->getLocation()); 15740b57cec5SDimitry Andric if (FID.isInvalid() || FID != PP.getPredefinesFileID()) 15750b57cec5SDimitry Andric continue; 15760b57cec5SDimitry Andric if (auto *DMD = dyn_cast<DefMacroDirective>(MD)) 15770b57cec5SDimitry Andric CmdLineDefinition = DMD->getMacroInfo(); 15780b57cec5SDimitry Andric break; 15790b57cec5SDimitry Andric } 15800b57cec5SDimitry Andric 15810b57cec5SDimitry Andric auto *CurrentDefinition = PP.getMacroInfo(Id); 15820b57cec5SDimitry Andric if (CurrentDefinition == CmdLineDefinition) { 15830b57cec5SDimitry Andric // Macro matches. Nothing to do. 15840b57cec5SDimitry Andric } else if (!CurrentDefinition) { 15850b57cec5SDimitry Andric // This macro was defined on the command line, then #undef'd later. 15860b57cec5SDimitry Andric // Complain. 15870b57cec5SDimitry Andric PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 15880b57cec5SDimitry Andric << true << ConfigMacro << Mod->getFullModuleName(); 15890b57cec5SDimitry Andric auto LatestDef = LatestLocalMD->getDefinition(); 15900b57cec5SDimitry Andric assert(LatestDef.isUndefined() && 15910b57cec5SDimitry Andric "predefined macro went away with no #undef?"); 15920b57cec5SDimitry Andric PP.Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here) 15930b57cec5SDimitry Andric << true; 15940b57cec5SDimitry Andric return; 15950b57cec5SDimitry Andric } else if (!CmdLineDefinition) { 15960b57cec5SDimitry Andric // There was no definition for this macro in the predefines buffer, 15970b57cec5SDimitry Andric // but there was a local definition. Complain. 15980b57cec5SDimitry Andric PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 15990b57cec5SDimitry Andric << false << ConfigMacro << Mod->getFullModuleName(); 16000b57cec5SDimitry Andric PP.Diag(CurrentDefinition->getDefinitionLoc(), 16010b57cec5SDimitry Andric diag::note_module_def_undef_here) 16020b57cec5SDimitry Andric << false; 16030b57cec5SDimitry Andric } else if (!CurrentDefinition->isIdenticalTo(*CmdLineDefinition, PP, 16040b57cec5SDimitry Andric /*Syntactically=*/true)) { 16050b57cec5SDimitry Andric // The macro definitions differ. 16060b57cec5SDimitry Andric PP.Diag(ImportLoc, diag::warn_module_config_macro_undef) 16070b57cec5SDimitry Andric << false << ConfigMacro << Mod->getFullModuleName(); 16080b57cec5SDimitry Andric PP.Diag(CurrentDefinition->getDefinitionLoc(), 16090b57cec5SDimitry Andric diag::note_module_def_undef_here) 16100b57cec5SDimitry Andric << false; 16110b57cec5SDimitry Andric } 16120b57cec5SDimitry Andric } 16130b57cec5SDimitry Andric 1614*0fca6ea1SDimitry Andric static void checkConfigMacros(Preprocessor &PP, Module *M, 1615*0fca6ea1SDimitry Andric SourceLocation ImportLoc) { 1616*0fca6ea1SDimitry Andric clang::Module *TopModule = M->getTopLevelModule(); 1617*0fca6ea1SDimitry Andric for (const StringRef ConMacro : TopModule->ConfigMacros) { 1618*0fca6ea1SDimitry Andric checkConfigMacro(PP, ConMacro, M, ImportLoc); 1619*0fca6ea1SDimitry Andric } 1620*0fca6ea1SDimitry Andric } 1621*0fca6ea1SDimitry Andric 16220b57cec5SDimitry Andric /// Write a new timestamp file with the given path. 16230b57cec5SDimitry Andric static void writeTimestampFile(StringRef TimestampFile) { 16240b57cec5SDimitry Andric std::error_code EC; 1625a7dea167SDimitry Andric llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::OF_None); 16260b57cec5SDimitry Andric } 16270b57cec5SDimitry Andric 16280b57cec5SDimitry Andric /// Prune the module cache of modules that haven't been accessed in 16290b57cec5SDimitry Andric /// a long time. 16300b57cec5SDimitry Andric static void pruneModuleCache(const HeaderSearchOptions &HSOpts) { 1631a7dea167SDimitry Andric llvm::sys::fs::file_status StatBuf; 16320b57cec5SDimitry Andric llvm::SmallString<128> TimestampFile; 16330b57cec5SDimitry Andric TimestampFile = HSOpts.ModuleCachePath; 16340b57cec5SDimitry Andric assert(!TimestampFile.empty()); 16350b57cec5SDimitry Andric llvm::sys::path::append(TimestampFile, "modules.timestamp"); 16360b57cec5SDimitry Andric 16370b57cec5SDimitry Andric // Try to stat() the timestamp file. 1638a7dea167SDimitry Andric if (std::error_code EC = llvm::sys::fs::status(TimestampFile, StatBuf)) { 16390b57cec5SDimitry Andric // If the timestamp file wasn't there, create one now. 1640a7dea167SDimitry Andric if (EC == std::errc::no_such_file_or_directory) { 16410b57cec5SDimitry Andric writeTimestampFile(TimestampFile); 16420b57cec5SDimitry Andric } 16430b57cec5SDimitry Andric return; 16440b57cec5SDimitry Andric } 16450b57cec5SDimitry Andric 16460b57cec5SDimitry Andric // Check whether the time stamp is older than our pruning interval. 16470b57cec5SDimitry Andric // If not, do nothing. 1648a7dea167SDimitry Andric time_t TimeStampModTime = 1649a7dea167SDimitry Andric llvm::sys::toTimeT(StatBuf.getLastModificationTime()); 16500b57cec5SDimitry Andric time_t CurrentTime = time(nullptr); 16510b57cec5SDimitry Andric if (CurrentTime - TimeStampModTime <= time_t(HSOpts.ModuleCachePruneInterval)) 16520b57cec5SDimitry Andric return; 16530b57cec5SDimitry Andric 16540b57cec5SDimitry Andric // Write a new timestamp file so that nobody else attempts to prune. 16550b57cec5SDimitry Andric // There is a benign race condition here, if two Clang instances happen to 16560b57cec5SDimitry Andric // notice at the same time that the timestamp is out-of-date. 16570b57cec5SDimitry Andric writeTimestampFile(TimestampFile); 16580b57cec5SDimitry Andric 16590b57cec5SDimitry Andric // Walk the entire module cache, looking for unused module files and module 16600b57cec5SDimitry Andric // indices. 16610b57cec5SDimitry Andric std::error_code EC; 16620b57cec5SDimitry Andric SmallString<128> ModuleCachePathNative; 16630b57cec5SDimitry Andric llvm::sys::path::native(HSOpts.ModuleCachePath, ModuleCachePathNative); 16640b57cec5SDimitry Andric for (llvm::sys::fs::directory_iterator Dir(ModuleCachePathNative, EC), DirEnd; 16650b57cec5SDimitry Andric Dir != DirEnd && !EC; Dir.increment(EC)) { 16660b57cec5SDimitry Andric // If we don't have a directory, there's nothing to look into. 16670b57cec5SDimitry Andric if (!llvm::sys::fs::is_directory(Dir->path())) 16680b57cec5SDimitry Andric continue; 16690b57cec5SDimitry Andric 16700b57cec5SDimitry Andric // Walk all of the files within this directory. 16710b57cec5SDimitry Andric for (llvm::sys::fs::directory_iterator File(Dir->path(), EC), FileEnd; 16720b57cec5SDimitry Andric File != FileEnd && !EC; File.increment(EC)) { 16730b57cec5SDimitry Andric // We only care about module and global module index files. 16740b57cec5SDimitry Andric StringRef Extension = llvm::sys::path::extension(File->path()); 16750b57cec5SDimitry Andric if (Extension != ".pcm" && Extension != ".timestamp" && 16760b57cec5SDimitry Andric llvm::sys::path::filename(File->path()) != "modules.idx") 16770b57cec5SDimitry Andric continue; 16780b57cec5SDimitry Andric 16790b57cec5SDimitry Andric // Look at this file. If we can't stat it, there's nothing interesting 16800b57cec5SDimitry Andric // there. 1681a7dea167SDimitry Andric if (llvm::sys::fs::status(File->path(), StatBuf)) 16820b57cec5SDimitry Andric continue; 16830b57cec5SDimitry Andric 16840b57cec5SDimitry Andric // If the file has been used recently enough, leave it there. 1685a7dea167SDimitry Andric time_t FileAccessTime = llvm::sys::toTimeT(StatBuf.getLastAccessedTime()); 16860b57cec5SDimitry Andric if (CurrentTime - FileAccessTime <= 16870b57cec5SDimitry Andric time_t(HSOpts.ModuleCachePruneAfter)) { 16880b57cec5SDimitry Andric continue; 16890b57cec5SDimitry Andric } 16900b57cec5SDimitry Andric 16910b57cec5SDimitry Andric // Remove the file. 16920b57cec5SDimitry Andric llvm::sys::fs::remove(File->path()); 16930b57cec5SDimitry Andric 16940b57cec5SDimitry Andric // Remove the timestamp file. 16950b57cec5SDimitry Andric std::string TimpestampFilename = File->path() + ".timestamp"; 16960b57cec5SDimitry Andric llvm::sys::fs::remove(TimpestampFilename); 16970b57cec5SDimitry Andric } 16980b57cec5SDimitry Andric 16990b57cec5SDimitry Andric // If we removed all of the files in the directory, remove the directory 17000b57cec5SDimitry Andric // itself. 17010b57cec5SDimitry Andric if (llvm::sys::fs::directory_iterator(Dir->path(), EC) == 17020b57cec5SDimitry Andric llvm::sys::fs::directory_iterator() && !EC) 17030b57cec5SDimitry Andric llvm::sys::fs::remove(Dir->path()); 17040b57cec5SDimitry Andric } 17050b57cec5SDimitry Andric } 17060b57cec5SDimitry Andric 1707480093f4SDimitry Andric void CompilerInstance::createASTReader() { 1708480093f4SDimitry Andric if (TheASTReader) 1709480093f4SDimitry Andric return; 1710480093f4SDimitry Andric 17110b57cec5SDimitry Andric if (!hasASTContext()) 17120b57cec5SDimitry Andric createASTContext(); 17130b57cec5SDimitry Andric 17140b57cec5SDimitry Andric // If we're implicitly building modules but not currently recursively 17150b57cec5SDimitry Andric // building a module, check whether we need to prune the module cache. 17160b57cec5SDimitry Andric if (getSourceManager().getModuleBuildStack().empty() && 17170b57cec5SDimitry Andric !getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty() && 17180b57cec5SDimitry Andric getHeaderSearchOpts().ModuleCachePruneInterval > 0 && 17190b57cec5SDimitry Andric getHeaderSearchOpts().ModuleCachePruneAfter > 0) { 17200b57cec5SDimitry Andric pruneModuleCache(getHeaderSearchOpts()); 17210b57cec5SDimitry Andric } 17220b57cec5SDimitry Andric 17230b57cec5SDimitry Andric HeaderSearchOptions &HSOpts = getHeaderSearchOpts(); 17240b57cec5SDimitry Andric std::string Sysroot = HSOpts.Sysroot; 17250b57cec5SDimitry Andric const PreprocessorOptions &PPOpts = getPreprocessorOpts(); 1726e8d8bef9SDimitry Andric const FrontendOptions &FEOpts = getFrontendOpts(); 17270b57cec5SDimitry Andric std::unique_ptr<llvm::Timer> ReadTimer; 1728e8d8bef9SDimitry Andric 17290b57cec5SDimitry Andric if (FrontendTimerGroup) 1730a7dea167SDimitry Andric ReadTimer = std::make_unique<llvm::Timer>("reading_modules", 17310b57cec5SDimitry Andric "Reading modules", 17320b57cec5SDimitry Andric *FrontendTimerGroup); 1733480093f4SDimitry Andric TheASTReader = new ASTReader( 17340b57cec5SDimitry Andric getPreprocessor(), getModuleCache(), &getASTContext(), 17350b57cec5SDimitry Andric getPCHContainerReader(), getFrontendOpts().ModuleFileExtensions, 1736e8d8bef9SDimitry Andric Sysroot.empty() ? "" : Sysroot.c_str(), 1737e8d8bef9SDimitry Andric PPOpts.DisablePCHOrModuleValidation, 1738e8d8bef9SDimitry Andric /*AllowASTWithCompilerErrors=*/FEOpts.AllowPCMWithCompilerErrors, 1739480093f4SDimitry Andric /*AllowConfigurationMismatch=*/false, HSOpts.ModulesValidateSystemHeaders, 1740a7dea167SDimitry Andric HSOpts.ValidateASTInputFilesContent, 17410b57cec5SDimitry Andric getFrontendOpts().UseGlobalModuleIndex, std::move(ReadTimer)); 17420b57cec5SDimitry Andric if (hasASTConsumer()) { 1743480093f4SDimitry Andric TheASTReader->setDeserializationListener( 17440b57cec5SDimitry Andric getASTConsumer().GetASTDeserializationListener()); 17450b57cec5SDimitry Andric getASTContext().setASTMutationListener( 17460b57cec5SDimitry Andric getASTConsumer().GetASTMutationListener()); 17470b57cec5SDimitry Andric } 1748480093f4SDimitry Andric getASTContext().setExternalSource(TheASTReader); 17490b57cec5SDimitry Andric if (hasSema()) 1750480093f4SDimitry Andric TheASTReader->InitializeSema(getSema()); 17510b57cec5SDimitry Andric if (hasASTConsumer()) 1752480093f4SDimitry Andric TheASTReader->StartTranslationUnit(&getASTConsumer()); 17530b57cec5SDimitry Andric 17540b57cec5SDimitry Andric for (auto &Listener : DependencyCollectors) 1755480093f4SDimitry Andric Listener->attachToASTReader(*TheASTReader); 17560b57cec5SDimitry Andric } 17570b57cec5SDimitry Andric 17585f757f3fSDimitry Andric bool CompilerInstance::loadModuleFile( 17595f757f3fSDimitry Andric StringRef FileName, serialization::ModuleFile *&LoadedModuleFile) { 17600b57cec5SDimitry Andric llvm::Timer Timer; 17610b57cec5SDimitry Andric if (FrontendTimerGroup) 17620b57cec5SDimitry Andric Timer.init("preloading." + FileName.str(), "Preloading " + FileName.str(), 17630b57cec5SDimitry Andric *FrontendTimerGroup); 17640b57cec5SDimitry Andric llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr); 17650b57cec5SDimitry Andric 17660b57cec5SDimitry Andric // If we don't already have an ASTReader, create one now. 1767480093f4SDimitry Andric if (!TheASTReader) 1768480093f4SDimitry Andric createASTReader(); 17690b57cec5SDimitry Andric 17700b57cec5SDimitry Andric // If -Wmodule-file-config-mismatch is mapped as an error or worse, allow the 17710b57cec5SDimitry Andric // ASTReader to diagnose it, since it can produce better errors that we can. 17720b57cec5SDimitry Andric bool ConfigMismatchIsRecoverable = 17730b57cec5SDimitry Andric getDiagnostics().getDiagnosticLevel(diag::warn_module_config_mismatch, 17740b57cec5SDimitry Andric SourceLocation()) 17750b57cec5SDimitry Andric <= DiagnosticsEngine::Warning; 17760b57cec5SDimitry Andric 1777349cc55cSDimitry Andric auto Listener = std::make_unique<ReadModuleNames>(*PP); 17780b57cec5SDimitry Andric auto &ListenerRef = *Listener; 1779480093f4SDimitry Andric ASTReader::ListenerScope ReadModuleNamesListener(*TheASTReader, 17800b57cec5SDimitry Andric std::move(Listener)); 17810b57cec5SDimitry Andric 17820b57cec5SDimitry Andric // Try to load the module file. 1783480093f4SDimitry Andric switch (TheASTReader->ReadAST( 17840b57cec5SDimitry Andric FileName, serialization::MK_ExplicitModule, SourceLocation(), 17855f757f3fSDimitry Andric ConfigMismatchIsRecoverable ? ASTReader::ARR_ConfigurationMismatch : 0, 17865f757f3fSDimitry Andric &LoadedModuleFile)) { 17870b57cec5SDimitry Andric case ASTReader::Success: 17880b57cec5SDimitry Andric // We successfully loaded the module file; remember the set of provided 17890b57cec5SDimitry Andric // modules so that we don't try to load implicit modules for them. 17900b57cec5SDimitry Andric ListenerRef.registerAll(); 17910b57cec5SDimitry Andric return true; 17920b57cec5SDimitry Andric 17930b57cec5SDimitry Andric case ASTReader::ConfigurationMismatch: 17940b57cec5SDimitry Andric // Ignore unusable module files. 17950b57cec5SDimitry Andric getDiagnostics().Report(SourceLocation(), diag::warn_module_config_mismatch) 17960b57cec5SDimitry Andric << FileName; 17970b57cec5SDimitry Andric // All modules provided by any files we tried and failed to load are now 17980b57cec5SDimitry Andric // unavailable; includes of those modules should now be handled textually. 17990b57cec5SDimitry Andric ListenerRef.markAllUnavailable(); 18000b57cec5SDimitry Andric return true; 18010b57cec5SDimitry Andric 18020b57cec5SDimitry Andric default: 18030b57cec5SDimitry Andric return false; 18040b57cec5SDimitry Andric } 18050b57cec5SDimitry Andric } 18060b57cec5SDimitry Andric 1807480093f4SDimitry Andric namespace { 18080b57cec5SDimitry Andric enum ModuleSource { 1809480093f4SDimitry Andric MS_ModuleNotFound, 1810480093f4SDimitry Andric MS_ModuleCache, 1811480093f4SDimitry Andric MS_PrebuiltModulePath, 1812480093f4SDimitry Andric MS_ModuleBuildPragma 1813480093f4SDimitry Andric }; 1814480093f4SDimitry Andric } // end namespace 1815480093f4SDimitry Andric 1816480093f4SDimitry Andric /// Select a source for loading the named module and compute the filename to 1817480093f4SDimitry Andric /// load it from. 18185ffd83dbSDimitry Andric static ModuleSource selectModuleSource( 18195ffd83dbSDimitry Andric Module *M, StringRef ModuleName, std::string &ModuleFilename, 18205ffd83dbSDimitry Andric const std::map<std::string, std::string, std::less<>> &BuiltModules, 1821480093f4SDimitry Andric HeaderSearch &HS) { 1822480093f4SDimitry Andric assert(ModuleFilename.empty() && "Already has a module source?"); 18230b57cec5SDimitry Andric 18240b57cec5SDimitry Andric // Check to see if the module has been built as part of this compilation 18250b57cec5SDimitry Andric // via a module build pragma. 18260b57cec5SDimitry Andric auto BuiltModuleIt = BuiltModules.find(ModuleName); 18270b57cec5SDimitry Andric if (BuiltModuleIt != BuiltModules.end()) { 1828480093f4SDimitry Andric ModuleFilename = BuiltModuleIt->second; 1829480093f4SDimitry Andric return MS_ModuleBuildPragma; 18300b57cec5SDimitry Andric } 18310b57cec5SDimitry Andric 18320b57cec5SDimitry Andric // Try to load the module from the prebuilt module path. 1833480093f4SDimitry Andric const HeaderSearchOptions &HSOpts = HS.getHeaderSearchOpts(); 1834480093f4SDimitry Andric if (!HSOpts.PrebuiltModuleFiles.empty() || 1835480093f4SDimitry Andric !HSOpts.PrebuiltModulePaths.empty()) { 1836480093f4SDimitry Andric ModuleFilename = HS.getPrebuiltModuleFileName(ModuleName); 1837e8d8bef9SDimitry Andric if (HSOpts.EnablePrebuiltImplicitModules && ModuleFilename.empty()) 1838e8d8bef9SDimitry Andric ModuleFilename = HS.getPrebuiltImplicitModuleFileName(M); 1839480093f4SDimitry Andric if (!ModuleFilename.empty()) 1840480093f4SDimitry Andric return MS_PrebuiltModulePath; 18410b57cec5SDimitry Andric } 18420b57cec5SDimitry Andric 18430b57cec5SDimitry Andric // Try to load the module from the module cache. 1844480093f4SDimitry Andric if (M) { 1845480093f4SDimitry Andric ModuleFilename = HS.getCachedModuleFileName(M); 1846480093f4SDimitry Andric return MS_ModuleCache; 18470b57cec5SDimitry Andric } 18480b57cec5SDimitry Andric 1849480093f4SDimitry Andric return MS_ModuleNotFound; 1850480093f4SDimitry Andric } 1851480093f4SDimitry Andric 1852480093f4SDimitry Andric ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST( 1853480093f4SDimitry Andric StringRef ModuleName, SourceLocation ImportLoc, 1854480093f4SDimitry Andric SourceLocation ModuleNameLoc, bool IsInclusionDirective) { 1855480093f4SDimitry Andric // Search for a module with the given name. 1856480093f4SDimitry Andric HeaderSearch &HS = PP->getHeaderSearchInfo(); 1857349cc55cSDimitry Andric Module *M = 1858349cc55cSDimitry Andric HS.lookupModule(ModuleName, ImportLoc, true, !IsInclusionDirective); 1859480093f4SDimitry Andric 1860*0fca6ea1SDimitry Andric // Check for any configuration macros that have changed. This is done 1861*0fca6ea1SDimitry Andric // immediately before potentially building a module in case this module 1862*0fca6ea1SDimitry Andric // depends on having one of its configuration macros defined to successfully 1863*0fca6ea1SDimitry Andric // build. If this is not done the user will never see the warning. 1864*0fca6ea1SDimitry Andric if (M) 1865*0fca6ea1SDimitry Andric checkConfigMacros(getPreprocessor(), M, ImportLoc); 1866*0fca6ea1SDimitry Andric 1867480093f4SDimitry Andric // Select the source and filename for loading the named module. 1868480093f4SDimitry Andric std::string ModuleFilename; 1869480093f4SDimitry Andric ModuleSource Source = 1870480093f4SDimitry Andric selectModuleSource(M, ModuleName, ModuleFilename, BuiltModules, HS); 1871480093f4SDimitry Andric if (Source == MS_ModuleNotFound) { 18720b57cec5SDimitry Andric // We can't find a module, error out here. 18730b57cec5SDimitry Andric getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found) 18740b57cec5SDimitry Andric << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); 1875fe6060f1SDimitry Andric return nullptr; 18760b57cec5SDimitry Andric } 1877480093f4SDimitry Andric if (ModuleFilename.empty()) { 1878480093f4SDimitry Andric if (M && M->HasIncompatibleModuleFile) { 18790b57cec5SDimitry Andric // We tried and failed to load a module file for this module. Fall 18800b57cec5SDimitry Andric // back to textual inclusion for its headers. 18810b57cec5SDimitry Andric return ModuleLoadResult::ConfigMismatch; 18820b57cec5SDimitry Andric } 18830b57cec5SDimitry Andric 18840b57cec5SDimitry Andric getDiagnostics().Report(ModuleNameLoc, diag::err_module_build_disabled) 18850b57cec5SDimitry Andric << ModuleName; 1886fe6060f1SDimitry Andric return nullptr; 18870b57cec5SDimitry Andric } 18880b57cec5SDimitry Andric 1889480093f4SDimitry Andric // Create an ASTReader on demand. 1890480093f4SDimitry Andric if (!getASTReader()) 1891480093f4SDimitry Andric createASTReader(); 18920b57cec5SDimitry Andric 1893480093f4SDimitry Andric // Time how long it takes to load the module. 18940b57cec5SDimitry Andric llvm::Timer Timer; 18950b57cec5SDimitry Andric if (FrontendTimerGroup) 1896480093f4SDimitry Andric Timer.init("loading." + ModuleFilename, "Loading " + ModuleFilename, 18970b57cec5SDimitry Andric *FrontendTimerGroup); 18980b57cec5SDimitry Andric llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr); 18990b57cec5SDimitry Andric llvm::TimeTraceScope TimeScope("Module Load", ModuleName); 19000b57cec5SDimitry Andric 19010b57cec5SDimitry Andric // Try to load the module file. If we are not trying to load from the 19020b57cec5SDimitry Andric // module cache, we don't know how to rebuild modules. 1903480093f4SDimitry Andric unsigned ARRFlags = Source == MS_ModuleCache 1904fe6060f1SDimitry Andric ? ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing | 1905fe6060f1SDimitry Andric ASTReader::ARR_TreatModuleWithErrorsAsOutOfDate 1906480093f4SDimitry Andric : Source == MS_PrebuiltModulePath 1907480093f4SDimitry Andric ? 0 1908480093f4SDimitry Andric : ASTReader::ARR_ConfigurationMismatch; 1909480093f4SDimitry Andric switch (getASTReader()->ReadAST(ModuleFilename, 1910480093f4SDimitry Andric Source == MS_PrebuiltModulePath 19110b57cec5SDimitry Andric ? serialization::MK_PrebuiltModule 1912480093f4SDimitry Andric : Source == MS_ModuleBuildPragma 19130b57cec5SDimitry Andric ? serialization::MK_ExplicitModule 19140b57cec5SDimitry Andric : serialization::MK_ImplicitModule, 19150b57cec5SDimitry Andric ImportLoc, ARRFlags)) { 19160b57cec5SDimitry Andric case ASTReader::Success: { 1917480093f4SDimitry Andric if (M) 1918480093f4SDimitry Andric return M; 1919480093f4SDimitry Andric assert(Source != MS_ModuleCache && 1920480093f4SDimitry Andric "missing module, but file loaded from cache"); 1921480093f4SDimitry Andric 1922480093f4SDimitry Andric // A prebuilt module is indexed as a ModuleFile; the Module does not exist 1923480093f4SDimitry Andric // until the first call to ReadAST. Look it up now. 1924349cc55cSDimitry Andric M = HS.lookupModule(ModuleName, ImportLoc, true, !IsInclusionDirective); 1925480093f4SDimitry Andric 1926480093f4SDimitry Andric // Check whether M refers to the file in the prebuilt module path. 1927480093f4SDimitry Andric if (M && M->getASTFile()) 1928480093f4SDimitry Andric if (auto ModuleFile = FileMgr->getFile(ModuleFilename)) 1929480093f4SDimitry Andric if (*ModuleFile == M->getASTFile()) 1930480093f4SDimitry Andric return M; 1931480093f4SDimitry Andric 19320b57cec5SDimitry Andric getDiagnostics().Report(ModuleNameLoc, diag::err_module_prebuilt) 19330b57cec5SDimitry Andric << ModuleName; 19340b57cec5SDimitry Andric return ModuleLoadResult(); 19350b57cec5SDimitry Andric } 19360b57cec5SDimitry Andric 19370b57cec5SDimitry Andric case ASTReader::OutOfDate: 1938480093f4SDimitry Andric case ASTReader::Missing: 1939480093f4SDimitry Andric // The most interesting case. 1940480093f4SDimitry Andric break; 1941480093f4SDimitry Andric 1942480093f4SDimitry Andric case ASTReader::ConfigurationMismatch: 1943480093f4SDimitry Andric if (Source == MS_PrebuiltModulePath) 1944480093f4SDimitry Andric // FIXME: We shouldn't be setting HadFatalFailure below if we only 1945480093f4SDimitry Andric // produce a warning here! 1946480093f4SDimitry Andric getDiagnostics().Report(SourceLocation(), 1947480093f4SDimitry Andric diag::warn_module_config_mismatch) 1948480093f4SDimitry Andric << ModuleFilename; 1949480093f4SDimitry Andric // Fall through to error out. 1950bdd1243dSDimitry Andric [[fallthrough]]; 1951480093f4SDimitry Andric case ASTReader::VersionMismatch: 1952480093f4SDimitry Andric case ASTReader::HadErrors: 1953480093f4SDimitry Andric ModuleLoader::HadFatalFailure = true; 1954480093f4SDimitry Andric // FIXME: The ASTReader will already have complained, but can we shoehorn 1955480093f4SDimitry Andric // that diagnostic information into a more useful form? 1956480093f4SDimitry Andric return ModuleLoadResult(); 1957480093f4SDimitry Andric 1958480093f4SDimitry Andric case ASTReader::Failure: 1959480093f4SDimitry Andric ModuleLoader::HadFatalFailure = true; 1960480093f4SDimitry Andric return ModuleLoadResult(); 1961480093f4SDimitry Andric } 1962480093f4SDimitry Andric 1963480093f4SDimitry Andric // ReadAST returned Missing or OutOfDate. 1964480093f4SDimitry Andric if (Source != MS_ModuleCache) { 19650b57cec5SDimitry Andric // We don't know the desired configuration for this module and don't 19660b57cec5SDimitry Andric // necessarily even have a module map. Since ReadAST already produces 19670b57cec5SDimitry Andric // diagnostics for these two cases, we simply error out here. 19680b57cec5SDimitry Andric return ModuleLoadResult(); 19690b57cec5SDimitry Andric } 19700b57cec5SDimitry Andric 19710b57cec5SDimitry Andric // The module file is missing or out-of-date. Build it. 1972480093f4SDimitry Andric assert(M && "missing module, but trying to compile for cache"); 1973480093f4SDimitry Andric 19740b57cec5SDimitry Andric // Check whether there is a cycle in the module graph. 19750b57cec5SDimitry Andric ModuleBuildStack ModPath = getSourceManager().getModuleBuildStack(); 19760b57cec5SDimitry Andric ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end(); 19770b57cec5SDimitry Andric for (; Pos != PosEnd; ++Pos) { 19780b57cec5SDimitry Andric if (Pos->first == ModuleName) 19790b57cec5SDimitry Andric break; 19800b57cec5SDimitry Andric } 19810b57cec5SDimitry Andric 19820b57cec5SDimitry Andric if (Pos != PosEnd) { 19830b57cec5SDimitry Andric SmallString<256> CyclePath; 19840b57cec5SDimitry Andric for (; Pos != PosEnd; ++Pos) { 19850b57cec5SDimitry Andric CyclePath += Pos->first; 19860b57cec5SDimitry Andric CyclePath += " -> "; 19870b57cec5SDimitry Andric } 19880b57cec5SDimitry Andric CyclePath += ModuleName; 19890b57cec5SDimitry Andric 19900b57cec5SDimitry Andric getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle) 19910b57cec5SDimitry Andric << ModuleName << CyclePath; 1992fe6060f1SDimitry Andric return nullptr; 19930b57cec5SDimitry Andric } 19940b57cec5SDimitry Andric 1995*0fca6ea1SDimitry Andric // Check whether we have already attempted to build this module (but failed). 1996*0fca6ea1SDimitry Andric if (FailedModules && FailedModules->hasAlreadyFailed(ModuleName)) { 19970b57cec5SDimitry Andric getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built) 1998480093f4SDimitry Andric << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); 1999fe6060f1SDimitry Andric return nullptr; 20000b57cec5SDimitry Andric } 20010b57cec5SDimitry Andric 2002480093f4SDimitry Andric // Try to compile and then read the AST. 2003480093f4SDimitry Andric if (!compileModuleAndReadAST(*this, ImportLoc, ModuleNameLoc, M, 2004480093f4SDimitry Andric ModuleFilename)) { 20050b57cec5SDimitry Andric assert(getDiagnostics().hasErrorOccurred() && 2006480093f4SDimitry Andric "undiagnosed error in compileModuleAndReadAST"); 2007*0fca6ea1SDimitry Andric if (FailedModules) 2008*0fca6ea1SDimitry Andric FailedModules->addFailed(ModuleName); 2009fe6060f1SDimitry Andric return nullptr; 20100b57cec5SDimitry Andric } 20110b57cec5SDimitry Andric 20120b57cec5SDimitry Andric // Okay, we've rebuilt and now loaded the module. 2013480093f4SDimitry Andric return M; 20140b57cec5SDimitry Andric } 20150b57cec5SDimitry Andric 2016480093f4SDimitry Andric ModuleLoadResult 2017480093f4SDimitry Andric CompilerInstance::loadModule(SourceLocation ImportLoc, 2018480093f4SDimitry Andric ModuleIdPath Path, 2019480093f4SDimitry Andric Module::NameVisibilityKind Visibility, 2020480093f4SDimitry Andric bool IsInclusionDirective) { 2021480093f4SDimitry Andric // Determine what file we're searching from. 2022480093f4SDimitry Andric StringRef ModuleName = Path[0].first->getName(); 2023480093f4SDimitry Andric SourceLocation ModuleNameLoc = Path[0].second; 20240b57cec5SDimitry Andric 2025480093f4SDimitry Andric // If we've already handled this import, just return the cached result. 2026480093f4SDimitry Andric // This one-element cache is important to eliminate redundant diagnostics 2027480093f4SDimitry Andric // when both the preprocessor and parser see the same import declaration. 2028480093f4SDimitry Andric if (ImportLoc.isValid() && LastModuleImportLoc == ImportLoc) { 2029480093f4SDimitry Andric // Make the named module visible. 2030480093f4SDimitry Andric if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule) 2031480093f4SDimitry Andric TheASTReader->makeModuleVisible(LastModuleImportResult, Visibility, 2032480093f4SDimitry Andric ImportLoc); 2033480093f4SDimitry Andric return LastModuleImportResult; 20340b57cec5SDimitry Andric } 20350b57cec5SDimitry Andric 2036480093f4SDimitry Andric // If we don't already have information on this module, load the module now. 2037480093f4SDimitry Andric Module *Module = nullptr; 2038480093f4SDimitry Andric ModuleMap &MM = getPreprocessor().getHeaderSearchInfo().getModuleMap(); 2039480093f4SDimitry Andric if (auto MaybeModule = MM.getCachedModuleLoad(*Path[0].first)) { 2040480093f4SDimitry Andric // Use the cached result, which may be nullptr. 2041480093f4SDimitry Andric Module = *MaybeModule; 2042*0fca6ea1SDimitry Andric // Config macros are already checked before building a module, but they need 2043*0fca6ea1SDimitry Andric // to be checked at each import location in case any of the config macros 2044*0fca6ea1SDimitry Andric // have a new value at the current `ImportLoc`. 2045*0fca6ea1SDimitry Andric if (Module) 2046*0fca6ea1SDimitry Andric checkConfigMacros(getPreprocessor(), Module, ImportLoc); 2047480093f4SDimitry Andric } else if (ModuleName == getLangOpts().CurrentModule) { 2048480093f4SDimitry Andric // This is the module we're building. 2049480093f4SDimitry Andric Module = PP->getHeaderSearchInfo().lookupModule( 2050349cc55cSDimitry Andric ModuleName, ImportLoc, /*AllowSearch*/ true, 2051480093f4SDimitry Andric /*AllowExtraModuleMapSearch*/ !IsInclusionDirective); 20521ac55f4cSDimitry Andric 2053*0fca6ea1SDimitry Andric // Config macros do not need to be checked here for two reasons. 2054*0fca6ea1SDimitry Andric // * This will always be textual inclusion, and thus the config macros 2055*0fca6ea1SDimitry Andric // actually do impact the content of the header. 2056*0fca6ea1SDimitry Andric // * `Preprocessor::HandleHeaderIncludeOrImport` will never call this 2057*0fca6ea1SDimitry Andric // function as the `#include` or `#import` is textual. 2058*0fca6ea1SDimitry Andric 2059480093f4SDimitry Andric MM.cacheModuleLoad(*Path[0].first, Module); 2060480093f4SDimitry Andric } else { 2061480093f4SDimitry Andric ModuleLoadResult Result = findOrCompileModuleAndReadAST( 2062480093f4SDimitry Andric ModuleName, ImportLoc, ModuleNameLoc, IsInclusionDirective); 2063480093f4SDimitry Andric if (!Result.isNormal()) 2064480093f4SDimitry Andric return Result; 2065fe6060f1SDimitry Andric if (!Result) 2066fe6060f1SDimitry Andric DisableGeneratingGlobalModuleIndex = true; 2067480093f4SDimitry Andric Module = Result; 2068480093f4SDimitry Andric MM.cacheModuleLoad(*Path[0].first, Module); 20690b57cec5SDimitry Andric } 20700b57cec5SDimitry Andric 2071480093f4SDimitry Andric // If we never found the module, fail. Otherwise, verify the module and link 2072480093f4SDimitry Andric // it up. 20730b57cec5SDimitry Andric if (!Module) 20740b57cec5SDimitry Andric return ModuleLoadResult(); 20750b57cec5SDimitry Andric 20760b57cec5SDimitry Andric // Verify that the rest of the module path actually corresponds to 20770b57cec5SDimitry Andric // a submodule. 20780b57cec5SDimitry Andric bool MapPrivateSubModToTopLevel = false; 20790b57cec5SDimitry Andric for (unsigned I = 1, N = Path.size(); I != N; ++I) { 20800b57cec5SDimitry Andric StringRef Name = Path[I].first->getName(); 20810b57cec5SDimitry Andric clang::Module *Sub = Module->findSubmodule(Name); 20820b57cec5SDimitry Andric 20830b57cec5SDimitry Andric // If the user is requesting Foo.Private and it doesn't exist, try to 20840b57cec5SDimitry Andric // match Foo_Private and emit a warning asking for the user to write 20850b57cec5SDimitry Andric // @import Foo_Private instead. FIXME: remove this when existing clients 20860b57cec5SDimitry Andric // migrate off of Foo.Private syntax. 2087bdd1243dSDimitry Andric if (!Sub && Name == "Private" && Module == Module->getTopLevelModule()) { 20880b57cec5SDimitry Andric SmallString<128> PrivateModule(Module->Name); 20890b57cec5SDimitry Andric PrivateModule.append("_Private"); 20900b57cec5SDimitry Andric 20910b57cec5SDimitry Andric SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> PrivPath; 20920b57cec5SDimitry Andric auto &II = PP->getIdentifierTable().get( 20930b57cec5SDimitry Andric PrivateModule, PP->getIdentifierInfo(Module->Name)->getTokenID()); 20940b57cec5SDimitry Andric PrivPath.push_back(std::make_pair(&II, Path[0].second)); 20950b57cec5SDimitry Andric 209606c3fb27SDimitry Andric std::string FileName; 209706c3fb27SDimitry Andric // If there is a modulemap module or prebuilt module, load it. 2098349cc55cSDimitry Andric if (PP->getHeaderSearchInfo().lookupModule(PrivateModule, ImportLoc, true, 209906c3fb27SDimitry Andric !IsInclusionDirective) || 210006c3fb27SDimitry Andric selectModuleSource(nullptr, PrivateModule, FileName, BuiltModules, 210106c3fb27SDimitry Andric PP->getHeaderSearchInfo()) != MS_ModuleNotFound) 2102349cc55cSDimitry Andric Sub = loadModule(ImportLoc, PrivPath, Visibility, IsInclusionDirective); 21030b57cec5SDimitry Andric if (Sub) { 21040b57cec5SDimitry Andric MapPrivateSubModToTopLevel = true; 2105bdd1243dSDimitry Andric PP->markClangModuleAsAffecting(Module); 21060b57cec5SDimitry Andric if (!getDiagnostics().isIgnored( 21070b57cec5SDimitry Andric diag::warn_no_priv_submodule_use_toplevel, ImportLoc)) { 21080b57cec5SDimitry Andric getDiagnostics().Report(Path[I].second, 21090b57cec5SDimitry Andric diag::warn_no_priv_submodule_use_toplevel) 21100b57cec5SDimitry Andric << Path[I].first << Module->getFullModuleName() << PrivateModule 21110b57cec5SDimitry Andric << SourceRange(Path[0].second, Path[I].second) 21120b57cec5SDimitry Andric << FixItHint::CreateReplacement(SourceRange(Path[0].second), 21130b57cec5SDimitry Andric PrivateModule); 21140b57cec5SDimitry Andric getDiagnostics().Report(Sub->DefinitionLoc, 21150b57cec5SDimitry Andric diag::note_private_top_level_defined); 21160b57cec5SDimitry Andric } 21170b57cec5SDimitry Andric } 21180b57cec5SDimitry Andric } 21190b57cec5SDimitry Andric 21200b57cec5SDimitry Andric if (!Sub) { 21210b57cec5SDimitry Andric // Attempt to perform typo correction to find a module name that works. 21220b57cec5SDimitry Andric SmallVector<StringRef, 2> Best; 21230b57cec5SDimitry Andric unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)(); 21240b57cec5SDimitry Andric 2125349cc55cSDimitry Andric for (class Module *SubModule : Module->submodules()) { 2126349cc55cSDimitry Andric unsigned ED = 2127349cc55cSDimitry Andric Name.edit_distance(SubModule->Name, 2128349cc55cSDimitry Andric /*AllowReplacements=*/true, BestEditDistance); 21290b57cec5SDimitry Andric if (ED <= BestEditDistance) { 21300b57cec5SDimitry Andric if (ED < BestEditDistance) { 21310b57cec5SDimitry Andric Best.clear(); 21320b57cec5SDimitry Andric BestEditDistance = ED; 21330b57cec5SDimitry Andric } 21340b57cec5SDimitry Andric 2135349cc55cSDimitry Andric Best.push_back(SubModule->Name); 21360b57cec5SDimitry Andric } 21370b57cec5SDimitry Andric } 21380b57cec5SDimitry Andric 21390b57cec5SDimitry Andric // If there was a clear winner, user it. 21400b57cec5SDimitry Andric if (Best.size() == 1) { 2141349cc55cSDimitry Andric getDiagnostics().Report(Path[I].second, diag::err_no_submodule_suggest) 21420b57cec5SDimitry Andric << Path[I].first << Module->getFullModuleName() << Best[0] 21430b57cec5SDimitry Andric << SourceRange(Path[0].second, Path[I - 1].second) 21440b57cec5SDimitry Andric << FixItHint::CreateReplacement(SourceRange(Path[I].second), 21450b57cec5SDimitry Andric Best[0]); 21460b57cec5SDimitry Andric 21470b57cec5SDimitry Andric Sub = Module->findSubmodule(Best[0]); 21480b57cec5SDimitry Andric } 21490b57cec5SDimitry Andric } 21500b57cec5SDimitry Andric 21510b57cec5SDimitry Andric if (!Sub) { 21520b57cec5SDimitry Andric // No submodule by this name. Complain, and don't look for further 21530b57cec5SDimitry Andric // submodules. 21540b57cec5SDimitry Andric getDiagnostics().Report(Path[I].second, diag::err_no_submodule) 21550b57cec5SDimitry Andric << Path[I].first << Module->getFullModuleName() 21560b57cec5SDimitry Andric << SourceRange(Path[0].second, Path[I - 1].second); 21570b57cec5SDimitry Andric break; 21580b57cec5SDimitry Andric } 21590b57cec5SDimitry Andric 21600b57cec5SDimitry Andric Module = Sub; 21610b57cec5SDimitry Andric } 21620b57cec5SDimitry Andric 21630b57cec5SDimitry Andric // Make the named module visible, if it's not already part of the module 21640b57cec5SDimitry Andric // we are parsing. 21650b57cec5SDimitry Andric if (ModuleName != getLangOpts().CurrentModule) { 21660b57cec5SDimitry Andric if (!Module->IsFromModuleFile && !MapPrivateSubModToTopLevel) { 21670b57cec5SDimitry Andric // We have an umbrella header or directory that doesn't actually include 21680b57cec5SDimitry Andric // all of the headers within the directory it covers. Complain about 21690b57cec5SDimitry Andric // this missing submodule and recover by forgetting that we ever saw 21700b57cec5SDimitry Andric // this submodule. 21710b57cec5SDimitry Andric // FIXME: Should we detect this at module load time? It seems fairly 21720b57cec5SDimitry Andric // expensive (and rare). 21730b57cec5SDimitry Andric getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule) 21740b57cec5SDimitry Andric << Module->getFullModuleName() 21750b57cec5SDimitry Andric << SourceRange(Path.front().second, Path.back().second); 21760b57cec5SDimitry Andric 2177bdd1243dSDimitry Andric return ModuleLoadResult(Module, ModuleLoadResult::MissingExpected); 21780b57cec5SDimitry Andric } 21790b57cec5SDimitry Andric 21800b57cec5SDimitry Andric // Check whether this module is available. 21810b57cec5SDimitry Andric if (Preprocessor::checkModuleIsAvailable(getLangOpts(), getTarget(), 21825f757f3fSDimitry Andric *Module, getDiagnostics())) { 21830b57cec5SDimitry Andric getDiagnostics().Report(ImportLoc, diag::note_module_import_here) 21840b57cec5SDimitry Andric << SourceRange(Path.front().second, Path.back().second); 21850b57cec5SDimitry Andric LastModuleImportLoc = ImportLoc; 21860b57cec5SDimitry Andric LastModuleImportResult = ModuleLoadResult(); 21870b57cec5SDimitry Andric return ModuleLoadResult(); 21880b57cec5SDimitry Andric } 21890b57cec5SDimitry Andric 2190480093f4SDimitry Andric TheASTReader->makeModuleVisible(Module, Visibility, ImportLoc); 21910b57cec5SDimitry Andric } 21920b57cec5SDimitry Andric 21930b57cec5SDimitry Andric // Resolve any remaining module using export_as for this one. 21940b57cec5SDimitry Andric getPreprocessor() 21950b57cec5SDimitry Andric .getHeaderSearchInfo() 21960b57cec5SDimitry Andric .getModuleMap() 2197*0fca6ea1SDimitry Andric .resolveLinkAsDependencies(Module->getTopLevelModule()); 21980b57cec5SDimitry Andric 21990b57cec5SDimitry Andric LastModuleImportLoc = ImportLoc; 22000b57cec5SDimitry Andric LastModuleImportResult = ModuleLoadResult(Module); 22010b57cec5SDimitry Andric return LastModuleImportResult; 22020b57cec5SDimitry Andric } 22030b57cec5SDimitry Andric 2204480093f4SDimitry Andric void CompilerInstance::createModuleFromSource(SourceLocation ImportLoc, 22050b57cec5SDimitry Andric StringRef ModuleName, 22060b57cec5SDimitry Andric StringRef Source) { 22070b57cec5SDimitry Andric // Avoid creating filenames with special characters. 22080b57cec5SDimitry Andric SmallString<128> CleanModuleName(ModuleName); 22090b57cec5SDimitry Andric for (auto &C : CleanModuleName) 22100b57cec5SDimitry Andric if (!isAlphanumeric(C)) 22110b57cec5SDimitry Andric C = '_'; 22120b57cec5SDimitry Andric 22130b57cec5SDimitry Andric // FIXME: Using a randomized filename here means that our intermediate .pcm 22140b57cec5SDimitry Andric // output is nondeterministic (as .pcm files refer to each other by name). 22150b57cec5SDimitry Andric // Can this affect the output in any way? 22160b57cec5SDimitry Andric SmallString<128> ModuleFileName; 22170b57cec5SDimitry Andric if (std::error_code EC = llvm::sys::fs::createTemporaryFile( 22180b57cec5SDimitry Andric CleanModuleName, "pcm", ModuleFileName)) { 22190b57cec5SDimitry Andric getDiagnostics().Report(ImportLoc, diag::err_fe_unable_to_open_output) 22200b57cec5SDimitry Andric << ModuleFileName << EC.message(); 22210b57cec5SDimitry Andric return; 22220b57cec5SDimitry Andric } 22230b57cec5SDimitry Andric std::string ModuleMapFileName = (CleanModuleName + ".map").str(); 22240b57cec5SDimitry Andric 22250b57cec5SDimitry Andric FrontendInputFile Input( 22260b57cec5SDimitry Andric ModuleMapFileName, 22275f757f3fSDimitry Andric InputKind(getLanguageFromOptions(Invocation->getLangOpts()), 22280b57cec5SDimitry Andric InputKind::ModuleMap, /*Preprocessed*/true)); 22290b57cec5SDimitry Andric 22300b57cec5SDimitry Andric std::string NullTerminatedSource(Source.str()); 22310b57cec5SDimitry Andric 22320b57cec5SDimitry Andric auto PreBuildStep = [&](CompilerInstance &Other) { 22330b57cec5SDimitry Andric // Create a virtual file containing our desired source. 22340b57cec5SDimitry Andric // FIXME: We shouldn't need to do this. 22355f757f3fSDimitry Andric FileEntryRef ModuleMapFile = Other.getFileManager().getVirtualFileRef( 22360b57cec5SDimitry Andric ModuleMapFileName, NullTerminatedSource.size(), 0); 22370b57cec5SDimitry Andric Other.getSourceManager().overrideFileContents( 2238349cc55cSDimitry Andric ModuleMapFile, llvm::MemoryBuffer::getMemBuffer(NullTerminatedSource)); 22390b57cec5SDimitry Andric 22400b57cec5SDimitry Andric Other.BuiltModules = std::move(BuiltModules); 22410b57cec5SDimitry Andric Other.DeleteBuiltModules = false; 22420b57cec5SDimitry Andric }; 22430b57cec5SDimitry Andric 22440b57cec5SDimitry Andric auto PostBuildStep = [this](CompilerInstance &Other) { 22450b57cec5SDimitry Andric BuiltModules = std::move(Other.BuiltModules); 22460b57cec5SDimitry Andric }; 22470b57cec5SDimitry Andric 22480b57cec5SDimitry Andric // Build the module, inheriting any modules that we've built locally. 22490b57cec5SDimitry Andric if (compileModuleImpl(*this, ImportLoc, ModuleName, Input, StringRef(), 22500b57cec5SDimitry Andric ModuleFileName, PreBuildStep, PostBuildStep)) { 22517a6dacacSDimitry Andric BuiltModules[std::string(ModuleName)] = std::string(ModuleFileName); 22520b57cec5SDimitry Andric llvm::sys::RemoveFileOnSignal(ModuleFileName); 22530b57cec5SDimitry Andric } 22540b57cec5SDimitry Andric } 22550b57cec5SDimitry Andric 22560b57cec5SDimitry Andric void CompilerInstance::makeModuleVisible(Module *Mod, 22570b57cec5SDimitry Andric Module::NameVisibilityKind Visibility, 22580b57cec5SDimitry Andric SourceLocation ImportLoc) { 2259480093f4SDimitry Andric if (!TheASTReader) 2260480093f4SDimitry Andric createASTReader(); 2261480093f4SDimitry Andric if (!TheASTReader) 22620b57cec5SDimitry Andric return; 22630b57cec5SDimitry Andric 2264480093f4SDimitry Andric TheASTReader->makeModuleVisible(Mod, Visibility, ImportLoc); 22650b57cec5SDimitry Andric } 22660b57cec5SDimitry Andric 22670b57cec5SDimitry Andric GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex( 22680b57cec5SDimitry Andric SourceLocation TriggerLoc) { 22690b57cec5SDimitry Andric if (getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty()) 22700b57cec5SDimitry Andric return nullptr; 2271480093f4SDimitry Andric if (!TheASTReader) 2272480093f4SDimitry Andric createASTReader(); 22730b57cec5SDimitry Andric // Can't do anything if we don't have the module manager. 2274480093f4SDimitry Andric if (!TheASTReader) 22750b57cec5SDimitry Andric return nullptr; 22760b57cec5SDimitry Andric // Get an existing global index. This loads it if not already 22770b57cec5SDimitry Andric // loaded. 2278480093f4SDimitry Andric TheASTReader->loadGlobalIndex(); 2279480093f4SDimitry Andric GlobalModuleIndex *GlobalIndex = TheASTReader->getGlobalIndex(); 22800b57cec5SDimitry Andric // If the global index doesn't exist, create it. 22810b57cec5SDimitry Andric if (!GlobalIndex && shouldBuildGlobalModuleIndex() && hasFileManager() && 22820b57cec5SDimitry Andric hasPreprocessor()) { 22830b57cec5SDimitry Andric llvm::sys::fs::create_directories( 22840b57cec5SDimitry Andric getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); 22850b57cec5SDimitry Andric if (llvm::Error Err = GlobalModuleIndex::writeIndex( 22860b57cec5SDimitry Andric getFileManager(), getPCHContainerReader(), 22870b57cec5SDimitry Andric getPreprocessor().getHeaderSearchInfo().getModuleCachePath())) { 22880b57cec5SDimitry Andric // FIXME this drops the error on the floor. This code is only used for 22890b57cec5SDimitry Andric // typo correction and drops more than just this one source of errors 22900b57cec5SDimitry Andric // (such as the directory creation failure above). It should handle the 22910b57cec5SDimitry Andric // error. 22920b57cec5SDimitry Andric consumeError(std::move(Err)); 22930b57cec5SDimitry Andric return nullptr; 22940b57cec5SDimitry Andric } 2295480093f4SDimitry Andric TheASTReader->resetForReload(); 2296480093f4SDimitry Andric TheASTReader->loadGlobalIndex(); 2297480093f4SDimitry Andric GlobalIndex = TheASTReader->getGlobalIndex(); 22980b57cec5SDimitry Andric } 22990b57cec5SDimitry Andric // For finding modules needing to be imported for fixit messages, 23000b57cec5SDimitry Andric // we need to make the global index cover all modules, so we do that here. 23010b57cec5SDimitry Andric if (!HaveFullGlobalModuleIndex && GlobalIndex && !buildingModule()) { 23020b57cec5SDimitry Andric ModuleMap &MMap = getPreprocessor().getHeaderSearchInfo().getModuleMap(); 23030b57cec5SDimitry Andric bool RecreateIndex = false; 23040b57cec5SDimitry Andric for (ModuleMap::module_iterator I = MMap.module_begin(), 23050b57cec5SDimitry Andric E = MMap.module_end(); I != E; ++I) { 23060b57cec5SDimitry Andric Module *TheModule = I->second; 23075f757f3fSDimitry Andric OptionalFileEntryRef Entry = TheModule->getASTFile(); 23080b57cec5SDimitry Andric if (!Entry) { 23090b57cec5SDimitry Andric SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path; 23100b57cec5SDimitry Andric Path.push_back(std::make_pair( 23110b57cec5SDimitry Andric getPreprocessor().getIdentifierInfo(TheModule->Name), TriggerLoc)); 23120b57cec5SDimitry Andric std::reverse(Path.begin(), Path.end()); 23130b57cec5SDimitry Andric // Load a module as hidden. This also adds it to the global index. 23140b57cec5SDimitry Andric loadModule(TheModule->DefinitionLoc, Path, Module::Hidden, false); 23150b57cec5SDimitry Andric RecreateIndex = true; 23160b57cec5SDimitry Andric } 23170b57cec5SDimitry Andric } 23180b57cec5SDimitry Andric if (RecreateIndex) { 23190b57cec5SDimitry Andric if (llvm::Error Err = GlobalModuleIndex::writeIndex( 23200b57cec5SDimitry Andric getFileManager(), getPCHContainerReader(), 23210b57cec5SDimitry Andric getPreprocessor().getHeaderSearchInfo().getModuleCachePath())) { 23220b57cec5SDimitry Andric // FIXME As above, this drops the error on the floor. 23230b57cec5SDimitry Andric consumeError(std::move(Err)); 23240b57cec5SDimitry Andric return nullptr; 23250b57cec5SDimitry Andric } 2326480093f4SDimitry Andric TheASTReader->resetForReload(); 2327480093f4SDimitry Andric TheASTReader->loadGlobalIndex(); 2328480093f4SDimitry Andric GlobalIndex = TheASTReader->getGlobalIndex(); 23290b57cec5SDimitry Andric } 23300b57cec5SDimitry Andric HaveFullGlobalModuleIndex = true; 23310b57cec5SDimitry Andric } 23320b57cec5SDimitry Andric return GlobalIndex; 23330b57cec5SDimitry Andric } 23340b57cec5SDimitry Andric 23350b57cec5SDimitry Andric // Check global module index for missing imports. 23360b57cec5SDimitry Andric bool 23370b57cec5SDimitry Andric CompilerInstance::lookupMissingImports(StringRef Name, 23380b57cec5SDimitry Andric SourceLocation TriggerLoc) { 23390b57cec5SDimitry Andric // Look for the symbol in non-imported modules, but only if an error 23400b57cec5SDimitry Andric // actually occurred. 23410b57cec5SDimitry Andric if (!buildingModule()) { 23420b57cec5SDimitry Andric // Load global module index, or retrieve a previously loaded one. 23430b57cec5SDimitry Andric GlobalModuleIndex *GlobalIndex = loadGlobalModuleIndex( 23440b57cec5SDimitry Andric TriggerLoc); 23450b57cec5SDimitry Andric 23460b57cec5SDimitry Andric // Only if we have a global index. 23470b57cec5SDimitry Andric if (GlobalIndex) { 23480b57cec5SDimitry Andric GlobalModuleIndex::HitSet FoundModules; 23490b57cec5SDimitry Andric 23500b57cec5SDimitry Andric // Find the modules that reference the identifier. 23510b57cec5SDimitry Andric // Note that this only finds top-level modules. 23520b57cec5SDimitry Andric // We'll let diagnoseTypo find the actual declaration module. 23530b57cec5SDimitry Andric if (GlobalIndex->lookupIdentifier(Name, FoundModules)) 23540b57cec5SDimitry Andric return true; 23550b57cec5SDimitry Andric } 23560b57cec5SDimitry Andric } 23570b57cec5SDimitry Andric 23580b57cec5SDimitry Andric return false; 23590b57cec5SDimitry Andric } 23600b57cec5SDimitry Andric void CompilerInstance::resetAndLeakSema() { llvm::BuryPointer(takeSema()); } 23610b57cec5SDimitry Andric 23620b57cec5SDimitry Andric void CompilerInstance::setExternalSemaSource( 23630b57cec5SDimitry Andric IntrusiveRefCntPtr<ExternalSemaSource> ESS) { 23640b57cec5SDimitry Andric ExternalSemaSrc = std::move(ESS); 23650b57cec5SDimitry Andric } 2366