From 013d811a7bab86d727278f31445c5eb5b2cdb407 Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Mon, 16 Dec 2013 14:53:57 +0000 Subject: [PATCH] Modules: Make missing headers in a module.map a warning not an error. Instead, mark the module as unavailable so that clang errors as soon as someone tries to build this module. A better long-term strategy might be to not stat the header files at all while reading the module map and instead read them only when the module is being built (there is a corresponding FIXME in parseHeaderDecl()). However, it seems non-trivial to get there and this would be a temporary solution to unblock us. Also changed the implementation to reuse the same DiagnosticsEngine as otherwise warnings can't be enabled or disabled with command-line flags. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@197388 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticGroups.td | 2 ++ include/clang/Basic/DiagnosticLexKinds.td | 5 ++-- include/clang/Lex/ModuleMap.h | 4 +-- lib/Lex/HeaderSearch.cpp | 2 +- lib/Lex/ModuleMap.cpp | 27 +++++++------------ .../declare-use/{module.map => custom.map} | 1 + test/Modules/Inputs/modular_maps/modulea.map | 1 + test/Modules/modular_maps.cpp | 4 ++- 8 files changed, 23 insertions(+), 23 deletions(-) rename test/Modules/Inputs/declare-use/{module.map => custom.map} (96%) diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 14b01040de..c6304dadc7 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -207,6 +207,7 @@ def MismatchedReturnTypes : DiagGroup<"mismatched-return-types">; def MismatchedTags : DiagGroup<"mismatched-tags">; def MissingFieldInitializers : DiagGroup<"missing-field-initializers">; def ModuleConflict : DiagGroup<"module-conflict">; +def ModuleMapWarnings : DiagGroup<"module-map-warnings">; def NewlineEOF : DiagGroup<"newline-eof">; def NullArithmetic : DiagGroup<"null-arithmetic">; def NullCharacter : DiagGroup<"null-character">; @@ -489,6 +490,7 @@ def Most : DiagGroup<"most", [ Implicit, MismatchedTags, MissingBraces, + ModuleMapWarnings, MultiChar, Reorder, ReturnType, diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index e9de4db036..7e49c42d90 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -551,8 +551,6 @@ def err_mmap_expected_mmap_file : Error<"expected a module map file name">; def err_mmap_module_redefinition : Error< "redefinition of module '%0'">; def note_mmap_prev_definition : Note<"previously defined here">; -def err_mmap_header_not_found : Error< - "%select{|umbrella }0header '%1' not found">; def err_mmap_umbrella_dir_not_found : Error< "umbrella directory '%0' not found">; def err_mmap_umbrella_clash : Error< @@ -599,6 +597,9 @@ def err_mmap_expected_feature : Error<"expected a feature name">; def err_mmap_expected_attribute : Error<"expected an attribute name">; def warn_mmap_unknown_attribute : Warning<"unknown attribute '%0'">, InGroup; +def warn_mmap_header_not_found : + Warning<"%select{|umbrella }0header '%1' not found">, + InGroup; def warn_auto_module_import : Warning< "treating #%select{include|import|include_next|__include_macros}0 as an " diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h index 483ae3d592..5339ec13b2 100644 --- a/include/clang/Lex/ModuleMap.h +++ b/include/clang/Lex/ModuleMap.h @@ -38,7 +38,7 @@ class ModuleMapParser; class ModuleMap { SourceManager &SourceMgr; - IntrusiveRefCntPtr Diags; + DiagnosticsEngine &Diags; const LangOptions &LangOpts; const TargetInfo *Target; HeaderSearch &HeaderInfo; @@ -188,7 +188,7 @@ public: /// \param LangOpts Language options for this translation unit. /// /// \param Target The target for this translation unit. - ModuleMap(SourceManager &SourceMgr, DiagnosticConsumer &DC, + ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo); diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp index 5770aaadf4..254c0293df 100644 --- a/lib/Lex/HeaderSearch.cpp +++ b/lib/Lex/HeaderSearch.cpp @@ -48,7 +48,7 @@ HeaderSearch::HeaderSearch(IntrusiveRefCntPtr HSOpts, const LangOptions &LangOpts, const TargetInfo *Target) : HSOpts(HSOpts), FileMgr(SourceMgr.getFileManager()), FrameworkMap(64), - ModMap(SourceMgr, *Diags.getClient(), LangOpts, Target, *this) + ModMap(SourceMgr, Diags, LangOpts, Target, *this) { AngledDirIdx = 0; SystemDirIdx = 0; diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp index 8a1fcaa69e..59cb40151a 100644 --- a/lib/Lex/ModuleMap.cpp +++ b/lib/Lex/ModuleMap.cpp @@ -59,7 +59,7 @@ Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod, Module *Context = lookupModuleUnqualified(Id[0].first, Mod); if (!Context) { if (Complain) - Diags->Report(Id[0].second, diag::err_mmap_missing_module_unqualified) + Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified) << Id[0].first << Mod->getFullModuleName(); return 0; @@ -70,7 +70,7 @@ Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod, Module *Sub = lookupModuleQualified(Id[I].first, Context); if (!Sub) { if (Complain) - Diags->Report(Id[I].second, diag::err_mmap_missing_module_qualified) + Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified) << Id[I].first << Context->getFullModuleName() << SourceRange(Id[0].second, Id[I-1].second); @@ -83,19 +83,12 @@ Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod, return Context; } -ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticConsumer &DC, +ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo) - : SourceMgr(SourceMgr), LangOpts(LangOpts), Target(Target), + : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target), HeaderInfo(HeaderInfo), BuiltinIncludeDir(0), CompilingModule(0), - SourceModule(0) { - IntrusiveRefCntPtr DiagIDs(new DiagnosticIDs); - Diags = IntrusiveRefCntPtr( - new DiagnosticsEngine(DiagIDs, new DiagnosticOptions)); - Diags->setClient(new ForwardingDiagnosticConsumer(DC), - /*ShouldOwnClient=*/true); - Diags->setSourceManager(&SourceMgr); -} + SourceModule(0) {} ModuleMap::~ModuleMap() { for (llvm::StringMap::iterator I = Modules.begin(), @@ -1578,9 +1571,11 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken, } else if (LeadingToken != MMToken::ExcludeKeyword) { // Ignore excluded header files. They're optional anyway. - Diags.Report(FileNameLoc, diag::err_mmap_header_not_found) + // If we find a module that has a missing header, we mark this module as + // unavailable. Layering warnings like -fmodules-decluse can still be used. + ActiveModule->IsAvailable = false; + Diags.Report(FileNameLoc, diag::warn_mmap_header_not_found) << (LeadingToken == MMToken::UmbrellaKeyword) << FileName; - HadError = true; } } @@ -2119,11 +2114,9 @@ bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem) { // Parse this module map file. Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts); - Diags->getClient()->BeginSourceFile(MMapLangOpts); - ModuleMapParser Parser(L, SourceMgr, Target, *Diags, *this, File->getDir(), + ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File->getDir(), BuiltinIncludeDir, IsSystem); bool Result = Parser.parseModuleMapFile(); - Diags->getClient()->EndSourceFile(); ParsedModuleMap[File] = Result; return Result; } diff --git a/test/Modules/Inputs/declare-use/module.map b/test/Modules/Inputs/declare-use/custom.map similarity index 96% rename from test/Modules/Inputs/declare-use/module.map rename to test/Modules/Inputs/declare-use/custom.map index ba615b6714..c5f43e86dc 100644 --- a/test/Modules/Inputs/declare-use/module.map +++ b/test/Modules/Inputs/declare-use/custom.map @@ -26,6 +26,7 @@ module XE { module XF { header "f.h" + header "missing.h" use XA use XB } diff --git a/test/Modules/Inputs/modular_maps/modulea.map b/test/Modules/Inputs/modular_maps/modulea.map index 58c5f6464e..e0da6f358d 100644 --- a/test/Modules/Inputs/modular_maps/modulea.map +++ b/test/Modules/Inputs/modular_maps/modulea.map @@ -1,6 +1,7 @@ module A { header "common.h" header "a.h" + header "doesnotexists.h" } extern module B "moduleb.map" diff --git a/test/Modules/modular_maps.cpp b/test/Modules/modular_maps.cpp index 9c9aba85a9..cb305f2dfd 100644 --- a/test/Modules/modular_maps.cpp +++ b/test/Modules/modular_maps.cpp @@ -1,5 +1,7 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -x objective-c++ -fmodules-cache-path=%t -fmodules -fmodule-map-file=%S/Inputs/modular_maps/modulea.map -I %S/Inputs/modular_maps %s -verify +// RUN: %clang_cc1 -fmodules -fmodule-maps -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/modular_maps/modulea.map -I %S/Inputs/modular_maps %s -verify + +// expected-warning@Inputs/modular_maps/modulea.map:4{{header 'doesnotexists.h' not found}} #include "common.h" #include "a.h" -- 2.40.0