aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Lex/HeaderSearch.cpp47
-rw-r--r--test/Modules/subframeworks.m4
2 files changed, 46 insertions, 5 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;
}
diff --git a/test/Modules/subframeworks.m b/test/Modules/subframeworks.m
index 82c4a4bbf2..e87bc6bac3 100644
--- a/test/Modules/subframeworks.m
+++ b/test/Modules/subframeworks.m
@@ -1,6 +1,6 @@
// RUN: rm -rf %t
-// RUN: %clang_cc1 -Wauto-import -fmodule-cache-path %t -fmodules -F %S/Inputs %s -verify
-// RUN: %clang_cc1 -x objective-c++ -Wauto-import -fmodule-cache-path %t -fmodules -F %S/Inputs %s -verify
+// RUN: %clang_cc1 -Wauto-import -fmodule-cache-path %t -fmodules -F %S/Inputs -F %S/Inputs/DependsOnModule.framework/Frameworks %s -verify
+// RUN: %clang_cc1 -x objective-c++ -Wauto-import -fmodule-cache-path %t -fmodules -F %S/Inputs -F %S/Inputs/DependsOnModule.framework/Frameworks %s -verify
@import DependsOnModule;