summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplateDeduction.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-25 17:19:08 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-25 17:19:08 +0000
commit85f240c788a983171cbac01eee25aca9dda3cac1 (patch)
treefb7c4c8646e150bf03fee1e1a36e4df51604bdf8 /clang/lib/Sema/SemaTemplateDeduction.cpp
parent109941b0782b25a48142c219c089612cd23b0165 (diff)
downloadbcm5719-llvm-85f240c788a983171cbac01eee25aca9dda3cac1.tar.gz
bcm5719-llvm-85f240c788a983171cbac01eee25aca9dda3cac1.zip
Implement the rvalue-reference deduction transformation (from T&& ->
T) when taking the address of an overloaded function or matching a specialization to a template (C++0x [temp.deduct.type]p10). Fixes PR9044. llvm-svn: 124197
Diffstat (limited to 'clang/lib/Sema/SemaTemplateDeduction.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp39
1 files changed, 33 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 5c899ebdea3..00d92bc6b53 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -49,7 +49,10 @@ namespace clang {
/// \brief Allow non-dependent types to differ, e.g., when performing
/// template argument deduction from a function call where conversions
/// may apply.
- TDF_SkipNonDependent = 0x08
+ TDF_SkipNonDependent = 0x08,
+ /// \brief Whether we are performing template argument deduction for
+ /// parameters and arguments in a top-level template argument
+ TDF_TopLevelParameterTypeList = 0x10
};
}
@@ -763,9 +766,9 @@ DeduceTemplateArguments(Sema &S,
// Deduce template arguments from the pattern.
if (Sema::TemplateDeductionResult Result
- = DeduceTemplateArguments(S, TemplateParams, Pattern, Args[ArgIdx],
- Info, Deduced, PartialOrdering,
- RefParamComparisons))
+ = DeduceTemplateArguments(S, TemplateParams, Pattern, Args[ArgIdx],
+ Info, Deduced, TDF, PartialOrdering,
+ RefParamComparisons))
return Result;
// Capture the deduced template arguments for each parameter pack expanded
@@ -898,6 +901,29 @@ DeduceTemplateArguments(Sema &S,
Arg.getCVRQualifiers());
Param = S.Context.getQualifiedType(UnqualParam, Quals);
}
+
+ if ((TDF & TDF_TopLevelParameterTypeList) && !Param->isFunctionType()) {
+ // C++0x [temp.deduct.type]p10:
+ // If P and A are function types that originated from deduction when
+ // taking the address of a function template (14.8.2.2) or when deducing
+ // template arguments from a function declaration (14.8.2.6) and Pi and
+ // Ai are parameters of the top-level parameter-type-list of P and A,
+ // respectively, Pi is adjusted if it is an rvalue reference to a
+ // cv-unqualified template parameter and Ai is an lvalue reference, in
+ // which case the type of Pi is changed to be the template parameter
+ // type (i.e., T&& is changed to simply T). [ Note: As a result, when
+ // Pi is T&& and Ai is X&, the adjusted Pi will be T, causing T to be
+ // deduced as X&. — end note ]
+ TDF &= ~TDF_TopLevelParameterTypeList;
+
+ if (const RValueReferenceType *ParamRef
+ = Param->getAs<RValueReferenceType>()) {
+ if (isa<TemplateTypeParmType>(ParamRef->getPointeeType()) &&
+ !ParamRef->getPointeeType().getQualifiers())
+ if (Arg->isLValueReferenceType())
+ Param = ParamRef->getPointeeType();
+ }
+ }
}
// If the parameter type is not dependent, there is nothing to deduce.
@@ -1119,6 +1145,7 @@ DeduceTemplateArguments(Sema &S,
// T(*)()
// T(*)(T)
case Type::FunctionProto: {
+ unsigned SubTDF = TDF & TDF_TopLevelParameterTypeList;
const FunctionProtoType *FunctionProtoArg =
dyn_cast<FunctionProtoType>(Arg);
if (!FunctionProtoArg)
@@ -1147,7 +1174,7 @@ DeduceTemplateArguments(Sema &S,
FunctionProtoParam->getNumArgs(),
FunctionProtoArg->arg_type_begin(),
FunctionProtoArg->getNumArgs(),
- Info, Deduced, 0);
+ Info, Deduced, SubTDF);
}
case Type::InjectedClassName: {
@@ -2767,7 +2794,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
if (TemplateDeductionResult Result
= ::DeduceTemplateArguments(*this, TemplateParams,
FunctionType, ArgFunctionType, Info,
- Deduced, 0))
+ Deduced, TDF_TopLevelParameterTypeList))
return Result;
}
OpenPOWER on IntegriCloud