[cfe-commits] r103339 - in /cfe/trunk: include/clang/AST/TemplateBase.h include/clang/Basic/DiagnosticSemaKinds.td lib/AST/TemplateBase.cpp lib/Sema/SemaOverload.cpp lib/Sema/SemaOverload.h test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp test/SemaTemplate/overload-candidates.cpp
Douglas Gregor
dgregor at apple.com
Sat May 8 10:41:32 PDT 2010
Author: dgregor
Date: Sat May 8 12:41:32 2010
New Revision: 103339
URL: http://llvm.org/viewvc/llvm-project?rev=103339&view=rev
Log:
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&);
^
Added:
cfe/trunk/test/SemaTemplate/overload-candidates.cpp (with props)
Modified:
cfe/trunk/include/clang/AST/TemplateBase.h
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/AST/TemplateBase.cpp
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/lib/Sema/SemaOverload.h
cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp
cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp
Modified: cfe/trunk/include/clang/AST/TemplateBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TemplateBase.h?rev=103339&r1=103338&r2=103339&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TemplateBase.h (original)
+++ cfe/trunk/include/clang/AST/TemplateBase.h Sat May 8 12:41:32 2010
@@ -28,6 +28,7 @@
namespace clang {
class Decl;
+class DiagnosticBuilder;
class Expr;
class TypeSourceInfo;
@@ -473,6 +474,9 @@
}
};
-}
+const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ const TemplateArgument &Arg);
+
+} // end namespace clang
#endif
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=103339&r1=103338&r2=103339&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sat May 8 12:41:32 2010
@@ -1060,7 +1060,10 @@
"candidate template ignored: failed template argument deduction">;
def note_ovl_candidate_incomplete_deduction : Note<"candidate template ignored: "
"couldn't infer template argument %0">;
-
+def note_ovl_candidate_inconsistent_deduction : Note<
+ "candidate template ignored: deduced conflicting %select{types|values|"
+ "templates}0 for parameter %1 (%2 vs. %3)">;
+
// 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/AST/TemplateBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TemplateBase.cpp?rev=103339&r1=103338&r2=103339&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TemplateBase.cpp (original)
+++ cfe/trunk/lib/AST/TemplateBase.cpp Sat May 8 12:41:32 2010
@@ -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;
+}
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=103339&r1=103338&r2=103339&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sat May 8 12:41:32 2010
@@ -275,7 +275,166 @@
new (&conversions()) ConversionSet(O.conversions());
}
+namespace {
+ // Structure used by OverloadCandidate::DeductionFailureInfo to store
+ // template parameter and template argument information.
+ struct DFIParamWithArguments {
+ TemplateParameter Param;
+ TemplateArgument FirstArg;
+ TemplateArgument SecondArg;
+ };
+}
+
+/// \brief Convert from Sema's representation of template deduction information
+/// to the form used in overload-candidate information.
+OverloadCandidate::DeductionFailureInfo
+static MakeDeductionFailureInfo(Sema::TemplateDeductionResult TDK,
+ const Sema::TemplateDeductionInfo &Info) {
+ OverloadCandidate::DeductionFailureInfo Result;
+ Result.Result = static_cast<unsigned>(TDK);
+ Result.Data = 0;
+ switch (TDK) {
+ case Sema::TDK_Success:
+ case Sema::TDK_InstantiationDepth:
+ break;
+
+ case Sema::TDK_Incomplete:
+ Result.Data = Info.Param.getOpaqueValue();
+ break;
+
+ // Unhandled
+ case Sema::TDK_Inconsistent:
+ case Sema::TDK_InconsistentQuals: {
+ DFIParamWithArguments *Saved = new DFIParamWithArguments;
+ Saved->Param = Info.Param;
+ Saved->FirstArg = Info.FirstArg;
+ Saved->SecondArg = Info.SecondArg;
+ Result.Data = Saved;
+ break;
+ }
+
+ case Sema::TDK_SubstitutionFailure:
+ case Sema::TDK_NonDeducedMismatch:
+ case Sema::TDK_TooManyArguments:
+ case Sema::TDK_TooFewArguments:
+ case Sema::TDK_InvalidExplicitArguments:
+ case Sema::TDK_FailedOverloadResolution:
+ break;
+ }
+
+ return Result;
+}
+
+void OverloadCandidate::DeductionFailureInfo::Destroy() {
+ switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
+ case Sema::TDK_Success:
+ case Sema::TDK_InstantiationDepth:
+ case Sema::TDK_Incomplete:
+ break;
+
+ // Unhandled
+ case Sema::TDK_Inconsistent:
+ case Sema::TDK_InconsistentQuals:
+ delete static_cast<DFIParamWithArguments*>(Data);
+ Data = 0;
+ break;
+
+ case Sema::TDK_SubstitutionFailure:
+ case Sema::TDK_NonDeducedMismatch:
+ case Sema::TDK_TooManyArguments:
+ case Sema::TDK_TooFewArguments:
+ case Sema::TDK_InvalidExplicitArguments:
+ case Sema::TDK_FailedOverloadResolution:
+ break;
+ }
+}
+
+TemplateParameter
+OverloadCandidate::DeductionFailureInfo::getTemplateParameter() {
+ switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
+ case Sema::TDK_Success:
+ case Sema::TDK_InstantiationDepth:
+ return TemplateParameter();
+
+ case Sema::TDK_Incomplete:
+ return TemplateParameter::getFromOpaqueValue(Data);
+ case Sema::TDK_Inconsistent:
+ case Sema::TDK_InconsistentQuals:
+ return static_cast<DFIParamWithArguments*>(Data)->Param;
+
+ // Unhandled
+ case Sema::TDK_SubstitutionFailure:
+ case Sema::TDK_NonDeducedMismatch:
+ case Sema::TDK_TooManyArguments:
+ case Sema::TDK_TooFewArguments:
+ case Sema::TDK_InvalidExplicitArguments:
+ case Sema::TDK_FailedOverloadResolution:
+ break;
+ }
+
+ return TemplateParameter();
+}
+
+const TemplateArgument *OverloadCandidate::DeductionFailureInfo::getFirstArg() {
+ switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
+ case Sema::TDK_Success:
+ case Sema::TDK_InstantiationDepth:
+ case Sema::TDK_Incomplete:
+ return 0;
+
+ // Unhandled
+ case Sema::TDK_Inconsistent:
+ case Sema::TDK_InconsistentQuals:
+ return &static_cast<DFIParamWithArguments*>(Data)->FirstArg;
+
+ case Sema::TDK_SubstitutionFailure:
+ case Sema::TDK_NonDeducedMismatch:
+ case Sema::TDK_TooManyArguments:
+ case Sema::TDK_TooFewArguments:
+ case Sema::TDK_InvalidExplicitArguments:
+ case Sema::TDK_FailedOverloadResolution:
+ break;
+ }
+
+ return 0;
+}
+
+const TemplateArgument *
+OverloadCandidate::DeductionFailureInfo::getSecondArg() {
+ switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
+ case Sema::TDK_Success:
+ case Sema::TDK_InstantiationDepth:
+ case Sema::TDK_Incomplete:
+ return 0;
+
+ // Unhandled
+ case Sema::TDK_Inconsistent:
+ case Sema::TDK_InconsistentQuals:
+ return &static_cast<DFIParamWithArguments*>(Data)->SecondArg;
+
+ case Sema::TDK_SubstitutionFailure:
+ case Sema::TDK_NonDeducedMismatch:
+ case Sema::TDK_TooManyArguments:
+ case Sema::TDK_TooFewArguments:
+ case Sema::TDK_InvalidExplicitArguments:
+ case Sema::TDK_FailedOverloadResolution:
+ break;
+ }
+
+ return 0;
+}
+
+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();
+}
+
// IsOverload - Determine whether the given New declaration is an
// overload of the declarations in Old. This routine returns false if
// New and Old cannot be overloaded, e.g., if New has the same
@@ -3028,7 +3187,7 @@
}
}
}
-
+
/// \brief Add a C++ member function template as a candidate to the candidate
/// set, using template argument deduction to produce an appropriate member
/// function template specialization.
@@ -3109,10 +3268,7 @@
Candidate.FailureKind = ovl_fail_bad_deduction;
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
-
- // TODO: record more information about failed template arguments
- Candidate.DeductionFailure.Result = Result;
- Candidate.DeductionFailure.TemplateParameter = Info.Param.getOpaqueValue();
+ Candidate.DeductionFailure = MakeDeductionFailureInfo(Result, Info);
return;
}
@@ -4929,9 +5085,7 @@
Expr **Args, unsigned NumArgs) {
FunctionDecl *Fn = Cand->Function; // pattern
- TemplateParameter Param = TemplateParameter::getFromOpaqueValue(
- Cand->DeductionFailure.TemplateParameter);
-
+ TemplateParameter Param = Cand->DeductionFailure.getTemplateParameter();
switch (Cand->DeductionFailure.Result) {
case Sema::TDK_Success:
llvm_unreachable("TDK_success while diagnosing bad deduction");
@@ -4947,11 +5101,29 @@
return;
}
+ case Sema::TDK_Inconsistent:
+ case Sema::TDK_InconsistentQuals: {
+ NamedDecl *ParamD;
+ int which = 0;
+ if ((ParamD = Param.dyn_cast<TemplateTypeParmDecl*>()))
+ which = 0;
+ else if ((ParamD = Param.dyn_cast<NonTypeTemplateParmDecl*>()))
+ which = 1;
+ else {
+ ParamD = Param.get<TemplateTemplateParmDecl*>();
+ which = 2;
+ }
+
+ S.Diag(Fn->getLocation(), diag::note_ovl_candidate_inconsistent_deduction)
+ << which << ParamD->getDeclName()
+ << *Cand->DeductionFailure.getFirstArg()
+ << *Cand->DeductionFailure.getSecondArg();
+ return;
+ }
+
// TODO: diagnose these individually, then kill off
// note_ovl_candidate_bad_deduction, which is uselessly vague.
case Sema::TDK_InstantiationDepth:
- case Sema::TDK_Inconsistent:
- case Sema::TDK_InconsistentQuals:
case Sema::TDK_SubstitutionFailure:
case Sema::TDK_NonDeducedMismatch:
case Sema::TDK_TooManyArguments:
Modified: cfe/trunk/lib/Sema/SemaOverload.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.h?rev=103339&r1=103338&r2=103339&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.h (original)
+++ cfe/trunk/lib/Sema/SemaOverload.h Sat May 8 12:41:32 2010
@@ -16,7 +16,9 @@
#define LLVM_CLANG_SEMA_OVERLOAD_H
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h"
#include "clang/AST/UnresolvedSet.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -529,8 +531,24 @@
// A Sema::TemplateDeductionResult.
unsigned Result;
- // A TemplateParameter.
- void *TemplateParameter;
+ /// \brief Opaque pointer containing additional data about
+ /// this deduction failure.
+ void *Data;
+
+ /// \brief Retrieve the template parameter this deduction failure
+ /// refers to, if any.
+ TemplateParameter getTemplateParameter();
+
+ /// \brief Return the first template argument this deduction failure
+ /// refers to, if any.
+ const TemplateArgument *getFirstArg();
+
+ /// \brief Return the second template argument this deduction failure
+ /// refers to, if any.
+ const TemplateArgument *getSecondArg();
+
+ /// \brief Free any memory associated with this deduction failure.
+ void Destroy();
};
union {
@@ -574,10 +592,9 @@
}
/// \brief Clear out all of the candidates.
- void clear() {
- inherited::clear();
- Functions.clear();
- }
+ void clear();
+
+ ~OverloadCandidateSet() { clear(); }
};
} // end namespace clang
Modified: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp?rev=103339&r1=103338&r2=103339&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp Sat May 8 12:41:32 2010
@@ -16,7 +16,8 @@
}
// TODO: this diagnostic can and should improve
-template<typename T> void f2(T*, T*); // expected-note 2 {{candidate template ignored: failed template argument deduction}}
+template<typename T> void f2(T*, T*); // expected-note {{candidate template ignored: failed template argument deduction}} \
+// expected-note{{candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'float')}}
struct ConvToIntPtr {
operator int*() const;
Modified: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp?rev=103339&r1=103338&r2=103339&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp Sat May 8 12:41:32 2010
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
namespace test0 {
- template<class T> void apply(T x, void (*f)(T)) { f(x); } // expected-note 2 {{failed template argument deduction}}\
+ template<class T> void apply(T x, void (*f)(T)) { f(x); } // expected-note 2 {{candidate template ignored: deduced conflicting types for parameter 'T'}}\
// expected-note {{no overload of 'temp2' matching 'void (*)(int)'}}
template<class A> void temp(A);
Added: cfe/trunk/test/SemaTemplate/overload-candidates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/overload-candidates.cpp?rev=103339&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/overload-candidates.cpp (added)
+++ cfe/trunk/test/SemaTemplate/overload-candidates.cpp Sat May 8 12:41:32 2010
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+const T& min(const T&, const T&); // expected-note{{candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'long')}}
+
+void test_min() {
+ (void)min(1, 2l); // expected-error{{no matching function for call to 'min'}}
+}
Propchange: cfe/trunk/test/SemaTemplate/overload-candidates.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/SemaTemplate/overload-candidates.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/SemaTemplate/overload-candidates.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the cfe-commits
mailing list