summaryrefslogtreecommitdiffstats
path: root/clang/lib/Lex/ModuleMap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Lex/ModuleMap.cpp')
-rw-r--r--clang/lib/Lex/ModuleMap.cpp84
1 files changed, 50 insertions, 34 deletions
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index 39c11210112..f89d91d0568 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
OpenPOWER on IntegriCloud