Template argument deduction for references

llvm-svn: 72822
This commit is contained in:
Douglas Gregor 2009-06-04 00:21:18 +00:00
parent 8a1be5e4a9
commit 5cdac0a52e
3 changed files with 52 additions and 8 deletions

View File

@ -1049,6 +1049,10 @@ TemplateSpecializationType::
anyDependentTemplateArguments(const TemplateArgument *Args, unsigned NumArgs) {
for (unsigned Idx = 0; Idx < NumArgs; ++Idx) {
switch (Args[Idx].getKind()) {
case TemplateArgument::Null:
assert(false && "Should not have a NULL template argument");
break;
case TemplateArgument::Type:
if (Args[Idx].getAsType()->isDependentType())
return true;

View File

@ -66,15 +66,42 @@ static bool DeduceTemplateArguments(ASTContext &Context, QualType Param,
if (Param.getCVRQualifiers() != Arg.getCVRQualifiers())
return false;
if (const PointerType *PointerParam = Param->getAsPointerType()) {
const PointerType *PointerArg = Arg->getAsPointerType();
if (!PointerArg)
return false;
switch (Param->getTypeClass()) {
case Type::Pointer: {
const PointerType *PointerArg = Arg->getAsPointerType();
if (!PointerArg)
return false;
return DeduceTemplateArguments(Context,
cast<PointerType>(Param)->getPointeeType(),
PointerArg->getPointeeType(),
Deduced);
}
case Type::LValueReference: {
const LValueReferenceType *ReferenceArg = Arg->getAsLValueReferenceType();
if (!ReferenceArg)
return false;
return DeduceTemplateArguments(Context,
cast<LValueReferenceType>(Param)->getPointeeType(),
ReferenceArg->getPointeeType(),
Deduced);
}
return DeduceTemplateArguments(Context,
PointerParam->getPointeeType(),
PointerArg->getPointeeType(),
Deduced);
case Type::RValueReference: {
const RValueReferenceType *ReferenceArg = Arg->getAsRValueReferenceType();
if (!ReferenceArg)
return false;
return DeduceTemplateArguments(Context,
cast<RValueReferenceType>(Param)->getPointeeType(),
ReferenceArg->getPointeeType(),
Deduced);
}
default:
break;
}
// FIXME: Many more cases to go (to go).

View File

@ -19,6 +19,19 @@ int array1[is_pointer<int*>::value? 1 : -1];
int array2[is_pointer<const int*>::value? 1 : -1]; // expected-error{{partial ordering}} \
// expected-error{{negative}}
template<typename T>
struct is_lvalue_reference {
static const bool value = false;
};
template<typename T>
struct is_lvalue_reference<T&> {
static const bool value = true;
};
int lvalue_ref0[is_lvalue_reference<int>::value? -1 : 1];
int lvalue_ref1[is_lvalue_reference<const int&>::value? 1 : -1];
template<typename T, typename U>
struct is_same {
static const bool value = false;