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.

llvm-svn: 149197
This commit is contained in:
Douglas Gregor
2012-01-29 17:08:11 +00:00
parent dd7cae51d8
commit 279a6c3747
5 changed files with 126 additions and 127 deletions

View File

@@ -184,6 +184,9 @@ class HeaderSearch {
explicit HeaderSearch(); explicit HeaderSearch();
explicit HeaderSearch(const HeaderSearch&); explicit HeaderSearch(const HeaderSearch&);
void operator=(const HeaderSearch&); void operator=(const HeaderSearch&);
friend class DirectoryLookup;
public: public:
HeaderSearch(FileManager &FM, DiagnosticsEngine &Diags, HeaderSearch(FileManager &FM, DiagnosticsEngine &Diags,
const LangOptions &LangOpts); const LangOptions &LangOpts);
@@ -343,20 +346,34 @@ public:
/// FileEntry, uniquing them through the the 'HeaderMaps' datastructure. /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure.
const HeaderMap *CreateHeaderMap(const FileEntry *FE); const HeaderMap *CreateHeaderMap(const FileEntry *FE);
/// \brief Search in the module cache path for a module with the given /// \brief Retrieve the name of the module file that should be used to
/// name. /// load the given module.
/// ///
/// \param Module The module that was found with the given name, which /// \param Module The module whose module file name will be returned.
/// describes the module and how to build it.
/// ///
/// \param If non-NULL, will be set to the module file name we expected to /// \returns The name of the module file that corresponds to this module,
/// find (regardless of whether it was actually found or not). /// 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 /// \param Module The module whose module file name will be returned.
/// cases, or NULL to indicate that the module could not be found. ///
const FileEntry *lookupModule(StringRef ModuleName, /// \returns The name of the module file that corresponds to this module,
Module *&Module, /// or an empty string if this module does not correspond to any module file.
std::string *ModuleFileName = 0); 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; } void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
@@ -384,16 +401,7 @@ public:
/// \returns true if an error occurred, false otherwise. /// \returns true if an error occurred, false otherwise.
bool loadModuleMapFile(const FileEntry *File); bool loadModuleMapFile(const FileEntry *File);
/// \brief Retrieve a module with the given name. private:
///
/// \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);
/// \brief Retrieve a module with the given name, which may be part of the /// \brief Retrieve a module with the given name, which may be part of the
/// given framework. /// given framework.
/// ///
@@ -405,10 +413,11 @@ public:
/// frameworks. /// frameworks.
/// ///
/// \returns The module, if found; otherwise, null. /// \returns The module, if found; otherwise, null.
Module *getFrameworkModule(StringRef Name, Module *loadFrameworkModule(StringRef Name,
const DirectoryEntry *Dir, const DirectoryEntry *Dir,
bool IsSystem); bool IsSystem);
public:
/// \brief Retrieve the module map. /// \brief Retrieve the module map.
ModuleMap &getModuleMap() { return ModMap; } ModuleMap &getModuleMap() { return ModMap; }

View File

@@ -1116,11 +1116,25 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
} else { } else {
// Search for a module with the given name. // Search for a module with the given name.
Module = PP->getHeaderSearchInfo().lookupModule(ModuleName);
std::string ModuleFileName; std::string ModuleFileName;
ModuleFile if (Module)
= PP->getHeaderSearchInfo().lookupModule(ModuleName, Module, ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module);
&ModuleFileName); 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; bool BuildingModule = false;
if (!ModuleFile && Module) { if (!ModuleFile && Module) {
// The module is not cached, but we have a module map from which we can // The module is not cached, but we have a module map from which we can

View File

@@ -226,7 +226,8 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI,
} }
// Dig out the module definition. // Dig out the module definition.
Module = HS.getModule(CI.getLangOpts().CurrentModule, /*AllowSearch=*/false); Module = HS.lookupModule(CI.getLangOpts().CurrentModule,
/*AllowSearch=*/false);
if (!Module) { if (!Module) {
CI.getDiagnostics().Report(diag::err_missing_module) CI.getDiagnostics().Report(diag::err_missing_module)
<< CI.getLangOpts().CurrentModule << Filename; << CI.getLangOpts().CurrentModule << Filename;

View File

@@ -103,28 +103,35 @@ const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) {
return 0; return 0;
} }
const FileEntry *HeaderSearch::lookupModule(StringRef ModuleName, std::string HeaderSearch::getModuleFileName(Module *Module) {
Module *&Module,
std::string *ModuleFileName) {
Module = 0;
// If we don't have a module cache path, we can't do anything. // If we don't have a module cache path, we can't do anything.
if (ModuleCachePath.empty()) { if (ModuleCachePath.empty())
if (ModuleFileName) return std::string();
ModuleFileName->clear();
return 0;
llvm::SmallString<256> Result(ModuleCachePath);
llvm::sys::path::append(Result, Module->getTopLevelModule()->Name + ".pcm");
return Result.str().str();
} }
// Try to find the module path. std::string HeaderSearch::getModuleFileName(StringRef ModuleName) {
llvm::SmallString<256> FileName(ModuleCachePath); // If we don't have a module cache path, we can't do anything.
llvm::sys::path::append(FileName, ModuleName + ".pcm"); if (ModuleCachePath.empty())
if (ModuleFileName) return std::string();
*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. // Look in the module map to determine if there is a module by this name.
Module = ModMap.findModule(ModuleName); Module *Module = ModMap.findModule(ModuleName);
if (!Module) { if (Module || !AllowSearch)
// Look through the various header search paths to load any avaiable module 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. // maps, searching for a module map that describes this module.
for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
if (SearchDirs[Idx].isFramework()) { if (SearchDirs[Idx].isFramework()) {
@@ -136,7 +143,7 @@ const FileEntry *HeaderSearch::lookupModule(StringRef ModuleName,
= FileMgr.getDirectory(FrameworkDirName)) { = FileMgr.getDirectory(FrameworkDirName)) {
bool IsSystem bool IsSystem
= SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User; = SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User;
Module = getFrameworkModule(ModuleName, FrameworkDir, IsSystem); Module = loadFrameworkModule(ModuleName, FrameworkDir, IsSystem);
if (Module) if (Module)
break; break;
} }
@@ -169,13 +176,8 @@ const FileEntry *HeaderSearch::lookupModule(StringRef ModuleName,
break; break;
} }
} }
}
// Look for the module file in the module cache. return Module;
// 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);
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@@ -323,7 +325,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup(
if (const DirectoryEntry *FrameworkDir if (const DirectoryEntry *FrameworkDir
= FileMgr.getDirectory(FrameworkName)) { = FileMgr.getDirectory(FrameworkName)) {
bool IsSystem = getDirCharacteristic() != SrcMgr::C_User; bool IsSystem = getDirCharacteristic() != SrcMgr::C_User;
Module = HS.getFrameworkModule(ModuleName, FrameworkDir, IsSystem); Module = HS.loadFrameworkModule(ModuleName, FrameworkDir, IsSystem);
} }
} }
@@ -834,34 +836,7 @@ bool HeaderSearch::loadModuleMapFile(const FileEntry *File) {
return Result; return Result;
} }
Module *HeaderSearch::getModule(StringRef Name, bool AllowSearch) { Module *HeaderSearch::loadFrameworkModule(StringRef Name,
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, const DirectoryEntry *Dir,
bool IsSystem) { bool IsSystem) {
if (Module *Module = ModMap.findModule(Name)) if (Module *Module = ModMap.findModule(Name))

View File

@@ -383,7 +383,7 @@ Module *Preprocessor::getCurrentModule() {
if (getLangOptions().CurrentModule.empty()) if (getLangOptions().CurrentModule.empty())
return 0; return 0;
return getHeaderSearchInfo().getModule(getLangOptions().CurrentModule); return getHeaderSearchInfo().lookupModule(getLangOptions().CurrentModule);
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//