diff options
author | Daniel Jasper <djasper@google.com> | 2013-12-11 12:13:00 +0000 |
---|---|---|
committer | Daniel Jasper <djasper@google.com> | 2013-12-11 12:13:00 +0000 |
commit | 4eaf0a6ca46afcaeafe90dc3423f3e9e92046450 (patch) | |
tree | ee252c0bf0d2262beae176a022418d0913a50708 | |
parent | 235dff7b630c9abcc57a338a816835c4eada5561 (diff) | |
download | bcm5719-llvm-4eaf0a6ca46afcaeafe90dc3423f3e9e92046450.tar.gz bcm5719-llvm-4eaf0a6ca46afcaeafe90dc3423f3e9e92046450.zip |
Modules: Let -fmodules-decluse ignore headers that aren't in a module
Includes might always pull in arbitrary header or data files outside of
modules. Among others, this includes builtin includes, which do not have
a module (story) yet.
Also cleanup implementation of ModuleMap::findModuleForHeader() to be
non-recursive.
llvm-svn: 197034
-rw-r--r-- | clang/include/clang/Lex/ModuleMap.h | 6 | ||||
-rw-r--r-- | clang/lib/Lex/ModuleMap.cpp | 38 | ||||
-rw-r--r-- | clang/lib/Lex/PPDirectives.cpp | 8 | ||||
-rw-r--r-- | clang/test/Modules/declare-use1.cpp | 3 |
4 files changed, 35 insertions, 20 deletions
diff --git a/clang/include/clang/Lex/ModuleMap.h b/clang/include/clang/Lex/ModuleMap.h index 3a17157f94d..483ae3d592a 100644 --- a/clang/include/clang/Lex/ModuleMap.h +++ b/clang/include/clang/Lex/ModuleMap.h @@ -213,11 +213,15 @@ public: /// used from. Used to disambiguate if a header is present in multiple /// modules. /// + /// \param FoundInModule If not null will be set to \c true if the header was + /// found in non-exclude header declaration of a module. + /// /// \returns The module KnownHeader, which provides the module that owns the /// given header file. The KnownHeader is default constructed to indicate /// that no module owns this header file. KnownHeader findModuleForHeader(const FileEntry *File, - Module *RequestingModule = NULL); + Module *RequestingModule = NULL, + bool *FoundInModule = NULL); /// \brief Determine whether the given header is part of a module /// marked 'unavailable'. diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp index 3ce0def1d1c..8a1fcaa69e7 100644 --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -168,8 +168,19 @@ static bool isBuiltinHeader(StringRef FileName) { ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File, - Module *RequestingModule) { + Module *RequestingModule, + bool *FoundInModule) { HeadersMap::iterator Known = Headers.find(File); + + // If we've found a builtin header within Clang's builtin include directory, + // load all of the module maps to see if it will get associated with a + // specific module (e.g., in /usr/include). + if (Known == Headers.end() && File->getDir() == BuiltinIncludeDir && + isBuiltinHeader(llvm::sys::path::filename(File->getName()))) { + HeaderInfo.loadTopLevelSystemModules(); + Known = Headers.find(File); + } + if (Known != Headers.end()) { ModuleMap::KnownHeader Result = KnownHeader(); @@ -177,9 +188,15 @@ ModuleMap::findModuleForHeader(const FileEntry *File, for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(), E = Known->second.end(); I != E; ++I) { - // Cannot use a module if the header is excluded or unavailable in it. - if (I->getRole() == ModuleMap::ExcludedHeader || - !I->getModule()->isAvailable()) + // Cannot use a module if the header is excluded in it. + if (I->getRole() == ModuleMap::ExcludedHeader) + continue; + + if (FoundInModule) + *FoundInModule = true; + + // Cannot use a module if it is unavailable. + if (!I->getModule()->isAvailable()) continue; // If 'File' is part of 'RequestingModule', 'RequestingModule' is the @@ -194,6 +211,7 @@ ModuleMap::findModuleForHeader(const FileEntry *File, RequestingModule->DirectUses.end(), I->getModule()) == RequestingModule->DirectUses.end()) continue; + Result = *I; // If 'File' is a public header of this module, this is as good as we // are going to get. @@ -203,18 +221,6 @@ ModuleMap::findModuleForHeader(const FileEntry *File, return Result; } - // If we've found a builtin header within Clang's builtin include directory, - // load all of the module maps to see if it will get associated with a - // specific module (e.g., in /usr/include). - if (File->getDir() == BuiltinIncludeDir && - isBuiltinHeader(llvm::sys::path::filename(File->getName()))) { - HeaderInfo.loadTopLevelSystemModules(); - - // Check again. - if (Headers.find(File) != Headers.end()) - return findModuleForHeader(File, RequestingModule); - } - const DirectoryEntry *Dir = File->getDir(); SmallVector<const DirectoryEntry *, 2> SkippedDirs; diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index 2aa67fb8626..1b33f45f4da 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -588,9 +588,13 @@ void Preprocessor::verifyModuleInclude(SourceLocation FilenameLoc, Module *RequestingModule = getModuleForLocation(FilenameLoc); if (RequestingModule) HeaderInfo.getModuleMap().resolveUses(RequestingModule, /*Complain=*/false); + bool FoundInModule = false; ModuleMap::KnownHeader RequestedModule = - HeaderInfo.getModuleMap().findModuleForHeader(IncFileEnt, - RequestingModule); + HeaderInfo.getModuleMap().findModuleForHeader( + IncFileEnt, RequestingModule, &FoundInModule); + + if (!FoundInModule) + return; // The header is not part of a module. if (RequestingModule == RequestedModule.getModule()) return; // No faults wihin a module, or between files both not in modules. diff --git a/clang/test/Modules/declare-use1.cpp b/clang/test/Modules/declare-use1.cpp index 49993cf488c..5fc43360ffa 100644 --- a/clang/test/Modules/declare-use1.cpp +++ b/clang/test/Modules/declare-use1.cpp @@ -4,4 +4,5 @@ #include "g.h" #include "e.h" #include "f.h" // expected-error {{module XG does not depend on a module exporting 'f.h'}} -const int g2 = g1+e+f; +#include "i.h" +const int g2 = g1 + e + f + aux_i; |