diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-01-25 17:19:08 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-01-25 17:19:08 +0000 |
commit | 73b3cf6503f72f054288cf474e1a8c8ae56383c2 (patch) | |
tree | 792f250e7d9bf62c7592c3b9cb615f348dabe64a /lib | |
parent | 88b22a432549e315662f96abe148923c921970cb (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124197 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 5c899ebdea..00d92bc6b5 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/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; } |