diff options
author | Nathan Sidwell <nathan@acm.org> | 2015-01-12 20:13:20 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@acm.org> | 2015-01-12 20:13:20 +0000 |
commit | c9ebfb4b4126dd92c6137d0485d62fd1eb624847 (patch) | |
tree | 8172787c4e5ff794452c2d6d20bc965fff76f0b3 /lib/Sema | |
parent | ea974ddde8eab51a6faa669bbc6e0a2a5f9cb0c3 (diff) |
reverting due to build bot failure
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@225684 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 47 |
1 files changed, 30 insertions, 17 deletions
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 90384f0b0a..dd2a4d2697 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -3136,16 +3136,34 @@ static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S, // are ignored for type deduction. if (ParamType.hasQualifiers()) ParamType = ParamType.getUnqualifiedType(); - - // [...] If P is a reference type, the type referred to by P is - // used for type deduction. const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>(); - if (ParamRefType) - ParamType = ParamRefType->getPointeeType(); + if (ParamRefType) { + QualType PointeeType = ParamRefType->getPointeeType(); + + // If the argument has incomplete array type, try to complete its type. + if (ArgType->isIncompleteArrayType() && !S.RequireCompleteExprType(Arg, 0)) + ArgType = Arg->getType(); - // Overload sets usually make this parameter an undeduced context, - // but there are sometimes special circumstances. Typically - // involving a template-id-expr. + // [C++0x] If P is an rvalue reference to a cv-unqualified + // template parameter and the argument is an lvalue, the type + // "lvalue reference to A" is used in place of A for type + // deduction. + if (isa<RValueReferenceType>(ParamType)) { + if (!PointeeType.getQualifiers() && + isa<TemplateTypeParmType>(PointeeType) && + Arg->Classify(S.Context).isLValue() && + Arg->getType() != S.Context.OverloadTy && + Arg->getType() != S.Context.BoundMemberTy) + ArgType = S.Context.getLValueReferenceType(ArgType); + } + + // [...] If P is a reference type, the type referred to by P is used + // for type deduction. + ParamType = PointeeType; + } + + // Overload sets usually make this parameter an undeduced + // context, but there are sometimes special circumstances. if (ArgType == S.Context.OverloadTy) { ArgType = ResolveOverloadForDeduction(S, TemplateParams, Arg, ParamType, @@ -3155,17 +3173,12 @@ static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S, } if (ParamRefType) { - // If the argument has incomplete array type, try to complete its type. - if (ArgType->isIncompleteArrayType() && !S.RequireCompleteExprType(Arg, 0)) - ArgType = Arg->getType(); - // C++0x [temp.deduct.call]p3: - // If P is an rvalue reference to a cv-unqualified template - // parameter and the argument is an lvalue, the type "lvalue - // reference to A" is used in place of A for type deduction. + // [...] If P is of the form T&&, where T is a template parameter, and + // the argument is an lvalue, the type A& is used in place of A for + // type deduction. if (ParamRefType->isRValueReferenceType() && - !ParamType.getQualifiers() && - isa<TemplateTypeParmType>(ParamType) && + ParamRefType->getAs<TemplateTypeParmType>() && Arg->isLValue()) ArgType = S.Context.getLValueReferenceType(ArgType); } else { |