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 | |
parent | 6beaa8adb8bce9c5f0bcd8e07edc620ddc6f28a0 (diff) | |
download | llvm-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.cpp | 84 | ||||
-rw-r--r-- | clang/lib/Lex/PPDirectives.cpp | 18 |
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; + } + } } } |