From: Douglas Gregor Date: Sun, 29 Jan 2012 17:08:11 +0000 (+0000) Subject: Rework HeaderSearch's interface for getting a module from a name and X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e434ec71fccfe078906403affd641f709702d598;p=clang Rework HeaderSearch's interface for getting a module from a name and for getting the name of the module file, unifying the code for searching for a module with a given name (into lookupModule()) and separating out the mapping to a module file (into getModuleFileName()). No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149197 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index f61f2adc5b..d1cd8af49a 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -184,6 +184,9 @@ class HeaderSearch { explicit HeaderSearch(); explicit HeaderSearch(const HeaderSearch&); void operator=(const HeaderSearch&); + + friend class DirectoryLookup; + public: HeaderSearch(FileManager &FM, DiagnosticsEngine &Diags, const LangOptions &LangOpts); @@ -343,20 +346,34 @@ public: /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure. const HeaderMap *CreateHeaderMap(const FileEntry *FE); - /// \brief Search in the module cache path for a module with the given - /// name. + /// \brief Retrieve the name of the module file that should be used to + /// load the given module. /// - /// \param Module The module that was found with the given name, which - /// describes the module and how to build it. + /// \param Module The module whose module file name will be returned. /// - /// \param If non-NULL, will be set to the module file name we expected to - /// find (regardless of whether it was actually found or not). + /// \returns The name of the module file that corresponds to this module, + /// or an empty string if this module does not correspond to any module file. + std::string getModuleFileName(Module *Module); + + /// \brief Retrieve the name of the module file that should be used to + /// load a module with the given name. /// - /// \returns A file describing the named module, if already available in the - /// cases, or NULL to indicate that the module could not be found. - const FileEntry *lookupModule(StringRef ModuleName, - Module *&Module, - std::string *ModuleFileName = 0); + /// \param Module The module whose module file name will be returned. + /// + /// \returns The name of the module file that corresponds to this module, + /// or an empty string if this module does not correspond to any module file. + std::string getModuleFileName(StringRef ModuleName); + + /// \brief Lookup a module Search for a module with the given name. + /// + /// \param ModuleName The name of the module we're looking for. + /// + /// \param AllowSearch Whether we are allowed to search in the various + /// search directories to produce a module definition. If not, this lookup + /// will only return an already-known module. + /// + /// \returns The module with the given name. + Module *lookupModule(StringRef ModuleName, bool AllowSearch = true); void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; } @@ -383,17 +400,8 @@ public: /// /// \returns true if an error occurred, false otherwise. bool loadModuleMapFile(const FileEntry *File); - - /// \brief Retrieve a module with the given name. - /// - /// \param Name The name of the module to retrieve. - /// - /// \param AllowSearch If true, we're allowed to look for module maps within - /// the header search path. Otherwise, the module must already be known. - /// - /// \returns The module, if found; otherwise, null. - Module *getModule(StringRef Name, bool AllowSearch = true); +private: /// \brief Retrieve a module with the given name, which may be part of the /// given framework. /// @@ -405,10 +413,11 @@ public: /// frameworks. /// /// \returns The module, if found; otherwise, null. - Module *getFrameworkModule(StringRef Name, - const DirectoryEntry *Dir, - bool IsSystem); - + Module *loadFrameworkModule(StringRef Name, + const DirectoryEntry *Dir, + bool IsSystem); + +public: /// \brief Retrieve the module map. ModuleMap &getModuleMap() { return ModMap; } diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index b8075ed87a..7f22247e57 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -1116,11 +1116,25 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc, Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; } else { // Search for a module with the given name. + Module = PP->getHeaderSearchInfo().lookupModule(ModuleName); std::string ModuleFileName; - ModuleFile - = PP->getHeaderSearchInfo().lookupModule(ModuleName, Module, - &ModuleFileName); - + if (Module) + ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module); + else + ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(ModuleName); + + if (ModuleFileName.empty()) { + getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found) + << ModuleName + << SourceRange(ImportLoc, ModuleNameLoc); + LastModuleImportLoc = ImportLoc; + LastModuleImportResult = 0; + return 0; + } + + const FileEntry *ModuleFile + = getFileManager().getFile(ModuleFileName, /*OpenFile=*/false, + /*CacheFailure=*/false); bool BuildingModule = false; if (!ModuleFile && Module) { // The module is not cached, but we have a module map from which we can diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp index e99e47eb19..669fe4acb3 100644 --- a/lib/Frontend/FrontendActions.cpp +++ b/lib/Frontend/FrontendActions.cpp @@ -226,7 +226,8 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, } // Dig out the module definition. - Module = HS.getModule(CI.getLangOpts().CurrentModule, /*AllowSearch=*/false); + Module = HS.lookupModule(CI.getLangOpts().CurrentModule, + /*AllowSearch=*/false); if (!Module) { CI.getDiagnostics().Report(diag::err_missing_module) << CI.getLangOpts().CurrentModule << Filename; diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp index ff63bdb31b..7c981f852b 100644 --- a/lib/Lex/HeaderSearch.cpp +++ b/lib/Lex/HeaderSearch.cpp @@ -103,79 +103,81 @@ const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) { return 0; } -const FileEntry *HeaderSearch::lookupModule(StringRef ModuleName, - Module *&Module, - std::string *ModuleFileName) { - Module = 0; - +std::string HeaderSearch::getModuleFileName(Module *Module) { // If we don't have a module cache path, we can't do anything. - if (ModuleCachePath.empty()) { - if (ModuleFileName) - ModuleFileName->clear(); - return 0; - } + if (ModuleCachePath.empty()) + return std::string(); + + + llvm::SmallString<256> Result(ModuleCachePath); + llvm::sys::path::append(Result, Module->getTopLevelModule()->Name + ".pcm"); + return Result.str().str(); +} + +std::string HeaderSearch::getModuleFileName(StringRef ModuleName) { + // If we don't have a module cache path, we can't do anything. + if (ModuleCachePath.empty()) + return std::string(); - // Try to find the module path. - llvm::SmallString<256> FileName(ModuleCachePath); - llvm::sys::path::append(FileName, ModuleName + ".pcm"); - if (ModuleFileName) - *ModuleFileName = FileName.str(); - + + llvm::SmallString<256> Result(ModuleCachePath); + llvm::sys::path::append(Result, ModuleName + ".pcm"); + return Result.str().str(); +} + +Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) { // Look in the module map to determine if there is a module by this name. - Module = ModMap.findModule(ModuleName); - if (!Module) { - // Look through the various header search paths to load any avaiable module - // maps, searching for a module map that describes this module. - for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { - if (SearchDirs[Idx].isFramework()) { - // Search for or infer a module map for a framework. - llvm::SmallString<128> FrameworkDirName; - FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName(); - llvm::sys::path::append(FrameworkDirName, ModuleName + ".framework"); - if (const DirectoryEntry *FrameworkDir - = FileMgr.getDirectory(FrameworkDirName)) { - bool IsSystem - = SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User; - Module = getFrameworkModule(ModuleName, FrameworkDir, IsSystem); - if (Module) - break; - } - } - - // FIXME: Figure out how header maps and module maps will work together. - - // Only deal with normal search directories. - if (!SearchDirs[Idx].isNormalDir()) - continue; - - // Search for a module map file in this directory. - if (loadModuleMapFile(SearchDirs[Idx].getDir()) == LMM_NewlyLoaded) { - // We just loaded a module map file; check whether the module is - // available now. - Module = ModMap.findModule(ModuleName); + Module *Module = ModMap.findModule(ModuleName); + if (Module || !AllowSearch) + return Module; + + // Look through the various header search paths to load any avai;able module + // maps, searching for a module map that describes this module. + for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { + if (SearchDirs[Idx].isFramework()) { + // Search for or infer a module map for a framework. + llvm::SmallString<128> FrameworkDirName; + FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName(); + llvm::sys::path::append(FrameworkDirName, ModuleName + ".framework"); + if (const DirectoryEntry *FrameworkDir + = FileMgr.getDirectory(FrameworkDirName)) { + bool IsSystem + = SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User; + Module = loadFrameworkModule(ModuleName, FrameworkDir, IsSystem); if (Module) break; } - - // Search for a module map in a subdirectory with the same name as the - // module. - llvm::SmallString<128> NestedModuleMapDirName; - NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName(); - llvm::sys::path::append(NestedModuleMapDirName, ModuleName); - if (loadModuleMapFile(NestedModuleMapDirName) == LMM_NewlyLoaded) { - // If we just loaded a module map file, look for the module again. - Module = ModMap.findModule(ModuleName); - if (Module) - break; - } + } + + // FIXME: Figure out how header maps and module maps will work together. + + // Only deal with normal search directories. + if (!SearchDirs[Idx].isNormalDir()) + continue; + + // Search for a module map file in this directory. + if (loadModuleMapFile(SearchDirs[Idx].getDir()) == LMM_NewlyLoaded) { + // We just loaded a module map file; check whether the module is + // available now. + Module = ModMap.findModule(ModuleName); + if (Module) + break; + } + + // Search for a module map in a subdirectory with the same name as the + // module. + llvm::SmallString<128> NestedModuleMapDirName; + NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName(); + llvm::sys::path::append(NestedModuleMapDirName, ModuleName); + if (loadModuleMapFile(NestedModuleMapDirName) == LMM_NewlyLoaded) { + // If we just loaded a module map file, look for the module again. + Module = ModMap.findModule(ModuleName); + if (Module) + break; } } - - // Look for the module file in the module cache. - // FIXME: If we didn't find a description of the module itself, should we - // even try to find the module in the cache? - return getFileMgr().getFile(FileName, /*OpenFile=*/false, - /*CacheFailure=*/false); + + return Module; } //===----------------------------------------------------------------------===// @@ -323,7 +325,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup( if (const DirectoryEntry *FrameworkDir = FileMgr.getDirectory(FrameworkName)) { bool IsSystem = getDirCharacteristic() != SrcMgr::C_User; - Module = HS.getFrameworkModule(ModuleName, FrameworkDir, IsSystem); + Module = HS.loadFrameworkModule(ModuleName, FrameworkDir, IsSystem); } } @@ -834,36 +836,9 @@ bool HeaderSearch::loadModuleMapFile(const FileEntry *File) { return Result; } -Module *HeaderSearch::getModule(StringRef Name, bool AllowSearch) { - if (Module *Module = ModMap.findModule(Name)) - return Module; - - if (!AllowSearch) - return 0; - - for (unsigned I = 0, N = SearchDirs.size(); I != N; ++I) { - if (!SearchDirs[I].isNormalDir()) - continue; - - switch (loadModuleMapFile(SearchDirs[I].getDir())) { - case LMM_AlreadyLoaded: - case LMM_InvalidModuleMap: - case LMM_NoDirectory: - break; - - case LMM_NewlyLoaded: - if (Module *Module = ModMap.findModule(Name)) - return Module; - break; - } - } - - return 0; -} - -Module *HeaderSearch::getFrameworkModule(StringRef Name, - const DirectoryEntry *Dir, - bool IsSystem) { +Module *HeaderSearch::loadFrameworkModule(StringRef Name, + const DirectoryEntry *Dir, + bool IsSystem) { if (Module *Module = ModMap.findModule(Name)) return Module; diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp index 5dda96451f..05cbffdfd1 100644 --- a/lib/Lex/Preprocessor.cpp +++ b/lib/Lex/Preprocessor.cpp @@ -383,7 +383,7 @@ Module *Preprocessor::getCurrentModule() { if (getLangOptions().CurrentModule.empty()) return 0; - return getHeaderSearchInfo().getModule(getLangOptions().CurrentModule); + return getHeaderSearchInfo().lookupModule(getLangOptions().CurrentModule); } //===----------------------------------------------------------------------===//