summaryrefslogtreecommitdiff
path: root/clang/lib/Lex
diff options
context:
space:
mode:
authorBen Langmuir <blangmuir@apple.com>2014-05-05 21:44:13 +0000
committerBen Langmuir <blangmuir@apple.com>2014-05-05 21:44:13 +0000
commit71e1a64f916eefe0af44b0fedfc06eebbc7c6ce6 (patch)
tree621e73d7be3e162f2d8879cf0f987c16f60d1c99 /clang/lib/Lex
parent6beaa8adb8bce9c5f0bcd8e07edc620ddc6f28a0 (diff)
downloadllvm-71e1a64f916eefe0af44b0fedfc06eebbc7c6ce6.tar.gz
Add -Wnon-modular-include* options
Warn on non-modular includes in various contexts. -Wnon-modular-include -Wnon-modular-include-in-module -Wnon-modular-include-in-framework-module Where each group is a subgroup of those above it. llvm-svn: 208004
Diffstat (limited to 'clang/lib/Lex')
-rw-r--r--clang/lib/Lex/ModuleMap.cpp84
-rw-r--r--clang/lib/Lex/PPDirectives.cpp18
2 files changed, 64 insertions, 38 deletions
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index 39c112101124..f89d91d05686 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -230,56 +230,57 @@ static bool violatesPrivateInclude(Module *RequestingModule,
RequestedModule->getTopLevelModule() != RequestingModule;
}
+static Module *getTopLevelOrNull(Module *M) {
+ return M ? M->getTopLevelModule() : nullptr;
+}
+
void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
SourceLocation FilenameLoc,
StringRef Filename,
const FileEntry *File) {
// No errors for indirect modules. This may be a bit of a problem for modules
// with no source files.
- if (RequestingModule != SourceModule)
+ if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
return;
if (RequestingModule)
resolveUses(RequestingModule, /*Complain=*/false);
- HeadersMap::iterator Known = findKnownHeader(File);
- if (Known == Headers.end()) {
- if (LangOpts.ModulesStrictDeclUse)
- Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module)
- << RequestingModule->getFullModuleName() << Filename;
- return;
- }
-
+ bool Excluded = false;
Module *Private = NULL;
Module *NotUsed = NULL;
- for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
- E = Known->second.end();
- I != E; ++I) {
- // Excluded headers don't really belong to a module.
- if (I->getRole() == ModuleMap::ExcludedHeader)
- continue;
- // If 'File' is part of 'RequestingModule' we can definitely include it.
- if (I->getModule() == RequestingModule)
- return;
+ HeadersMap::iterator Known = findKnownHeader(File);
+ if (Known != Headers.end()) {
+ for (const KnownHeader &Header : Known->second) {
+ // Excluded headers don't really belong to a module.
+ if (Header.getRole() == ModuleMap::ExcludedHeader) {
+ Excluded = true;
+ continue;
+ }
- // Remember private headers for later printing of a diagnostic.
- if (violatesPrivateInclude(RequestingModule, File, I->getRole(),
- I->getModule())) {
- Private = I->getModule();
- continue;
- }
+ // If 'File' is part of 'RequestingModule' we can definitely include it.
+ if (Header.getModule() == RequestingModule)
+ return;
- // If uses need to be specified explicitly, we are only allowed to return
- // modules that are explicitly used by the requesting module.
- if (RequestingModule && LangOpts.ModulesDeclUse &&
- !directlyUses(RequestingModule, I->getModule())) {
- NotUsed = I->getModule();
- continue;
- }
+ // Remember private headers for later printing of a diagnostic.
+ if (violatesPrivateInclude(RequestingModule, File, Header.getRole(),
+ Header.getModule())) {
+ Private = Header.getModule();
+ continue;
+ }
- // We have found a module that we can happily use.
- return;
+ // If uses need to be specified explicitly, we are only allowed to return
+ // modules that are explicitly used by the requesting module.
+ if (RequestingModule && LangOpts.ModulesDeclUse &&
+ !directlyUses(RequestingModule, Header.getModule())) {
+ NotUsed = Header.getModule();
+ continue;
+ }
+
+ // We have found a module that we can happily use.
+ return;
+ }
}
// We have found a header, but it is private.
@@ -296,7 +297,22 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
return;
}
- // Headers for which we have not found a module are fine to include.
+ if (Excluded || isHeaderInUmbrellaDirs(File))
+ return;
+
+ // At this point, only non-modular includes remain.
+
+ if (LangOpts.ModulesStrictDeclUse) {
+ Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module)
+ << RequestingModule->getFullModuleName() << Filename;
+ } else if (RequestingModule) {
+ diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
+ diag::warn_non_modular_include_in_framework_module :
+ diag::warn_non_modular_include_in_module;
+ Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName();
+ } else {
+ Diags.Report(FilenameLoc, diag::warn_non_modular_include);
+ }
}
ModuleMap::KnownHeader
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 57dc49536af2..b1675bc043cb 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -611,22 +611,32 @@ const FileEntry *Preprocessor::LookupFile(
// 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.
if (IsFileLexer()) {
- if ((CurFileEnt = SourceMgr.getFileEntryForID(CurPPLexer->getFileID())))
+ if ((CurFileEnt = SourceMgr.getFileEntryForID(CurPPLexer->getFileID()))) {
if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt,
SearchPath, RelativePath,
- SuggestedModule)))
+ SuggestedModule))) {
+ if (SuggestedModule && !LangOpts.AsmPreprocessor)
+ HeaderInfo.getModuleMap().diagnoseHeaderInclusion(
+ getModuleForLocation(FilenameLoc), FilenameLoc, Filename, FE);
return FE;
+ }
+ }
}
for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) {
IncludeStackInfo &ISEntry = IncludeMacroStack[e-i-1];
if (IsFileLexer(ISEntry)) {
if ((CurFileEnt =
- SourceMgr.getFileEntryForID(ISEntry.ThePPLexer->getFileID())))
+ SourceMgr.getFileEntryForID(ISEntry.ThePPLexer->getFileID()))) {
if ((FE = HeaderInfo.LookupSubframeworkHeader(
Filename, CurFileEnt, SearchPath, RelativePath,
- SuggestedModule)))
+ SuggestedModule))) {
+ if (SuggestedModule && !LangOpts.AsmPreprocessor)
+ HeaderInfo.getModuleMap().diagnoseHeaderInclusion(
+ getModuleForLocation(FilenameLoc), FilenameLoc, Filename, FE);
return FE;
+ }
+ }
}
}