summaryrefslogtreecommitdiffstats
path: root/clang/lib/Lex
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
commitfaeb1d46586271ab1b8a0158cbd5073ef0c6abca (patch)
tree8aacb49a399f80b3c93ee1279e7d8fa0a20e5aac /clang/lib/Lex
parentd4a2b37091486619386db4ccd0b1698fba8db92c (diff)
downloadbcm5719-llvm-faeb1d46586271ab1b8a0158cbd5073ef0c6abca.tar.gz
bcm5719-llvm-faeb1d46586271ab1b8a0158cbd5073ef0c6abca.zip
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. llvm-svn: 139558
Diffstat (limited to 'clang/lib/Lex')
-rw-r--r--clang/lib/Lex/HeaderSearch.cpp40
1 files changed, 37 insertions, 3 deletions
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index 36826756b8b..5cf65cbb0df 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/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;
}
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud