aboutsummaryrefslogtreecommitdiff
path: root/lib/Lex/HeaderSearch.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-11-12 00:05:07 +0000
committerDouglas Gregor <dgregor@apple.com>2011-11-12 00:05:07 +0000
commitcf70d7873fe3098bdac72e7628f4e832d14d5143 (patch)
tree9b2b859a9268eb18e4bd3656627facccacacc502 /lib/Lex/HeaderSearch.cpp
parent194428cc83c8127982abd7a6a420e10f366aa7e6 (diff)
When searching for a module, speculatively load module maps to see if
the module is described in one of the module maps in a search path or in a subdirectory off the search path that has the same name as the module we're looking for. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144433 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Lex/HeaderSearch.cpp')
-rw-r--r--lib/Lex/HeaderSearch.cpp115
1 files changed, 75 insertions, 40 deletions
diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp
index 3f50285430..3e4a1d32a0 100644
--- a/lib/Lex/HeaderSearch.cpp
+++ b/lib/Lex/HeaderSearch.cpp
@@ -127,15 +127,45 @@ const FileEntry *HeaderSearch::lookupModule(StringRef ModuleName,
if (!UmbrellaHeader)
return 0;
- // Look in the module map to determine if there is a module by this name
- // that has an umbrella header.
+ // Look in the module map to determine if there is a module by this name.
+ ModuleMap::Module *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) {
+ // Skip non-normal include paths
+ if (!SearchDirs[Idx].isNormalDir())
+ continue;
+
+ // Search for a module map in this directory, if we haven't already
+ // looked there.
+ if (!loadModuleMapFile(SearchDirs[Idx].getDir())) {
+ // If we found a module map, look for the module again.
+ 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)) {
+ // If we found a module map, look for the module again.
+ Module = ModMap.findModule(ModuleName);
+ if (Module)
+ break;
+ }
+ }
+ }
+
+ // If we have a module with an umbrella header
// FIXME: Even if it doesn't have an umbrella header, we should be able to
// handle the module. However, the caller isn't ready for that yet.
- if (ModuleMap::Module *Module = ModMap.findModule(ModuleName)) {
- if (Module->UmbrellaHeader) {
- *UmbrellaHeader = Module->UmbrellaHeader->getName();
- return 0;
- }
+ if (Module && Module->UmbrellaHeader) {
+ *UmbrellaHeader = Module->UmbrellaHeader->getName();
+ return 0;
}
// Look in each of the framework directories for an umbrella header with
@@ -735,45 +765,20 @@ bool HeaderSearch::hasModuleMap(StringRef FileName,
if (!Dir)
return false;
- llvm::DenseMap<const DirectoryEntry *, bool>::iterator
- KnownDir = DirectoryHasModuleMap.find(Dir);
- if (KnownDir != DirectoryHasModuleMap.end()) {
- // We have seen this directory before. If it has no module map file,
- // we're done.
- if (!KnownDir->second)
- return false;
-
- // All of the directories we stepped through inherit this module map
- // file.
+ // Try to load the module map file in this directory.
+ if (!loadModuleMapFile(Dir)) {
+ // Success. All of the directories we stepped through inherit this module
+ // map file.
for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I)
DirectoryHasModuleMap[FixUpDirectories[I]] = true;
return true;
}
-
- // We have not checked for a module map file in this directory yet;
- // do so now.
- llvm::SmallString<128> ModuleMapFileName;
- ModuleMapFileName += Dir->getName();
- llvm::sys::path::append(ModuleMapFileName, "module.map");
- if (const FileEntry *ModuleMapFile = FileMgr.getFile(ModuleMapFileName)) {
- // We have found a module map file. Try to parse it.
- if (!ModMap.parseModuleMapFile(ModuleMapFile)) {
- // This directory has a module map.
- DirectoryHasModuleMap[Dir] = true;
-
- // All of the directories we stepped through inherit this module map
- // file.
- for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I)
- DirectoryHasModuleMap[FixUpDirectories[I]] = true;
-
- return true;
- }
- }
- // This directory did not have a module map file.
- DirectoryHasModuleMap[Dir] = false;
-
+ // If we hit the top of our search, we're done.
+ if (Dir == Root)
+ return false;
+
// Keep track of all of the directories we checked, so we can mark them as
// having module maps if we eventually do find a module map.
FixUpDirectories.push_back(Dir);
@@ -789,4 +794,34 @@ StringRef HeaderSearch::findModuleForHeader(const FileEntry *File) {
return StringRef();
}
+bool HeaderSearch::loadModuleMapFile(StringRef DirName) {
+ if (const DirectoryEntry *Dir = FileMgr.getDirectory(DirName))
+ return loadModuleMapFile(Dir);
+
+ return true;
+}
+
+bool HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir) {
+ llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir
+ = DirectoryHasModuleMap.find(Dir);
+ if (KnownDir != DirectoryHasModuleMap.end())
+ return !KnownDir->second;
+
+ llvm::SmallString<128> ModuleMapFileName;
+ ModuleMapFileName += Dir->getName();
+ llvm::sys::path::append(ModuleMapFileName, "module.map");
+ if (const FileEntry *ModuleMapFile = FileMgr.getFile(ModuleMapFileName)) {
+ // We have found a module map file. Try to parse it.
+ if (!ModMap.parseModuleMapFile(ModuleMapFile)) {
+ // This directory has a module map.
+ DirectoryHasModuleMap[Dir] = true;
+
+ return false;
+ }
+ }
+
+ // No suitable module map.
+ DirectoryHasModuleMap[Dir] = false;
+ return true;
+}