When printing a non-viable overload candidate that failed due to
conflicting deduced template argument values, give a more specific
reason along with those values, e.g.,
test/SemaTemplate/overload-candidates.cpp:4:10: note: candidate template
ignored: deduced conflicting types for parameter 'T' ('int' vs. 'long')
const T& min(const T&, const T&);
^
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103339 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp
index e9b1725..0bf9f2f 100644
--- a/lib/AST/TemplateBase.cpp
+++ b/lib/AST/TemplateBase.cpp
@@ -18,6 +18,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/Diagnostic.h"
using namespace clang;
@@ -119,3 +120,42 @@
// Silence bonus gcc warning.
return SourceRange();
}
+
+const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
+ const TemplateArgument &Arg) {
+ switch (Arg.getKind()) {
+ case TemplateArgument::Null:
+ return DB;
+
+ case TemplateArgument::Type:
+ return DB << Arg.getAsType();
+
+ case TemplateArgument::Declaration:
+ return DB << Arg.getAsDecl();
+
+ case TemplateArgument::Integral:
+ return DB << Arg.getAsIntegral()->toString(10);
+
+ case TemplateArgument::Template:
+ return DB << Arg.getAsTemplate();
+
+ case TemplateArgument::Expression: {
+ // This shouldn't actually ever happen, so it's okay that we're
+ // regurgitating an expression here.
+ // FIXME: We're guessing at LangOptions!
+ llvm::SmallString<32> Str;
+ llvm::raw_svector_ostream OS(Str);
+ LangOptions LangOpts;
+ LangOpts.CPlusPlus = true;
+ PrintingPolicy Policy(LangOpts);
+ Arg.getAsExpr()->printPretty(OS, 0, Policy);
+ return DB << OS.str();
+ }
+
+ case TemplateArgument::Pack:
+ // FIXME: Format arguments in a list!
+ return DB << "<parameter pack>";
+ }
+
+ return DB;
+}