Path: blob/main/contrib/llvm-project/clang/lib/Frontend/CompilerInstance.cpp
35232 views
//===--- CompilerInstance.cpp ---------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "clang/Frontend/CompilerInstance.h"9#include "clang/AST/ASTConsumer.h"10#include "clang/AST/ASTContext.h"11#include "clang/AST/Decl.h"12#include "clang/Basic/CharInfo.h"13#include "clang/Basic/Diagnostic.h"14#include "clang/Basic/DiagnosticOptions.h"15#include "clang/Basic/FileManager.h"16#include "clang/Basic/LangStandard.h"17#include "clang/Basic/SourceManager.h"18#include "clang/Basic/Stack.h"19#include "clang/Basic/TargetInfo.h"20#include "clang/Basic/Version.h"21#include "clang/Config/config.h"22#include "clang/Frontend/ChainedDiagnosticConsumer.h"23#include "clang/Frontend/FrontendAction.h"24#include "clang/Frontend/FrontendActions.h"25#include "clang/Frontend/FrontendDiagnostic.h"26#include "clang/Frontend/FrontendPluginRegistry.h"27#include "clang/Frontend/LogDiagnosticPrinter.h"28#include "clang/Frontend/SARIFDiagnosticPrinter.h"29#include "clang/Frontend/SerializedDiagnosticPrinter.h"30#include "clang/Frontend/TextDiagnosticPrinter.h"31#include "clang/Frontend/Utils.h"32#include "clang/Frontend/VerifyDiagnosticConsumer.h"33#include "clang/Lex/HeaderSearch.h"34#include "clang/Lex/Preprocessor.h"35#include "clang/Lex/PreprocessorOptions.h"36#include "clang/Sema/CodeCompleteConsumer.h"37#include "clang/Sema/Sema.h"38#include "clang/Serialization/ASTReader.h"39#include "clang/Serialization/GlobalModuleIndex.h"40#include "clang/Serialization/InMemoryModuleCache.h"41#include "llvm/ADT/STLExtras.h"42#include "llvm/ADT/ScopeExit.h"43#include "llvm/ADT/Statistic.h"44#include "llvm/Config/llvm-config.h"45#include "llvm/Support/BuryPointer.h"46#include "llvm/Support/CrashRecoveryContext.h"47#include "llvm/Support/Errc.h"48#include "llvm/Support/FileSystem.h"49#include "llvm/Support/LockFileManager.h"50#include "llvm/Support/MemoryBuffer.h"51#include "llvm/Support/Path.h"52#include "llvm/Support/Program.h"53#include "llvm/Support/Signals.h"54#include "llvm/Support/TimeProfiler.h"55#include "llvm/Support/Timer.h"56#include "llvm/Support/raw_ostream.h"57#include "llvm/TargetParser/Host.h"58#include <optional>59#include <time.h>60#include <utility>6162using namespace clang;6364CompilerInstance::CompilerInstance(65std::shared_ptr<PCHContainerOperations> PCHContainerOps,66InMemoryModuleCache *SharedModuleCache)67: ModuleLoader(/* BuildingModule = */ SharedModuleCache),68Invocation(new CompilerInvocation()),69ModuleCache(SharedModuleCache ? SharedModuleCache70: new InMemoryModuleCache),71ThePCHContainerOperations(std::move(PCHContainerOps)) {}7273CompilerInstance::~CompilerInstance() {74assert(OutputFiles.empty() && "Still output files in flight?");75}7677void CompilerInstance::setInvocation(78std::shared_ptr<CompilerInvocation> Value) {79Invocation = std::move(Value);80}8182bool CompilerInstance::shouldBuildGlobalModuleIndex() const {83return (BuildGlobalModuleIndex ||84(TheASTReader && TheASTReader->isGlobalIndexUnavailable() &&85getFrontendOpts().GenerateGlobalModuleIndex)) &&86!DisableGeneratingGlobalModuleIndex;87}8889void CompilerInstance::setDiagnostics(DiagnosticsEngine *Value) {90Diagnostics = Value;91}9293void CompilerInstance::setVerboseOutputStream(raw_ostream &Value) {94OwnedVerboseOutputStream.reset();95VerboseOutputStream = &Value;96}9798void CompilerInstance::setVerboseOutputStream(std::unique_ptr<raw_ostream> Value) {99OwnedVerboseOutputStream.swap(Value);100VerboseOutputStream = OwnedVerboseOutputStream.get();101}102103void CompilerInstance::setTarget(TargetInfo *Value) { Target = Value; }104void CompilerInstance::setAuxTarget(TargetInfo *Value) { AuxTarget = Value; }105106bool CompilerInstance::createTarget() {107// Create the target instance.108setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(),109getInvocation().TargetOpts));110if (!hasTarget())111return false;112113// Check whether AuxTarget exists, if not, then create TargetInfo for the114// other side of CUDA/OpenMP/SYCL compilation.115if (!getAuxTarget() &&116(getLangOpts().CUDA || getLangOpts().OpenMPIsTargetDevice ||117getLangOpts().SYCLIsDevice) &&118!getFrontendOpts().AuxTriple.empty()) {119auto TO = std::make_shared<TargetOptions>();120TO->Triple = llvm::Triple::normalize(getFrontendOpts().AuxTriple);121if (getFrontendOpts().AuxTargetCPU)122TO->CPU = *getFrontendOpts().AuxTargetCPU;123if (getFrontendOpts().AuxTargetFeatures)124TO->FeaturesAsWritten = *getFrontendOpts().AuxTargetFeatures;125TO->HostTriple = getTarget().getTriple().str();126setAuxTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), TO));127}128129if (!getTarget().hasStrictFP() && !getLangOpts().ExpStrictFP) {130if (getLangOpts().RoundingMath) {131getDiagnostics().Report(diag::warn_fe_backend_unsupported_fp_rounding);132getLangOpts().RoundingMath = false;133}134auto FPExc = getLangOpts().getFPExceptionMode();135if (FPExc != LangOptions::FPE_Default && FPExc != LangOptions::FPE_Ignore) {136getDiagnostics().Report(diag::warn_fe_backend_unsupported_fp_exceptions);137getLangOpts().setFPExceptionMode(LangOptions::FPE_Ignore);138}139// FIXME: can we disable FEnvAccess?140}141142// We should do it here because target knows nothing about143// language options when it's being created.144if (getLangOpts().OpenCL &&145!getTarget().validateOpenCLTarget(getLangOpts(), getDiagnostics()))146return false;147148// Inform the target of the language options.149// FIXME: We shouldn't need to do this, the target should be immutable once150// created. This complexity should be lifted elsewhere.151getTarget().adjust(getDiagnostics(), getLangOpts());152153if (auto *Aux = getAuxTarget())154getTarget().setAuxTarget(Aux);155156return true;157}158159llvm::vfs::FileSystem &CompilerInstance::getVirtualFileSystem() const {160return getFileManager().getVirtualFileSystem();161}162163void CompilerInstance::setFileManager(FileManager *Value) {164FileMgr = Value;165}166167void CompilerInstance::setSourceManager(SourceManager *Value) {168SourceMgr = Value;169}170171void CompilerInstance::setPreprocessor(std::shared_ptr<Preprocessor> Value) {172PP = std::move(Value);173}174175void CompilerInstance::setASTContext(ASTContext *Value) {176Context = Value;177178if (Context && Consumer)179getASTConsumer().Initialize(getASTContext());180}181182void CompilerInstance::setSema(Sema *S) {183TheSema.reset(S);184}185186void CompilerInstance::setASTConsumer(std::unique_ptr<ASTConsumer> Value) {187Consumer = std::move(Value);188189if (Context && Consumer)190getASTConsumer().Initialize(getASTContext());191}192193void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) {194CompletionConsumer.reset(Value);195}196197std::unique_ptr<Sema> CompilerInstance::takeSema() {198return std::move(TheSema);199}200201IntrusiveRefCntPtr<ASTReader> CompilerInstance::getASTReader() const {202return TheASTReader;203}204void CompilerInstance::setASTReader(IntrusiveRefCntPtr<ASTReader> Reader) {205assert(ModuleCache.get() == &Reader->getModuleManager().getModuleCache() &&206"Expected ASTReader to use the same PCM cache");207TheASTReader = std::move(Reader);208}209210std::shared_ptr<ModuleDependencyCollector>211CompilerInstance::getModuleDepCollector() const {212return ModuleDepCollector;213}214215void CompilerInstance::setModuleDepCollector(216std::shared_ptr<ModuleDependencyCollector> Collector) {217ModuleDepCollector = std::move(Collector);218}219220static void collectHeaderMaps(const HeaderSearch &HS,221std::shared_ptr<ModuleDependencyCollector> MDC) {222SmallVector<std::string, 4> HeaderMapFileNames;223HS.getHeaderMapFileNames(HeaderMapFileNames);224for (auto &Name : HeaderMapFileNames)225MDC->addFile(Name);226}227228static void collectIncludePCH(CompilerInstance &CI,229std::shared_ptr<ModuleDependencyCollector> MDC) {230const PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();231if (PPOpts.ImplicitPCHInclude.empty())232return;233234StringRef PCHInclude = PPOpts.ImplicitPCHInclude;235FileManager &FileMgr = CI.getFileManager();236auto PCHDir = FileMgr.getOptionalDirectoryRef(PCHInclude);237if (!PCHDir) {238MDC->addFile(PCHInclude);239return;240}241242std::error_code EC;243SmallString<128> DirNative;244llvm::sys::path::native(PCHDir->getName(), DirNative);245llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();246SimpleASTReaderListener Validator(CI.getPreprocessor());247for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;248Dir != DirEnd && !EC; Dir.increment(EC)) {249// Check whether this is an AST file. ASTReader::isAcceptableASTFile is not250// used here since we're not interested in validating the PCH at this time,251// but only to check whether this is a file containing an AST.252if (!ASTReader::readASTFileControlBlock(253Dir->path(), FileMgr, CI.getModuleCache(),254CI.getPCHContainerReader(),255/*FindModuleFileExtensions=*/false, Validator,256/*ValidateDiagnosticOptions=*/false))257MDC->addFile(Dir->path());258}259}260261static void collectVFSEntries(CompilerInstance &CI,262std::shared_ptr<ModuleDependencyCollector> MDC) {263if (CI.getHeaderSearchOpts().VFSOverlayFiles.empty())264return;265266// Collect all VFS found.267SmallVector<llvm::vfs::YAMLVFSEntry, 16> VFSEntries;268for (const std::string &VFSFile : CI.getHeaderSearchOpts().VFSOverlayFiles) {269llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =270llvm::MemoryBuffer::getFile(VFSFile);271if (!Buffer)272return;273llvm::vfs::collectVFSFromYAML(std::move(Buffer.get()),274/*DiagHandler*/ nullptr, VFSFile, VFSEntries);275}276277for (auto &E : VFSEntries)278MDC->addFile(E.VPath, E.RPath);279}280281// Diagnostics282static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts,283const CodeGenOptions *CodeGenOpts,284DiagnosticsEngine &Diags) {285std::error_code EC;286std::unique_ptr<raw_ostream> StreamOwner;287raw_ostream *OS = &llvm::errs();288if (DiagOpts->DiagnosticLogFile != "-") {289// Create the output stream.290auto FileOS = std::make_unique<llvm::raw_fd_ostream>(291DiagOpts->DiagnosticLogFile, EC,292llvm::sys::fs::OF_Append | llvm::sys::fs::OF_TextWithCRLF);293if (EC) {294Diags.Report(diag::warn_fe_cc_log_diagnostics_failure)295<< DiagOpts->DiagnosticLogFile << EC.message();296} else {297FileOS->SetUnbuffered();298OS = FileOS.get();299StreamOwner = std::move(FileOS);300}301}302303// Chain in the diagnostic client which will log the diagnostics.304auto Logger = std::make_unique<LogDiagnosticPrinter>(*OS, DiagOpts,305std::move(StreamOwner));306if (CodeGenOpts)307Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags);308if (Diags.ownsClient()) {309Diags.setClient(310new ChainedDiagnosticConsumer(Diags.takeClient(), std::move(Logger)));311} else {312Diags.setClient(313new ChainedDiagnosticConsumer(Diags.getClient(), std::move(Logger)));314}315}316317static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts,318DiagnosticsEngine &Diags,319StringRef OutputFile) {320auto SerializedConsumer =321clang::serialized_diags::create(OutputFile, DiagOpts);322323if (Diags.ownsClient()) {324Diags.setClient(new ChainedDiagnosticConsumer(325Diags.takeClient(), std::move(SerializedConsumer)));326} else {327Diags.setClient(new ChainedDiagnosticConsumer(328Diags.getClient(), std::move(SerializedConsumer)));329}330}331332void CompilerInstance::createDiagnostics(DiagnosticConsumer *Client,333bool ShouldOwnClient) {334Diagnostics = createDiagnostics(&getDiagnosticOpts(), Client,335ShouldOwnClient, &getCodeGenOpts());336}337338IntrusiveRefCntPtr<DiagnosticsEngine>339CompilerInstance::createDiagnostics(DiagnosticOptions *Opts,340DiagnosticConsumer *Client,341bool ShouldOwnClient,342const CodeGenOptions *CodeGenOpts) {343IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());344IntrusiveRefCntPtr<DiagnosticsEngine>345Diags(new DiagnosticsEngine(DiagID, Opts));346347// Create the diagnostic client for reporting errors or for348// implementing -verify.349if (Client) {350Diags->setClient(Client, ShouldOwnClient);351} else if (Opts->getFormat() == DiagnosticOptions::SARIF) {352Diags->setClient(new SARIFDiagnosticPrinter(llvm::errs(), Opts));353} else354Diags->setClient(new TextDiagnosticPrinter(llvm::errs(), Opts));355356// Chain in -verify checker, if requested.357if (Opts->VerifyDiagnostics)358Diags->setClient(new VerifyDiagnosticConsumer(*Diags));359360// Chain in -diagnostic-log-file dumper, if requested.361if (!Opts->DiagnosticLogFile.empty())362SetUpDiagnosticLog(Opts, CodeGenOpts, *Diags);363364if (!Opts->DiagnosticSerializationFile.empty())365SetupSerializedDiagnostics(Opts, *Diags,366Opts->DiagnosticSerializationFile);367368// Configure our handling of diagnostics.369ProcessWarningOptions(*Diags, *Opts);370371return Diags;372}373374// File Manager375376FileManager *CompilerInstance::createFileManager(377IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {378if (!VFS)379VFS = FileMgr ? &FileMgr->getVirtualFileSystem()380: createVFSFromCompilerInvocation(getInvocation(),381getDiagnostics());382assert(VFS && "FileManager has no VFS?");383FileMgr = new FileManager(getFileSystemOpts(), std::move(VFS));384return FileMgr.get();385}386387// Source Manager388389void CompilerInstance::createSourceManager(FileManager &FileMgr) {390SourceMgr = new SourceManager(getDiagnostics(), FileMgr);391}392393// Initialize the remapping of files to alternative contents, e.g.,394// those specified through other files.395static void InitializeFileRemapping(DiagnosticsEngine &Diags,396SourceManager &SourceMgr,397FileManager &FileMgr,398const PreprocessorOptions &InitOpts) {399// Remap files in the source manager (with buffers).400for (const auto &RB : InitOpts.RemappedFileBuffers) {401// Create the file entry for the file that we're mapping from.402FileEntryRef FromFile =403FileMgr.getVirtualFileRef(RB.first, RB.second->getBufferSize(), 0);404405// Override the contents of the "from" file with the contents of the406// "to" file. If the caller owns the buffers, then pass a MemoryBufferRef;407// otherwise, pass as a std::unique_ptr<MemoryBuffer> to transfer ownership408// to the SourceManager.409if (InitOpts.RetainRemappedFileBuffers)410SourceMgr.overrideFileContents(FromFile, RB.second->getMemBufferRef());411else412SourceMgr.overrideFileContents(413FromFile, std::unique_ptr<llvm::MemoryBuffer>(RB.second));414}415416// Remap files in the source manager (with other files).417for (const auto &RF : InitOpts.RemappedFiles) {418// Find the file that we're mapping to.419OptionalFileEntryRef ToFile = FileMgr.getOptionalFileRef(RF.second);420if (!ToFile) {421Diags.Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second;422continue;423}424425// Create the file entry for the file that we're mapping from.426const FileEntry *FromFile =427FileMgr.getVirtualFile(RF.first, ToFile->getSize(), 0);428if (!FromFile) {429Diags.Report(diag::err_fe_remap_missing_from_file) << RF.first;430continue;431}432433// Override the contents of the "from" file with the contents of434// the "to" file.435SourceMgr.overrideFileContents(FromFile, *ToFile);436}437438SourceMgr.setOverridenFilesKeepOriginalName(439InitOpts.RemappedFilesKeepOriginalName);440}441442// Preprocessor443444void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {445const PreprocessorOptions &PPOpts = getPreprocessorOpts();446447// The AST reader holds a reference to the old preprocessor (if any).448TheASTReader.reset();449450// Create the Preprocessor.451HeaderSearch *HeaderInfo =452new HeaderSearch(getHeaderSearchOptsPtr(), getSourceManager(),453getDiagnostics(), getLangOpts(), &getTarget());454PP = std::make_shared<Preprocessor>(Invocation->getPreprocessorOptsPtr(),455getDiagnostics(), getLangOpts(),456getSourceManager(), *HeaderInfo, *this,457/*IdentifierInfoLookup=*/nullptr,458/*OwnsHeaderSearch=*/true, TUKind);459getTarget().adjust(getDiagnostics(), getLangOpts());460PP->Initialize(getTarget(), getAuxTarget());461462if (PPOpts.DetailedRecord)463PP->createPreprocessingRecord();464465// Apply remappings to the source manager.466InitializeFileRemapping(PP->getDiagnostics(), PP->getSourceManager(),467PP->getFileManager(), PPOpts);468469// Predefine macros and configure the preprocessor.470InitializePreprocessor(*PP, PPOpts, getPCHContainerReader(),471getFrontendOpts(), getCodeGenOpts());472473// Initialize the header search object. In CUDA compilations, we use the aux474// triple (the host triple) to initialize our header search, since we need to475// find the host headers in order to compile the CUDA code.476const llvm::Triple *HeaderSearchTriple = &PP->getTargetInfo().getTriple();477if (PP->getTargetInfo().getTriple().getOS() == llvm::Triple::CUDA &&478PP->getAuxTargetInfo())479HeaderSearchTriple = &PP->getAuxTargetInfo()->getTriple();480481ApplyHeaderSearchOptions(PP->getHeaderSearchInfo(), getHeaderSearchOpts(),482PP->getLangOpts(), *HeaderSearchTriple);483484PP->setPreprocessedOutput(getPreprocessorOutputOpts().ShowCPP);485486if (PP->getLangOpts().Modules && PP->getLangOpts().ImplicitModules) {487std::string ModuleHash = getInvocation().getModuleHash();488PP->getHeaderSearchInfo().setModuleHash(ModuleHash);489PP->getHeaderSearchInfo().setModuleCachePath(490getSpecificModuleCachePath(ModuleHash));491}492493// Handle generating dependencies, if requested.494const DependencyOutputOptions &DepOpts = getDependencyOutputOpts();495if (!DepOpts.OutputFile.empty())496addDependencyCollector(std::make_shared<DependencyFileGenerator>(DepOpts));497if (!DepOpts.DOTOutputFile.empty())498AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile,499getHeaderSearchOpts().Sysroot);500501// If we don't have a collector, but we are collecting module dependencies,502// then we're the top level compiler instance and need to create one.503if (!ModuleDepCollector && !DepOpts.ModuleDependencyOutputDir.empty()) {504ModuleDepCollector = std::make_shared<ModuleDependencyCollector>(505DepOpts.ModuleDependencyOutputDir);506}507508// If there is a module dep collector, register with other dep collectors509// and also (a) collect header maps and (b) TODO: input vfs overlay files.510if (ModuleDepCollector) {511addDependencyCollector(ModuleDepCollector);512collectHeaderMaps(PP->getHeaderSearchInfo(), ModuleDepCollector);513collectIncludePCH(*this, ModuleDepCollector);514collectVFSEntries(*this, ModuleDepCollector);515}516517for (auto &Listener : DependencyCollectors)518Listener->attachToPreprocessor(*PP);519520// Handle generating header include information, if requested.521if (DepOpts.ShowHeaderIncludes)522AttachHeaderIncludeGen(*PP, DepOpts);523if (!DepOpts.HeaderIncludeOutputFile.empty()) {524StringRef OutputPath = DepOpts.HeaderIncludeOutputFile;525if (OutputPath == "-")526OutputPath = "";527AttachHeaderIncludeGen(*PP, DepOpts,528/*ShowAllHeaders=*/true, OutputPath,529/*ShowDepth=*/false);530}531532if (DepOpts.ShowIncludesDest != ShowIncludesDestination::None) {533AttachHeaderIncludeGen(*PP, DepOpts,534/*ShowAllHeaders=*/true, /*OutputPath=*/"",535/*ShowDepth=*/true, /*MSStyle=*/true);536}537}538539std::string CompilerInstance::getSpecificModuleCachePath(StringRef ModuleHash) {540// Set up the module path, including the hash for the module-creation options.541SmallString<256> SpecificModuleCache(getHeaderSearchOpts().ModuleCachePath);542if (!SpecificModuleCache.empty() && !getHeaderSearchOpts().DisableModuleHash)543llvm::sys::path::append(SpecificModuleCache, ModuleHash);544return std::string(SpecificModuleCache);545}546547// ASTContext548549void CompilerInstance::createASTContext() {550Preprocessor &PP = getPreprocessor();551auto *Context = new ASTContext(getLangOpts(), PP.getSourceManager(),552PP.getIdentifierTable(), PP.getSelectorTable(),553PP.getBuiltinInfo(), PP.TUKind);554Context->InitBuiltinTypes(getTarget(), getAuxTarget());555setASTContext(Context);556}557558// ExternalASTSource559560namespace {561// Helper to recursively read the module names for all modules we're adding.562// We mark these as known and redirect any attempt to load that module to563// the files we were handed.564struct ReadModuleNames : ASTReaderListener {565Preprocessor &PP;566llvm::SmallVector<std::string, 8> LoadedModules;567568ReadModuleNames(Preprocessor &PP) : PP(PP) {}569570void ReadModuleName(StringRef ModuleName) override {571// Keep the module name as a string for now. It's not safe to create a new572// IdentifierInfo from an ASTReader callback.573LoadedModules.push_back(ModuleName.str());574}575576void registerAll() {577ModuleMap &MM = PP.getHeaderSearchInfo().getModuleMap();578for (const std::string &LoadedModule : LoadedModules)579MM.cacheModuleLoad(*PP.getIdentifierInfo(LoadedModule),580MM.findModule(LoadedModule));581LoadedModules.clear();582}583584void markAllUnavailable() {585for (const std::string &LoadedModule : LoadedModules) {586if (Module *M = PP.getHeaderSearchInfo().getModuleMap().findModule(587LoadedModule)) {588M->HasIncompatibleModuleFile = true;589590// Mark module as available if the only reason it was unavailable591// was missing headers.592SmallVector<Module *, 2> Stack;593Stack.push_back(M);594while (!Stack.empty()) {595Module *Current = Stack.pop_back_val();596if (Current->IsUnimportable) continue;597Current->IsAvailable = true;598auto SubmodulesRange = Current->submodules();599Stack.insert(Stack.end(), SubmodulesRange.begin(),600SubmodulesRange.end());601}602}603}604LoadedModules.clear();605}606};607} // namespace608609void CompilerInstance::createPCHExternalASTSource(610StringRef Path, DisableValidationForModuleKind DisableValidation,611bool AllowPCHWithCompilerErrors, void *DeserializationListener,612bool OwnDeserializationListener) {613bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;614TheASTReader = createPCHExternalASTSource(615Path, getHeaderSearchOpts().Sysroot, DisableValidation,616AllowPCHWithCompilerErrors, getPreprocessor(), getModuleCache(),617getASTContext(), getPCHContainerReader(),618getFrontendOpts().ModuleFileExtensions, DependencyCollectors,619DeserializationListener, OwnDeserializationListener, Preamble,620getFrontendOpts().UseGlobalModuleIndex);621}622623IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(624StringRef Path, StringRef Sysroot,625DisableValidationForModuleKind DisableValidation,626bool AllowPCHWithCompilerErrors, Preprocessor &PP,627InMemoryModuleCache &ModuleCache, ASTContext &Context,628const PCHContainerReader &PCHContainerRdr,629ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,630ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,631void *DeserializationListener, bool OwnDeserializationListener,632bool Preamble, bool UseGlobalModuleIndex) {633HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();634635IntrusiveRefCntPtr<ASTReader> Reader(new ASTReader(636PP, ModuleCache, &Context, PCHContainerRdr, Extensions,637Sysroot.empty() ? "" : Sysroot.data(), DisableValidation,638AllowPCHWithCompilerErrors, /*AllowConfigurationMismatch*/ false,639HSOpts.ModulesValidateSystemHeaders, HSOpts.ValidateASTInputFilesContent,640UseGlobalModuleIndex));641642// We need the external source to be set up before we read the AST, because643// eagerly-deserialized declarations may use it.644Context.setExternalSource(Reader.get());645646Reader->setDeserializationListener(647static_cast<ASTDeserializationListener *>(DeserializationListener),648/*TakeOwnership=*/OwnDeserializationListener);649650for (auto &Listener : DependencyCollectors)651Listener->attachToASTReader(*Reader);652653auto Listener = std::make_unique<ReadModuleNames>(PP);654auto &ListenerRef = *Listener;655ASTReader::ListenerScope ReadModuleNamesListener(*Reader,656std::move(Listener));657658switch (Reader->ReadAST(Path,659Preamble ? serialization::MK_Preamble660: serialization::MK_PCH,661SourceLocation(),662ASTReader::ARR_None)) {663case ASTReader::Success:664// Set the predefines buffer as suggested by the PCH reader. Typically, the665// predefines buffer will be empty.666PP.setPredefines(Reader->getSuggestedPredefines());667ListenerRef.registerAll();668return Reader;669670case ASTReader::Failure:671// Unrecoverable failure: don't even try to process the input file.672break;673674case ASTReader::Missing:675case ASTReader::OutOfDate:676case ASTReader::VersionMismatch:677case ASTReader::ConfigurationMismatch:678case ASTReader::HadErrors:679// No suitable PCH file could be found. Return an error.680break;681}682683ListenerRef.markAllUnavailable();684Context.setExternalSource(nullptr);685return nullptr;686}687688// Code Completion689690static bool EnableCodeCompletion(Preprocessor &PP,691StringRef Filename,692unsigned Line,693unsigned Column) {694// Tell the source manager to chop off the given file at a specific695// line and column.696auto Entry = PP.getFileManager().getOptionalFileRef(Filename);697if (!Entry) {698PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file)699<< Filename;700return true;701}702703// Truncate the named file at the given line/column.704PP.SetCodeCompletionPoint(*Entry, Line, Column);705return false;706}707708void CompilerInstance::createCodeCompletionConsumer() {709const ParsedSourceLocation &Loc = getFrontendOpts().CodeCompletionAt;710if (!CompletionConsumer) {711setCodeCompletionConsumer(createCodeCompletionConsumer(712getPreprocessor(), Loc.FileName, Loc.Line, Loc.Column,713getFrontendOpts().CodeCompleteOpts, llvm::outs()));714return;715} else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName,716Loc.Line, Loc.Column)) {717setCodeCompletionConsumer(nullptr);718return;719}720}721722void CompilerInstance::createFrontendTimer() {723FrontendTimerGroup.reset(724new llvm::TimerGroup("frontend", "Clang front-end time report"));725FrontendTimer.reset(726new llvm::Timer("frontend", "Clang front-end timer",727*FrontendTimerGroup));728}729730CodeCompleteConsumer *731CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP,732StringRef Filename,733unsigned Line,734unsigned Column,735const CodeCompleteOptions &Opts,736raw_ostream &OS) {737if (EnableCodeCompletion(PP, Filename, Line, Column))738return nullptr;739740// Set up the creation routine for code-completion.741return new PrintingCodeCompleteConsumer(Opts, OS);742}743744void CompilerInstance::createSema(TranslationUnitKind TUKind,745CodeCompleteConsumer *CompletionConsumer) {746TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(),747TUKind, CompletionConsumer));748749// Set up API notes.750TheSema->APINotes.setSwiftVersion(getAPINotesOpts().SwiftVersion);751752// Attach the external sema source if there is any.753if (ExternalSemaSrc) {754TheSema->addExternalSource(ExternalSemaSrc.get());755ExternalSemaSrc->InitializeSema(*TheSema);756}757758// If we're building a module and are supposed to load API notes,759// notify the API notes manager.760if (auto *currentModule = getPreprocessor().getCurrentModule()) {761(void)TheSema->APINotes.loadCurrentModuleAPINotes(762currentModule, getLangOpts().APINotesModules,763getAPINotesOpts().ModuleSearchPaths);764}765}766767// Output Files768769void CompilerInstance::clearOutputFiles(bool EraseFiles) {770// The ASTConsumer can own streams that write to the output files.771assert(!hasASTConsumer() && "ASTConsumer should be reset");772// Ignore errors that occur when trying to discard the temp file.773for (OutputFile &OF : OutputFiles) {774if (EraseFiles) {775if (OF.File)776consumeError(OF.File->discard());777if (!OF.Filename.empty())778llvm::sys::fs::remove(OF.Filename);779continue;780}781782if (!OF.File)783continue;784785if (OF.File->TmpName.empty()) {786consumeError(OF.File->discard());787continue;788}789790llvm::Error E = OF.File->keep(OF.Filename);791if (!E)792continue;793794getDiagnostics().Report(diag::err_unable_to_rename_temp)795<< OF.File->TmpName << OF.Filename << std::move(E);796797llvm::sys::fs::remove(OF.File->TmpName);798}799OutputFiles.clear();800if (DeleteBuiltModules) {801for (auto &Module : BuiltModules)802llvm::sys::fs::remove(Module.second);803BuiltModules.clear();804}805}806807std::unique_ptr<raw_pwrite_stream> CompilerInstance::createDefaultOutputFile(808bool Binary, StringRef InFile, StringRef Extension, bool RemoveFileOnSignal,809bool CreateMissingDirectories, bool ForceUseTemporary) {810StringRef OutputPath = getFrontendOpts().OutputFile;811std::optional<SmallString<128>> PathStorage;812if (OutputPath.empty()) {813if (InFile == "-" || Extension.empty()) {814OutputPath = "-";815} else {816PathStorage.emplace(InFile);817llvm::sys::path::replace_extension(*PathStorage, Extension);818OutputPath = *PathStorage;819}820}821822return createOutputFile(OutputPath, Binary, RemoveFileOnSignal,823getFrontendOpts().UseTemporary || ForceUseTemporary,824CreateMissingDirectories);825}826827std::unique_ptr<raw_pwrite_stream> CompilerInstance::createNullOutputFile() {828return std::make_unique<llvm::raw_null_ostream>();829}830831std::unique_ptr<raw_pwrite_stream>832CompilerInstance::createOutputFile(StringRef OutputPath, bool Binary,833bool RemoveFileOnSignal, bool UseTemporary,834bool CreateMissingDirectories) {835Expected<std::unique_ptr<raw_pwrite_stream>> OS =836createOutputFileImpl(OutputPath, Binary, RemoveFileOnSignal, UseTemporary,837CreateMissingDirectories);838if (OS)839return std::move(*OS);840getDiagnostics().Report(diag::err_fe_unable_to_open_output)841<< OutputPath << errorToErrorCode(OS.takeError()).message();842return nullptr;843}844845Expected<std::unique_ptr<llvm::raw_pwrite_stream>>846CompilerInstance::createOutputFileImpl(StringRef OutputPath, bool Binary,847bool RemoveFileOnSignal,848bool UseTemporary,849bool CreateMissingDirectories) {850assert((!CreateMissingDirectories || UseTemporary) &&851"CreateMissingDirectories is only allowed when using temporary files");852853// If '-working-directory' was passed, the output filename should be854// relative to that.855std::optional<SmallString<128>> AbsPath;856if (OutputPath != "-" && !llvm::sys::path::is_absolute(OutputPath)) {857assert(hasFileManager() &&858"File Manager is required to fix up relative path.\n");859860AbsPath.emplace(OutputPath);861FileMgr->FixupRelativePath(*AbsPath);862OutputPath = *AbsPath;863}864865std::unique_ptr<llvm::raw_fd_ostream> OS;866std::optional<StringRef> OSFile;867868if (UseTemporary) {869if (OutputPath == "-")870UseTemporary = false;871else {872llvm::sys::fs::file_status Status;873llvm::sys::fs::status(OutputPath, Status);874if (llvm::sys::fs::exists(Status)) {875// Fail early if we can't write to the final destination.876if (!llvm::sys::fs::can_write(OutputPath))877return llvm::errorCodeToError(878make_error_code(llvm::errc::operation_not_permitted));879880// Don't use a temporary if the output is a special file. This handles881// things like '-o /dev/null'882if (!llvm::sys::fs::is_regular_file(Status))883UseTemporary = false;884}885}886}887888std::optional<llvm::sys::fs::TempFile> Temp;889if (UseTemporary) {890// Create a temporary file.891// Insert -%%%%%%%% before the extension (if any), and because some tools892// (noticeable, clang's own GlobalModuleIndex.cpp) glob for build893// artifacts, also append .tmp.894StringRef OutputExtension = llvm::sys::path::extension(OutputPath);895SmallString<128> TempPath =896StringRef(OutputPath).drop_back(OutputExtension.size());897TempPath += "-%%%%%%%%";898TempPath += OutputExtension;899TempPath += ".tmp";900llvm::sys::fs::OpenFlags BinaryFlags =901Binary ? llvm::sys::fs::OF_None : llvm::sys::fs::OF_Text;902Expected<llvm::sys::fs::TempFile> ExpectedFile =903llvm::sys::fs::TempFile::create(904TempPath, llvm::sys::fs::all_read | llvm::sys::fs::all_write,905BinaryFlags);906907llvm::Error E = handleErrors(908ExpectedFile.takeError(), [&](const llvm::ECError &E) -> llvm::Error {909std::error_code EC = E.convertToErrorCode();910if (CreateMissingDirectories &&911EC == llvm::errc::no_such_file_or_directory) {912StringRef Parent = llvm::sys::path::parent_path(OutputPath);913EC = llvm::sys::fs::create_directories(Parent);914if (!EC) {915ExpectedFile = llvm::sys::fs::TempFile::create(916TempPath, llvm::sys::fs::all_read | llvm::sys::fs::all_write,917BinaryFlags);918if (!ExpectedFile)919return llvm::errorCodeToError(920llvm::errc::no_such_file_or_directory);921}922}923return llvm::errorCodeToError(EC);924});925926if (E) {927consumeError(std::move(E));928} else {929Temp = std::move(ExpectedFile.get());930OS.reset(new llvm::raw_fd_ostream(Temp->FD, /*shouldClose=*/false));931OSFile = Temp->TmpName;932}933// If we failed to create the temporary, fallback to writing to the file934// directly. This handles the corner case where we cannot write to the935// directory, but can write to the file.936}937938if (!OS) {939OSFile = OutputPath;940std::error_code EC;941OS.reset(new llvm::raw_fd_ostream(942*OSFile, EC,943(Binary ? llvm::sys::fs::OF_None : llvm::sys::fs::OF_TextWithCRLF)));944if (EC)945return llvm::errorCodeToError(EC);946}947948// Add the output file -- but don't try to remove "-", since this means we are949// using stdin.950OutputFiles.emplace_back(((OutputPath != "-") ? OutputPath : "").str(),951std::move(Temp));952953if (!Binary || OS->supportsSeeking())954return std::move(OS);955956return std::make_unique<llvm::buffer_unique_ostream>(std::move(OS));957}958959// Initialization Utilities960961bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input){962return InitializeSourceManager(Input, getDiagnostics(), getFileManager(),963getSourceManager());964}965966// static967bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input,968DiagnosticsEngine &Diags,969FileManager &FileMgr,970SourceManager &SourceMgr) {971SrcMgr::CharacteristicKind Kind =972Input.getKind().getFormat() == InputKind::ModuleMap973? Input.isSystem() ? SrcMgr::C_System_ModuleMap974: SrcMgr::C_User_ModuleMap975: Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User;976977if (Input.isBuffer()) {978SourceMgr.setMainFileID(SourceMgr.createFileID(Input.getBuffer(), Kind));979assert(SourceMgr.getMainFileID().isValid() &&980"Couldn't establish MainFileID!");981return true;982}983984StringRef InputFile = Input.getFile();985986// Figure out where to get and map in the main file.987auto FileOrErr = InputFile == "-"988? FileMgr.getSTDIN()989: FileMgr.getFileRef(InputFile, /*OpenFile=*/true);990if (!FileOrErr) {991auto EC = llvm::errorToErrorCode(FileOrErr.takeError());992if (InputFile != "-")993Diags.Report(diag::err_fe_error_reading) << InputFile << EC.message();994else995Diags.Report(diag::err_fe_error_reading_stdin) << EC.message();996return false;997}998999SourceMgr.setMainFileID(1000SourceMgr.createFileID(*FileOrErr, SourceLocation(), Kind));10011002assert(SourceMgr.getMainFileID().isValid() &&1003"Couldn't establish MainFileID!");1004return true;1005}10061007// High-Level Operations10081009bool CompilerInstance::ExecuteAction(FrontendAction &Act) {1010assert(hasDiagnostics() && "Diagnostics engine is not initialized!");1011assert(!getFrontendOpts().ShowHelp && "Client must handle '-help'!");1012assert(!getFrontendOpts().ShowVersion && "Client must handle '-version'!");10131014// Mark this point as the bottom of the stack if we don't have somewhere1015// better. We generally expect frontend actions to be invoked with (nearly)1016// DesiredStackSpace available.1017noteBottomOfStack();10181019auto FinishDiagnosticClient = llvm::make_scope_exit([&]() {1020// Notify the diagnostic client that all files were processed.1021getDiagnosticClient().finish();1022});10231024raw_ostream &OS = getVerboseOutputStream();10251026if (!Act.PrepareToExecute(*this))1027return false;10281029if (!createTarget())1030return false;10311032// rewriter project will change target built-in bool type from its default.1033if (getFrontendOpts().ProgramAction == frontend::RewriteObjC)1034getTarget().noSignedCharForObjCBool();10351036// Validate/process some options.1037if (getHeaderSearchOpts().Verbose)1038OS << "clang -cc1 version " CLANG_VERSION_STRING << " based upon LLVM "1039<< LLVM_VERSION_STRING << " default target "1040<< llvm::sys::getDefaultTargetTriple() << "\n";10411042if (getCodeGenOpts().TimePasses)1043createFrontendTimer();10441045if (getFrontendOpts().ShowStats || !getFrontendOpts().StatsFile.empty())1046llvm::EnableStatistics(false);10471048// Sort vectors containing toc data and no toc data variables to facilitate1049// binary search later.1050llvm::sort(getCodeGenOpts().TocDataVarsUserSpecified);1051llvm::sort(getCodeGenOpts().NoTocDataVars);10521053for (const FrontendInputFile &FIF : getFrontendOpts().Inputs) {1054// Reset the ID tables if we are reusing the SourceManager and parsing1055// regular files.1056if (hasSourceManager() && !Act.isModelParsingAction())1057getSourceManager().clearIDTables();10581059if (Act.BeginSourceFile(*this, FIF)) {1060if (llvm::Error Err = Act.Execute()) {1061consumeError(std::move(Err)); // FIXME this drops errors on the floor.1062}1063Act.EndSourceFile();1064}1065}10661067printDiagnosticStats();10681069if (getFrontendOpts().ShowStats) {1070if (hasFileManager()) {1071getFileManager().PrintStats();1072OS << '\n';1073}1074llvm::PrintStatistics(OS);1075}1076StringRef StatsFile = getFrontendOpts().StatsFile;1077if (!StatsFile.empty()) {1078llvm::sys::fs::OpenFlags FileFlags = llvm::sys::fs::OF_TextWithCRLF;1079if (getFrontendOpts().AppendStats)1080FileFlags |= llvm::sys::fs::OF_Append;1081std::error_code EC;1082auto StatS =1083std::make_unique<llvm::raw_fd_ostream>(StatsFile, EC, FileFlags);1084if (EC) {1085getDiagnostics().Report(diag::warn_fe_unable_to_open_stats_file)1086<< StatsFile << EC.message();1087} else {1088llvm::PrintStatisticsJSON(*StatS);1089}1090}10911092return !getDiagnostics().getClient()->getNumErrors();1093}10941095void CompilerInstance::printDiagnosticStats() {1096if (!getDiagnosticOpts().ShowCarets)1097return;10981099raw_ostream &OS = getVerboseOutputStream();11001101// We can have multiple diagnostics sharing one diagnostic client.1102// Get the total number of warnings/errors from the client.1103unsigned NumWarnings = getDiagnostics().getClient()->getNumWarnings();1104unsigned NumErrors = getDiagnostics().getClient()->getNumErrors();11051106if (NumWarnings)1107OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s");1108if (NumWarnings && NumErrors)1109OS << " and ";1110if (NumErrors)1111OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s");1112if (NumWarnings || NumErrors) {1113OS << " generated";1114if (getLangOpts().CUDA) {1115if (!getLangOpts().CUDAIsDevice) {1116OS << " when compiling for host";1117} else {1118OS << " when compiling for " << getTargetOpts().CPU;1119}1120}1121OS << ".\n";1122}1123}11241125void CompilerInstance::LoadRequestedPlugins() {1126// Load any requested plugins.1127for (const std::string &Path : getFrontendOpts().Plugins) {1128std::string Error;1129if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error))1130getDiagnostics().Report(diag::err_fe_unable_to_load_plugin)1131<< Path << Error;1132}11331134// Check if any of the loaded plugins replaces the main AST action1135for (const FrontendPluginRegistry::entry &Plugin :1136FrontendPluginRegistry::entries()) {1137std::unique_ptr<PluginASTAction> P(Plugin.instantiate());1138if (P->getActionType() == PluginASTAction::ReplaceAction) {1139getFrontendOpts().ProgramAction = clang::frontend::PluginAction;1140getFrontendOpts().ActionName = Plugin.getName().str();1141break;1142}1143}1144}11451146/// Determine the appropriate source input kind based on language1147/// options.1148static Language getLanguageFromOptions(const LangOptions &LangOpts) {1149if (LangOpts.OpenCL)1150return Language::OpenCL;1151if (LangOpts.CUDA)1152return Language::CUDA;1153if (LangOpts.ObjC)1154return LangOpts.CPlusPlus ? Language::ObjCXX : Language::ObjC;1155return LangOpts.CPlusPlus ? Language::CXX : Language::C;1156}11571158/// Compile a module file for the given module, using the options1159/// provided by the importing compiler instance. Returns true if the module1160/// was built without errors.1161static bool1162compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,1163StringRef ModuleName, FrontendInputFile Input,1164StringRef OriginalModuleMapFile, StringRef ModuleFileName,1165llvm::function_ref<void(CompilerInstance &)> PreBuildStep =1166[](CompilerInstance &) {},1167llvm::function_ref<void(CompilerInstance &)> PostBuildStep =1168[](CompilerInstance &) {}) {1169llvm::TimeTraceScope TimeScope("Module Compile", ModuleName);11701171// Never compile a module that's already finalized - this would cause the1172// existing module to be freed, causing crashes if it is later referenced1173if (ImportingInstance.getModuleCache().isPCMFinal(ModuleFileName)) {1174ImportingInstance.getDiagnostics().Report(1175ImportLoc, diag::err_module_rebuild_finalized)1176<< ModuleName;1177return false;1178}11791180// Construct a compiler invocation for creating this module.1181auto Invocation =1182std::make_shared<CompilerInvocation>(ImportingInstance.getInvocation());11831184PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();11851186// For any options that aren't intended to affect how a module is built,1187// reset them to their default values.1188Invocation->resetNonModularOptions();11891190// Remove any macro definitions that are explicitly ignored by the module.1191// They aren't supposed to affect how the module is built anyway.1192HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts();1193llvm::erase_if(PPOpts.Macros,1194[&HSOpts](const std::pair<std::string, bool> &def) {1195StringRef MacroDef = def.first;1196return HSOpts.ModulesIgnoreMacros.contains(1197llvm::CachedHashString(MacroDef.split('=').first));1198});11991200// If the original compiler invocation had -fmodule-name, pass it through.1201Invocation->getLangOpts().ModuleName =1202ImportingInstance.getInvocation().getLangOpts().ModuleName;12031204// Note the name of the module we're building.1205Invocation->getLangOpts().CurrentModule = std::string(ModuleName);12061207// If there is a module map file, build the module using the module map.1208// Set up the inputs/outputs so that we build the module from its umbrella1209// header.1210FrontendOptions &FrontendOpts = Invocation->getFrontendOpts();1211FrontendOpts.OutputFile = ModuleFileName.str();1212FrontendOpts.DisableFree = false;1213FrontendOpts.GenerateGlobalModuleIndex = false;1214FrontendOpts.BuildingImplicitModule = true;1215FrontendOpts.OriginalModuleMap = std::string(OriginalModuleMapFile);1216// Force implicitly-built modules to hash the content of the module file.1217HSOpts.ModulesHashContent = true;1218FrontendOpts.Inputs = {Input};12191220// Don't free the remapped file buffers; they are owned by our caller.1221PPOpts.RetainRemappedFileBuffers = true;12221223DiagnosticOptions &DiagOpts = Invocation->getDiagnosticOpts();12241225DiagOpts.VerifyDiagnostics = 0;1226assert(ImportingInstance.getInvocation().getModuleHash() ==1227Invocation->getModuleHash() && "Module hash mismatch!");12281229// Construct a compiler instance that will be used to actually create the1230// module. Since we're sharing an in-memory module cache,1231// CompilerInstance::CompilerInstance is responsible for finalizing the1232// buffers to prevent use-after-frees.1233CompilerInstance Instance(ImportingInstance.getPCHContainerOperations(),1234&ImportingInstance.getModuleCache());1235auto &Inv = *Invocation;1236Instance.setInvocation(std::move(Invocation));12371238Instance.createDiagnostics(new ForwardingDiagnosticConsumer(1239ImportingInstance.getDiagnosticClient()),1240/*ShouldOwnClient=*/true);12411242if (llvm::is_contained(DiagOpts.SystemHeaderWarningsModules, ModuleName))1243Instance.getDiagnostics().setSuppressSystemWarnings(false);12441245if (FrontendOpts.ModulesShareFileManager) {1246Instance.setFileManager(&ImportingInstance.getFileManager());1247} else {1248Instance.createFileManager(&ImportingInstance.getVirtualFileSystem());1249}1250Instance.createSourceManager(Instance.getFileManager());1251SourceManager &SourceMgr = Instance.getSourceManager();12521253// Note that this module is part of the module build stack, so that we1254// can detect cycles in the module graph.1255SourceMgr.setModuleBuildStack(1256ImportingInstance.getSourceManager().getModuleBuildStack());1257SourceMgr.pushModuleBuildStack(ModuleName,1258FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager()));12591260// Make sure that the failed-module structure has been allocated in1261// the importing instance, and propagate the pointer to the newly-created1262// instance.1263if (!ImportingInstance.hasFailedModulesSet())1264ImportingInstance.createFailedModulesSet();1265Instance.setFailedModulesSet(ImportingInstance.getFailedModulesSetPtr());12661267// If we're collecting module dependencies, we need to share a collector1268// between all of the module CompilerInstances. Other than that, we don't1269// want to produce any dependency output from the module build.1270Instance.setModuleDepCollector(ImportingInstance.getModuleDepCollector());1271Inv.getDependencyOutputOpts() = DependencyOutputOptions();12721273ImportingInstance.getDiagnostics().Report(ImportLoc,1274diag::remark_module_build)1275<< ModuleName << ModuleFileName;12761277PreBuildStep(Instance);12781279// Execute the action to actually build the module in-place. Use a separate1280// thread so that we get a stack large enough.1281bool Crashed = !llvm::CrashRecoveryContext().RunSafelyOnThread(1282[&]() {1283GenerateModuleFromModuleMapAction Action;1284Instance.ExecuteAction(Action);1285},1286DesiredStackSize);12871288PostBuildStep(Instance);12891290ImportingInstance.getDiagnostics().Report(ImportLoc,1291diag::remark_module_build_done)1292<< ModuleName;12931294// Propagate the statistics to the parent FileManager.1295if (!FrontendOpts.ModulesShareFileManager)1296ImportingInstance.getFileManager().AddStats(Instance.getFileManager());12971298if (Crashed) {1299// Clear the ASTConsumer if it hasn't been already, in case it owns streams1300// that must be closed before clearing output files.1301Instance.setSema(nullptr);1302Instance.setASTConsumer(nullptr);13031304// Delete any remaining temporary files related to Instance.1305Instance.clearOutputFiles(/*EraseFiles=*/true);1306}13071308// If \p AllowPCMWithCompilerErrors is set return 'success' even if errors1309// occurred.1310return !Instance.getDiagnostics().hasErrorOccurred() ||1311Instance.getFrontendOpts().AllowPCMWithCompilerErrors;1312}13131314static OptionalFileEntryRef getPublicModuleMap(FileEntryRef File,1315FileManager &FileMgr) {1316StringRef Filename = llvm::sys::path::filename(File.getName());1317SmallString<128> PublicFilename(File.getDir().getName());1318if (Filename == "module_private.map")1319llvm::sys::path::append(PublicFilename, "module.map");1320else if (Filename == "module.private.modulemap")1321llvm::sys::path::append(PublicFilename, "module.modulemap");1322else1323return std::nullopt;1324return FileMgr.getOptionalFileRef(PublicFilename);1325}13261327/// Compile a module file for the given module in a separate compiler instance,1328/// using the options provided by the importing compiler instance. Returns true1329/// if the module was built without errors.1330static bool compileModule(CompilerInstance &ImportingInstance,1331SourceLocation ImportLoc, Module *Module,1332StringRef ModuleFileName) {1333InputKind IK(getLanguageFromOptions(ImportingInstance.getLangOpts()),1334InputKind::ModuleMap);13351336// Get or create the module map that we'll use to build this module.1337ModuleMap &ModMap1338= ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();1339SourceManager &SourceMgr = ImportingInstance.getSourceManager();1340bool Result;1341if (FileID ModuleMapFID = ModMap.getContainingModuleMapFileID(Module);1342ModuleMapFID.isValid()) {1343// We want to use the top-level module map. If we don't, the compiling1344// instance may think the containing module map is a top-level one, while1345// the importing instance knows it's included from a parent module map via1346// the extern directive. This mismatch could bite us later.1347SourceLocation Loc = SourceMgr.getIncludeLoc(ModuleMapFID);1348while (Loc.isValid() && isModuleMap(SourceMgr.getFileCharacteristic(Loc))) {1349ModuleMapFID = SourceMgr.getFileID(Loc);1350Loc = SourceMgr.getIncludeLoc(ModuleMapFID);1351}13521353OptionalFileEntryRef ModuleMapFile =1354SourceMgr.getFileEntryRefForID(ModuleMapFID);1355assert(ModuleMapFile && "Top-level module map with no FileID");13561357// Canonicalize compilation to start with the public module map. This is1358// vital for submodules declarations in the private module maps to be1359// correctly parsed when depending on a top level module in the public one.1360if (OptionalFileEntryRef PublicMMFile = getPublicModuleMap(1361*ModuleMapFile, ImportingInstance.getFileManager()))1362ModuleMapFile = PublicMMFile;13631364StringRef ModuleMapFilePath = ModuleMapFile->getNameAsRequested();13651366// Use the module map where this module resides.1367Result = compileModuleImpl(1368ImportingInstance, ImportLoc, Module->getTopLevelModuleName(),1369FrontendInputFile(ModuleMapFilePath, IK, +Module->IsSystem),1370ModMap.getModuleMapFileForUniquing(Module)->getName(), ModuleFileName);1371} else {1372// FIXME: We only need to fake up an input file here as a way of1373// transporting the module's directory to the module map parser. We should1374// be able to do that more directly, and parse from a memory buffer without1375// inventing this file.1376SmallString<128> FakeModuleMapFile(Module->Directory->getName());1377llvm::sys::path::append(FakeModuleMapFile, "__inferred_module.map");13781379std::string InferredModuleMapContent;1380llvm::raw_string_ostream OS(InferredModuleMapContent);1381Module->print(OS);1382OS.flush();13831384Result = compileModuleImpl(1385ImportingInstance, ImportLoc, Module->getTopLevelModuleName(),1386FrontendInputFile(FakeModuleMapFile, IK, +Module->IsSystem),1387ModMap.getModuleMapFileForUniquing(Module)->getName(),1388ModuleFileName,1389[&](CompilerInstance &Instance) {1390std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer =1391llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent);1392FileEntryRef ModuleMapFile = Instance.getFileManager().getVirtualFileRef(1393FakeModuleMapFile, InferredModuleMapContent.size(), 0);1394Instance.getSourceManager().overrideFileContents(1395ModuleMapFile, std::move(ModuleMapBuffer));1396});1397}13981399// We've rebuilt a module. If we're allowed to generate or update the global1400// module index, record that fact in the importing compiler instance.1401if (ImportingInstance.getFrontendOpts().GenerateGlobalModuleIndex) {1402ImportingInstance.setBuildGlobalModuleIndex(true);1403}14041405return Result;1406}14071408/// Read the AST right after compiling the module.1409static bool readASTAfterCompileModule(CompilerInstance &ImportingInstance,1410SourceLocation ImportLoc,1411SourceLocation ModuleNameLoc,1412Module *Module, StringRef ModuleFileName,1413bool *OutOfDate) {1414DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics();14151416unsigned ModuleLoadCapabilities = ASTReader::ARR_Missing;1417if (OutOfDate)1418ModuleLoadCapabilities |= ASTReader::ARR_OutOfDate;14191420// Try to read the module file, now that we've compiled it.1421ASTReader::ASTReadResult ReadResult =1422ImportingInstance.getASTReader()->ReadAST(1423ModuleFileName, serialization::MK_ImplicitModule, ImportLoc,1424ModuleLoadCapabilities);1425if (ReadResult == ASTReader::Success)1426return true;14271428// The caller wants to handle out-of-date failures.1429if (OutOfDate && ReadResult == ASTReader::OutOfDate) {1430*OutOfDate = true;1431return false;1432}14331434// The ASTReader didn't diagnose the error, so conservatively report it.1435if (ReadResult == ASTReader::Missing || !Diags.hasErrorOccurred())1436Diags.Report(ModuleNameLoc, diag::err_module_not_built)1437<< Module->Name << SourceRange(ImportLoc, ModuleNameLoc);14381439return false;1440}14411442/// Compile a module in a separate compiler instance and read the AST,1443/// returning true if the module compiles without errors.1444static bool compileModuleAndReadASTImpl(CompilerInstance &ImportingInstance,1445SourceLocation ImportLoc,1446SourceLocation ModuleNameLoc,1447Module *Module,1448StringRef ModuleFileName) {1449if (!compileModule(ImportingInstance, ModuleNameLoc, Module,1450ModuleFileName)) {1451ImportingInstance.getDiagnostics().Report(ModuleNameLoc,1452diag::err_module_not_built)1453<< Module->Name << SourceRange(ImportLoc, ModuleNameLoc);1454return false;1455}14561457return readASTAfterCompileModule(ImportingInstance, ImportLoc, ModuleNameLoc,1458Module, ModuleFileName,1459/*OutOfDate=*/nullptr);1460}14611462/// Compile a module in a separate compiler instance and read the AST,1463/// returning true if the module compiles without errors, using a lock manager1464/// to avoid building the same module in multiple compiler instances.1465///1466/// Uses a lock file manager and exponential backoff to reduce the chances that1467/// multiple instances will compete to create the same module. On timeout,1468/// deletes the lock file in order to avoid deadlock from crashing processes or1469/// bugs in the lock file manager.1470static bool compileModuleAndReadASTBehindLock(1471CompilerInstance &ImportingInstance, SourceLocation ImportLoc,1472SourceLocation ModuleNameLoc, Module *Module, StringRef ModuleFileName) {1473DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics();14741475Diags.Report(ModuleNameLoc, diag::remark_module_lock)1476<< ModuleFileName << Module->Name;14771478// FIXME: have LockFileManager return an error_code so that we can1479// avoid the mkdir when the directory already exists.1480StringRef Dir = llvm::sys::path::parent_path(ModuleFileName);1481llvm::sys::fs::create_directories(Dir);14821483while (true) {1484llvm::LockFileManager Locked(ModuleFileName);1485switch (Locked) {1486case llvm::LockFileManager::LFS_Error:1487// ModuleCache takes care of correctness and locks are only necessary for1488// performance. Fallback to building the module in case of any lock1489// related errors.1490Diags.Report(ModuleNameLoc, diag::remark_module_lock_failure)1491<< Module->Name << Locked.getErrorMessage();1492// Clear out any potential leftover.1493Locked.unsafeRemoveLockFile();1494[[fallthrough]];1495case llvm::LockFileManager::LFS_Owned:1496// We're responsible for building the module ourselves.1497return compileModuleAndReadASTImpl(ImportingInstance, ImportLoc,1498ModuleNameLoc, Module, ModuleFileName);14991500case llvm::LockFileManager::LFS_Shared:1501break; // The interesting case.1502}15031504// Someone else is responsible for building the module. Wait for them to1505// finish.1506switch (Locked.waitForUnlock()) {1507case llvm::LockFileManager::Res_Success:1508break; // The interesting case.1509case llvm::LockFileManager::Res_OwnerDied:1510continue; // try again to get the lock.1511case llvm::LockFileManager::Res_Timeout:1512// Since ModuleCache takes care of correctness, we try waiting for1513// another process to complete the build so clang does not do it done1514// twice. If case of timeout, build it ourselves.1515Diags.Report(ModuleNameLoc, diag::remark_module_lock_timeout)1516<< Module->Name;1517// Clear the lock file so that future invocations can make progress.1518Locked.unsafeRemoveLockFile();1519continue;1520}15211522// Read the module that was just written by someone else.1523bool OutOfDate = false;1524if (readASTAfterCompileModule(ImportingInstance, ImportLoc, ModuleNameLoc,1525Module, ModuleFileName, &OutOfDate))1526return true;1527if (!OutOfDate)1528return false;15291530// The module may be out of date in the presence of file system races,1531// or if one of its imports depends on header search paths that are not1532// consistent with this ImportingInstance. Try again...1533}1534}15351536/// Compile a module in a separate compiler instance and read the AST,1537/// returning true if the module compiles without errors, potentially using a1538/// lock manager to avoid building the same module in multiple compiler1539/// instances.1540static bool compileModuleAndReadAST(CompilerInstance &ImportingInstance,1541SourceLocation ImportLoc,1542SourceLocation ModuleNameLoc,1543Module *Module, StringRef ModuleFileName) {1544return ImportingInstance.getInvocation()1545.getFrontendOpts()1546.BuildingImplicitModuleUsesLock1547? compileModuleAndReadASTBehindLock(ImportingInstance, ImportLoc,1548ModuleNameLoc, Module,1549ModuleFileName)1550: compileModuleAndReadASTImpl(ImportingInstance, ImportLoc,1551ModuleNameLoc, Module,1552ModuleFileName);1553}15541555/// Diagnose differences between the current definition of the given1556/// configuration macro and the definition provided on the command line.1557static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro,1558Module *Mod, SourceLocation ImportLoc) {1559IdentifierInfo *Id = PP.getIdentifierInfo(ConfigMacro);1560SourceManager &SourceMgr = PP.getSourceManager();15611562// If this identifier has never had a macro definition, then it could1563// not have changed.1564if (!Id->hadMacroDefinition())1565return;1566auto *LatestLocalMD = PP.getLocalMacroDirectiveHistory(Id);15671568// Find the macro definition from the command line.1569MacroInfo *CmdLineDefinition = nullptr;1570for (auto *MD = LatestLocalMD; MD; MD = MD->getPrevious()) {1571// We only care about the predefines buffer.1572FileID FID = SourceMgr.getFileID(MD->getLocation());1573if (FID.isInvalid() || FID != PP.getPredefinesFileID())1574continue;1575if (auto *DMD = dyn_cast<DefMacroDirective>(MD))1576CmdLineDefinition = DMD->getMacroInfo();1577break;1578}15791580auto *CurrentDefinition = PP.getMacroInfo(Id);1581if (CurrentDefinition == CmdLineDefinition) {1582// Macro matches. Nothing to do.1583} else if (!CurrentDefinition) {1584// This macro was defined on the command line, then #undef'd later.1585// Complain.1586PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)1587<< true << ConfigMacro << Mod->getFullModuleName();1588auto LatestDef = LatestLocalMD->getDefinition();1589assert(LatestDef.isUndefined() &&1590"predefined macro went away with no #undef?");1591PP.Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here)1592<< true;1593return;1594} else if (!CmdLineDefinition) {1595// There was no definition for this macro in the predefines buffer,1596// but there was a local definition. Complain.1597PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)1598<< false << ConfigMacro << Mod->getFullModuleName();1599PP.Diag(CurrentDefinition->getDefinitionLoc(),1600diag::note_module_def_undef_here)1601<< false;1602} else if (!CurrentDefinition->isIdenticalTo(*CmdLineDefinition, PP,1603/*Syntactically=*/true)) {1604// The macro definitions differ.1605PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)1606<< false << ConfigMacro << Mod->getFullModuleName();1607PP.Diag(CurrentDefinition->getDefinitionLoc(),1608diag::note_module_def_undef_here)1609<< false;1610}1611}16121613static void checkConfigMacros(Preprocessor &PP, Module *M,1614SourceLocation ImportLoc) {1615clang::Module *TopModule = M->getTopLevelModule();1616for (const StringRef ConMacro : TopModule->ConfigMacros) {1617checkConfigMacro(PP, ConMacro, M, ImportLoc);1618}1619}16201621/// Write a new timestamp file with the given path.1622static void writeTimestampFile(StringRef TimestampFile) {1623std::error_code EC;1624llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::OF_None);1625}16261627/// Prune the module cache of modules that haven't been accessed in1628/// a long time.1629static void pruneModuleCache(const HeaderSearchOptions &HSOpts) {1630llvm::sys::fs::file_status StatBuf;1631llvm::SmallString<128> TimestampFile;1632TimestampFile = HSOpts.ModuleCachePath;1633assert(!TimestampFile.empty());1634llvm::sys::path::append(TimestampFile, "modules.timestamp");16351636// Try to stat() the timestamp file.1637if (std::error_code EC = llvm::sys::fs::status(TimestampFile, StatBuf)) {1638// If the timestamp file wasn't there, create one now.1639if (EC == std::errc::no_such_file_or_directory) {1640writeTimestampFile(TimestampFile);1641}1642return;1643}16441645// Check whether the time stamp is older than our pruning interval.1646// If not, do nothing.1647time_t TimeStampModTime =1648llvm::sys::toTimeT(StatBuf.getLastModificationTime());1649time_t CurrentTime = time(nullptr);1650if (CurrentTime - TimeStampModTime <= time_t(HSOpts.ModuleCachePruneInterval))1651return;16521653// Write a new timestamp file so that nobody else attempts to prune.1654// There is a benign race condition here, if two Clang instances happen to1655// notice at the same time that the timestamp is out-of-date.1656writeTimestampFile(TimestampFile);16571658// Walk the entire module cache, looking for unused module files and module1659// indices.1660std::error_code EC;1661SmallString<128> ModuleCachePathNative;1662llvm::sys::path::native(HSOpts.ModuleCachePath, ModuleCachePathNative);1663for (llvm::sys::fs::directory_iterator Dir(ModuleCachePathNative, EC), DirEnd;1664Dir != DirEnd && !EC; Dir.increment(EC)) {1665// If we don't have a directory, there's nothing to look into.1666if (!llvm::sys::fs::is_directory(Dir->path()))1667continue;16681669// Walk all of the files within this directory.1670for (llvm::sys::fs::directory_iterator File(Dir->path(), EC), FileEnd;1671File != FileEnd && !EC; File.increment(EC)) {1672// We only care about module and global module index files.1673StringRef Extension = llvm::sys::path::extension(File->path());1674if (Extension != ".pcm" && Extension != ".timestamp" &&1675llvm::sys::path::filename(File->path()) != "modules.idx")1676continue;16771678// Look at this file. If we can't stat it, there's nothing interesting1679// there.1680if (llvm::sys::fs::status(File->path(), StatBuf))1681continue;16821683// If the file has been used recently enough, leave it there.1684time_t FileAccessTime = llvm::sys::toTimeT(StatBuf.getLastAccessedTime());1685if (CurrentTime - FileAccessTime <=1686time_t(HSOpts.ModuleCachePruneAfter)) {1687continue;1688}16891690// Remove the file.1691llvm::sys::fs::remove(File->path());16921693// Remove the timestamp file.1694std::string TimpestampFilename = File->path() + ".timestamp";1695llvm::sys::fs::remove(TimpestampFilename);1696}16971698// If we removed all of the files in the directory, remove the directory1699// itself.1700if (llvm::sys::fs::directory_iterator(Dir->path(), EC) ==1701llvm::sys::fs::directory_iterator() && !EC)1702llvm::sys::fs::remove(Dir->path());1703}1704}17051706void CompilerInstance::createASTReader() {1707if (TheASTReader)1708return;17091710if (!hasASTContext())1711createASTContext();17121713// If we're implicitly building modules but not currently recursively1714// building a module, check whether we need to prune the module cache.1715if (getSourceManager().getModuleBuildStack().empty() &&1716!getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty() &&1717getHeaderSearchOpts().ModuleCachePruneInterval > 0 &&1718getHeaderSearchOpts().ModuleCachePruneAfter > 0) {1719pruneModuleCache(getHeaderSearchOpts());1720}17211722HeaderSearchOptions &HSOpts = getHeaderSearchOpts();1723std::string Sysroot = HSOpts.Sysroot;1724const PreprocessorOptions &PPOpts = getPreprocessorOpts();1725const FrontendOptions &FEOpts = getFrontendOpts();1726std::unique_ptr<llvm::Timer> ReadTimer;17271728if (FrontendTimerGroup)1729ReadTimer = std::make_unique<llvm::Timer>("reading_modules",1730"Reading modules",1731*FrontendTimerGroup);1732TheASTReader = new ASTReader(1733getPreprocessor(), getModuleCache(), &getASTContext(),1734getPCHContainerReader(), getFrontendOpts().ModuleFileExtensions,1735Sysroot.empty() ? "" : Sysroot.c_str(),1736PPOpts.DisablePCHOrModuleValidation,1737/*AllowASTWithCompilerErrors=*/FEOpts.AllowPCMWithCompilerErrors,1738/*AllowConfigurationMismatch=*/false, HSOpts.ModulesValidateSystemHeaders,1739HSOpts.ValidateASTInputFilesContent,1740getFrontendOpts().UseGlobalModuleIndex, std::move(ReadTimer));1741if (hasASTConsumer()) {1742TheASTReader->setDeserializationListener(1743getASTConsumer().GetASTDeserializationListener());1744getASTContext().setASTMutationListener(1745getASTConsumer().GetASTMutationListener());1746}1747getASTContext().setExternalSource(TheASTReader);1748if (hasSema())1749TheASTReader->InitializeSema(getSema());1750if (hasASTConsumer())1751TheASTReader->StartTranslationUnit(&getASTConsumer());17521753for (auto &Listener : DependencyCollectors)1754Listener->attachToASTReader(*TheASTReader);1755}17561757bool CompilerInstance::loadModuleFile(1758StringRef FileName, serialization::ModuleFile *&LoadedModuleFile) {1759llvm::Timer Timer;1760if (FrontendTimerGroup)1761Timer.init("preloading." + FileName.str(), "Preloading " + FileName.str(),1762*FrontendTimerGroup);1763llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr);17641765// If we don't already have an ASTReader, create one now.1766if (!TheASTReader)1767createASTReader();17681769// If -Wmodule-file-config-mismatch is mapped as an error or worse, allow the1770// ASTReader to diagnose it, since it can produce better errors that we can.1771bool ConfigMismatchIsRecoverable =1772getDiagnostics().getDiagnosticLevel(diag::warn_module_config_mismatch,1773SourceLocation())1774<= DiagnosticsEngine::Warning;17751776auto Listener = std::make_unique<ReadModuleNames>(*PP);1777auto &ListenerRef = *Listener;1778ASTReader::ListenerScope ReadModuleNamesListener(*TheASTReader,1779std::move(Listener));17801781// Try to load the module file.1782switch (TheASTReader->ReadAST(1783FileName, serialization::MK_ExplicitModule, SourceLocation(),1784ConfigMismatchIsRecoverable ? ASTReader::ARR_ConfigurationMismatch : 0,1785&LoadedModuleFile)) {1786case ASTReader::Success:1787// We successfully loaded the module file; remember the set of provided1788// modules so that we don't try to load implicit modules for them.1789ListenerRef.registerAll();1790return true;17911792case ASTReader::ConfigurationMismatch:1793// Ignore unusable module files.1794getDiagnostics().Report(SourceLocation(), diag::warn_module_config_mismatch)1795<< FileName;1796// All modules provided by any files we tried and failed to load are now1797// unavailable; includes of those modules should now be handled textually.1798ListenerRef.markAllUnavailable();1799return true;18001801default:1802return false;1803}1804}18051806namespace {1807enum ModuleSource {1808MS_ModuleNotFound,1809MS_ModuleCache,1810MS_PrebuiltModulePath,1811MS_ModuleBuildPragma1812};1813} // end namespace18141815/// Select a source for loading the named module and compute the filename to1816/// load it from.1817static ModuleSource selectModuleSource(1818Module *M, StringRef ModuleName, std::string &ModuleFilename,1819const std::map<std::string, std::string, std::less<>> &BuiltModules,1820HeaderSearch &HS) {1821assert(ModuleFilename.empty() && "Already has a module source?");18221823// Check to see if the module has been built as part of this compilation1824// via a module build pragma.1825auto BuiltModuleIt = BuiltModules.find(ModuleName);1826if (BuiltModuleIt != BuiltModules.end()) {1827ModuleFilename = BuiltModuleIt->second;1828return MS_ModuleBuildPragma;1829}18301831// Try to load the module from the prebuilt module path.1832const HeaderSearchOptions &HSOpts = HS.getHeaderSearchOpts();1833if (!HSOpts.PrebuiltModuleFiles.empty() ||1834!HSOpts.PrebuiltModulePaths.empty()) {1835ModuleFilename = HS.getPrebuiltModuleFileName(ModuleName);1836if (HSOpts.EnablePrebuiltImplicitModules && ModuleFilename.empty())1837ModuleFilename = HS.getPrebuiltImplicitModuleFileName(M);1838if (!ModuleFilename.empty())1839return MS_PrebuiltModulePath;1840}18411842// Try to load the module from the module cache.1843if (M) {1844ModuleFilename = HS.getCachedModuleFileName(M);1845return MS_ModuleCache;1846}18471848return MS_ModuleNotFound;1849}18501851ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST(1852StringRef ModuleName, SourceLocation ImportLoc,1853SourceLocation ModuleNameLoc, bool IsInclusionDirective) {1854// Search for a module with the given name.1855HeaderSearch &HS = PP->getHeaderSearchInfo();1856Module *M =1857HS.lookupModule(ModuleName, ImportLoc, true, !IsInclusionDirective);18581859// Check for any configuration macros that have changed. This is done1860// immediately before potentially building a module in case this module1861// depends on having one of its configuration macros defined to successfully1862// build. If this is not done the user will never see the warning.1863if (M)1864checkConfigMacros(getPreprocessor(), M, ImportLoc);18651866// Select the source and filename for loading the named module.1867std::string ModuleFilename;1868ModuleSource Source =1869selectModuleSource(M, ModuleName, ModuleFilename, BuiltModules, HS);1870if (Source == MS_ModuleNotFound) {1871// We can't find a module, error out here.1872getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found)1873<< ModuleName << SourceRange(ImportLoc, ModuleNameLoc);1874return nullptr;1875}1876if (ModuleFilename.empty()) {1877if (M && M->HasIncompatibleModuleFile) {1878// We tried and failed to load a module file for this module. Fall1879// back to textual inclusion for its headers.1880return ModuleLoadResult::ConfigMismatch;1881}18821883getDiagnostics().Report(ModuleNameLoc, diag::err_module_build_disabled)1884<< ModuleName;1885return nullptr;1886}18871888// Create an ASTReader on demand.1889if (!getASTReader())1890createASTReader();18911892// Time how long it takes to load the module.1893llvm::Timer Timer;1894if (FrontendTimerGroup)1895Timer.init("loading." + ModuleFilename, "Loading " + ModuleFilename,1896*FrontendTimerGroup);1897llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr);1898llvm::TimeTraceScope TimeScope("Module Load", ModuleName);18991900// Try to load the module file. If we are not trying to load from the1901// module cache, we don't know how to rebuild modules.1902unsigned ARRFlags = Source == MS_ModuleCache1903? ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing |1904ASTReader::ARR_TreatModuleWithErrorsAsOutOfDate1905: Source == MS_PrebuiltModulePath1906? 01907: ASTReader::ARR_ConfigurationMismatch;1908switch (getASTReader()->ReadAST(ModuleFilename,1909Source == MS_PrebuiltModulePath1910? serialization::MK_PrebuiltModule1911: Source == MS_ModuleBuildPragma1912? serialization::MK_ExplicitModule1913: serialization::MK_ImplicitModule,1914ImportLoc, ARRFlags)) {1915case ASTReader::Success: {1916if (M)1917return M;1918assert(Source != MS_ModuleCache &&1919"missing module, but file loaded from cache");19201921// A prebuilt module is indexed as a ModuleFile; the Module does not exist1922// until the first call to ReadAST. Look it up now.1923M = HS.lookupModule(ModuleName, ImportLoc, true, !IsInclusionDirective);19241925// Check whether M refers to the file in the prebuilt module path.1926if (M && M->getASTFile())1927if (auto ModuleFile = FileMgr->getFile(ModuleFilename))1928if (*ModuleFile == M->getASTFile())1929return M;19301931getDiagnostics().Report(ModuleNameLoc, diag::err_module_prebuilt)1932<< ModuleName;1933return ModuleLoadResult();1934}19351936case ASTReader::OutOfDate:1937case ASTReader::Missing:1938// The most interesting case.1939break;19401941case ASTReader::ConfigurationMismatch:1942if (Source == MS_PrebuiltModulePath)1943// FIXME: We shouldn't be setting HadFatalFailure below if we only1944// produce a warning here!1945getDiagnostics().Report(SourceLocation(),1946diag::warn_module_config_mismatch)1947<< ModuleFilename;1948// Fall through to error out.1949[[fallthrough]];1950case ASTReader::VersionMismatch:1951case ASTReader::HadErrors:1952ModuleLoader::HadFatalFailure = true;1953// FIXME: The ASTReader will already have complained, but can we shoehorn1954// that diagnostic information into a more useful form?1955return ModuleLoadResult();19561957case ASTReader::Failure:1958ModuleLoader::HadFatalFailure = true;1959return ModuleLoadResult();1960}19611962// ReadAST returned Missing or OutOfDate.1963if (Source != MS_ModuleCache) {1964// We don't know the desired configuration for this module and don't1965// necessarily even have a module map. Since ReadAST already produces1966// diagnostics for these two cases, we simply error out here.1967return ModuleLoadResult();1968}19691970// The module file is missing or out-of-date. Build it.1971assert(M && "missing module, but trying to compile for cache");19721973// Check whether there is a cycle in the module graph.1974ModuleBuildStack ModPath = getSourceManager().getModuleBuildStack();1975ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end();1976for (; Pos != PosEnd; ++Pos) {1977if (Pos->first == ModuleName)1978break;1979}19801981if (Pos != PosEnd) {1982SmallString<256> CyclePath;1983for (; Pos != PosEnd; ++Pos) {1984CyclePath += Pos->first;1985CyclePath += " -> ";1986}1987CyclePath += ModuleName;19881989getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle)1990<< ModuleName << CyclePath;1991return nullptr;1992}19931994// Check whether we have already attempted to build this module (but failed).1995if (FailedModules && FailedModules->hasAlreadyFailed(ModuleName)) {1996getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built)1997<< ModuleName << SourceRange(ImportLoc, ModuleNameLoc);1998return nullptr;1999}20002001// Try to compile and then read the AST.2002if (!compileModuleAndReadAST(*this, ImportLoc, ModuleNameLoc, M,2003ModuleFilename)) {2004assert(getDiagnostics().hasErrorOccurred() &&2005"undiagnosed error in compileModuleAndReadAST");2006if (FailedModules)2007FailedModules->addFailed(ModuleName);2008return nullptr;2009}20102011// Okay, we've rebuilt and now loaded the module.2012return M;2013}20142015ModuleLoadResult2016CompilerInstance::loadModule(SourceLocation ImportLoc,2017ModuleIdPath Path,2018Module::NameVisibilityKind Visibility,2019bool IsInclusionDirective) {2020// Determine what file we're searching from.2021StringRef ModuleName = Path[0].first->getName();2022SourceLocation ModuleNameLoc = Path[0].second;20232024// If we've already handled this import, just return the cached result.2025// This one-element cache is important to eliminate redundant diagnostics2026// when both the preprocessor and parser see the same import declaration.2027if (ImportLoc.isValid() && LastModuleImportLoc == ImportLoc) {2028// Make the named module visible.2029if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule)2030TheASTReader->makeModuleVisible(LastModuleImportResult, Visibility,2031ImportLoc);2032return LastModuleImportResult;2033}20342035// If we don't already have information on this module, load the module now.2036Module *Module = nullptr;2037ModuleMap &MM = getPreprocessor().getHeaderSearchInfo().getModuleMap();2038if (auto MaybeModule = MM.getCachedModuleLoad(*Path[0].first)) {2039// Use the cached result, which may be nullptr.2040Module = *MaybeModule;2041// Config macros are already checked before building a module, but they need2042// to be checked at each import location in case any of the config macros2043// have a new value at the current `ImportLoc`.2044if (Module)2045checkConfigMacros(getPreprocessor(), Module, ImportLoc);2046} else if (ModuleName == getLangOpts().CurrentModule) {2047// This is the module we're building.2048Module = PP->getHeaderSearchInfo().lookupModule(2049ModuleName, ImportLoc, /*AllowSearch*/ true,2050/*AllowExtraModuleMapSearch*/ !IsInclusionDirective);20512052// Config macros do not need to be checked here for two reasons.2053// * This will always be textual inclusion, and thus the config macros2054// actually do impact the content of the header.2055// * `Preprocessor::HandleHeaderIncludeOrImport` will never call this2056// function as the `#include` or `#import` is textual.20572058MM.cacheModuleLoad(*Path[0].first, Module);2059} else {2060ModuleLoadResult Result = findOrCompileModuleAndReadAST(2061ModuleName, ImportLoc, ModuleNameLoc, IsInclusionDirective);2062if (!Result.isNormal())2063return Result;2064if (!Result)2065DisableGeneratingGlobalModuleIndex = true;2066Module = Result;2067MM.cacheModuleLoad(*Path[0].first, Module);2068}20692070// If we never found the module, fail. Otherwise, verify the module and link2071// it up.2072if (!Module)2073return ModuleLoadResult();20742075// Verify that the rest of the module path actually corresponds to2076// a submodule.2077bool MapPrivateSubModToTopLevel = false;2078for (unsigned I = 1, N = Path.size(); I != N; ++I) {2079StringRef Name = Path[I].first->getName();2080clang::Module *Sub = Module->findSubmodule(Name);20812082// If the user is requesting Foo.Private and it doesn't exist, try to2083// match Foo_Private and emit a warning asking for the user to write2084// @import Foo_Private instead. FIXME: remove this when existing clients2085// migrate off of Foo.Private syntax.2086if (!Sub && Name == "Private" && Module == Module->getTopLevelModule()) {2087SmallString<128> PrivateModule(Module->Name);2088PrivateModule.append("_Private");20892090SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> PrivPath;2091auto &II = PP->getIdentifierTable().get(2092PrivateModule, PP->getIdentifierInfo(Module->Name)->getTokenID());2093PrivPath.push_back(std::make_pair(&II, Path[0].second));20942095std::string FileName;2096// If there is a modulemap module or prebuilt module, load it.2097if (PP->getHeaderSearchInfo().lookupModule(PrivateModule, ImportLoc, true,2098!IsInclusionDirective) ||2099selectModuleSource(nullptr, PrivateModule, FileName, BuiltModules,2100PP->getHeaderSearchInfo()) != MS_ModuleNotFound)2101Sub = loadModule(ImportLoc, PrivPath, Visibility, IsInclusionDirective);2102if (Sub) {2103MapPrivateSubModToTopLevel = true;2104PP->markClangModuleAsAffecting(Module);2105if (!getDiagnostics().isIgnored(2106diag::warn_no_priv_submodule_use_toplevel, ImportLoc)) {2107getDiagnostics().Report(Path[I].second,2108diag::warn_no_priv_submodule_use_toplevel)2109<< Path[I].first << Module->getFullModuleName() << PrivateModule2110<< SourceRange(Path[0].second, Path[I].second)2111<< FixItHint::CreateReplacement(SourceRange(Path[0].second),2112PrivateModule);2113getDiagnostics().Report(Sub->DefinitionLoc,2114diag::note_private_top_level_defined);2115}2116}2117}21182119if (!Sub) {2120// Attempt to perform typo correction to find a module name that works.2121SmallVector<StringRef, 2> Best;2122unsigned BestEditDistance = (std::numeric_limits<unsigned>::max)();21232124for (class Module *SubModule : Module->submodules()) {2125unsigned ED =2126Name.edit_distance(SubModule->Name,2127/*AllowReplacements=*/true, BestEditDistance);2128if (ED <= BestEditDistance) {2129if (ED < BestEditDistance) {2130Best.clear();2131BestEditDistance = ED;2132}21332134Best.push_back(SubModule->Name);2135}2136}21372138// If there was a clear winner, user it.2139if (Best.size() == 1) {2140getDiagnostics().Report(Path[I].second, diag::err_no_submodule_suggest)2141<< Path[I].first << Module->getFullModuleName() << Best[0]2142<< SourceRange(Path[0].second, Path[I - 1].second)2143<< FixItHint::CreateReplacement(SourceRange(Path[I].second),2144Best[0]);21452146Sub = Module->findSubmodule(Best[0]);2147}2148}21492150if (!Sub) {2151// No submodule by this name. Complain, and don't look for further2152// submodules.2153getDiagnostics().Report(Path[I].second, diag::err_no_submodule)2154<< Path[I].first << Module->getFullModuleName()2155<< SourceRange(Path[0].second, Path[I - 1].second);2156break;2157}21582159Module = Sub;2160}21612162// Make the named module visible, if it's not already part of the module2163// we are parsing.2164if (ModuleName != getLangOpts().CurrentModule) {2165if (!Module->IsFromModuleFile && !MapPrivateSubModToTopLevel) {2166// We have an umbrella header or directory that doesn't actually include2167// all of the headers within the directory it covers. Complain about2168// this missing submodule and recover by forgetting that we ever saw2169// this submodule.2170// FIXME: Should we detect this at module load time? It seems fairly2171// expensive (and rare).2172getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule)2173<< Module->getFullModuleName()2174<< SourceRange(Path.front().second, Path.back().second);21752176return ModuleLoadResult(Module, ModuleLoadResult::MissingExpected);2177}21782179// Check whether this module is available.2180if (Preprocessor::checkModuleIsAvailable(getLangOpts(), getTarget(),2181*Module, getDiagnostics())) {2182getDiagnostics().Report(ImportLoc, diag::note_module_import_here)2183<< SourceRange(Path.front().second, Path.back().second);2184LastModuleImportLoc = ImportLoc;2185LastModuleImportResult = ModuleLoadResult();2186return ModuleLoadResult();2187}21882189TheASTReader->makeModuleVisible(Module, Visibility, ImportLoc);2190}21912192// Resolve any remaining module using export_as for this one.2193getPreprocessor()2194.getHeaderSearchInfo()2195.getModuleMap()2196.resolveLinkAsDependencies(Module->getTopLevelModule());21972198LastModuleImportLoc = ImportLoc;2199LastModuleImportResult = ModuleLoadResult(Module);2200return LastModuleImportResult;2201}22022203void CompilerInstance::createModuleFromSource(SourceLocation ImportLoc,2204StringRef ModuleName,2205StringRef Source) {2206// Avoid creating filenames with special characters.2207SmallString<128> CleanModuleName(ModuleName);2208for (auto &C : CleanModuleName)2209if (!isAlphanumeric(C))2210C = '_';22112212// FIXME: Using a randomized filename here means that our intermediate .pcm2213// output is nondeterministic (as .pcm files refer to each other by name).2214// Can this affect the output in any way?2215SmallString<128> ModuleFileName;2216if (std::error_code EC = llvm::sys::fs::createTemporaryFile(2217CleanModuleName, "pcm", ModuleFileName)) {2218getDiagnostics().Report(ImportLoc, diag::err_fe_unable_to_open_output)2219<< ModuleFileName << EC.message();2220return;2221}2222std::string ModuleMapFileName = (CleanModuleName + ".map").str();22232224FrontendInputFile Input(2225ModuleMapFileName,2226InputKind(getLanguageFromOptions(Invocation->getLangOpts()),2227InputKind::ModuleMap, /*Preprocessed*/true));22282229std::string NullTerminatedSource(Source.str());22302231auto PreBuildStep = [&](CompilerInstance &Other) {2232// Create a virtual file containing our desired source.2233// FIXME: We shouldn't need to do this.2234FileEntryRef ModuleMapFile = Other.getFileManager().getVirtualFileRef(2235ModuleMapFileName, NullTerminatedSource.size(), 0);2236Other.getSourceManager().overrideFileContents(2237ModuleMapFile, llvm::MemoryBuffer::getMemBuffer(NullTerminatedSource));22382239Other.BuiltModules = std::move(BuiltModules);2240Other.DeleteBuiltModules = false;2241};22422243auto PostBuildStep = [this](CompilerInstance &Other) {2244BuiltModules = std::move(Other.BuiltModules);2245};22462247// Build the module, inheriting any modules that we've built locally.2248if (compileModuleImpl(*this, ImportLoc, ModuleName, Input, StringRef(),2249ModuleFileName, PreBuildStep, PostBuildStep)) {2250BuiltModules[std::string(ModuleName)] = std::string(ModuleFileName);2251llvm::sys::RemoveFileOnSignal(ModuleFileName);2252}2253}22542255void CompilerInstance::makeModuleVisible(Module *Mod,2256Module::NameVisibilityKind Visibility,2257SourceLocation ImportLoc) {2258if (!TheASTReader)2259createASTReader();2260if (!TheASTReader)2261return;22622263TheASTReader->makeModuleVisible(Mod, Visibility, ImportLoc);2264}22652266GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex(2267SourceLocation TriggerLoc) {2268if (getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty())2269return nullptr;2270if (!TheASTReader)2271createASTReader();2272// Can't do anything if we don't have the module manager.2273if (!TheASTReader)2274return nullptr;2275// Get an existing global index. This loads it if not already2276// loaded.2277TheASTReader->loadGlobalIndex();2278GlobalModuleIndex *GlobalIndex = TheASTReader->getGlobalIndex();2279// If the global index doesn't exist, create it.2280if (!GlobalIndex && shouldBuildGlobalModuleIndex() && hasFileManager() &&2281hasPreprocessor()) {2282llvm::sys::fs::create_directories(2283getPreprocessor().getHeaderSearchInfo().getModuleCachePath());2284if (llvm::Error Err = GlobalModuleIndex::writeIndex(2285getFileManager(), getPCHContainerReader(),2286getPreprocessor().getHeaderSearchInfo().getModuleCachePath())) {2287// FIXME this drops the error on the floor. This code is only used for2288// typo correction and drops more than just this one source of errors2289// (such as the directory creation failure above). It should handle the2290// error.2291consumeError(std::move(Err));2292return nullptr;2293}2294TheASTReader->resetForReload();2295TheASTReader->loadGlobalIndex();2296GlobalIndex = TheASTReader->getGlobalIndex();2297}2298// For finding modules needing to be imported for fixit messages,2299// we need to make the global index cover all modules, so we do that here.2300if (!HaveFullGlobalModuleIndex && GlobalIndex && !buildingModule()) {2301ModuleMap &MMap = getPreprocessor().getHeaderSearchInfo().getModuleMap();2302bool RecreateIndex = false;2303for (ModuleMap::module_iterator I = MMap.module_begin(),2304E = MMap.module_end(); I != E; ++I) {2305Module *TheModule = I->second;2306OptionalFileEntryRef Entry = TheModule->getASTFile();2307if (!Entry) {2308SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path;2309Path.push_back(std::make_pair(2310getPreprocessor().getIdentifierInfo(TheModule->Name), TriggerLoc));2311std::reverse(Path.begin(), Path.end());2312// Load a module as hidden. This also adds it to the global index.2313loadModule(TheModule->DefinitionLoc, Path, Module::Hidden, false);2314RecreateIndex = true;2315}2316}2317if (RecreateIndex) {2318if (llvm::Error Err = GlobalModuleIndex::writeIndex(2319getFileManager(), getPCHContainerReader(),2320getPreprocessor().getHeaderSearchInfo().getModuleCachePath())) {2321// FIXME As above, this drops the error on the floor.2322consumeError(std::move(Err));2323return nullptr;2324}2325TheASTReader->resetForReload();2326TheASTReader->loadGlobalIndex();2327GlobalIndex = TheASTReader->getGlobalIndex();2328}2329HaveFullGlobalModuleIndex = true;2330}2331return GlobalIndex;2332}23332334// Check global module index for missing imports.2335bool2336CompilerInstance::lookupMissingImports(StringRef Name,2337SourceLocation TriggerLoc) {2338// Look for the symbol in non-imported modules, but only if an error2339// actually occurred.2340if (!buildingModule()) {2341// Load global module index, or retrieve a previously loaded one.2342GlobalModuleIndex *GlobalIndex = loadGlobalModuleIndex(2343TriggerLoc);23442345// Only if we have a global index.2346if (GlobalIndex) {2347GlobalModuleIndex::HitSet FoundModules;23482349// Find the modules that reference the identifier.2350// Note that this only finds top-level modules.2351// We'll let diagnoseTypo find the actual declaration module.2352if (GlobalIndex->lookupIdentifier(Name, FoundModules))2353return true;2354}2355}23562357return false;2358}2359void CompilerInstance::resetAndLeakSema() { llvm::BuryPointer(takeSema()); }23602361void CompilerInstance::setExternalSemaSource(2362IntrusiveRefCntPtr<ExternalSemaSource> ESS) {2363ExternalSemaSrc = std::move(ESS);2364}236523662367