summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Jasper <djasper@google.com>2013-12-11 12:13:00 +0000
committerDaniel Jasper <djasper@google.com>2013-12-11 12:13:00 +0000
commit4eaf0a6ca46afcaeafe90dc3423f3e9e92046450 (patch)
treeee252c0bf0d2262beae176a022418d0913a50708
parent235dff7b630c9abcc57a338a816835c4eada5561 (diff)
downloadbcm5719-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.h6
-rw-r--r--clang/lib/Lex/ModuleMap.cpp38
-rw-r--r--clang/lib/Lex/PPDirectives.cpp8
-rw-r--r--clang/test/Modules/declare-use1.cpp3
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;
OpenPOWER on IntegriCloud