diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-01-13 22:31:52 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-01-13 22:31:52 +0000 |
commit | a8c6fea0234bc23de6106a84646dc049cf45e8c8 (patch) | |
tree | 6462deec8e2e867cca99821b42e6d976f2be4bea /lib/Lex/HeaderSearch.cpp | |
parent | d9b859a74ecaede23a78d37f364498102ef418c9 (diff) |
When inferring a module for a framework, first determine whether that
framework is actually a subframework within a top-level framework. If
so, only infer a module for the top-level framework and then dig out
the appropriate submodule.
This helps us cope with an amusing subframeworks anti-pattern, where
one uses -F <framework>/Frameworks to get direct include access to the
subframeworks of a framework (which otherwise would not be
permitted).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148148 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Lex/HeaderSearch.cpp')
-rw-r--r-- | lib/Lex/HeaderSearch.cpp | 47 |
1 files changed, 44 insertions, 3 deletions
diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp index 070daa0cd1..6d2d72fc22 100644 --- a/lib/Lex/HeaderSearch.cpp +++ b/lib/Lex/HeaderSearch.cpp @@ -860,7 +860,7 @@ Module *HeaderSearch::getModule(StringRef Name, bool AllowSearch) { } Module *HeaderSearch::getFrameworkModule(StringRef Name, - const DirectoryEntry *Dir) { + const DirectoryEntry *Dir) { if (Module *Module = ModMap.findModule(Name)) return Module; @@ -876,9 +876,50 @@ Module *HeaderSearch::getFrameworkModule(StringRef Name, case LMM_NewlyLoaded: return ModMap.findModule(Name); } + + // The top-level framework directory, from which we'll infer a framework + // module. + const DirectoryEntry *TopFrameworkDir = Dir; + + // The path from the module we're actually looking for back to the top-level + // framework name. + llvm::SmallVector<StringRef, 2> SubmodulePath; + SubmodulePath.push_back(Name); - // Try to infer a module map. - return ModMap.inferFrameworkModule(Name, Dir, /*Parent=*/0); + // Walk the directory structure to find any enclosing frameworks. + StringRef DirName = Dir->getName(); + do { + // Get the parent directory name. + DirName = llvm::sys::path::parent_path(DirName); + if (DirName.empty()) + break; + + // Determine whether this directory exists. + Dir = FileMgr.getDirectory(DirName); + if (!Dir) + break; + + // If this is a framework directory, then we're a subframework of this + // framework. + if (llvm::sys::path::extension(DirName) == ".framework") { + SubmodulePath.push_back(llvm::sys::path::stem(DirName)); + TopFrameworkDir = Dir; + } + } while (true); + + // Try to infer a module map from the top-level framework directory. + Module *Result = ModMap.inferFrameworkModule(SubmodulePath.back(), + TopFrameworkDir, + /*Parent=*/0); + + // Follow the submodule path to find the requested (sub)framework module + // within the top-level framework module. + SubmodulePath.pop_back(); + while (!SubmodulePath.empty() && Result) { + Result = ModMap.lookupModuleQualified(SubmodulePath.back(), Result); + SubmodulePath.pop_back(); + } + return Result; } |