forked from OSchip/llvm-project
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. llvm-svn: 122461
This commit is contained in:
parent
d5f66fcbac
commit
d0ad2949fa
|
@ -1059,6 +1059,33 @@ static TemplateParameter makeTemplateParameter(Decl *D) {
|
|||
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 @@ DeduceTemplateArguments(Sema &S,
|
|||
// 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 @@ MarkUsedTemplateParameters(Sema &SemaRef, QualType T,
|
|||
= 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 @@ MarkUsedTemplateParameters(Sema &SemaRef, QualType T,
|
|||
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 @@ void
|
|||
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 @@ Sema::MarkDeducedTemplateParameters(FunctionTemplateDecl *FunctionTemplate,
|
|||
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(),
|
||||
|
|
|
@ -18,6 +18,6 @@ struct same_tuple<tuple<Types1...>, tuple<Types1...> > {
|
|||
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];
|
||||
|
||||
|
|
|
@ -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}}
|
||||
}
|
Loading…
Reference in New Issue