summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-06-04 00:21:18 +0000
committerDouglas Gregor <dgregor@apple.com>2009-06-04 00:21:18 +0000
commit5cdac0a52ec319215b83ae2cf0df5c9baa228aa4 (patch)
tree34f1e06c89c67f1c3c506beb905286886c332f52 /clang
parent8a1be5e4a93eb6e29dc759b5357274267b5d4722 (diff)
downloadbcm5719-llvm-5cdac0a52ec319215b83ae2cf0df5c9baa228aa4.tar.gz
bcm5719-llvm-5cdac0a52ec319215b83ae2cf0df5c9baa228aa4.zip
Template argument deduction for references
llvm-svn: 72822
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/AST/Type.cpp4
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp43
-rw-r--r--clang/test/SemaTemplate/temp_class_spec.cpp13
3 files changed, 52 insertions, 8 deletions
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index f573744083a..1fd616a0866 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/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/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index a55dadd932b..c9891323916 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/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/clang/test/SemaTemplate/temp_class_spec.cpp b/clang/test/SemaTemplate/temp_class_spec.cpp
index 1efb364a1b2..710fa4ada55 100644
--- a/clang/test/SemaTemplate/temp_class_spec.cpp
+++ b/clang/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;
OpenPOWER on IntegriCloud