aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateDeduction.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-16 16:03:23 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-16 16:03:23 +0000
commit9da95e6eefc4b0ca25e18bdab1b703f5c185deab (patch)
tree65fc8cce902d8df09c8c95a1d1a11de89288423a /lib/Sema/SemaTemplateDeduction.cpp
parent657ca6683d754c903026221a3aa3aa9cedb7556f (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123581 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateDeduction.cpp')
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp32
1 files changed, 30 insertions, 2 deletions
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index fddd14e28b..a608bea34c 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -3077,6 +3077,26 @@ static bool isAtLeastAsSpecializedAs(Sema &S,
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 @@ Sema::getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
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.