[cfe-commits] r122461 - in /cfe/trunk: lib/Sema/SemaTemplateDeduction.cpp test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p2-0x.cpp test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
Douglas Gregor
dgregor at apple.com
Wed Dec 22 17:24:45 PST 2010
Author: dgregor
Date: Wed Dec 22 19:24:45 2010
New Revision: 122461
URL: http://llvm.org/viewvc/llvm-project?rev=122461&view=rev
Log:
Implement the rest of C++0x [temp.deduct.type]p9, which specifies that
the presence of a pack expansion anywhere except at the end of a
template-argument-list causes the entire template-argument-list to be
a non-deduced context.
Added:
cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp (with props)
Modified:
cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p2-0x.cpp
Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=122461&r1=122460&r2=122461&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Wed Dec 22 19:24:45 2010
@@ -1059,6 +1059,33 @@
return TemplateParameter(cast<TemplateTemplateParmDecl>(D));
}
+/// \brief Determine whether the given set of template arguments has a pack
+/// expansion that is not the last template argument.
+static bool hasPackExpansionBeforeEnd(const TemplateArgument *Args,
+ unsigned NumArgs) {
+ unsigned ArgIdx = 0;
+ while (ArgIdx < NumArgs) {
+ const TemplateArgument &Arg = Args[ArgIdx];
+
+ // Unwrap argument packs.
+ if (Args[ArgIdx].getKind() == TemplateArgument::Pack) {
+ Args = Arg.pack_begin();
+ NumArgs = Arg.pack_size();
+ ArgIdx = 0;
+ continue;
+ }
+
+ ++ArgIdx;
+ if (ArgIdx == NumArgs)
+ return false;
+
+ if (Arg.isPackExpansion())
+ return true;
+ }
+
+ return false;
+}
+
static Sema::TemplateDeductionResult
DeduceTemplateArguments(Sema &S,
TemplateParameterList *TemplateParams,
@@ -1071,9 +1098,9 @@
// If the template argument list of P contains a pack expansion that is not
// the last template argument, the entire template argument list is a
// non-deduced context.
- // FIXME: Implement this.
-
-
+ if (hasPackExpansionBeforeEnd(Params, NumParams))
+ return Sema::TDK_Success;
+
// C++0x [temp.deduct.type]p9:
// If P has a form that contains <T> or <i>, then each argument Pi of the
// respective template argument list P is compared with the corresponding
@@ -3052,6 +3079,15 @@
= cast<TemplateSpecializationType>(T);
MarkUsedTemplateParameters(SemaRef, Spec->getTemplateName(), OnlyDeduced,
Depth, Used);
+
+ // C++0x [temp.deduct.type]p9:
+ // If the template argument list of P contains a pack expansion that is not
+ // the last template argument, the entire template argument list is a
+ // non-deduced context.
+ if (OnlyDeduced &&
+ hasPackExpansionBeforeEnd(Spec->getArgs(), Spec->getNumArgs()))
+ break;
+
for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I)
MarkUsedTemplateParameters(SemaRef, Spec->getArg(I), OnlyDeduced, Depth,
Used);
@@ -3078,6 +3114,15 @@
if (!OnlyDeduced)
MarkUsedTemplateParameters(SemaRef, Spec->getQualifier(),
OnlyDeduced, Depth, Used);
+
+ // C++0x [temp.deduct.type]p9:
+ // If the template argument list of P contains a pack expansion that is not
+ // the last template argument, the entire template argument list is a
+ // non-deduced context.
+ if (OnlyDeduced &&
+ hasPackExpansionBeforeEnd(Spec->getArgs(), Spec->getNumArgs()))
+ break;
+
for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I)
MarkUsedTemplateParameters(SemaRef, Spec->getArg(I), OnlyDeduced, Depth,
Used);
@@ -3181,6 +3226,14 @@
Sema::MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs,
bool OnlyDeduced, unsigned Depth,
llvm::SmallVectorImpl<bool> &Used) {
+ // C++0x [temp.deduct.type]p9:
+ // If the template argument list of P contains a pack expansion that is not
+ // the last template argument, the entire template argument list is a
+ // non-deduced context.
+ if (OnlyDeduced &&
+ hasPackExpansionBeforeEnd(TemplateArgs.data(), TemplateArgs.size()))
+ return;
+
for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
::MarkUsedTemplateParameters(*this, TemplateArgs[I], OnlyDeduced,
Depth, Used);
@@ -3196,6 +3249,7 @@
Deduced.clear();
Deduced.resize(TemplateParams->size());
+ // FIXME: Variadic templates.
FunctionDecl *Function = FunctionTemplate->getTemplatedDecl();
for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I)
::MarkUsedTemplateParameters(*this, Function->getParamDecl(I)->getType(),
Modified: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p2-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p2-0x.cpp?rev=122461&r1=122460&r2=122461&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p2-0x.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p2-0x.cpp Wed Dec 22 19:24:45 2010
@@ -18,6 +18,6 @@
static const bool value = true;
};
-//int same_tuple_check1[same_tuple<tuple<int, float>, tuple<int, double>>::value? -1 : 1];
+int same_tuple_check1[same_tuple<tuple<int, float>, tuple<int, double>>::value? -1 : 1];
int same_tuple_check2[same_tuple<tuple<float, double>, tuple<float, double>>::value? 1 : -1];
Added: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp?rev=122461&view=auto
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp (added)
+++ cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp Wed Dec 22 19:24:45 2010
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+template<typename ...Types> struct tuple;
+
+namespace PackExpansionNotAtEnd {
+ template<typename T, typename U>
+ struct tuple_same_with_int {
+ static const bool value = false;
+ };
+
+ template<typename ...Types>
+ struct tuple_same_with_int<tuple<Types...>, tuple<Types..., int>> {
+ static const bool value = true;
+ };
+
+ int tuple_same_with_int_1[tuple_same_with_int<tuple<int, float, double>,
+ tuple<int, float, double, int>
+ >::value? 1 : -1];
+
+ template<typename ... Types> struct UselessPartialSpec;
+
+ template<typename ... Types, // expected-note{{non-deducible template parameter 'Types'}}
+ typename Tail> // expected-note{{non-deducible template parameter 'Tail'}}
+ struct UselessPartialSpec<Types..., Tail>; // expected-warning{{class template partial specialization contains template parameters that can not be deduced; this partial specialization will never be used}}
+}
Propchange: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the cfe-commits
mailing list