forked from OSchip/llvm-project
Template argument deduction for references
llvm-svn: 72822
This commit is contained in:
parent
8a1be5e4a9
commit
5cdac0a52e
|
@ -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;
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue