[cfe-commits] r103344 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaOverload.cpp lib/Sema/SemaTemplateDeduction.cpp test/SemaTemplate/overload-candidates.cpp

Douglas Gregor dgregor at apple.com
Sat May 8 12:15:54 PDT 2010


Author: dgregor
Date: Sat May  8 14:15:54 2010
New Revision: 103344

URL: http://llvm.org/viewvc/llvm-project?rev=103344&view=rev
Log:
Improve overload-candidate diagnostic for a function template that
failed because the explicitly-specified template arguments did not
match its template parameters, e.g.,

test/SemaTemplate/overload-candidates.cpp:18:8: note: candidate
template
      ignored: invalid explicitly-specified argument for template
      parameter 'I'
  void get(const T&);
       ^
test/SemaTemplate/overload-candidates.cpp:20:8: note: candidate
template
      ignored: invalid explicitly-specified argument for 1st template
      parameter
  void get(const T&);
       ^


Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/test/SemaTemplate/overload-candidates.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=103344&r1=103343&r2=103344&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sat May  8 14:15:54 2010
@@ -1063,7 +1063,13 @@
 def note_ovl_candidate_inconsistent_deduction : Note<
     "candidate template ignored: deduced conflicting %select{types|values|"
     "templates}0 for parameter %1 (%2 vs. %3)">;
-    
+def note_ovl_candidate_explicit_arg_mismatch_named : Note<
+    "candidate template ignored: invalid explicitly-specified argument "
+    "for template parameter %0">;
+def note_ovl_candidate_explicit_arg_mismatch_unnamed : Note<
+    "candidate template ignored: invalid explicitly-specified argument "
+    "for %ordinal0 template parameter">;
+
 // Note that we don't treat templates differently for this diagnostic.
 def note_ovl_candidate_arity : Note<"candidate "
     "%select{function|function|constructor|function|function|constructor|"

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=103344&r1=103343&r2=103344&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sat May  8 14:15:54 2010
@@ -301,6 +301,7 @@
     break;
       
   case Sema::TDK_Incomplete:
+  case Sema::TDK_InvalidExplicitArguments:
     Result.Data = Info.Param.getOpaqueValue();
     break;
       
@@ -316,7 +317,6 @@
       
   case Sema::TDK_SubstitutionFailure:
   case Sema::TDK_NonDeducedMismatch:
-  case Sema::TDK_InvalidExplicitArguments:
   case Sema::TDK_FailedOverloadResolution:
     break;  
   }
@@ -331,6 +331,7 @@
   case Sema::TDK_Incomplete:
   case Sema::TDK_TooManyArguments:
   case Sema::TDK_TooFewArguments:
+  case Sema::TDK_InvalidExplicitArguments:
     break;
       
   case Sema::TDK_Inconsistent:
@@ -342,7 +343,6 @@
   // Unhandled
   case Sema::TDK_SubstitutionFailure:
   case Sema::TDK_NonDeducedMismatch:
-  case Sema::TDK_InvalidExplicitArguments:
   case Sema::TDK_FailedOverloadResolution:
     break;
   }
@@ -358,6 +358,7 @@
     return TemplateParameter();
     
   case Sema::TDK_Incomplete:
+  case Sema::TDK_InvalidExplicitArguments:
     return TemplateParameter::getFromOpaqueValue(Data);    
 
   case Sema::TDK_Inconsistent:
@@ -367,7 +368,6 @@
   // Unhandled
   case Sema::TDK_SubstitutionFailure:
   case Sema::TDK_NonDeducedMismatch:
-  case Sema::TDK_InvalidExplicitArguments:
   case Sema::TDK_FailedOverloadResolution:
     break;
   }
@@ -382,6 +382,7 @@
   case Sema::TDK_Incomplete:
   case Sema::TDK_TooManyArguments:
   case Sema::TDK_TooFewArguments:
+  case Sema::TDK_InvalidExplicitArguments:
     return 0;
 
   case Sema::TDK_Inconsistent:
@@ -391,7 +392,6 @@
   // Unhandled
   case Sema::TDK_SubstitutionFailure:
   case Sema::TDK_NonDeducedMismatch:
-  case Sema::TDK_InvalidExplicitArguments:
   case Sema::TDK_FailedOverloadResolution:
     break;
   }
@@ -407,6 +407,7 @@
   case Sema::TDK_Incomplete:
   case Sema::TDK_TooManyArguments:
   case Sema::TDK_TooFewArguments:
+  case Sema::TDK_InvalidExplicitArguments:
     return 0;
 
   case Sema::TDK_Inconsistent:
@@ -416,7 +417,6 @@
   // Unhandled
   case Sema::TDK_SubstitutionFailure:
   case Sema::TDK_NonDeducedMismatch:
-  case Sema::TDK_InvalidExplicitArguments:
   case Sema::TDK_FailedOverloadResolution:
     break;
   }
@@ -425,6 +425,12 @@
 }
 
 void OverloadCandidateSet::clear() {
+  // 
+  for (iterator C = begin(), CEnd = end(); C != CEnd; ++C) {
+    if (C->FailureKind == ovl_fail_bad_deduction)
+      C->DeductionFailure.Destroy();
+  }
+       
   inherited::clear();
   Functions.clear();
 }
@@ -5086,15 +5092,15 @@
   FunctionDecl *Fn = Cand->Function; // pattern
 
   TemplateParameter Param = Cand->DeductionFailure.getTemplateParameter();
+  NamedDecl *ParamD;
+  (ParamD = Param.dyn_cast<TemplateTypeParmDecl*>()) ||
+  (ParamD = Param.dyn_cast<NonTypeTemplateParmDecl*>()) ||
+  (ParamD = Param.dyn_cast<TemplateTemplateParmDecl*>());
   switch (Cand->DeductionFailure.Result) {
   case Sema::TDK_Success:
     llvm_unreachable("TDK_success while diagnosing bad deduction");
 
   case Sema::TDK_Incomplete: {
-    NamedDecl *ParamD;
-    (ParamD = Param.dyn_cast<TemplateTypeParmDecl*>()) ||
-    (ParamD = Param.dyn_cast<NonTypeTemplateParmDecl*>()) ||
-    (ParamD = Param.dyn_cast<TemplateTemplateParmDecl*>());
     assert(ParamD && "no parameter found for incomplete deduction result");
     S.Diag(Fn->getLocation(), diag::note_ovl_candidate_incomplete_deduction)
       << ParamD->getDeclName();
@@ -5103,14 +5109,13 @@
 
   case Sema::TDK_Inconsistent:
   case Sema::TDK_InconsistentQuals: {
-    NamedDecl *ParamD;
+    assert(ParamD && "no parameter found for inconsistent deduction result");    
     int which = 0;
-    if ((ParamD = Param.dyn_cast<TemplateTypeParmDecl*>()))
+    if (isa<TemplateTypeParmDecl>(ParamD))
       which = 0;
-    else if ((ParamD = Param.dyn_cast<NonTypeTemplateParmDecl*>()))
+    else if (isa<NonTypeTemplateParmDecl>(ParamD))
       which = 1;
     else {
-      ParamD = Param.get<TemplateTemplateParmDecl*>();
       which = 2;
     }
     
@@ -5121,6 +5126,27 @@
     return;
   }
 
+  case Sema::TDK_InvalidExplicitArguments:
+    assert(ParamD && "no parameter found for invalid explicit arguments");    
+    if (ParamD->getDeclName())
+      S.Diag(Fn->getLocation(), 
+             diag::note_ovl_candidate_explicit_arg_mismatch_named)
+        << ParamD->getDeclName();
+    else {
+      int index = 0;
+      if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ParamD))
+        index = TTP->getIndex();
+      else if (NonTypeTemplateParmDecl *NTTP
+                                  = dyn_cast<NonTypeTemplateParmDecl>(ParamD))
+        index = NTTP->getIndex();
+      else
+        index = cast<TemplateTemplateParmDecl>(ParamD)->getIndex();
+      S.Diag(Fn->getLocation(), 
+             diag::note_ovl_candidate_explicit_arg_mismatch_unnamed)
+        << (index + 1);
+    }
+    return;
+      
   case Sema::TDK_TooManyArguments:
   case Sema::TDK_TooFewArguments:
     DiagnoseArityMismatch(S, Cand, NumArgs);
@@ -5131,7 +5157,6 @@
   case Sema::TDK_InstantiationDepth:
   case Sema::TDK_SubstitutionFailure:
   case Sema::TDK_NonDeducedMismatch:
-  case Sema::TDK_InvalidExplicitArguments:
   case Sema::TDK_FailedOverloadResolution:
     S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_deduction);
     return;

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=103344&r1=103343&r2=103344&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Sat May  8 14:15:54 2010
@@ -1190,8 +1190,11 @@
                                 SourceLocation(),
                                 ExplicitTemplateArgs,
                                 true,
-                                Builder) || Trap.hasErrorOccurred())
+                                Builder) || Trap.hasErrorOccurred()) {
+    Info.Param = makeTemplateParameter(TemplateParams->getParam(
+                                                    Builder.structuredSize()));
     return TDK_InvalidExplicitArguments;
+  }
 
   // Form the template argument list from the explicitly-specified
   // template arguments.

Modified: cfe/trunk/test/SemaTemplate/overload-candidates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/overload-candidates.cpp?rev=103344&r1=103343&r2=103344&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/overload-candidates.cpp (original)
+++ cfe/trunk/test/SemaTemplate/overload-candidates.cpp Sat May  8 14:15:54 2010
@@ -6,3 +6,19 @@
 void test_min() {
   (void)min(1, 2l); // expected-error{{no matching function for call to 'min'}}
 }
+
+template<typename R, typename T>
+R *dyn_cast(const T&); // expected-note{{candidate template ignored: couldn't infer template argument 'R'}}
+
+void test_dyn_cast(int* ptr) {
+  (void)dyn_cast(ptr); // expected-error{{no matching function for call to 'dyn_cast'}}
+}
+
+template<int I, typename T> 
+  void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for template parameter 'I'}}
+template<template<class T> class, typename T> 
+  void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
+
+void test_get(void *ptr) {
+  get<int>(ptr); // expected-error{{no matching function for call to 'get'}}
+}





More information about the cfe-commits mailing list