diff options
author | Ben Langmuir <blangmuir@apple.com> | 2014-05-05 21:44:13 +0000 |
---|---|---|
committer | Ben Langmuir <blangmuir@apple.com> | 2014-05-05 21:44:13 +0000 |
commit | 71e1a64f916eefe0af44b0fedfc06eebbc7c6ce6 (patch) | |
tree | 621e73d7be3e162f2d8879cf0f987c16f60d1c99 /clang/lib/Lex/ModuleMap.cpp | |
parent | 6beaa8adb8bce9c5f0bcd8e07edc620ddc6f28a0 (diff) | |
download | bcm5719-llvm-71e1a64f916eefe0af44b0fedfc06eebbc7c6ce6.tar.gz bcm5719-llvm-71e1a64f916eefe0af44b0fedfc06eebbc7c6ce6.zip |
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/ModuleMap.cpp')
-rw-r--r-- | clang/lib/Lex/ModuleMap.cpp | 84 |
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 |