diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Driver/ToolChains/Clang.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInstance.cpp | 17 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Frontend/FrontendActions.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Lex/HeaderSearch.cpp | 23 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 32 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 18 | ||||
-rw-r--r-- | clang/lib/Serialization/GlobalModuleIndex.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Serialization/ModuleManager.cpp | 16 |
9 files changed, 113 insertions, 32 deletions
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index af7b46475fa..137b34ed6d0 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3651,9 +3651,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (HaveAnyModules) { // -fprebuilt-module-path specifies where to load the prebuilt module files. - for (const Arg *A : Args.filtered(options::OPT_fprebuilt_module_path)) + for (const Arg *A : Args.filtered(options::OPT_fprebuilt_module_path)) { CmdArgs.push_back(Args.MakeArgString( std::string("-fprebuilt-module-path=") + A->getValue())); + A->claim(); + } } // -fmodule-name specifies the module that is currently being built (or @@ -3676,7 +3678,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } } - // -fmodule-file can be used to specify files containing precompiled modules. + // The -fmodule-file=<name>=<file> form specifies the mapping of module + // names to precompiled module files (the module is loaded only if used). + // The -fmodule-file=<file> form can be used to unconditionally load + // precompiled module files (whether used or not). if (HaveAnyModules) Args.AddAllArgs(CmdArgs, options::OPT_fmodule_file); else diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 84d837d4883..9a4bcc2722e 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -1641,6 +1641,14 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, } else if (ModuleName == getLangOpts().CurrentModule) { // This is the module we're building. Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); + /// FIXME: perhaps we should (a) look for a module using the module name + // to file map (PrebuiltModuleFiles) and (b) diagnose if still not found? + //if (Module == nullptr) { + // getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found) + // << ModuleName; + // ModuleBuildFailed = true; + // return ModuleLoadResult(); + //} Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; } else { // Search for a module with the given name. @@ -1662,16 +1670,17 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, } // Try to load the module from the prebuilt module path. - if (Source == ModuleNotFound && !HSOpts.PrebuiltModulePaths.empty()) { - ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName( - ModuleName, "", /*UsePrebuiltPath*/ true); + if (Source == ModuleNotFound && (!HSOpts.PrebuiltModuleFiles.empty() || + !HSOpts.PrebuiltModulePaths.empty())) { + ModuleFileName = + PP->getHeaderSearchInfo().getPrebuiltModuleFileName(ModuleName); if (!ModuleFileName.empty()) Source = PrebuiltModulePath; } // Try to load the module from the module cache. if (Source == ModuleNotFound && Module) { - ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module); + ModuleFileName = PP->getHeaderSearchInfo().getCachedModuleFileName(Module); Source = ModuleCache; } diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 2cc93c1f13d..f9dafbb88ea 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1009,9 +1009,12 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts, // They won't be discovered by the regular preprocessor, so // we let make / ninja to know about this implicit dependency. Opts.ExtraDeps = Args.getAllArgValues(OPT_fdepfile_entry); - auto ModuleFiles = Args.getAllArgValues(OPT_fmodule_file); - Opts.ExtraDeps.insert(Opts.ExtraDeps.end(), ModuleFiles.begin(), - ModuleFiles.end()); + // Only the -fmodule-file=<file> form. + for (const Arg *A : Args.filtered(OPT_fmodule_file)) { + StringRef Val = A->getValue(); + if (Val.find('=') == StringRef::npos) + Opts.ExtraDeps.push_back(Val); + } } static bool parseShowColorsArgs(const ArgList &Args, bool DefaultColor) { @@ -1340,7 +1343,12 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Opts.UseGlobalModuleIndex = !Args.hasArg(OPT_fno_modules_global_index); Opts.GenerateGlobalModuleIndex = Opts.UseGlobalModuleIndex; Opts.ModuleMapFiles = Args.getAllArgValues(OPT_fmodule_map_file); - Opts.ModuleFiles = Args.getAllArgValues(OPT_fmodule_file); + // Only the -fmodule-file=<file> form. + for (const Arg *A : Args.filtered(OPT_fmodule_file)) { + StringRef Val = A->getValue(); + if (Val.find('=') == StringRef::npos) + Opts.ModuleFiles.push_back(Val); + } Opts.ModulesEmbedFiles = Args.getAllArgValues(OPT_fmodules_embed_file_EQ); Opts.ModulesEmbedAllFiles = Args.hasArg(OPT_fmodules_embed_all_files); Opts.IncludeTimestamps = !Args.hasArg(OPT_fno_pch_timestamp); @@ -1544,6 +1552,12 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, Opts.ModuleCachePath = P.str(); Opts.ModuleUserBuildPath = Args.getLastArgValue(OPT_fmodules_user_build_path); + // Only the -fmodule-file=<name>=<file> form. + for (const Arg *A : Args.filtered(OPT_fmodule_file)) { + StringRef Val = A->getValue(); + if (Val.find('=') != StringRef::npos) + Opts.PrebuiltModuleFiles.insert(Val.split('=')); + } for (const Arg *A : Args.filtered(OPT_fprebuilt_module_path)) Opts.AddPrebuiltModulePath(A->getValue()); Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash); diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index d42400183a4..3e3483d2c6b 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -185,8 +185,8 @@ GenerateModuleFromModuleMapAction::CreateOutputFile(CompilerInstance &CI, HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo(); CI.getFrontendOpts().OutputFile = - HS.getModuleFileName(CI.getLangOpts().CurrentModule, ModuleMapFile, - /*UsePrebuiltPath=*/false); + HS.getCachedModuleFileName(CI.getLangOpts().CurrentModule, + ModuleMapFile); } // We use createOutputFile here because this is exposed via libclang, and we diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp index 1ebcc0a1c65..b18d27376a5 100644 --- a/clang/lib/Lex/HeaderSearch.cpp +++ b/clang/lib/Lex/HeaderSearch.cpp @@ -128,21 +128,24 @@ void HeaderSearch::getHeaderMapFileNames( Names.push_back(HM.first->getName()); } -std::string HeaderSearch::getModuleFileName(Module *Module) { +std::string HeaderSearch::getCachedModuleFileName(Module *Module) { const FileEntry *ModuleMap = getModuleMap().getModuleMapFileForUniquing(Module); - return getModuleFileName(Module->Name, ModuleMap->getName(), - /*UsePrebuiltPath*/false); + return getCachedModuleFileName(Module->Name, ModuleMap->getName()); } -std::string HeaderSearch::getModuleFileName(StringRef ModuleName, - StringRef ModuleMapPath, - bool UsePrebuiltPath) { - if (UsePrebuiltPath) { - if (HSOpts->PrebuiltModulePaths.empty()) +std::string HeaderSearch::getPrebuiltModuleFileName(StringRef ModuleName, + bool FileMapOnly) { + // First check the module name to pcm file map. + auto i (HSOpts->PrebuiltModuleFiles.find(ModuleName)); + if (i != HSOpts->PrebuiltModuleFiles.end()) + return i->second; + + if (FileMapOnly || HSOpts->PrebuiltModulePaths.empty()) return std::string(); - // Go though each prebuilt module path and try to find the pcm file. + // Then go through each prebuilt module directory and try to find the pcm + // file. for (const std::string &Dir : HSOpts->PrebuiltModulePaths) { SmallString<256> Result(Dir); llvm::sys::fs::make_absolute(Result); @@ -154,6 +157,8 @@ std::string HeaderSearch::getModuleFileName(StringRef ModuleName, return std::string(); } +std::string HeaderSearch::getCachedModuleFileName(StringRef ModuleName, + StringRef ModuleMapPath) { // If we don't have a module cache path or aren't supposed to use one, we // can't do anything. if (getModuleCachePath().empty()) diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 55136e3a3ce..2db46a65709 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -2485,7 +2485,23 @@ ASTReader::ReadControlBlock(ModuleFile &F, {{(uint32_t)Record[Idx++], (uint32_t)Record[Idx++], (uint32_t)Record[Idx++], (uint32_t)Record[Idx++], (uint32_t)Record[Idx++]}}}; - auto ImportedFile = ReadPath(F, Record, Idx); + + std::string ImportedName = ReadString(Record, Idx); + std::string ImportedFile; + + // For prebuilt and explicit modules first consult the file map for + // an override. Note that here we don't search prebuilt module + // directories, only the explicit name to file mappings. Also, we will + // still verify the size/signature making sure it is essentially the + // same file but perhaps in a different location. + if (ImportedKind == MK_PrebuiltModule || ImportedKind == MK_ExplicitModule) + ImportedFile = PP.getHeaderSearchInfo().getPrebuiltModuleFileName( + ImportedName, /*FileMapOnly*/ true); + + if (ImportedFile.empty()) + ImportedFile = ReadPath(F, Record, Idx); + else + SkipPath(Record, Idx); // If our client can't cope with us being out of date, we can't cope with // our dependency being missing. @@ -3420,12 +3436,18 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const { RemapBuilder TypeRemap(F.TypeRemap); while (Data < DataEnd) { - // FIXME: Looking up dependency modules by filename is horrible. + // FIXME: Looking up dependency modules by filename is horrible. Let's + // start fixing this with prebuilt and explicit modules and see how it + // goes... using namespace llvm::support; + ModuleKind Kind = static_cast<ModuleKind>( + endian::readNext<uint8_t, little, unaligned>(Data)); uint16_t Len = endian::readNext<uint16_t, little, unaligned>(Data); StringRef Name = StringRef((const char*)Data, Len); Data += Len; - ModuleFile *OM = ModuleMgr.lookup(Name); + ModuleFile *OM = (Kind == MK_PrebuiltModule || Kind == MK_ExplicitModule + ? ModuleMgr.lookupByModuleName(Name) + : ModuleMgr.lookupByFileName(Name)); if (!OM) { std::string Msg = "SourceLocation remap refers to unknown module, cannot find "; @@ -4756,6 +4778,7 @@ bool ASTReader::readASTFileControlBlock( while (Idx < N) { // Read information about the AST file. Idx += 5; // ImportLoc, Size, ModTime, Signature + SkipString(Record, Idx); // Module name; FIXME: pass to listener? std::string Filename = ReadString(Record, Idx); ResolveImportedPath(Filename, ModuleDir); Listener.visitImport(Filename); @@ -10346,7 +10369,8 @@ ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context, SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()), PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()), PP(PP), ContextObj(Context), - ModuleMgr(PP.getFileManager(), PP.getPCMCache(), PCHContainerRdr), + ModuleMgr(PP.getFileManager(), PP.getPCMCache(), PCHContainerRdr, + PP.getHeaderSearchInfo()), PCMCache(PP.getPCMCache()), DummyIdResolver(PP), ReadTimer(std::move(ReadTimer)), isysroot(isysroot), DisableValidation(DisableValidation), diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 62c9fb46203..0d45b27cbe6 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -1505,6 +1505,7 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, for (auto I : M.Signature) Record.push_back(I); + AddString(M.ModuleName, Record); AddPath(M.FileName, Record); } Stream.EmitRecord(IMPORTS, Record); @@ -4779,7 +4780,8 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, // each of those modules were mapped into our own offset/ID space, so that // the reader can build the appropriate mapping to its own offset/ID space. // The map consists solely of a blob with the following format: - // *(module-name-len:i16 module-name:len*i8 + // *(module-kind:i8 + // module-name-len:i16 module-name:len*i8 // source-location-offset:i32 // identifier-id:i32 // preprocessed-entity-id:i32 @@ -4790,6 +4792,10 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, // c++-base-specifiers-id:i32 // type-id:i32) // + // module-kind is the ModuleKind enum value. If it is MK_PrebuiltModule or + // MK_ExplicitModule, then the module-name is the module name. Otherwise, + // it is the module file name. + // auto Abbrev = std::make_shared<BitCodeAbbrev>(); Abbrev->Add(BitCodeAbbrevOp(MODULE_OFFSET_MAP)); Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); @@ -4800,9 +4806,13 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, for (ModuleFile &M : Chain->ModuleMgr) { using namespace llvm::support; endian::Writer<little> LE(Out); - StringRef FileName = M.FileName; - LE.write<uint16_t>(FileName.size()); - Out.write(FileName.data(), FileName.size()); + LE.write<uint8_t>(static_cast<uint8_t>(M.Kind)); + StringRef Name = + M.Kind == MK_PrebuiltModule || M.Kind == MK_ExplicitModule + ? M.ModuleName + : M.FileName; + LE.write<uint16_t>(Name.size()); + Out.write(Name.data(), Name.size()); // Note: if a base ID was uint max, it would not be possible to load // another module after it or have more than one entity inside it. diff --git a/clang/lib/Serialization/GlobalModuleIndex.cpp b/clang/lib/Serialization/GlobalModuleIndex.cpp index 6978e7e0977..20c114297b9 100644 --- a/clang/lib/Serialization/GlobalModuleIndex.cpp +++ b/clang/lib/Serialization/GlobalModuleIndex.cpp @@ -619,6 +619,10 @@ bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) { (uint32_t)Record[Idx++], (uint32_t)Record[Idx++], (uint32_t)Record[Idx++]}}}; + // Skip the module name (currently this is only used for prebuilt + // modules while here we are only dealing with cached). + Idx += Record[Idx] + 1; + // Retrieve the imported file name. unsigned Length = Record[Idx++]; SmallString<128> ImportedFile(Record.begin() + Idx, diff --git a/clang/lib/Serialization/ModuleManager.cpp b/clang/lib/Serialization/ModuleManager.cpp index 1dee4d06986..75634401f66 100644 --- a/clang/lib/Serialization/ModuleManager.cpp +++ b/clang/lib/Serialization/ModuleManager.cpp @@ -28,7 +28,7 @@ using namespace clang; using namespace serialization; -ModuleFile *ModuleManager::lookup(StringRef Name) const { +ModuleFile *ModuleManager::lookupByFileName(StringRef Name) const { const FileEntry *Entry = FileMgr.getFile(Name, /*openFile=*/false, /*cacheFailure=*/false); if (Entry) @@ -37,6 +37,14 @@ ModuleFile *ModuleManager::lookup(StringRef Name) const { return nullptr; } +ModuleFile *ModuleManager::lookupByModuleName(StringRef Name) const { + if (const Module *Mod = HeaderSearchInfo.getModuleMap().findModule(Name)) + if (const FileEntry *File = Mod->getASTFile()) + return lookup(File); + + return nullptr; +} + ModuleFile *ModuleManager::lookup(const FileEntry *File) const { auto Known = Modules.find(File); if (Known == Modules.end()) @@ -306,9 +314,11 @@ void ModuleManager::moduleFileAccepted(ModuleFile *MF) { } ModuleManager::ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache, - const PCHContainerReader &PCHContainerRdr) + const PCHContainerReader &PCHContainerRdr, + const HeaderSearch& HeaderSearchInfo) : FileMgr(FileMgr), PCMCache(&PCMCache), PCHContainerRdr(PCHContainerRdr), - GlobalIndex(), FirstVisitState(nullptr) {} + HeaderSearchInfo (HeaderSearchInfo), GlobalIndex(), + FirstVisitState(nullptr) {} ModuleManager::~ModuleManager() { delete FirstVisitState; } |