aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2013-02-08 00:10:48 +0000
committerDouglas Gregor <dgregor@apple.com>2013-02-08 00:10:48 +0000
commit1b58c74af272a1d8228b8161c93a8a018456098e (patch)
treea00e8950068520a1697260fdb30ba06d8a44d1d7
parent8135886ab74d852a6702b1f5656a0b146abe210a (diff)
Teach subframework header lookup to suggest modules <rdar://problem/13176200>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174683 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Lex/HeaderSearch.h3
-rw-r--r--lib/Lex/HeaderSearch.cpp23
-rw-r--r--lib/Lex/PPDirectives.cpp7
-rw-r--r--test/Index/index-module.m1
-rw-r--r--test/Modules/Inputs/HasSubModules.framework/Frameworks/Sub.framework/Headers/Sub.h1
-rw-r--r--test/Modules/Inputs/HasSubModules.framework/Frameworks/Sub.framework/Headers/Types.h4
-rw-r--r--test/Modules/Inputs/HasSubModules.framework/Frameworks/Sub.framework/PrivateHeaders/SubPriv.h1
-rw-r--r--test/Modules/Inputs/HasSubModules.framework/Headers/HasSubModules.h1
-rw-r--r--test/Modules/Inputs/HasSubModules.framework/PrivateHeaders/HasSubModulesPriv.h2
-rw-r--r--test/Modules/subframeworks.m7
10 files changed, 45 insertions, 5 deletions
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index 36e179c84b..1729e240cc 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -363,7 +363,8 @@ public:
StringRef Filename,
const FileEntry *RelativeFileEnt,
SmallVectorImpl<char> *SearchPath,
- SmallVectorImpl<char> *RelativePath);
+ SmallVectorImpl<char> *RelativePath,
+ Module **SuggestedModule);
/// \brief Look up the specified framework name in our framework cache.
/// \returns The DirectoryEntry it is in if we know, null otherwise.
diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp
index 3bf38e00cd..3b6c5ccde4 100644
--- a/lib/Lex/HeaderSearch.cpp
+++ b/lib/Lex/HeaderSearch.cpp
@@ -665,7 +665,8 @@ const FileEntry *HeaderSearch::
LookupSubframeworkHeader(StringRef Filename,
const FileEntry *ContextFileEnt,
SmallVectorImpl<char> *SearchPath,
- SmallVectorImpl<char> *RelativePath) {
+ SmallVectorImpl<char> *RelativePath,
+ Module **SuggestedModule) {
assert(ContextFileEnt && "No context file?");
// Framework names must have a '/' in the filename. Find it.
@@ -754,6 +755,26 @@ LookupSubframeworkHeader(StringRef Filename,
// of evaluation.
unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo;
getFileInfo(FE).DirInfo = DirInfo;
+
+ // If we're supposed to suggest a module, look for one now.
+ if (SuggestedModule) {
+ // Find the top-level framework based on this framework.
+ FrameworkName.pop_back(); // remove the trailing '/'
+ SmallVector<std::string, 4> SubmodulePath;
+ const DirectoryEntry *TopFrameworkDir
+ = ::getTopFrameworkDir(FileMgr, FrameworkName, SubmodulePath);
+
+ // Determine the name of the top-level framework.
+ StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName());
+
+ // Load this framework module. If that succeeds, find the suggested module
+ // for this header, if any.
+ bool IsSystem = false;
+ if (loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystem)) {
+ *SuggestedModule = findModuleForHeader(FE);
+ }
+ }
+
return FE;
}
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 74376e47ac..3356637b20 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -537,11 +537,11 @@ const FileEntry *Preprocessor::LookupFile(
// Otherwise, see if this is a subframework header. If so, this is relative
// to one of the headers on the #include stack. Walk the list of the current
// headers on the #include stack and pass them to HeaderInfo.
- // FIXME: SuggestedModule!
if (IsFileLexer()) {
if ((CurFileEnt = SourceMgr.getFileEntryForID(CurPPLexer->getFileID())))
if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt,
- SearchPath, RelativePath)))
+ SearchPath, RelativePath,
+ SuggestedModule)))
return FE;
}
@@ -551,7 +551,8 @@ const FileEntry *Preprocessor::LookupFile(
if ((CurFileEnt =
SourceMgr.getFileEntryForID(ISEntry.ThePPLexer->getFileID())))
if ((FE = HeaderInfo.LookupSubframeworkHeader(
- Filename, CurFileEnt, SearchPath, RelativePath)))
+ Filename, CurFileEnt, SearchPath, RelativePath,
+ SuggestedModule)))
return FE;
}
}
diff --git a/test/Index/index-module.m b/test/Index/index-module.m
index 2fccf75d7b..77dee98b4a 100644
--- a/test/Index/index-module.m
+++ b/test/Index/index-module.m
@@ -26,6 +26,7 @@ int glob;
// CHECK-DMOD-NEXT: [ppIncludedFile]: [[DMOD_PRIVATE_H:.*/Modules/Inputs/DependsOnModule.framework[/\\]PrivateHeaders[/\\]DependsOnModulePrivate.h]] | {{.*}} | hash loc: <invalid>
// CHECK-DMOD-NEXT: [importedASTFile]: {{.*}}.cache{{[/\\]}}Module.pcm | loc: [[DMOD_MODULE_H]]:1:2 | name: "Module" | isImplicit: 1
// CHECK-DMOD-NEXT: [indexDeclaration]: kind: variable | name: depends_on_module_other | {{.*}} | loc: [[DMOD_OTHER_H]]:1:5
+// CHECK-DMOD-NEXT: [importedASTFile]: {{.*}}.cache/DependsOnModule.pcm | loc: {{.*}}SubFramework.h:1:2 | name: "DependsOnModule.SubFramework.Other" | isImplicit: 1
// CHECK-DMOD-NEXT: [indexDeclaration]: kind: variable | name: sub_framework | {{.*}} | loc: [[DMOD_SUB_H]]:2:8
// CHECK-DMOD-NEXT: [indexDeclaration]: kind: variable | name: sub_framework_other | {{.*}} | loc: [[DMOD_SUB_OTHER_H]]:1:9
// CHECK-DMOD-NEXT: [indexDeclaration]: kind: variable | name: depends_on_module_private | {{.*}} | loc: [[DMOD_PRIVATE_H]]:1:5
diff --git a/test/Modules/Inputs/HasSubModules.framework/Frameworks/Sub.framework/Headers/Sub.h b/test/Modules/Inputs/HasSubModules.framework/Frameworks/Sub.framework/Headers/Sub.h
new file mode 100644
index 0000000000..8a7eb8499c
--- /dev/null
+++ b/test/Modules/Inputs/HasSubModules.framework/Frameworks/Sub.framework/Headers/Sub.h
@@ -0,0 +1 @@
+#include <Sub/Types.h>
diff --git a/test/Modules/Inputs/HasSubModules.framework/Frameworks/Sub.framework/Headers/Types.h b/test/Modules/Inputs/HasSubModules.framework/Frameworks/Sub.framework/Headers/Types.h
new file mode 100644
index 0000000000..7285c5ffa5
--- /dev/null
+++ b/test/Modules/Inputs/HasSubModules.framework/Frameworks/Sub.framework/Headers/Types.h
@@ -0,0 +1,4 @@
+struct FrameworkSubStruct {
+ const char * name;
+ unsigned version;
+};
diff --git a/test/Modules/Inputs/HasSubModules.framework/Frameworks/Sub.framework/PrivateHeaders/SubPriv.h b/test/Modules/Inputs/HasSubModules.framework/Frameworks/Sub.framework/PrivateHeaders/SubPriv.h
new file mode 100644
index 0000000000..8a7eb8499c
--- /dev/null
+++ b/test/Modules/Inputs/HasSubModules.framework/Frameworks/Sub.framework/PrivateHeaders/SubPriv.h
@@ -0,0 +1 @@
+#include <Sub/Types.h>
diff --git a/test/Modules/Inputs/HasSubModules.framework/Headers/HasSubModules.h b/test/Modules/Inputs/HasSubModules.framework/Headers/HasSubModules.h
new file mode 100644
index 0000000000..a1bdc4621c
--- /dev/null
+++ b/test/Modules/Inputs/HasSubModules.framework/Headers/HasSubModules.h
@@ -0,0 +1 @@
+#import <Sub/Sub.h>
diff --git a/test/Modules/Inputs/HasSubModules.framework/PrivateHeaders/HasSubModulesPriv.h b/test/Modules/Inputs/HasSubModules.framework/PrivateHeaders/HasSubModulesPriv.h
new file mode 100644
index 0000000000..7b82058f42
--- /dev/null
+++ b/test/Modules/Inputs/HasSubModules.framework/PrivateHeaders/HasSubModulesPriv.h
@@ -0,0 +1,2 @@
+#import <Sub/SubPriv.h>
+
diff --git a/test/Modules/subframeworks.m b/test/Modules/subframeworks.m
index efdf896657..22dfcca365 100644
--- a/test/Modules/subframeworks.m
+++ b/test/Modules/subframeworks.m
@@ -20,3 +20,10 @@ void testSubFrameworkAgain() {
CXXOnly cxxonly;
#endif
+
+@import HasSubModules;
+
+// expected-warning@1{{treating #include as an import of module 'HasSubModules.Sub.Types'}}
+#import <HasSubModules/HasSubModulesPriv.h>
+
+struct FrameworkSubStruct ss;