[cfe-commits] r99560 - in /cfe/trunk: include/clang/Basic/Diagnostic.h lib/Basic/Diagnostic.cpp lib/Sema/Sema.cpp lib/Sema/Sema.h

Douglas Gregor dgregor at apple.com
Thu Mar 25 15:17:48 PDT 2010


Author: dgregor
Date: Thu Mar 25 17:17:48 2010
New Revision: 99560

URL: http://llvm.org/viewvc/llvm-project?rev=99560&view=rev
Log:
Teach the diagnostic engine to provide more detailed information about
how to handle a diagnostic during template argument deduction, which
may be "substitution failure", "suppress", or "report". This keeps us
from, e.g., emitting warnings while performing template argument
deduction.

Modified:
    cfe/trunk/include/clang/Basic/Diagnostic.h
    cfe/trunk/lib/Basic/Diagnostic.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/Sema.h

Modified: cfe/trunk/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Diagnostic.h?rev=99560&r1=99559&r2=99560&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Diagnostic.h (original)
+++ cfe/trunk/include/clang/Basic/Diagnostic.h Thu Mar 25 17:17:48 2010
@@ -389,6 +389,28 @@
   /// the diagnostic, this returns null.
   static const char *getWarningOptionForDiag(unsigned DiagID);
 
+  /// \brief Enumeration describing how the the emission of a diagnostic should
+  /// be treated when it occurs during C++ template argument deduction.
+  enum SFINAEResponse {
+    /// \brief The diagnostic should not be reported, but it should cause
+    /// template argument deduction to fail.
+    ///
+    /// The vast majority of errors that occur during template argument 
+    /// deduction fall into this category.
+    SFINAE_SubstitutionFailure,
+    
+    /// \brief The diagnostic should be suppressed entirely.
+    ///
+    /// Warnings generally fall into this category.
+    SFINAE_Suppress,
+    
+    /// \brief The diagnostic should be reported.
+    ///
+    /// The diagnostic should be reported. Various fatal errors (e.g., 
+    /// template instantiation depth exceeded) fall into this category.
+    SFINAE_Report
+  };
+  
   /// \brief Determines whether the given built-in diagnostic ID is
   /// for an error that is suppressed if it occurs during C++ template
   /// argument deduction.
@@ -397,7 +419,7 @@
   /// deduction fails but no diagnostic is emitted. Certain classes of
   /// errors, such as those errors that involve C++ access control,
   /// are not SFINAE errors.
-  static bool isBuiltinSFINAEDiag(unsigned DiagID);
+  static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID);
 
   /// getDiagnosticLevel - Based on the way the client configured the Diagnostic
   /// object, classify the specified diagnostic ID into a Level, consumable by

Modified: cfe/trunk/lib/Basic/Diagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Diagnostic.cpp?rev=99560&r1=99559&r2=99560&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Diagnostic.cpp (original)
+++ cfe/trunk/lib/Basic/Diagnostic.cpp Thu Mar 25 17:17:48 2010
@@ -124,10 +124,20 @@
   return 0;
 }
 
-bool Diagnostic::isBuiltinSFINAEDiag(unsigned DiagID) {
-  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
-    return Info->SFINAE && Info->Class == CLASS_ERROR;
-  return false;
+Diagnostic::SFINAEResponse 
+Diagnostic::getDiagnosticSFINAEResponse(unsigned DiagID) {
+  if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) {
+    if (!Info->SFINAE)
+      return SFINAE_Report;
+
+    if (Info->Class == CLASS_ERROR)
+      return SFINAE_SubstitutionFailure;
+    
+    // Suppress notes, warnings, and extensions;
+    return SFINAE_Suppress;
+  }
+  
+  return SFINAE_Report;
 }
 
 /// getDiagClass - Return the class field of the diagnostic.

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=99560&r1=99559&r2=99560&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Thu Mar 25 17:17:48 2010
@@ -348,6 +348,30 @@
   }
 }
 
+Sema::SemaDiagnosticBuilder Sema::Diag(SourceLocation Loc, unsigned DiagID) {
+  if (isSFINAEContext()) {
+    switch (Diagnostic::getDiagnosticSFINAEResponse(DiagID)) {
+    case Diagnostic::SFINAE_Report:
+      // Fall through; we'll report the diagnostic below.
+      break;
+
+    case Diagnostic::SFINAE_SubstitutionFailure:
+      // Count this failure so that we know that template argument deduction
+      // has failed.
+      ++NumSFINAEErrors;
+      // Fall through
+        
+    case Diagnostic::SFINAE_Suppress:
+      // Suppress this diagnostic.
+      Diags.setLastDiagnosticIgnored();
+      return SemaDiagnosticBuilder(*this);
+    }
+  }
+  
+  DiagnosticBuilder DB = Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID);
+  return SemaDiagnosticBuilder(DB, *this, DiagID);
+}
+
 Sema::SemaDiagnosticBuilder
 Sema::Diag(SourceLocation Loc, const PartialDiagnostic& PD) {
   SemaDiagnosticBuilder Builder(Diag(Loc, PD.getDiagID()));

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=99560&r1=99559&r2=99560&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Thu Mar 25 17:17:48 2010
@@ -610,19 +610,7 @@
   };
 
   /// \brief Emit a diagnostic.
-  SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
-    if (isSFINAEContext() && Diagnostic::isBuiltinSFINAEDiag(DiagID)) {
-      // If we encountered an error during template argument
-      // deduction, and that error is one of the SFINAE errors,
-      // suppress the diagnostic.
-      ++NumSFINAEErrors;
-      Diags.setLastDiagnosticIgnored();
-      return SemaDiagnosticBuilder(*this);
-    }
-
-    DiagnosticBuilder DB = Diags.Report(FullSourceLoc(Loc, SourceMgr), DiagID);
-    return SemaDiagnosticBuilder(DB, *this, DiagID);
-  }
+  SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
 
   /// \brief Emit a partial diagnostic.
   SemaDiagnosticBuilder Diag(SourceLocation Loc, const PartialDiagnostic& PD);





More information about the cfe-commits mailing list