Template argument deduction of a non-type template parameter from a

template argument.

llvm-svn: 88722
This commit is contained in:
Douglas Gregor 2009-11-13 23:45:44 +00:00
parent 78fa302e7d
commit 2bb756a3be
2 changed files with 48 additions and 2 deletions

View File

@ -126,7 +126,6 @@ DeduceNonTypeTemplateArgument(ASTContext &Context,
/// from the given type- or value-dependent expression.
///
/// \returns true if deduction succeeded, false otherwise.
static Sema::TemplateDeductionResult
DeduceNonTypeTemplateArgument(ASTContext &Context,
NonTypeTemplateParmDecl *NTTP,
@ -166,6 +165,43 @@ DeduceNonTypeTemplateArgument(ASTContext &Context,
return Sema::TDK_Success;
}
/// \brief Deduce the value of the given non-type template parameter
/// from the given declaration.
///
/// \returns true if deduction succeeded, false otherwise.
static Sema::TemplateDeductionResult
DeduceNonTypeTemplateArgument(ASTContext &Context,
NonTypeTemplateParmDecl *NTTP,
Decl *D,
Sema::TemplateDeductionInfo &Info,
llvm::SmallVectorImpl<TemplateArgument> &Deduced) {
assert(NTTP->getDepth() == 0 &&
"Cannot deduce non-type template argument with depth > 0");
if (Deduced[NTTP->getIndex()].isNull()) {
Deduced[NTTP->getIndex()] = TemplateArgument(D->getCanonicalDecl());
return Sema::TDK_Success;
}
if (Deduced[NTTP->getIndex()].getKind() == TemplateArgument::Expression) {
// Okay, we deduced a declaration in one case and a dependent expression
// in another case.
return Sema::TDK_Success;
}
if (Deduced[NTTP->getIndex()].getKind() == TemplateArgument::Declaration) {
// Compare the declarations for equality
if (Deduced[NTTP->getIndex()].getAsDecl()->getCanonicalDecl() ==
D->getCanonicalDecl())
return Sema::TDK_Success;
// FIXME: Fill in argument mismatch information
return Sema::TDK_NonDeducedMismatch;
}
return Sema::TDK_Success;
}
static Sema::TemplateDeductionResult
DeduceTemplateArguments(ASTContext &Context,
TemplateParameterList *TemplateParams,
@ -847,7 +883,10 @@ DeduceTemplateArguments(ASTContext &Context,
if (Arg.getKind() == TemplateArgument::Expression)
return DeduceNonTypeTemplateArgument(Context, NTTP, Arg.getAsExpr(),
Info, Deduced);
if (Arg.getKind() == TemplateArgument::Declaration)
return DeduceNonTypeTemplateArgument(Context, NTTP, Arg.getAsDecl(),
Info, Deduced);
assert(false && "Type/value mismatch");
Info.FirstArg = Param;
Info.SecondArg = Arg;

View File

@ -46,3 +46,10 @@ struct X4 {
int &get_X4(X4<&Y::x> x4, Y& y) {
return x4.getMember(y);
}
template<IntMember Member>
void accept_X4(X4<Member>);
void test_accept_X4(X4<&Y::x> x4) {
accept_X4(x4);
}