Sema: print qualified name for overload candidates
authorSaleem Abdulrasool <compnerd@compnerd.org>
Thu, 22 Dec 2016 04:26:57 +0000 (04:26 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Thu, 22 Dec 2016 04:26:57 +0000 (04:26 +0000)
Print the fully qualified names for the overload candidates.  This makes
it easier to tell what the ambiguity is.  Especially if a template
is instantiated after a using namespace, it will not inherit the
namespace where it was declared.  The specialization will give a message
about a partial order being ambiguous for the same (unqualified) name,
which does not help identify the failure.

Addresses PR31450!

llvm-svn: 290315

clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaOverload.cpp
clang/lib/Sema/SemaTemplateDeduction.cpp
clang/test/SemaCXX/template-ambiguous-overload.cpp [new file with mode: 0644]

index 5339de3..7a6598b 100644 (file)
@@ -3318,18 +3318,18 @@ def note_ovl_candidate : Note<"candidate "
     "is the implicit copy assignment operator|"
     "is the implicit move assignment operator|"
     "inherited constructor|"
-    "inherited constructor }0%1"
-    "%select{| has different class%diff{ (expected $ but has $)|}3,4"
-    "| has different number of parameters (expected %3 but has %4)"
-    "| has type mismatch at %ordinal3 parameter"
-    "%diff{ (expected $ but has $)|}4,5"
-    "| has different return type%diff{ ($ expected but has $)|}3,4"
+    "inherited constructor }0%2"
+    "%select{| has different class%diff{ (expected $ but has $)|}4,5"
+    "| has different number of parameters (expected %4 but has %5)"
+    "| has type mismatch at %ordinal4 parameter"
+    "%diff{ (expected $ but has $)|}5,6"
+    "| has different return type%diff{ ($ expected but has $)|}4,5"
     "| has different qualifiers (expected "
     "%select{none|const|restrict|const and restrict|volatile|const and volatile"
-    "|volatile and restrict|const, volatile, and restrict}3 but found "
+    "|volatile and restrict|const, volatile, and restrict}4 but found "
     "%select{none|const|restrict|const and restrict|volatile|const and volatile"
-    "|volatile and restrict|const, volatile, and restrict}4)"
-    "| has different exception specification}2">;
+    "|volatile and restrict|const, volatile, and restrict}5)"
+    "| has different exception specification}3">;
 
 def note_ovl_candidate_inherited_constructor : Note<
     "constructor from base class %0 inherited here">;
@@ -4076,7 +4076,7 @@ def err_function_template_spec_ambiguous : Error<
     "function template; explicitly specify%select{| additional}1 template "
     "arguments to identify a particular function template">;
 def note_function_template_spec_matched : Note<
-    "function template matches specialization %0">;
+    "function template %q0 matches specialization %1">;
 def err_function_template_partial_spec : Error<
     "function template partial specialization is not allowed">;
 
@@ -4214,7 +4214,7 @@ def err_explicit_instantiation_member_function_not_instantiated : Error<
 def err_explicit_instantiation_ambiguous : Error<
   "partial ordering for explicit instantiation of %0 is ambiguous">;
 def note_explicit_instantiation_candidate : Note<
-  "explicit instantiation candidate function template here %0">;
+  "explicit instantiation candidate function %q0 template here %1">;
 def err_explicit_instantiation_inline : Error<
   "explicit instantiation cannot be 'inline'">;
 def warn_explicit_instantiation_inline_0x : Warning<
index fb378b8..5252e6a 100644 (file)
@@ -9160,7 +9160,7 @@ void Sema::NoteOverloadCandidate(NamedDecl *Found, FunctionDecl *Fn,
   std::string FnDesc;
   OverloadCandidateKind K = ClassifyOverloadCandidate(*this, Found, Fn, FnDesc);
   PartialDiagnostic PD = PDiag(diag::note_ovl_candidate)
-                             << (unsigned) K << FnDesc;
+                             << (unsigned) K << Fn << FnDesc;
 
   HandleFunctionTypeMismatch(PD, Fn->getType(), DestType);
   Diag(Fn->getLocation(), PD);
index 213c515..23532ce 100644 (file)
@@ -4581,12 +4581,12 @@ UnresolvedSetIterator Sema::getMostSpecialized(
     // FIXME: Can we order the candidates in some sane way?
     for (UnresolvedSetIterator I = SpecBegin; I != SpecEnd; ++I) {
       PartialDiagnostic PD = CandidateDiag;
-      PD << getTemplateArgumentBindingsText(
-          cast<FunctionDecl>(*I)->getPrimaryTemplate()->getTemplateParameters(),
-                    *cast<FunctionDecl>(*I)->getTemplateSpecializationArgs());
+      const auto *FD = cast<FunctionDecl>(*I);
+      PD << FD << getTemplateArgumentBindingsText(
+                      FD->getPrimaryTemplate()->getTemplateParameters(),
+                      *FD->getTemplateSpecializationArgs());
       if (!TargetType.isNull())
-        HandleFunctionTypeMismatch(PD, cast<FunctionDecl>(*I)->getType(),
-                                   TargetType);
+        HandleFunctionTypeMismatch(PD, FD->getType(), TargetType);
       Diag((*I)->getLocation(), PD);
     }
   }
diff --git a/clang/test/SemaCXX/template-ambiguous-overload.cpp b/clang/test/SemaCXX/template-ambiguous-overload.cpp
new file mode 100644 (file)
index 0000000..bbb7e39
--- /dev/null
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace n {
+template <int>
+void f(); // expected-note{{explicit instantiation candidate function 'n::f<0>' template here [with $0 = 0]}}
+
+extern template void f<0>();
+}
+
+using namespace n;
+
+template <int>
+void f() {} // expected-note{{explicit instantiation candidate function 'f<0>' template here [with $0 = 0]}}
+
+template void f<0>(); // expected-error{{partial ordering for explicit instantiation of 'f' is ambiguous}}
+