[cfe-commits] r123581 - in /cfe/trunk: lib/Sema/SemaTemplateDeduction.cpp test/CXX/temp/temp.decls/temp.variadic/partial-ordering.cpp
Douglas Gregor
dgregor at apple.com
Sun Jan 16 08:03:23 PST 2011
Author: dgregor
Date: Sun Jan 16 10:03:23 2011
New Revision: 123581
URL: http://llvm.org/viewvc/llvm-project?rev=123581&view=rev
Log:
Tweak the partial ordering rules for function templates to prefer a
non-variadic function template over a variadic one. This matches GCC
and the intent of the C++0x wording, in a way that I think is likely
to be acceptable to the committee.
Modified:
cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/partial-ordering.cpp
Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=123581&r1=123580&r2=123581&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Sun Jan 16 10:03:23 2011
@@ -3077,6 +3077,26 @@
return true;
}
+/// \brief Determine whether this a function template whose parameter-type-list
+/// ends with a function parameter pack.
+static bool isVariadicFunctionTemplate(FunctionTemplateDecl *FunTmpl) {
+ FunctionDecl *Function = FunTmpl->getTemplatedDecl();
+ unsigned NumParams = Function->getNumParams();
+ if (NumParams == 0)
+ return false;
+
+ ParmVarDecl *Last = Function->getParamDecl(NumParams - 1);
+ if (!Last->isParameterPack())
+ return false;
+
+ // Make sure that no previous parameter is a parameter pack.
+ while (--NumParams > 0) {
+ if (Function->getParamDecl(NumParams - 1)->isParameterPack())
+ return false;
+ }
+
+ return true;
+}
/// \brief Returns the more specialized function template according
/// to the rules of function template partial ordering (C++ [temp.func.order]).
@@ -3153,8 +3173,16 @@
return FT1;
else if (Better2)
return FT2;
- else
- return 0;
+
+ // FIXME: This mimics what GCC implements, but doesn't match up with the
+ // proposed resolution for core issue 692. This area needs to be sorted out,
+ // but for now we attempt to maintain compatibility.
+ bool Variadic1 = isVariadicFunctionTemplate(FT1);
+ bool Variadic2 = isVariadicFunctionTemplate(FT2);
+ if (Variadic1 != Variadic2)
+ return Variadic1? FT2 : FT1;
+
+ return 0;
}
/// \brief Determine if the two templates are equivalent.
Modified: cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/partial-ordering.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/partial-ordering.cpp?rev=123581&r1=123580&r2=123581&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/partial-ordering.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/partial-ordering.cpp Sun Jan 16 10:03:23 2011
@@ -31,16 +31,14 @@
// Partial ordering of function templates.
template<typename T1, typename T2, typename ...Rest>
-int &f0(T1, T2, Rest...); // expected-note{{candidate function [with T1 = int, T2 = double, Rest = <>]}}
+int &f0(T1, T2, Rest...);
template<typename T1, typename T2>
-float &f0(T1, T2); // expected-note{{candidate function [with T1 = int, T2 = double]}}
+float &f0(T1, T2);
-// FIXME: this is currently ambiguous, based on the proposed resolution
-// to core issue 692.
void test_f0() {
int &ir1 = f0(1, 2.0, 'a');
- float &fr1 = f0(1, 2.0); // expected-error{{call to 'f0' is ambiguous}}
+ float &fr1 = f0(1, 2.0);
}
template<typename T1, typename T2, typename ...Rest>
More information about the cfe-commits
mailing list