Hi klimek, rsmith, doug.gregor,

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.

http://llvm-reviews.chandlerc.com/D2352

Files:
  include/clang/Basic/DiagnosticGroups.td
  include/clang/Basic/DiagnosticLexKinds.td
  include/clang/Lex/ModuleMap.h
  lib/Lex/HeaderSearch.cpp
  lib/Lex/ModuleMap.cpp
  test/Modules/Inputs/declare-use/custom.map
  test/Modules/Inputs/declare-use/module.map
  test/Modules/Inputs/modular_maps/modulea.map
  test/Modules/declare-use1.cpp
  test/Modules/declare-use2.cpp
  test/Modules/modular_maps.cpp
Index: include/clang/Basic/DiagnosticGroups.td
===================================================================
--- include/clang/Basic/DiagnosticGroups.td
+++ include/clang/Basic/DiagnosticGroups.td
@@ -207,6 +207,7 @@
 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">;
@@ -490,6 +491,7 @@
     Implicit,
     MismatchedTags,
     MissingBraces,
+    ModuleMapWarnings,
     MultiChar,
     Reorder,
     ReturnType,
Index: include/clang/Basic/DiagnosticLexKinds.td
===================================================================
--- include/clang/Basic/DiagnosticLexKinds.td
+++ include/clang/Basic/DiagnosticLexKinds.td
@@ -551,8 +551,6 @@
 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_attribute : Error<"expected an attribute name">;
 def warn_mmap_unknown_attribute : Warning<"unknown attribute '%0'">,
   InGroup<IgnoredAttributes>;
+def warn_mmap_header_not_found :
+  Warning<"%select{|umbrella }0header '%1' not found">,
+  InGroup<ModuleMapWarnings>;
 
 def warn_auto_module_import : Warning<
   "treating #%select{include|import|include_next|__include_macros}0 as an "
Index: include/clang/Lex/ModuleMap.h
===================================================================
--- include/clang/Lex/ModuleMap.h
+++ include/clang/Lex/ModuleMap.h
@@ -38,7 +38,7 @@
   
 class ModuleMap {
   SourceManager &SourceMgr;
-  IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
+  DiagnosticsEngine &Diags;
   const LangOptions &LangOpts;
   const TargetInfo *Target;
   HeaderSearch &HeaderInfo;
@@ -188,7 +188,7 @@
   /// \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);
 
Index: lib/Lex/HeaderSearch.cpp
===================================================================
--- lib/Lex/HeaderSearch.cpp
+++ lib/Lex/HeaderSearch.cpp
@@ -48,7 +48,7 @@
                            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;
Index: lib/Lex/ModuleMap.cpp
===================================================================
--- lib/Lex/ModuleMap.cpp
+++ lib/Lex/ModuleMap.cpp
@@ -59,7 +59,7 @@
   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 *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 @@
   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<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
-  Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
-            new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
-  Diags->setClient(new ForwardingDiagnosticConsumer(DC),
-                   /*ShouldOwnClient=*/true);
-  Diags->setSourceManager(&SourceMgr);
-}
+      SourceModule(0) {}
 
 ModuleMap::~ModuleMap() {
   for (llvm::StringMap<Module *>::iterator I = Modules.begin(), 
@@ -1572,9 +1565,11 @@
   } 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;
   }
 }
 
@@ -2113,11 +2108,9 @@
   
   // 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;
 }
Index: test/Modules/Inputs/declare-use/custom.map
===================================================================
--- /dev/null
+++ test/Modules/Inputs/declare-use/custom.map
@@ -0,0 +1,44 @@
+module XA {
+  header "a.h"
+}
+
+module XB {
+  header "b.h"
+}
+
+module XC {
+  header "c.h"
+  use XA
+}
+
+module XD {
+  header "d.h"
+  use XA
+}
+
+module XE {
+  header "e.h"
+  use XA
+  use XB
+}
+
+module XF {
+  header "f.h"
+  header "missing.h"
+  use XA
+  use XB
+}
+
+module XG {
+  header "g.h"
+  header "g1.h"
+  use XC
+  use XE
+}
+
+module XH {
+  header "h.h"
+  header "h1.h"
+  use XC
+  use XE
+}
Index: test/Modules/Inputs/declare-use/module.map
===================================================================
--- test/Modules/Inputs/declare-use/module.map
+++ /dev/null
@@ -1,43 +0,0 @@
-module XA {
-  header "a.h"
-}
-
-module XB {
-  header "b.h"
-}
-
-module XC {
-  header "c.h"
-  use XA
-}
-
-module XD {
-  header "d.h"
-  use XA
-}
-
-module XE {
-  header "e.h"
-  use XA
-  use XB
-}
-
-module XF {
-  header "f.h"
-  use XA
-  use XB
-}
-
-module XG {
-  header "g.h"
-  header "g1.h"
-  use XC
-  use XE
-}
-
-module XH {
-  header "h.h"
-  header "h1.h"
-  use XC
-  use XE
-}
Index: test/Modules/Inputs/modular_maps/modulea.map
===================================================================
--- test/Modules/Inputs/modular_maps/modulea.map
+++ 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"
Index: test/Modules/declare-use1.cpp
===================================================================
--- test/Modules/declare-use1.cpp
+++ test/Modules/declare-use1.cpp
@@ -1,7 +1,8 @@
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -x objective-c++ -fmodules-cache-path=%t -fmodules -fmodules-decluse -fmodule-name=XG -I %S/Inputs/declare-use %s -verify
+// RUN: %clang_cc1 -fmodule-maps -fmodule-map-file=%S/Inputs/declare-use/custom.map -fmodules -fmodules-decluse -fmodule-name=XG -Wno-module-map-warnings -I %S/Inputs/declare-use %s -verify
 
 #include "g.h"
 #include "e.h"
 #include "f.h" // expected-error {{module XG does not depend on a module exporting 'f.h'}}
+
 const int g2 = g1+e+f;
Index: test/Modules/declare-use2.cpp
===================================================================
--- test/Modules/declare-use2.cpp
+++ test/Modules/declare-use2.cpp
@@ -1,5 +1,5 @@
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -x objective-c++ -fmodules-cache-path=%t -fmodules -fmodules-decluse -fmodule-name=XH -I %S/Inputs/declare-use %s -verify
+// RUN: %clang_cc1 -fmodule-maps -fmodule-map-file=%S/Inputs/declare-use/custom.map -fmodules -fmodules-decluse -fmodule-name=XH -Wno-module-map-warnings -I %S/Inputs/declare-use %s -verify
 
 #include "h.h"
 #include "e.h"
Index: test/Modules/modular_maps.cpp
===================================================================
--- test/Modules/modular_maps.cpp
+++ 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"
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to