From 1b58c74af272a1d8228b8161c93a8a018456098e Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 8 Feb 2013 00:10:48 +0000 Subject: [PATCH] Teach subframework header lookup to suggest modules . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174683 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Lex/HeaderSearch.h | 3 ++- lib/Lex/HeaderSearch.cpp | 23 ++++++++++++++++++- lib/Lex/PPDirectives.cpp | 7 +++--- test/Index/index-module.m | 1 + .../Frameworks/Sub.framework/Headers/Sub.h | 1 + .../Frameworks/Sub.framework/Headers/Types.h | 4 ++++ .../Sub.framework/PrivateHeaders/SubPriv.h | 1 + .../Headers/HasSubModules.h | 1 + .../PrivateHeaders/HasSubModulesPriv.h | 2 ++ test/Modules/subframeworks.m | 7 ++++++ 10 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 test/Modules/Inputs/HasSubModules.framework/Frameworks/Sub.framework/Headers/Sub.h create mode 100644 test/Modules/Inputs/HasSubModules.framework/Frameworks/Sub.framework/Headers/Types.h create mode 100644 test/Modules/Inputs/HasSubModules.framework/Frameworks/Sub.framework/PrivateHeaders/SubPriv.h create mode 100644 test/Modules/Inputs/HasSubModules.framework/Headers/HasSubModules.h create mode 100644 test/Modules/Inputs/HasSubModules.framework/PrivateHeaders/HasSubModulesPriv.h 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 *SearchPath, - SmallVectorImpl *RelativePath); + SmallVectorImpl *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 *SearchPath, - SmallVectorImpl *RelativePath) { + SmallVectorImpl *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 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: // 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 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 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 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 + 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 + +struct FrameworkSubStruct ss; -- 2.40.0