diff options
Diffstat (limited to 'clang/lib/Lex/HeaderSearch.cpp')
-rw-r--r-- | clang/lib/Lex/HeaderSearch.cpp | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp index c85aaa2ecc0..d01881c1456 100644 --- a/clang/lib/Lex/HeaderSearch.cpp +++ b/clang/lib/Lex/HeaderSearch.cpp @@ -413,6 +413,12 @@ getTopFrameworkDir(FileManager &FileMgr, StringRef DirName, return TopFrameworkDir; } +static bool needModuleLookup(Module *RequestingModule, + bool HasSuggestedModule) { + return HasSuggestedModule || + (RequestingModule && RequestingModule->NoUndeclaredIncludes); +} + /// DoFrameworkLookup - Do a lookup of the specified file in the current /// DirectoryLookup, which is a framework directory. const FileEntry *DirectoryLookup::DoFrameworkLookup( @@ -508,7 +514,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup( } // If we found the header and are allowed to suggest a module, do so now. - if (FE && SuggestedModule) { + if (FE && needModuleLookup(RequestingModule, SuggestedModule)) { // Find the framework in which this header occurs. StringRef FrameworkPath = FE->getDir()->getName(); bool FoundFramework = false; @@ -1158,22 +1164,45 @@ bool HeaderSearch::hasModuleMap(StringRef FileName, } ModuleMap::KnownHeader -HeaderSearch::findModuleForHeader(const FileEntry *File) const { +HeaderSearch::findModuleForHeader(const FileEntry *File, + bool AllowTextual) const { if (ExternalSource) { // Make sure the external source has handled header info about this file, // which includes whether the file is part of a module. (void)getExistingFileInfo(File); } - return ModMap.findModuleForHeader(File); + return ModMap.findModuleForHeader(File, AllowTextual); +} + +static bool suggestModule(HeaderSearch &HS, const FileEntry *File, + Module *RequestingModule, + ModuleMap::KnownHeader *SuggestedModule) { + ModuleMap::KnownHeader Module = + HS.findModuleForHeader(File, /*AllowTextual*/true); + if (SuggestedModule) + *SuggestedModule = (Module.getRole() & ModuleMap::TextualHeader) + ? ModuleMap::KnownHeader() + : Module; + + // If this module specifies [no_undeclared_includes], we cannot find any + // file that's in a non-dependency module. + if (RequestingModule && Module && RequestingModule->NoUndeclaredIncludes) { + HS.getModuleMap().resolveUses(RequestingModule, /*Complain*/false); + if (!RequestingModule->directlyUses(Module.getModule())) { + return false; + } + } + + return true; } bool HeaderSearch::findUsableModuleForHeader( const FileEntry *File, const DirectoryEntry *Root, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool IsSystemHeaderDir) { - if (File && SuggestedModule) { + if (File && needModuleLookup(RequestingModule, SuggestedModule)) { // If there is a module that corresponds to this header, suggest it. hasModuleMap(File->getName(), Root, IsSystemHeaderDir); - *SuggestedModule = findModuleForHeader(File); + return suggestModule(*this, File, RequestingModule, SuggestedModule); } return true; } @@ -1182,7 +1211,7 @@ bool HeaderSearch::findUsableModuleForFrameworkHeader( const FileEntry *File, StringRef FrameworkName, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework) { // If we're supposed to suggest a module, look for one now. - if (SuggestedModule) { + if (needModuleLookup(RequestingModule, SuggestedModule)) { // Find the top-level framework based on this framework. SmallVector<std::string, 4> SubmodulePath; const DirectoryEntry *TopFrameworkDir @@ -1199,7 +1228,7 @@ bool HeaderSearch::findUsableModuleForFrameworkHeader( // important so that we're consistent about whether this header // corresponds to a module. Possibly we should lock down framework modules // so that this is not possible. - *SuggestedModule = findModuleForHeader(File); + return suggestModule(*this, File, RequestingModule, SuggestedModule); } return true; } |