diff options
Diffstat (limited to 'lib/Sema/SemaTemplateDeduction.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index f2f989ce1241..b55a232d26c2 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -1,9 +1,8 @@ //===- SemaTemplateDeduction.cpp - Template Argument Deduction ------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -1671,8 +1670,8 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, const FunctionProtoType *FunctionProtoParam = cast<FunctionProtoType>(Param); - if (FunctionProtoParam->getTypeQuals() - != FunctionProtoArg->getTypeQuals() || + if (FunctionProtoParam->getMethodQuals() + != FunctionProtoArg->getMethodQuals() || FunctionProtoParam->getRefQualifier() != FunctionProtoArg->getRefQualifier() || FunctionProtoParam->isVariadic() != FunctionProtoArg->isVariadic()) @@ -2873,7 +2872,7 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, return Sema::TDK_SubstitutionFailure; return ::FinishTemplateArgumentDeduction( - *this, Partial, /*PartialOrdering=*/false, TemplateArgs, Deduced, Info); + *this, Partial, /*IsPartialOrdering=*/false, TemplateArgs, Deduced, Info); } /// Perform template argument deduction to determine whether @@ -2914,7 +2913,7 @@ Sema::DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial, return Sema::TDK_SubstitutionFailure; return ::FinishTemplateArgumentDeduction( - *this, Partial, /*PartialOrdering=*/false, TemplateArgs, Deduced, Info); + *this, Partial, /*IsPartialOrdering=*/false, TemplateArgs, Deduced, Info); } /// Determine whether the given type T is a simple-template-id type. @@ -3082,7 +3081,7 @@ Sema::SubstituteExplicitTemplateArguments( CXXRecordDecl *ThisContext = nullptr; if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Function)) { ThisContext = Method->getParent(); - ThisTypeQuals = Method->getTypeQualifiers(); + ThisTypeQuals = Method->getMethodQualifiers(); } CXXThisScopeRAII ThisScope(*this, ThisContext, ThisTypeQuals, @@ -4281,19 +4280,26 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( } namespace { + struct DependentAuto { bool IsPack; }; /// Substitute the 'auto' specifier or deduced template specialization type /// specifier within a type for a given replacement type. class SubstituteDeducedTypeTransform : public TreeTransform<SubstituteDeducedTypeTransform> { QualType Replacement; + bool ReplacementIsPack; bool UseTypeSugar; public: + SubstituteDeducedTypeTransform(Sema &SemaRef, DependentAuto DA) + : TreeTransform<SubstituteDeducedTypeTransform>(SemaRef), Replacement(), + ReplacementIsPack(DA.IsPack), UseTypeSugar(true) {} + SubstituteDeducedTypeTransform(Sema &SemaRef, QualType Replacement, - bool UseTypeSugar = true) + bool UseTypeSugar = true) : TreeTransform<SubstituteDeducedTypeTransform>(SemaRef), - Replacement(Replacement), UseTypeSugar(UseTypeSugar) {} + Replacement(Replacement), ReplacementIsPack(false), + UseTypeSugar(UseTypeSugar) {} QualType TransformDesugared(TypeLocBuilder &TLB, DeducedTypeLoc TL) { assert(isa<TemplateTypeParmType>(Replacement) && @@ -4318,7 +4324,8 @@ namespace { return TransformDesugared(TLB, TL); QualType Result = SemaRef.Context.getAutoType( - Replacement, TL.getTypePtr()->getKeyword(), Replacement.isNull()); + Replacement, TL.getTypePtr()->getKeyword(), Replacement.isNull(), + ReplacementIsPack); auto NewTL = TLB.push<AutoTypeLoc>(Result); NewTL.setNameLoc(TL.getNameLoc()); return Result; @@ -4409,9 +4416,12 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, Init = NonPlaceholder.get(); } + DependentAuto DependentResult = { + /*.IsPack = */ (bool)Type.getAs<PackExpansionTypeLoc>()}; + if (!DependentDeductionDepth && (Type.getType()->isDependentType() || Init->isTypeDependent())) { - Result = SubstituteDeducedTypeTransform(*this, QualType()).Apply(Type); + Result = SubstituteDeducedTypeTransform(*this, DependentResult).Apply(Type); assert(!Result.isNull() && "substituting DependentTy can't fail"); return DAR_Succeeded; } @@ -4479,7 +4489,8 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, auto DeductionFailed = [&](TemplateDeductionResult TDK, ArrayRef<SourceRange> Ranges) -> DeduceAutoResult { if (Init->isTypeDependent()) { - Result = SubstituteDeducedTypeTransform(*this, QualType()).Apply(Type); + Result = + SubstituteDeducedTypeTransform(*this, DependentResult).Apply(Type); assert(!Result.isNull() && "substituting DependentTy can't fail"); return DAR_Succeeded; } @@ -4560,7 +4571,10 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, QualType Sema::SubstAutoType(QualType TypeWithAuto, QualType TypeToReplaceAuto) { if (TypeToReplaceAuto->isDependentType()) - TypeToReplaceAuto = QualType(); + return SubstituteDeducedTypeTransform( + *this, DependentAuto{ + TypeToReplaceAuto->containsUnexpandedParameterPack()}) + .TransformType(TypeWithAuto); return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto) .TransformType(TypeWithAuto); } @@ -4568,7 +4582,11 @@ QualType Sema::SubstAutoType(QualType TypeWithAuto, TypeSourceInfo *Sema::SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, QualType TypeToReplaceAuto) { if (TypeToReplaceAuto->isDependentType()) - TypeToReplaceAuto = QualType(); + return SubstituteDeducedTypeTransform( + *this, + DependentAuto{ + TypeToReplaceAuto->containsUnexpandedParameterPack()}) + .TransformType(TypeWithAuto); return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto) .TransformType(TypeWithAuto); } @@ -4661,7 +4679,7 @@ AddImplicitObjectParameterType(ASTContext &Context, // The standard doesn't say explicitly, but we pick the appropriate kind of // reference type based on [over.match.funcs]p4. QualType ArgTy = Context.getTypeDeclType(Method->getParent()); - ArgTy = Context.getQualifiedType(ArgTy, Method->getTypeQualifiers()); + ArgTy = Context.getQualifiedType(ArgTy, Method->getMethodQualifiers()); if (Method->getRefQualifier() == RQ_RValue) ArgTy = Context.getRValueReferenceType(ArgTy); else @@ -5049,7 +5067,7 @@ static bool isAtLeastAsSpecializedAs(Sema &S, QualType T1, QualType T2, Info); auto *TST1 = T1->castAs<TemplateSpecializationType>(); if (FinishTemplateArgumentDeduction( - S, P2, /*PartialOrdering=*/true, + S, P2, /*IsPartialOrdering=*/true, TemplateArgumentList(TemplateArgumentList::OnStack, TST1->template_arguments()), Deduced, Info)) |