aboutsummaryrefslogtreecommitdiff
path: root/lib/Lex/HeaderSearch.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-09-12 23:31:24 +0000
committerDouglas Gregor <dgregor@apple.com>2011-09-12 23:31:24 +0000
commit21cae2059a06f7d89eee169409c9266def1b1aca (patch)
tree4e73722923a65113a110c7b3003ce0d27b731b42 /lib/Lex/HeaderSearch.cpp
parent41bdde9e961c4d96a94148f20f0b18397f4358dd (diff)
When an import statement fails to find a module in the module cache,
but there is a corresponding umbrella header in a framework, build the module on-the-fly so it can be immediately loaded at the import statement. This is very much proof-of-concept code, with details to be fleshed out over time. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139558 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Lex/HeaderSearch.cpp')
-rw-r--r--lib/Lex/HeaderSearch.cpp40
1 files changed, 37 insertions, 3 deletions
diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp
index 36826756b8..5cf65cbb0d 100644
--- a/lib/Lex/HeaderSearch.cpp
+++ b/lib/Lex/HeaderSearch.cpp
@@ -98,14 +98,48 @@ const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) {
return 0;
}
-const FileEntry *HeaderSearch::lookupModule(StringRef ModuleName) {
+const FileEntry *HeaderSearch::lookupModule(StringRef ModuleName,
+ std::string *UmbrellaHeader) {
// If we don't have a module cache path, we can't do anything.
if (ModuleCachePath.empty())
return 0;
-
+
+ // Try to find the module path.
llvm::SmallString<256> FileName(ModuleCachePath);
llvm::sys::path::append(FileName, ModuleName + ".pcm");
- return getFileMgr().getFile(FileName);
+ if (const FileEntry *ModuleFile = getFileMgr().getFile(FileName))
+ return ModuleFile;
+
+ // We didn't find the module. If we're not supposed to look for an
+ // umbrella header, this is the end of the road.
+ if (!UmbrellaHeader)
+ return 0;
+
+ // Look in each of the framework directories for an umbrella header with
+ // the same name as the module.
+ // FIXME: We need a way for non-frameworks to provide umbrella headers.
+ llvm::SmallString<128> UmbrellaHeaderName;
+ UmbrellaHeaderName = ModuleName;
+ UmbrellaHeaderName += '/';
+ UmbrellaHeaderName += ModuleName;
+ UmbrellaHeaderName += ".h";
+ for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
+ // Skip non-framework include paths
+ if (!SearchDirs[Idx].isFramework())
+ continue;
+
+ // Look for the umbrella header in this directory.
+ if (const FileEntry *HeaderFile
+ = SearchDirs[Idx].LookupFile(UmbrellaHeaderName, *this, 0, 0)) {
+ *UmbrellaHeader = HeaderFile->getName();
+ return 0;
+ }
+ }
+
+ // We did not find an umbrella header. Clear out the UmbrellaHeader pointee
+ // so our caller knows that we failed.
+ UmbrellaHeader->clear();
+ return 0;
}
//===----------------------------------------------------------------------===//