diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-01-16 16:03:23 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-01-16 16:03:23 +0000 |
commit | 9da95e6eefc4b0ca25e18bdab1b703f5c185deab (patch) | |
tree | 65fc8cce902d8df09c8c95a1d1a11de89288423a /lib/Sema/SemaTemplateDeduction.cpp | |
parent | 657ca6683d754c903026221a3aa3aa9cedb7556f (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.cpp | 32 |
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. |