r207549 - Reapply r207477 and r207479 without cyclic dependency

Ben Langmuir blangmuir at apple.com
Tue Apr 29 09:25:26 PDT 2014


Author: benlangmuir
Date: Tue Apr 29 11:25:26 2014
New Revision: 207549

URL: http://llvm.org/viewvc/llvm-project?rev=207549&view=rev
Log:
Reapply r207477 and r207479 without cyclic dependency

Fixed by moving ProcessWarningOptions from Frontend into Basic. All of
the dependencies for ProcessWarningOptions were already in Basic, so
this was a small change.

Added:
    cfe/trunk/lib/Basic/Warnings.cpp
      - copied, changed from r207521, cfe/trunk/lib/Frontend/Warnings.cpp
    cfe/trunk/test/Modules/Werror-Wsystem-headers.m
    cfe/trunk/test/Modules/Werror.m
Removed:
    cfe/trunk/lib/Frontend/Warnings.cpp
Modified:
    cfe/trunk/include/clang/Basic/Diagnostic.h
    cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td
    cfe/trunk/include/clang/Frontend/Utils.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/lib/Basic/CMakeLists.txt
    cfe/trunk/lib/Frontend/CMakeLists.txt
    cfe/trunk/lib/Frontend/FrontendActions.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/test/Modules/module_file_info.m
    cfe/trunk/test/Modules/resolution-change.m

Modified: cfe/trunk/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Diagnostic.h?rev=207549&r1=207548&r2=207549&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Diagnostic.h (original)
+++ cfe/trunk/include/clang/Basic/Diagnostic.h Tue Apr 29 11:25:26 2014
@@ -21,6 +21,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/iterator_range.h"
 #include <list>
 #include <vector>
 
@@ -364,6 +365,14 @@ public:
   /// \brief Retrieve the diagnostic options.
   DiagnosticOptions &getDiagnosticOptions() const { return *DiagOpts; }
 
+  typedef llvm::iterator_range<DiagState::const_iterator> diag_mapping_range;
+
+  /// \brief Get the current set of diagnostic mappings.
+  diag_mapping_range getDiagnosticMappings() const {
+    const DiagState &DS = *GetCurDiagState();
+    return diag_mapping_range(DS.begin(), DS.end());
+  }
+
   DiagnosticConsumer *getClient() { return Client; }
   const DiagnosticConsumer *getClient() const { return Client; }
 
@@ -1404,6 +1413,13 @@ struct TemplateDiffTypes {
 /// attribute.  The character itself will be not be printed.
 const char ToggleHighlight = 127;
 
+
+/// ProcessWarningOptions - Initialize the diagnostic client and process the
+/// warning options specified on the command line.
+void ProcessWarningOptions(DiagnosticsEngine &Diags,
+                           const DiagnosticOptions &Opts,
+                           bool ReportDiags = true);
+
 }  // end namespace clang
 
 #endif

Modified: cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td?rev=207549&r1=207548&r2=207549&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td Tue Apr 29 11:25:26 2014
@@ -39,6 +39,8 @@ def err_pch_langopt_mismatch : Error<"%0
     "PCH file but is currently %select{disabled|enabled}2">;
 def err_pch_langopt_value_mismatch : Error<
   "%0 differs in PCH file vs. current file">;
+def err_pch_diagopt_mismatch : Error<"%0 is currently enabled, but was not in "
+  "the PCH file">;
   
 def err_pch_version_too_old : Error<
     "PCH file uses an older PCH format that is no longer supported">;

Modified: cfe/trunk/include/clang/Frontend/Utils.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/Utils.h?rev=207549&r1=207548&r2=207549&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/Utils.h (original)
+++ cfe/trunk/include/clang/Frontend/Utils.h Tue Apr 29 11:25:26 2014
@@ -63,12 +63,6 @@ void InitializePreprocessor(Preprocessor
                             const HeaderSearchOptions &HSOpts,
                             const FrontendOptions &FEOpts);
 
-/// ProcessWarningOptions - Initialize the diagnostic client and process the
-/// warning options specified on the command line.
-void ProcessWarningOptions(DiagnosticsEngine &Diags,
-                           const DiagnosticOptions &Opts,
-                           bool ReportDiags = true);
-
 /// DoPrintPreprocessedInput - Implement -E mode.
 void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream* OS,
                               const PreprocessorOutputOptions &Opts);

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=207549&r1=207548&r2=207549&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Tue Apr 29 11:25:26 2014
@@ -133,8 +133,9 @@ public:
   ///
   /// \returns true to indicate the diagnostic options are invalid, or false
   /// otherwise.
-  virtual bool ReadDiagnosticOptions(const DiagnosticOptions &DiagOpts,
-                                     bool Complain) {
+  virtual bool
+  ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
+                        bool Complain) {
     return false;
   }
 
@@ -211,7 +212,7 @@ public:
   bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain) override;
   bool ReadTargetOptions(const TargetOptions &TargetOpts,
                          bool Complain) override;
-  bool ReadDiagnosticOptions(const DiagnosticOptions &DiagOpts,
+  bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
                              bool Complain) override;
   bool ReadFileSystemOptions(const FileSystemOptions &FSOpts,
                              bool Complain) override;
@@ -244,6 +245,8 @@ public:
                            bool Complain) override;
   bool ReadTargetOptions(const TargetOptions &TargetOpts,
                          bool Complain) override;
+  bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
+                             bool Complain) override;
   bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain,
                                std::string &SuggestedPredefines) override;
   void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override;

Modified: cfe/trunk/lib/Basic/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/CMakeLists.txt?rev=207549&r1=207548&r2=207549&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/CMakeLists.txt (original)
+++ cfe/trunk/lib/Basic/CMakeLists.txt Tue Apr 29 11:25:26 2014
@@ -25,6 +25,7 @@ add_clang_library(clangBasic
   Version.cpp
   VersionTuple.cpp
   VirtualFileSystem.cpp
+  Warnings.cpp
   )
 
 # Determine Subversion revision.

Copied: cfe/trunk/lib/Basic/Warnings.cpp (from r207521, cfe/trunk/lib/Frontend/Warnings.cpp)
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Warnings.cpp?p2=cfe/trunk/lib/Basic/Warnings.cpp&p1=cfe/trunk/lib/Frontend/Warnings.cpp&r1=207521&r2=207549&rev=207549&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/Warnings.cpp (original)
+++ cfe/trunk/lib/Basic/Warnings.cpp Tue Apr 29 11:25:26 2014
@@ -20,12 +20,9 @@
 // Given a warning option 'foo', the following are valid:
 //    -Wfoo, -Wno-foo, -Werror=foo, -Wfatal-errors=foo
 //
-#include "clang/Frontend/Utils.h"
+#include "clang/Basic/AllDiagnostics.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Frontend/FrontendDiagnostic.h"
-#include "clang/Lex/LexDiagnostic.h"
-#include "clang/Sema/SemaDiagnostic.h"
 #include <algorithm>
 #include <cstring>
 #include <utility>

Modified: cfe/trunk/lib/Frontend/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CMakeLists.txt?rev=207549&r1=207548&r2=207549&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CMakeLists.txt (original)
+++ cfe/trunk/lib/Frontend/CMakeLists.txt Tue Apr 29 11:25:26 2014
@@ -32,7 +32,6 @@ add_clang_library(clangFrontend
   TextDiagnosticBuffer.cpp
   TextDiagnosticPrinter.cpp
   VerifyDiagnosticConsumer.cpp
-  Warnings.cpp
 
   DEPENDS
   ClangDriverOptions

Modified: cfe/trunk/lib/Frontend/FrontendActions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendActions.cpp?rev=207549&r1=207548&r2=207549&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/FrontendActions.cpp (original)
+++ cfe/trunk/lib/Frontend/FrontendActions.cpp Tue Apr 29 11:25:26 2014
@@ -459,6 +459,25 @@ namespace {
       return false;
     }
 
+    virtual bool
+    ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
+                          bool Complain) override {
+      Out.indent(2) << "Diagnostic options:\n";
+#define DIAGOPT(Name, Bits, Default) DUMP_BOOLEAN(DiagOpts->Name, #Name);
+#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
+      Out.indent(4) << #Name << ": " << DiagOpts->get##Name() << "\n";
+#define VALUE_DIAGOPT(Name, Bits, Default) \
+      Out.indent(4) << #Name << ": " << DiagOpts->Name << "\n";
+#include "clang/Basic/DiagnosticOptions.def"
+
+      Out.indent(4) << "Warning options:\n";
+      for (const std::string &Warning : DiagOpts->Warnings) {
+        Out.indent(6) << "-W" << Warning << "\n";
+      }
+
+      return false;
+    }
+
     bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
                                  bool Complain) override {
       Out.indent(2) << "Header search options:\n";

Removed: cfe/trunk/lib/Frontend/Warnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/Warnings.cpp?rev=207548&view=auto
==============================================================================
--- cfe/trunk/lib/Frontend/Warnings.cpp (original)
+++ cfe/trunk/lib/Frontend/Warnings.cpp (removed)
@@ -1,203 +0,0 @@
-//===--- Warnings.cpp - C-Language Front-end ------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Command line warning options handler.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is responsible for handling all warning options. This includes
-// a number of -Wfoo options and their variants, which are driven by TableGen-
-// generated data, and the special cases -pedantic, -pedantic-errors, -w,
-// -Werror and -Wfatal-errors.
-//
-// Each warning option controls any number of actual warnings.
-// Given a warning option 'foo', the following are valid:
-//    -Wfoo, -Wno-foo, -Werror=foo, -Wfatal-errors=foo
-//
-#include "clang/Frontend/Utils.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Frontend/FrontendDiagnostic.h"
-#include "clang/Lex/LexDiagnostic.h"
-#include "clang/Sema/SemaDiagnostic.h"
-#include <algorithm>
-#include <cstring>
-#include <utility>
-using namespace clang;
-
-// EmitUnknownDiagWarning - Emit a warning and typo hint for unknown warning
-// opts
-static void EmitUnknownDiagWarning(DiagnosticsEngine &Diags,
-                                  StringRef Prefix, StringRef Opt,
-                                  bool isPositive) {
-  StringRef Suggestion = DiagnosticIDs::getNearestWarningOption(Opt);
-  if (!Suggestion.empty())
-    Diags.Report(isPositive? diag::warn_unknown_warning_option_suggest :
-                             diag::warn_unknown_negative_warning_option_suggest)
-      << (Prefix.str() += Opt) << (Prefix.str() += Suggestion);
-  else
-    Diags.Report(isPositive? diag::warn_unknown_warning_option :
-                             diag::warn_unknown_negative_warning_option)
-      << (Prefix.str() += Opt);
-}
-
-void clang::ProcessWarningOptions(DiagnosticsEngine &Diags,
-                                  const DiagnosticOptions &Opts,
-                                  bool ReportDiags) {
-  Diags.setSuppressSystemWarnings(true);  // Default to -Wno-system-headers
-  Diags.setIgnoreAllWarnings(Opts.IgnoreWarnings);
-  Diags.setShowOverloads(Opts.getShowOverloads());
-
-  Diags.setElideType(Opts.ElideType);
-  Diags.setPrintTemplateTree(Opts.ShowTemplateTree);
-  Diags.setShowColors(Opts.ShowColors);
- 
-  // Handle -ferror-limit
-  if (Opts.ErrorLimit)
-    Diags.setErrorLimit(Opts.ErrorLimit);
-  if (Opts.TemplateBacktraceLimit)
-    Diags.setTemplateBacktraceLimit(Opts.TemplateBacktraceLimit);
-  if (Opts.ConstexprBacktraceLimit)
-    Diags.setConstexprBacktraceLimit(Opts.ConstexprBacktraceLimit);
-
-  // If -pedantic or -pedantic-errors was specified, then we want to map all
-  // extension diagnostics onto WARNING or ERROR unless the user has futz'd
-  // around with them explicitly.
-  if (Opts.PedanticErrors)
-    Diags.setExtensionHandlingBehavior(DiagnosticsEngine::Ext_Error);
-  else if (Opts.Pedantic)
-    Diags.setExtensionHandlingBehavior(DiagnosticsEngine::Ext_Warn);
-  else
-    Diags.setExtensionHandlingBehavior(DiagnosticsEngine::Ext_Ignore);
-
-  SmallVector<diag::kind, 10> _Diags;
-  const IntrusiveRefCntPtr< DiagnosticIDs > DiagIDs =
-    Diags.getDiagnosticIDs();
-  // We parse the warning options twice.  The first pass sets diagnostic state,
-  // while the second pass reports warnings/errors.  This has the effect that
-  // we follow the more canonical "last option wins" paradigm when there are 
-  // conflicting options.
-  for (unsigned Report = 0, ReportEnd = 2; Report != ReportEnd; ++Report) {
-    bool SetDiagnostic = (Report == 0);
-
-    // If we've set the diagnostic state and are not reporting diagnostics then
-    // we're done.
-    if (!SetDiagnostic && !ReportDiags)
-      break;
-
-    for (unsigned i = 0, e = Opts.Warnings.size(); i != e; ++i) {
-      StringRef Opt = Opts.Warnings[i];
-      StringRef OrigOpt = Opts.Warnings[i];
-
-      // Treat -Wformat=0 as an alias for -Wno-format.
-      if (Opt == "format=0")
-        Opt = "no-format";
-
-      // Check to see if this warning starts with "no-", if so, this is a
-      // negative form of the option.
-      bool isPositive = true;
-      if (Opt.startswith("no-")) {
-        isPositive = false;
-        Opt = Opt.substr(3);
-      }
-
-      // Figure out how this option affects the warning.  If -Wfoo, map the
-      // diagnostic to a warning, if -Wno-foo, map it to ignore.
-      diag::Mapping Mapping = isPositive ? diag::MAP_WARNING : diag::MAP_IGNORE;
-      
-      // -Wsystem-headers is a special case, not driven by the option table.  It
-      // cannot be controlled with -Werror.
-      if (Opt == "system-headers") {
-        if (SetDiagnostic)
-          Diags.setSuppressSystemWarnings(!isPositive);
-        continue;
-      }
-      
-      // -Weverything is a special case as well.  It implicitly enables all
-      // warnings, including ones not explicitly in a warning group.
-      if (Opt == "everything") {
-        if (SetDiagnostic) {
-          if (isPositive) {
-            Diags.setEnableAllWarnings(true);
-          } else {
-            Diags.setEnableAllWarnings(false);
-            Diags.setMappingToAllDiagnostics(diag::MAP_IGNORE);
-          }
-        }
-        continue;
-      }
-      
-      // -Werror/-Wno-error is a special case, not controlled by the option 
-      // table. It also has the "specifier" form of -Werror=foo and -Werror-foo.
-      if (Opt.startswith("error")) {
-        StringRef Specifier;
-        if (Opt.size() > 5) {  // Specifier must be present.
-          if ((Opt[5] != '=' && Opt[5] != '-') || Opt.size() == 6) {
-            if (Report)
-              Diags.Report(diag::warn_unknown_warning_specifier)
-                << "-Werror" << ("-W" + OrigOpt.str());
-            continue;
-          }
-          Specifier = Opt.substr(6);
-        }
-        
-        if (Specifier.empty()) {
-          if (SetDiagnostic)
-            Diags.setWarningsAsErrors(isPositive);
-          continue;
-        }
-        
-        if (SetDiagnostic) {
-          // Set the warning as error flag for this specifier.
-          Diags.setDiagnosticGroupWarningAsError(Specifier, isPositive);
-        } else if (DiagIDs->getDiagnosticsInGroup(Specifier, _Diags)) {
-          EmitUnknownDiagWarning(Diags, "-Werror=", Specifier, isPositive);
-        }
-        continue;
-      }
-      
-      // -Wfatal-errors is yet another special case.
-      if (Opt.startswith("fatal-errors")) {
-        StringRef Specifier;
-        if (Opt.size() != 12) {
-          if ((Opt[12] != '=' && Opt[12] != '-') || Opt.size() == 13) {
-            if (Report)
-              Diags.Report(diag::warn_unknown_warning_specifier)
-                << "-Wfatal-errors" << ("-W" + OrigOpt.str());
-            continue;
-          }
-          Specifier = Opt.substr(13);
-        }
-
-        if (Specifier.empty()) {
-          if (SetDiagnostic)
-            Diags.setErrorsAsFatal(isPositive);
-          continue;
-        }
-        
-        if (SetDiagnostic) {
-          // Set the error as fatal flag for this specifier.
-          Diags.setDiagnosticGroupErrorAsFatal(Specifier, isPositive);
-        } else if (DiagIDs->getDiagnosticsInGroup(Specifier, _Diags)) {
-          EmitUnknownDiagWarning(Diags, "-Wfatal-errors=", Specifier,
-                                 isPositive);
-        }
-        continue;
-      }
-      
-      if (Report) {
-        if (DiagIDs->getDiagnosticsInGroup(Opt, _Diags))
-          EmitUnknownDiagWarning(Diags, isPositive ? "-W" : "-Wno-", Opt,
-                                 isPositive);
-      } else {
-        Diags.setDiagnosticGroupMapping(Opt, Mapping);
-      }
-    }
-  }
-}

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=207549&r1=207548&r2=207549&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Apr 29 11:25:26 2014
@@ -29,6 +29,7 @@
 #include "clang/Basic/TargetOptions.h"
 #include "clang/Basic/Version.h"
 #include "clang/Basic/VersionTuple.h"
+#include "clang/Frontend/Utils.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/HeaderSearchOptions.h"
 #include "clang/Lex/MacroInfo.h"
@@ -90,7 +91,7 @@ ChainedASTReaderListener::ReadTargetOpti
          Second->ReadTargetOptions(TargetOpts, Complain);
 }
 bool ChainedASTReaderListener::ReadDiagnosticOptions(
-    const DiagnosticOptions &DiagOpts, bool Complain) {
+    IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) {
   return First->ReadDiagnosticOptions(DiagOpts, Complain) ||
          Second->ReadDiagnosticOptions(DiagOpts, Complain);
 }
@@ -291,6 +292,120 @@ namespace {
     DeclsMap;
 }
 
+static bool checkDiagnosticGroupMappings(DiagnosticsEngine &StoredDiags,
+                                         DiagnosticsEngine &Diags,
+                                         bool Complain) {
+  typedef DiagnosticsEngine::Level Level;
+
+  // Check current mappings for new -Werror mappings, and the stored mappings
+  // for cases that were explicitly mapped to *not* be errors that are now
+  // errors because of options like -Werror.
+  DiagnosticsEngine *MappingSources[] = { &Diags, &StoredDiags };
+
+  for (DiagnosticsEngine *MappingSource : MappingSources) {
+    for (auto DiagIDMappingPair : MappingSource->getDiagnosticMappings()) {
+      diag::kind DiagID = DiagIDMappingPair.first;
+      Level CurLevel = Diags.getDiagnosticLevel(DiagID, SourceLocation());
+      if (CurLevel < DiagnosticsEngine::Error)
+        continue; // not significant
+      Level StoredLevel =
+          StoredDiags.getDiagnosticLevel(DiagID, SourceLocation());
+      if (StoredLevel < DiagnosticsEngine::Error) {
+        if (Complain)
+          Diags.Report(diag::err_pch_diagopt_mismatch) << "-Werror=" +
+              Diags.getDiagnosticIDs()->getWarningOptionForDiag(DiagID).str();
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+static DiagnosticsEngine::ExtensionHandling
+isExtHandlingFromDiagsError(DiagnosticsEngine &Diags) {
+  DiagnosticsEngine::ExtensionHandling Ext =
+      Diags.getExtensionHandlingBehavior();
+  if (Ext == DiagnosticsEngine::Ext_Warn && Diags.getWarningsAsErrors())
+    Ext = DiagnosticsEngine::Ext_Error;
+  return Ext;
+}
+
+static bool checkDiagnosticMappings(DiagnosticsEngine &StoredDiags,
+                                    DiagnosticsEngine &Diags,
+                                    bool IsSystem, bool Complain) {
+  // Top-level options
+  if (IsSystem) {
+    if (Diags.getSuppressSystemWarnings())
+      return false;
+    // If -Wsystem-headers was not enabled before, be conservative
+    if (StoredDiags.getSuppressSystemWarnings()) {
+      if (Complain)
+        Diags.Report(diag::err_pch_diagopt_mismatch) << "-Wsystem-headers";
+      return true;
+    }
+  }
+
+  if (Diags.getWarningsAsErrors() && !StoredDiags.getWarningsAsErrors()) {
+    if (Complain)
+      Diags.Report(diag::err_pch_diagopt_mismatch) << "-Werror";
+    return true;
+  }
+
+  if (Diags.getWarningsAsErrors() && Diags.getEnableAllWarnings() &&
+      !StoredDiags.getEnableAllWarnings()) {
+    if (Complain)
+      Diags.Report(diag::err_pch_diagopt_mismatch) << "-Weverything -Werror";
+    return true;
+  }
+
+  if (isExtHandlingFromDiagsError(Diags) &&
+      !isExtHandlingFromDiagsError(StoredDiags)) {
+    if (Complain)
+      Diags.Report(diag::err_pch_diagopt_mismatch) << "-pedantic-errors";
+    return true;
+  }
+
+  return checkDiagnosticGroupMappings(StoredDiags, Diags, Complain);
+}
+
+bool PCHValidator::ReadDiagnosticOptions(
+    IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) {
+  DiagnosticsEngine &ExistingDiags = PP.getDiagnostics();
+  IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(ExistingDiags.getDiagnosticIDs());
+  IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
+      new DiagnosticsEngine(DiagIDs, DiagOpts.getPtr()));
+  // This should never fail, because we would have processed these options
+  // before writing them to an ASTFile.
+  ProcessWarningOptions(*Diags, *DiagOpts, /*Report*/false);
+
+  ModuleManager &ModuleMgr = Reader.getModuleManager();
+  assert(ModuleMgr.size() >= 1 && "what ASTFile is this then");
+
+  // If the original import came from a file explicitly generated by the user,
+  // don't check the diagnostic mappings.
+  // FIXME: currently this is approximated by checking whether this is not a
+  // module import.
+  // Note: ModuleMgr.rbegin() may not be the current module, but it must be in
+  // the transitive closure of its imports, since unrelated modules cannot be
+  // imported until after this module finishes validation.
+  ModuleFile *TopImport = *ModuleMgr.rbegin();
+  while (!TopImport->ImportedBy.empty())
+    TopImport = TopImport->ImportedBy[0];
+  if (TopImport->Kind != MK_Module)
+    return false;
+
+  StringRef ModuleName = TopImport->ModuleName;
+  assert(!ModuleName.empty() && "diagnostic options read before module name");
+
+  Module *M = PP.getHeaderSearchInfo().lookupModule(ModuleName);
+  assert(M && "missing module");
+
+  // FIXME: if the diagnostics are incompatible, save a DiagnosticOptions that
+  // contains the union of their flags.
+  return checkDiagnosticMappings(*Diags, ExistingDiags, M->IsSystem, Complain);
+}
+
 /// \brief Collect the macro definitions provided by the given preprocessor
 /// options.
 static void collectMacroDefinitions(const PreprocessorOptions &PPOpts,
@@ -2268,11 +2383,11 @@ ASTReader::ReadControlBlock(ModuleFile &
     }
 
     case DIAGNOSTIC_OPTIONS: {
-      bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
+      bool Complain = (ClientLoadCapabilities & ARR_OutOfDate)==0;
       if (Listener && &F == *ModuleMgr.begin() &&
           ParseDiagnosticOptions(Record, Complain, *Listener) &&
-          !DisableValidation && !AllowConfigurationMismatch)
-        return ConfigurationMismatch;
+          !DisableValidation)
+        return OutOfDate;
       break;
     }
 
@@ -4481,15 +4596,15 @@ bool ASTReader::ParseTargetOptions(const
 
 bool ASTReader::ParseDiagnosticOptions(const RecordData &Record, bool Complain,
                                        ASTReaderListener &Listener) {
-  DiagnosticOptions DiagOpts;
+  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions);
   unsigned Idx = 0;
-#define DIAGOPT(Name, Bits, Default) DiagOpts.Name = Record[Idx++];
+#define DIAGOPT(Name, Bits, Default) DiagOpts->Name = Record[Idx++];
 #define ENUM_DIAGOPT(Name, Type, Bits, Default) \
-  DiagOpts.set##Name(static_cast<Type>(Record[Idx++]));
+  DiagOpts->set##Name(static_cast<Type>(Record[Idx++]));
 #include "clang/Basic/DiagnosticOptions.def"
 
   for (unsigned N = Record[Idx++]; N; --N) {
-    DiagOpts.Warnings.push_back(ReadString(Record, Idx));
+    DiagOpts->Warnings.push_back(ReadString(Record, Idx));
   }
 
   return Listener.ReadDiagnosticOptions(DiagOpts, Complain);

Added: cfe/trunk/test/Modules/Werror-Wsystem-headers.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Werror-Wsystem-headers.m?rev=207549&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Werror-Wsystem-headers.m (added)
+++ cfe/trunk/test/Modules/Werror-Wsystem-headers.m Tue Apr 29 11:25:26 2014
@@ -0,0 +1,23 @@
+// REQUIRES: shell
+// RUN: rm -rf %t
+// RUN: rm -rf %t-saved
+// RUN: mkdir %t-saved
+
+// Initial module build
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -fsyntax-only %s -verify
+// RUN: cp %t/cstd.pcm %t-saved/cstd.pcm
+
+// Even with -Werror don't rebuild a system module
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -fsyntax-only %s -verify -Werror
+// RUN: diff %t/cstd.pcm %t-saved/cstd.pcm
+
+// Unless -Wsystem-headers is on
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -fsyntax-only %s -verify \
+// RUN:     -Werror=unused -Wsystem-headers
+// RUN: not diff %t/cstd.pcm %t-saved/cstd.pcm
+
+// expected-no-diagnostics
+ at import cstd;

Added: cfe/trunk/test/Modules/Werror.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Werror.m?rev=207549&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Werror.m (added)
+++ cfe/trunk/test/Modules/Werror.m Tue Apr 29 11:25:26 2014
@@ -0,0 +1,75 @@
+// REQUIRES: shell
+// RUN: rm -rf %t
+// RUN: rm -rf %t-saved
+// RUN: mkdir -p %t-saved
+
+// Initial module build (-Werror=header-guard)
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella  \
+// RUN:     -Werror=header-guard
+// RUN: cp %t/Module.pcm %t-saved/Module.pcm
+
+// Building with looser -Werror options does not rebuild
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella 
+// RUN: diff %t/Module.pcm %t-saved/Module.pcm
+
+// Make the build more restricted (-Werror)
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella \
+// RUN:     -Werror -Wno-incomplete-umbrella
+// RUN: not diff %t/Module.pcm %t-saved/Module.pcm
+// RUN: cp %t/Module.pcm %t-saved/Module.pcm
+
+// Ensure -Werror=header-guard is less strict than -Werror
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella \
+// RUN:     -Werror=header-guard -Wno-incomplete-umbrella
+// RUN: diff %t/Module.pcm %t-saved/Module.pcm
+
+// But -Werror=unused is not, because some of its diags are DefaultIgnore
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella \
+// RUN:     -Werror=unused
+// RUN: not diff %t/Module.pcm %t-saved/Module.pcm
+// RUN: cp %t/Module.pcm %t-saved/Module.pcm
+
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella \
+// RUN:     -Werror -Wno-incomplete-umbrella
+
+// FIXME: when rebuilding the module, take the union of the diagnostic options
+// so that we don't need to rebuild here
+// RUN-DISABLED: diff %t/Module.pcm %t-saved/Module.pcm
+
+// -Wno-everything, -Werror
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella \
+// RUN:     -Wno-everything -Wall -Werror
+// RUN: cp %t/Module.pcm %t-saved/Module.pcm
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella \
+// RUN:     -Wall -Werror
+// RUN: not diff %t/Module.pcm %t-saved/Module.pcm
+
+// -pedantic, -Werror is not compatible with -Wall -Werror
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella \
+// RUN:     -Werror -pedantic
+// RUN: not diff %t/Module.pcm %t-saved/Module.pcm
+// RUN: cp %t/Module.pcm %t-saved/Module.pcm
+
+// -pedantic-errors is less strict that -pedantic, -Werror
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella \
+// RUN:     -pedantic-errors
+// RUN: diff %t/Module.pcm %t-saved/Module.pcm
+
+// -Wsystem-headers does not affect non-system modules
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella \
+// RUN:     -pedantic-errors -Wsystem-headers
+// RUN: diff %t/Module.pcm %t-saved/Module.pcm
+
+// expected-no-diagnostics
+ at import Module;

Modified: cfe/trunk/test/Modules/module_file_info.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/module_file_info.m?rev=207549&r1=207548&r2=207549&view=diff
==============================================================================
--- cfe/trunk/test/Modules/module_file_info.m (original)
+++ cfe/trunk/test/Modules/module_file_info.m Tue Apr 29 11:25:26 2014
@@ -2,7 +2,7 @@
 @import DependsOnModule;
 
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -w -fmodules -fdisable-module-hash -fmodules-cache-path=%t -F %S/Inputs -DBLARG -DWIBBLE=WOBBLE %s
+// RUN: %clang_cc1 -w -Wunused -fmodules -fdisable-module-hash -fmodules-cache-path=%t -F %S/Inputs -DBLARG -DWIBBLE=WOBBLE %s
 // RUN: %clang_cc1 -module-file-info %t/DependsOnModule.pcm | FileCheck %s
 
 // CHECK: Generated by this Clang:
@@ -21,6 +21,11 @@
 // CHECK:     ABI: 
 // CHECK:     Linker version: 
 
+// CHECK: Diagnostic options:
+// CHECK:   IgnoreWarnings: Yes
+// CHECK:   Warning options:
+// CHECK:     -Wunused
+
 // CHECK: Header search options:
 // CHECK:   System root [-isysroot=]: '/'
 // CHECK:   Use builtin include directories [-nobuiltininc]: Yes

Modified: cfe/trunk/test/Modules/resolution-change.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/resolution-change.m?rev=207549&r1=207548&r2=207549&view=diff
==============================================================================
--- cfe/trunk/test/Modules/resolution-change.m (original)
+++ cfe/trunk/test/Modules/resolution-change.m Tue Apr 29 11:25:26 2014
@@ -6,6 +6,9 @@
 // Use the PCH with the same header search options; should be fine
 // RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/modules-with-same-name/DependsOnA -I %S/Inputs/modules-with-same-name/path1/A -include-pch %t-A.pch %s -fsyntax-only -Werror
 
+// Different -W options are ok
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/modules-with-same-name/DependsOnA -I %S/Inputs/modules-with-same-name/path1/A -include-pch %t-A.pch %s -fsyntax-only -Werror -Wauto-import
+
 // Use the PCH with no way to resolve DependsOnA
 // RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -include-pch %t-A.pch %s -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-NODOA %s
 // CHECK-NODOA: module 'DependsOnA' imported by AST file '{{.*A.pch}}' not found





More information about the cfe-commits mailing list