aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/AST/Type.cpp4
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp43
-rw-r--r--test/SemaTemplate/temp_class_spec.cpp13
3 files changed, 52 insertions, 8 deletions
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index f573744083..1fd616a086 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -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;
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index a55dadd932..c989132391 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -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).
diff --git a/test/SemaTemplate/temp_class_spec.cpp b/test/SemaTemplate/temp_class_spec.cpp
index 1efb364a1b..710fa4ada5 100644
--- a/test/SemaTemplate/temp_class_spec.cpp
+++ b/test/SemaTemplate/temp_class_spec.cpp
@@ -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;