diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-11-19 20:06:13 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-11-19 20:06:13 +0000 |
| commit | c0981da47d5696fe36474fcf86b4ce03ae3ff818 (patch) | |
| tree | f42add1021b9f2ac6a69ac7cf6c4499962739a45 /clang/lib/Sema/SemaTemplateDeduction.cpp | |
| parent | 344a3780b2e33f6ca763666c380202b18aab72a3 (diff) | |
Diffstat (limited to 'clang/lib/Sema/SemaTemplateDeduction.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 1147 |
1 files changed, 511 insertions, 636 deletions
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 08e798304b0c..81edae10335d 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -131,30 +131,16 @@ static bool hasSameExtendedValue(llvm::APSInt X, llvm::APSInt Y) { return X == Y; } -static Sema::TemplateDeductionResult -DeduceTemplateArguments(Sema &S, - TemplateParameterList *TemplateParams, - const TemplateArgument &Param, - TemplateArgument Arg, - TemplateDeductionInfo &Info, - SmallVectorImpl<DeducedTemplateArgument> &Deduced); - -static Sema::TemplateDeductionResult -DeduceTemplateArgumentsByTypeMatch(Sema &S, - TemplateParameterList *TemplateParams, - QualType Param, - QualType Arg, - TemplateDeductionInfo &Info, - SmallVectorImpl<DeducedTemplateArgument> & - Deduced, - unsigned TDF, - bool PartialOrdering = false, - bool DeducedFromArrayBound = false); +static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( + Sema &S, TemplateParameterList *TemplateParams, QualType Param, + QualType Arg, TemplateDeductionInfo &Info, + SmallVectorImpl<DeducedTemplateArgument> &Deduced, unsigned TDF, + bool PartialOrdering = false, bool DeducedFromArrayBound = false); static Sema::TemplateDeductionResult DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, - ArrayRef<TemplateArgument> Params, - ArrayRef<TemplateArgument> Args, + ArrayRef<TemplateArgument> Ps, + ArrayRef<TemplateArgument> As, TemplateDeductionInfo &Info, SmallVectorImpl<DeducedTemplateArgument> &Deduced, bool NumberOfArgumentsMustMatch); @@ -559,75 +545,67 @@ DeduceTemplateArguments(Sema &S, /// "success" result means that template argument deduction has not yet failed, /// but it may still fail, later, for other reasons. static Sema::TemplateDeductionResult -DeduceTemplateArguments(Sema &S, - TemplateParameterList *TemplateParams, - const TemplateSpecializationType *Param, - QualType Arg, - TemplateDeductionInfo &Info, - SmallVectorImpl<DeducedTemplateArgument> &Deduced) { - assert(Arg.isCanonical() && "Argument type must be canonical"); +DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams, + const QualType P, QualType A, + TemplateDeductionInfo &Info, + SmallVectorImpl<DeducedTemplateArgument> &Deduced) { + QualType UP = P; + if (const auto *IP = P->getAs<InjectedClassNameType>()) + UP = IP->getInjectedSpecializationType(); + // FIXME: Try to preserve type sugar here, which is hard + // because of the unresolved template arguments. + const auto *TP = UP.getCanonicalType()->castAs<TemplateSpecializationType>(); + ArrayRef<TemplateArgument> PResolved = TP->template_arguments(); + QualType UA = A; // Treat an injected-class-name as its underlying template-id. - if (auto *Injected = dyn_cast<InjectedClassNameType>(Arg)) - Arg = Injected->getInjectedSpecializationType(); + if (const auto *Injected = A->getAs<InjectedClassNameType>()) + UA = Injected->getInjectedSpecializationType(); // Check whether the template argument is a dependent template-id. - if (const TemplateSpecializationType *SpecArg - = dyn_cast<TemplateSpecializationType>(Arg)) { + // FIXME: Should not lose sugar here. + if (const auto *SA = + dyn_cast<TemplateSpecializationType>(UA.getCanonicalType())) { // Perform template argument deduction for the template name. - if (Sema::TemplateDeductionResult Result - = DeduceTemplateArguments(S, TemplateParams, - Param->getTemplateName(), - SpecArg->getTemplateName(), - Info, Deduced)) + if (auto Result = + DeduceTemplateArguments(S, TemplateParams, TP->getTemplateName(), + SA->getTemplateName(), Info, Deduced)) return Result; - - // Perform template argument deduction on each template // argument. Ignore any missing/extra arguments, since they could be // filled in by default arguments. - return DeduceTemplateArguments(S, TemplateParams, - Param->template_arguments(), - SpecArg->template_arguments(), Info, Deduced, + return DeduceTemplateArguments(S, TemplateParams, PResolved, + SA->template_arguments(), Info, Deduced, /*NumberOfArgumentsMustMatch=*/false); } // If the argument type is a class template specialization, we // perform template argument deduction using its template // arguments. - const RecordType *RecordArg = dyn_cast<RecordType>(Arg); - if (!RecordArg) { - Info.FirstArg = TemplateArgument(QualType(Param, 0)); - Info.SecondArg = TemplateArgument(Arg); - return Sema::TDK_NonDeducedMismatch; - } - - ClassTemplateSpecializationDecl *SpecArg - = dyn_cast<ClassTemplateSpecializationDecl>(RecordArg->getDecl()); - if (!SpecArg) { - Info.FirstArg = TemplateArgument(QualType(Param, 0)); - Info.SecondArg = TemplateArgument(Arg); + const auto *RA = UA->getAs<RecordType>(); + const auto *SA = + RA ? dyn_cast<ClassTemplateSpecializationDecl>(RA->getDecl()) : nullptr; + if (!SA) { + Info.FirstArg = TemplateArgument(P); + Info.SecondArg = TemplateArgument(A); return Sema::TDK_NonDeducedMismatch; } // Perform template argument deduction for the template name. - if (Sema::TemplateDeductionResult Result - = DeduceTemplateArguments(S, - TemplateParams, - Param->getTemplateName(), - TemplateName(SpecArg->getSpecializedTemplate()), - Info, Deduced)) + if (auto Result = DeduceTemplateArguments( + S, TemplateParams, TP->getTemplateName(), + TemplateName(SA->getSpecializedTemplate()), Info, Deduced)) return Result; // Perform template argument deduction for the template arguments. - return DeduceTemplateArguments(S, TemplateParams, Param->template_arguments(), - SpecArg->getTemplateArgs().asArray(), Info, - Deduced, /*NumberOfArgumentsMustMatch=*/true); + return DeduceTemplateArguments(S, TemplateParams, PResolved, + SA->getTemplateArgs().asArray(), Info, Deduced, + /*NumberOfArgumentsMustMatch=*/true); } -/// Determines whether the given type is an opaque type that -/// might be more qualified when instantiated. -static bool IsPossiblyOpaquelyQualifiedType(QualType T) { +static bool IsPossiblyOpaquelyQualifiedTypeInternal(const Type *T) { + assert(T->isCanonicalUnqualified()); + switch (T->getTypeClass()) { case Type::TypeOfExpr: case Type::TypeOf: @@ -641,14 +619,21 @@ static bool IsPossiblyOpaquelyQualifiedType(QualType T) { case Type::IncompleteArray: case Type::VariableArray: case Type::DependentSizedArray: - return IsPossiblyOpaquelyQualifiedType( - cast<ArrayType>(T)->getElementType()); + return IsPossiblyOpaquelyQualifiedTypeInternal( + cast<ArrayType>(T)->getElementType().getTypePtr()); default: return false; } } +/// Determines whether the given type is an opaque type that +/// might be more qualified when instantiated. +static bool IsPossiblyOpaquelyQualifiedType(QualType T) { + return IsPossiblyOpaquelyQualifiedTypeInternal( + T->getCanonicalTypeInternal().getTypePtr()); +} + /// Helper function to build a TemplateParameter when we don't /// know its type statically. static TemplateParameter makeTemplateParameter(Decl *D) { @@ -1047,11 +1032,12 @@ DeduceTemplateArguments(Sema &S, return Sema::TDK_MiscellaneousDeductionFailure; } - if (Sema::TemplateDeductionResult Result - = DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, - Params[ParamIdx], Args[ArgIdx], - Info, Deduced, TDF, - PartialOrdering)) + if (Sema::TemplateDeductionResult Result = + DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, Params[ParamIdx].getUnqualifiedType(), + Args[ArgIdx].getUnqualifiedType(), Info, Deduced, TDF, + PartialOrdering, + /*DeducedFromArrayBound=*/false)) return Result; ++ArgIdx; @@ -1073,10 +1059,11 @@ DeduceTemplateArguments(Sema &S, if (ParamIdx + 1 == NumParams || PackScope.hasFixedArity()) { for (; ArgIdx < NumArgs && PackScope.hasNextElement(); ++ArgIdx) { // Deduce template arguments from the pattern. - if (Sema::TemplateDeductionResult Result - = DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, Pattern, - Args[ArgIdx], Info, Deduced, - TDF, PartialOrdering)) + if (Sema::TemplateDeductionResult Result = + DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, Pattern.getUnqualifiedType(), + Args[ArgIdx].getUnqualifiedType(), Info, Deduced, TDF, + PartialOrdering, /*DeducedFromArrayBound=*/false)) return Result; PackScope.nextPackElement(); @@ -1155,26 +1142,25 @@ static bool hasInconsistentOrSupersetQualifiersOf(QualType ParamType, /// function types (noreturn adjustment, implicit calling conventions). If any /// of parameter and argument is not a function, just perform type comparison. /// -/// \param Param the template parameter type. +/// \param P the template parameter type. /// -/// \param Arg the argument type. -bool Sema::isSameOrCompatibleFunctionType(CanQualType Param, - CanQualType Arg) { - const FunctionType *ParamFunction = Param->getAs<FunctionType>(), - *ArgFunction = Arg->getAs<FunctionType>(); +/// \param A the argument type. +bool Sema::isSameOrCompatibleFunctionType(QualType P, QualType A) { + const FunctionType *PF = P->getAs<FunctionType>(), + *AF = A->getAs<FunctionType>(); // Just compare if not functions. - if (!ParamFunction || !ArgFunction) - return Param == Arg; + if (!PF || !AF) + return Context.hasSameType(P, A); // Noreturn and noexcept adjustment. QualType AdjustedParam; - if (IsFunctionConversion(Param, Arg, AdjustedParam)) - return Arg == Context.getCanonicalType(AdjustedParam); + if (IsFunctionConversion(P, A, AdjustedParam)) + return Context.hasSameType(AdjustedParam, A); // FIXME: Compatible calling conventions. - return Param == Arg; + return Context.hasSameType(P, A); } /// Get the index of the first template parameter that was originally from the @@ -1203,6 +1189,11 @@ static bool isForwardingReference(QualType Param, unsigned FirstInnerIndex) { return false; } +static CXXRecordDecl *getCanonicalRD(QualType T) { + return cast<CXXRecordDecl>( + T->castAs<RecordType>()->getDecl()->getCanonicalDecl()); +} + /// Attempt to deduce the template arguments by checking the base types /// according to (C++20 [temp.deduct.call] p4b3. /// @@ -1221,10 +1212,11 @@ static bool isForwardingReference(QualType Param, unsigned FirstInnerIndex) { /// \returns the result of template argument deduction with the bases. "invalid" /// means no matches, "success" found a single item, and the /// "MiscellaneousDeductionFailure" result happens when the match is ambiguous. -static Sema::TemplateDeductionResult DeduceTemplateBases( - Sema &S, const RecordType *RecordT, TemplateParameterList *TemplateParams, - const TemplateSpecializationType *SpecParam, TemplateDeductionInfo &Info, - SmallVectorImpl<DeducedTemplateArgument> &Deduced) { +static Sema::TemplateDeductionResult +DeduceTemplateBases(Sema &S, const CXXRecordDecl *RD, + TemplateParameterList *TemplateParams, QualType P, + TemplateDeductionInfo &Info, + SmallVectorImpl<DeducedTemplateArgument> &Deduced) { // C++14 [temp.deduct.call] p4b3: // If P is a class and P has the form simple-template-id, then the // transformed A can be a derived class of the deduced A. Likewise if @@ -1244,45 +1236,44 @@ static Sema::TemplateDeductionResult DeduceTemplateBases( // visited, while ToVisit is our stack of records that we still need to // visit. Matches contains a list of matches that have yet to be // disqualified. - llvm::SmallPtrSet<const RecordType *, 8> Visited; - SmallVector<const RecordType *, 8> ToVisit; + llvm::SmallPtrSet<const CXXRecordDecl *, 8> Visited; + SmallVector<QualType, 8> ToVisit; // We iterate over this later, so we have to use MapVector to ensure // determinism. - llvm::MapVector<const RecordType *, SmallVector<DeducedTemplateArgument, 8>> + llvm::MapVector<const CXXRecordDecl *, + SmallVector<DeducedTemplateArgument, 8>> Matches; - auto AddBases = [&Visited, &ToVisit](const RecordType *RT) { - CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); + auto AddBases = [&Visited, &ToVisit](const CXXRecordDecl *RD) { for (const auto &Base : RD->bases()) { - assert(Base.getType()->isRecordType() && - "Base class that isn't a record?"); - const RecordType *RT = Base.getType()->getAs<RecordType>(); - if (Visited.insert(RT).second) - ToVisit.push_back(Base.getType()->getAs<RecordType>()); + QualType T = Base.getType(); + assert(T->isRecordType() && "Base class that isn't a record?"); + if (Visited.insert(::getCanonicalRD(T)).second) + ToVisit.push_back(T); } }; // Set up the loop by adding all the bases. - AddBases(RecordT); + AddBases(RD); // Search each path of bases until we either run into a successful match // (where all bases of it are invalid), or we run out of bases. while (!ToVisit.empty()) { - const RecordType *NextT = ToVisit.pop_back_val(); + QualType NextT = ToVisit.pop_back_val(); SmallVector<DeducedTemplateArgument, 8> DeducedCopy(Deduced.begin(), Deduced.end()); TemplateDeductionInfo BaseInfo(TemplateDeductionInfo::ForBase, Info); - Sema::TemplateDeductionResult BaseResult = - DeduceTemplateArguments(S, TemplateParams, SpecParam, - QualType(NextT, 0), BaseInfo, DeducedCopy); + Sema::TemplateDeductionResult BaseResult = DeduceTemplateSpecArguments( + S, TemplateParams, P, NextT, BaseInfo, DeducedCopy); // If this was a successful deduction, add it to the list of matches, // otherwise we need to continue searching its bases. + const CXXRecordDecl *RD = ::getCanonicalRD(NextT); if (BaseResult == Sema::TDK_Success) - Matches.insert({NextT, DeducedCopy}); + Matches.insert({RD, DeducedCopy}); else - AddBases(NextT); + AddBases(RD); } // At this point, 'Matches' contains a list of seemingly valid bases, however @@ -1297,14 +1288,14 @@ static Sema::TemplateDeductionResult DeduceTemplateBases( AddBases(Match.first); // We can give up once we have a single item (or have run out of things to - // search) since cyclical inheritence isn't valid. + // search) since cyclical inheritance isn't valid. while (Matches.size() > 1 && !ToVisit.empty()) { - const RecordType *NextT = ToVisit.pop_back_val(); - Matches.erase(NextT); + const CXXRecordDecl *RD = ::getCanonicalRD(ToVisit.pop_back_val()); + Matches.erase(RD); - // Always add all bases, since the inheritence tree can contain + // Always add all bases, since the inheritance tree can contain // disqualifications for multiple matches. - AddBases(NextT); + AddBases(RD); } } @@ -1341,41 +1332,33 @@ static Sema::TemplateDeductionResult DeduceTemplateBases( /// \returns the result of template argument deduction so far. Note that a /// "success" result means that template argument deduction has not yet failed, /// but it may still fail, later, for other reasons. -static Sema::TemplateDeductionResult -DeduceTemplateArgumentsByTypeMatch(Sema &S, - TemplateParameterList *TemplateParams, - QualType ParamIn, QualType ArgIn, - TemplateDeductionInfo &Info, - SmallVectorImpl<DeducedTemplateArgument> &Deduced, - unsigned TDF, - bool PartialOrdering, - bool DeducedFromArrayBound) { - // We only want to look at the canonical types, since typedefs and - // sugar are not part of template argument deduction. - QualType Param = S.Context.getCanonicalType(ParamIn); - QualType Arg = S.Context.getCanonicalType(ArgIn); +static Sema::TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( + Sema &S, TemplateParameterList *TemplateParams, QualType P, QualType A, + TemplateDeductionInfo &Info, + SmallVectorImpl<DeducedTemplateArgument> &Deduced, unsigned TDF, + bool PartialOrdering, bool DeducedFromArrayBound) { // If the argument type is a pack expansion, look at its pattern. // This isn't explicitly called out - if (const PackExpansionType *ArgExpansion - = dyn_cast<PackExpansionType>(Arg)) - Arg = ArgExpansion->getPattern(); + if (const auto *AExp = dyn_cast<PackExpansionType>(A)) + A = AExp->getPattern(); + assert(!isa<PackExpansionType>(A.getCanonicalType())); if (PartialOrdering) { // C++11 [temp.deduct.partial]p5: // Before the partial ordering is done, certain transformations are // performed on the types used for partial ordering: // - If P is a reference type, P is replaced by the type referred to. - const ReferenceType *ParamRef = Param->getAs<ReferenceType>(); - if (ParamRef) - Param = ParamRef->getPointeeType(); + const ReferenceType *PRef = P->getAs<ReferenceType>(); + if (PRef) + P = PRef->getPointeeType(); // - If A is a reference type, A is replaced by the type referred to. - const ReferenceType *ArgRef = Arg->getAs<ReferenceType>(); - if (ArgRef) - Arg = ArgRef->getPointeeType(); + const ReferenceType *ARef = A->getAs<ReferenceType>(); + if (ARef) + A = A->getPointeeType(); - if (ParamRef && ArgRef && S.Context.hasSameUnqualifiedType(Param, Arg)) { + if (PRef && ARef && S.Context.hasSameUnqualifiedType(P, A)) { // C++11 [temp.deduct.partial]p9: // If, for a given type, deduction succeeds in both directions (i.e., // the types are identical after the transformations above) and both @@ -1395,29 +1378,26 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, // succeeds, so we model this as a deduction failure. Note that // [the first type] is P and [the other type] is A here; the standard // gets this backwards. - Qualifiers ParamQuals = Param.getQualifiers(); - Qualifiers ArgQuals = Arg.getQualifiers(); - if ((ParamRef->isLValueReferenceType() && - !ArgRef->isLValueReferenceType()) || - ParamQuals.isStrictSupersetOf(ArgQuals) || - (ParamQuals.hasNonTrivialObjCLifetime() && - ArgQuals.getObjCLifetime() == Qualifiers::OCL_ExplicitNone && - ParamQuals.withoutObjCLifetime() == - ArgQuals.withoutObjCLifetime())) { - Info.FirstArg = TemplateArgument(ParamIn); - Info.SecondArg = TemplateArgument(ArgIn); + Qualifiers PQuals = P.getQualifiers(), AQuals = A.getQualifiers(); + if ((PRef->isLValueReferenceType() && !ARef->isLValueReferenceType()) || + PQuals.isStrictSupersetOf(AQuals) || + (PQuals.hasNonTrivialObjCLifetime() && + AQuals.getObjCLifetime() == Qualifiers::OCL_ExplicitNone && + PQuals.withoutObjCLifetime() == AQuals.withoutObjCLifetime())) { + Info.FirstArg = TemplateArgument(P); + Info.SecondArg = TemplateArgument(A); return Sema::TDK_NonDeducedMismatch; } } - + Qualifiers DiscardedQuals; // C++11 [temp.deduct.partial]p7: // Remove any top-level cv-qualifiers: // - If P is a cv-qualified type, P is replaced by the cv-unqualified // version of P. - Param = Param.getUnqualifiedType(); + P = S.Context.getUnqualifiedArrayType(P, DiscardedQuals); // - If A is a cv-qualified type, A is replaced by the cv-unqualified // version of A. - Arg = Arg.getUnqualifiedType(); + A = S.Context.getUnqualifiedArrayType(A, DiscardedQuals); } else { // C++0x [temp.deduct.call]p4 bullet 1: // - If the original P is a reference type, the deduced A (i.e., the type @@ -1425,13 +1405,12 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, // transformed A. if (TDF & TDF_ParamWithReferenceType) { Qualifiers Quals; - QualType UnqualParam = S.Context.getUnqualifiedArrayType(Param, Quals); - Quals.setCVRQualifiers(Quals.getCVRQualifiers() & - Arg.getCVRQualifiers()); - Param = S.Context.getQualifiedType(UnqualParam, Quals); + QualType UnqualP = S.Context.getUnqualifiedArrayType(P, Quals); + Quals.setCVRQualifiers(Quals.getCVRQualifiers() & A.getCVRQualifiers()); + P = S.Context.getQualifiedType(UnqualP, Quals); } - if ((TDF & TDF_TopLevelParameterTypeList) && !Param->isFunctionType()) { + if ((TDF & TDF_TopLevelParameterTypeList) && !P->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 @@ -1444,8 +1423,9 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, // 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 (isForwardingReference(Param, 0) && Arg->isLValueReferenceType()) - Param = Param->getPointeeType(); + if (isForwardingReference(P, /*FirstInnerIndex=*/0) && + A->isLValueReferenceType()) + P = P->getPointeeType(); } } @@ -1456,53 +1436,48 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, // // T // cv-list T - if (const TemplateTypeParmType *TemplateTypeParm - = Param->getAs<TemplateTypeParmType>()) { + if (const auto *TTP = P->getAs<TemplateTypeParmType>()) { // Just skip any attempts to deduce from a placeholder type or a parameter // at a different depth. - if (Arg->isPlaceholderType() || - Info.getDeducedDepth() != TemplateTypeParm->getDepth()) + if (A->isPlaceholderType() || Info.getDeducedDepth() != TTP->getDepth()) return Sema::TDK_Success; - unsigned Index = TemplateTypeParm->getIndex(); - bool RecanonicalizeArg = false; + unsigned Index = TTP->getIndex(); // If the argument type is an array type, move the qualifiers up to the // top level, so they can be matched with the qualifiers on the parameter. - if (isa<ArrayType>(Arg)) { + if (A->isArrayType()) { Qualifiers Quals; - Arg = S.Context.getUnqualifiedArrayType(Arg, Quals); - if (Quals) { - Arg = S.Context.getQualifiedType(Arg, Quals); - RecanonicalizeArg = true; - } + A = S.Context.getUnqualifiedArrayType(A, Quals); + if (Quals) + A = S.Context.getQualifiedType(A, Quals); } // The argument type can not be less qualified than the parameter // type. if (!(TDF & TDF_IgnoreQualifiers) && - hasInconsistentOrSupersetQualifiersOf(Param, Arg)) { + hasInconsistentOrSupersetQualifiersOf(P, A)) { Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index)); - Info.FirstArg = TemplateArgument(Param); - Info.SecondArg = TemplateArgument(Arg); + Info.FirstArg = TemplateArgument(P); + Info.SecondArg = TemplateArgument(A); return Sema::TDK_Underqualified; } // Do not match a function type with a cv-qualified type. // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1584 - if (Arg->isFunctionType() && Param.hasQualifiers()) { + if (A->isFunctionType() && P.hasQualifiers()) return Sema::TDK_NonDeducedMismatch; - } - assert(TemplateTypeParm->getDepth() == Info.getDeducedDepth() && + assert(TTP->getDepth() == Info.getDeducedDepth() && "saw template type parameter with wrong depth"); - assert(Arg != S.Context.OverloadTy && "Unresolved overloaded function"); - QualType DeducedType = Arg; + assert(A->getCanonicalTypeInternal() != S.Context.OverloadTy && + "Unresolved overloaded function"); + QualType DeducedType = A; // Remove any qualifiers on the parameter from the deduced type. // We checked the qualifiers for consistency above. Qualifiers DeducedQs = DeducedType.getQualifiers(); - Qualifiers ParamQs = Param.getQualifiers(); + Qualifiers ParamQs = P.getQualifiers(); DeducedQs.removeCVRQualifiers(ParamQs.getCVRQualifiers()); if (ParamQs.hasObjCGCAttr()) DeducedQs.removeObjCGCAttr(); @@ -1517,29 +1492,24 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, if (ParamQs.hasObjCLifetime() && !DeducedType->isObjCLifetimeType() && !DeducedType->isDependentType()) { Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index)); - Info.FirstArg = TemplateArgument(Param); - Info.SecondArg = TemplateArgument(Arg); + Info.FirstArg = TemplateArgument(P); + Info.SecondArg = TemplateArgument(A); return Sema::TDK_Underqualified; } // Objective-C ARC: // If template deduction would produce an argument type with lifetime type // but no lifetime qualifier, the __strong lifetime qualifier is inferred. - if (S.getLangOpts().ObjCAutoRefCount && - DeducedType->isObjCLifetimeType() && + if (S.getLangOpts().ObjCAutoRefCount && DeducedType->isObjCLifetimeType() && !DeducedQs.hasObjCLifetime()) DeducedQs.setObjCLifetime(Qualifiers::OCL_Strong); - DeducedType = S.Context.getQualifiedType(DeducedType.getUnqualifiedType(), - DeducedQs); - - if (RecanonicalizeArg) - DeducedType = S.Context.getCanonicalType(DeducedType); + DeducedType = + S.Context.getQualifiedType(DeducedType.getUnqualifiedType(), DeducedQs); DeducedTemplateArgument NewDeduced(DeducedType, DeducedFromArrayBound); - DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context, - Deduced[Index], - NewDeduced); + DeducedTemplateArgument Result = + checkDeducedTemplateArguments(S.Context, Deduced[Index], NewDeduced); if (Result.isNull()) { Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index)); Info.FirstArg = Deduced[Index]; @@ -1552,69 +1522,57 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, } // Set up the template argument deduction information for a failure. - Info.FirstArg = TemplateArgument(ParamIn); - Info.SecondArg = TemplateArgument(ArgIn); + Info.FirstArg = TemplateArgument(P); + Info.SecondArg = TemplateArgument(A); // If the parameter is an already-substituted template parameter // pack, do nothing: we don't know which of its arguments to look // at, so we have to wait until all of the parameter packs in this // expansion have arguments. - if (isa<SubstTemplateTypeParmPackType>(Param)) + if (P->getAs<SubstTemplateTypeParmPackType>()) return Sema::TDK_Success; // Check the cv-qualifiers on the parameter and argument types. - CanQualType CanParam = S.Context.getCanonicalType(Param); - CanQualType CanArg = S.Context.getCanonicalType(Arg); if (!(TDF & TDF_IgnoreQualifiers)) { if (TDF & TDF_ParamWithReferenceType) { - if (hasInconsistentOrSupersetQualifiersOf(Param, Arg)) + if (hasInconsistentOrSupersetQualifiersOf(P, A)) return Sema::TDK_NonDeducedMismatch; } else if (TDF & TDF_ArgWithReferenceType) { // C++ [temp.deduct.conv]p4: // If the original A is a reference type, A can be more cv-qualified // than the deduced A - if (!Arg.getQualifiers().compatiblyIncludes(Param.getQualifiers())) + if (!A.getQualifiers().compatiblyIncludes(P.getQualifiers())) return Sema::TDK_NonDeducedMismatch; // Strip out all extra qualifiers from the argument to figure out the // type we're converting to, prior to the qualification conversion. Qualifiers Quals; - Arg = S.Context.getUnqualifiedArrayType(Arg, Quals); - Arg = S.Context.getQualifiedType(Arg, Param.getQualifiers()); - } else if (!IsPossiblyOpaquelyQualifiedType(Param)) { - if (Param.getCVRQualifiers() != Arg.getCVRQualifiers()) + A = S.Context.getUnqualifiedArrayType(A, Quals); + A = S.Context.getQualifiedType(A, P.getQualifiers()); + } else if (!IsPossiblyOpaquelyQualifiedType(P)) { + if (P.getCVRQualifiers() != A.getCVRQualifiers()) return Sema::TDK_NonDeducedMismatch; } + } - // If the parameter type is not dependent, there is nothing to deduce. - if (!Param->isDependentType()) { - if (!(TDF & TDF_SkipNonDependent)) { - bool NonDeduced = - (TDF & TDF_AllowCompatibleFunctionType) - ? !S.isSameOrCompatibleFunctionType(CanParam, CanArg) - : Param != Arg; - if (NonDeduced) { - return Sema::TDK_NonDeducedMismatch; - } - } + // If the parameter type is not dependent, there is nothing to deduce. + if (!P->isDependentType()) { + if (TDF & TDF_SkipNonDependent) return Sema::TDK_Success; - } - } else if (!Param->isDependentType()) { - if (!(TDF & TDF_SkipNonDependent)) { - CanQualType ParamUnqualType = CanParam.getUnqualifiedType(), - ArgUnqualType = CanArg.getUnqualifiedType(); - bool Success = - (TDF & TDF_AllowCompatibleFunctionType) - ? S.isSameOrCompatibleFunctionType(ParamUnqualType, ArgUnqualType) - : ParamUnqualType == ArgUnqualType; - if (Success) - return Sema::TDK_Success; - } else { + if ((TDF & TDF_IgnoreQualifiers) ? S.Context.hasSameUnqualifiedType(P, A) + : S.Context.hasSameType(P, A)) return Sema::TDK_Success; - } + if (TDF & TDF_AllowCompatibleFunctionType && + S.isSameOrCompatibleFunctionType(P, A)) + return Sema::TDK_Success; + if (!(TDF & TDF_IgnoreQualifiers)) + return Sema::TDK_NonDeducedMismatch; + // Otherwise, when ignoring qualifiers, the types not having the same + // unqualified type does not mean they do not match, so in this case we + // must keep going and analyze with a non-dependent parameter type. } - switch (Param->getTypeClass()) { + switch (P.getCanonicalType()->getTypeClass()) { // Non-canonical types cannot appear here. #define NON_CANONICAL_TYPE(Class, Base) \ case Type::Class: llvm_unreachable("deducing non-canonical type: " #Class); @@ -1625,8 +1583,11 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, case Type::SubstTemplateTypeParmPack: llvm_unreachable("Type nodes handled above"); - // These types cannot be dependent, so simply check whether the types are - // the same. + case Type::Auto: + // FIXME: Implement deduction in dependent case. + if (P->isDependentType()) + return Sema::TDK_Success; + LLVM_FALLTHROUGH; case Type::Builtin: case Type::VariableArray: case Type::Vector: @@ -1637,134 +1598,115 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, case Type::ObjCInterface: case Type::ObjCObjectPointer: case Type::ExtInt: - if (TDF & TDF_SkipNonDependent) - return Sema::TDK_Success; - - if (TDF & TDF_IgnoreQualifiers) { - Param = Param.getUnqualifiedType(); - Arg = Arg.getUnqualifiedType(); - } - - return Param == Arg? Sema::TDK_Success : Sema::TDK_NonDeducedMismatch; + return (TDF & TDF_SkipNonDependent) || + ((TDF & TDF_IgnoreQualifiers) + ? S.Context.hasSameUnqualifiedType(P, A) + : S.Context.hasSameType(P, A)) + ? Sema::TDK_Success + : Sema::TDK_NonDeducedMismatch; // _Complex T [placeholder extension] - case Type::Complex: - if (const ComplexType *ComplexArg = Arg->getAs<ComplexType>()) - return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, - cast<ComplexType>(Param)->getElementType(), - ComplexArg->getElementType(), - Info, Deduced, TDF); - - return Sema::TDK_NonDeducedMismatch; + case Type::Complex: { + const auto *CP = P->castAs<ComplexType>(), *CA = A->getAs<ComplexType>(); + if (!CA) + return Sema::TDK_NonDeducedMismatch; + return DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, CP->getElementType(), CA->getElementType(), Info, + Deduced, TDF); + } // _Atomic T [extension] - case Type::Atomic: - if (const AtomicType *AtomicArg = Arg->getAs<AtomicType>()) - return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, - cast<AtomicType>(Param)->getValueType(), - AtomicArg->getValueType(), - Info, Deduced, TDF); - - return Sema::TDK_NonDeducedMismatch; + case Type::Atomic: { + const auto *PA = P->castAs<AtomicType>(), *AA = A->getAs<AtomicType>(); + if (!AA) + return Sema::TDK_NonDeducedMismatch; + return DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, PA->getValueType(), AA->getValueType(), Info, + Deduced, TDF); + } // T * case Type::Pointer: { QualType PointeeType; - if (const PointerType *PointerArg = Arg->getAs<PointerType>()) { - PointeeType = PointerArg->getPointeeType(); - } else if (const ObjCObjectPointerType *PointerArg - = Arg->getAs<ObjCObjectPointerType>()) { - PointeeType = PointerArg->getPointeeType(); + if (const auto *PA = A->getAs<PointerType>()) { + PointeeType = PA->getPointeeType(); + } else if (const auto *PA = A->getAs<ObjCObjectPointerType>()) { + PointeeType = PA->getPointeeType(); } else { return Sema::TDK_NonDeducedMismatch; } - - unsigned SubTDF = TDF & (TDF_IgnoreQualifiers | TDF_DerivedClass); - return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, - cast<PointerType>(Param)->getPointeeType(), - PointeeType, - Info, Deduced, SubTDF); + return DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, P->castAs<PointerType>()->getPointeeType(), + PointeeType, Info, Deduced, + TDF & (TDF_IgnoreQualifiers | TDF_DerivedClass)); } // T & case Type::LValueReference: { - const LValueReferenceType *ReferenceArg = - Arg->getAs<LValueReferenceType>(); - if (!ReferenceArg) + const auto *RP = P->castAs<LValueReferenceType>(), + *RA = A->getAs<LValueReferenceType>(); + if (!RA) return Sema::TDK_NonDeducedMismatch; - return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, - cast<LValueReferenceType>(Param)->getPointeeType(), - ReferenceArg->getPointeeType(), Info, Deduced, 0); + return DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info, + Deduced, 0); } // T && [C++0x] case Type::RValueReference: { - const RValueReferenceType *ReferenceArg = - Arg->getAs<RValueReferenceType>(); - if (!ReferenceArg) + const auto *RP = P->castAs<RValueReferenceType>(), + *RA = A->getAs<RValueReferenceType>(); + if (!RA) return Sema::TDK_NonDeducedMismatch; - return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, - cast<RValueReferenceType>(Param)->getPointeeType(), - ReferenceArg->getPointeeType(), - Info, Deduced, 0); + return DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, RP->getPointeeType(), RA->getPointeeType(), Info, + Deduced, 0); } // T [] (implied, but not stated explicitly) case Type::IncompleteArray: { - const IncompleteArrayType *IncompleteArrayArg = - S.Context.getAsIncompleteArrayType(Arg); - if (!IncompleteArrayArg) + const auto *IAA = S.Context.getAsIncompleteArrayType(A); + if (!IAA) return Sema::TDK_NonDeducedMismatch; - unsigned SubTDF = TDF & TDF_IgnoreQualifiers; - return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, - S.Context.getAsIncompleteArrayType(Param)->getElementType(), - IncompleteArrayArg->getElementType(), - Info, Deduced, SubTDF); + return DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, + S.Context.getAsIncompleteArrayType(P)->getElementType(), + IAA->getElementType(), Info, Deduced, TDF & TDF_IgnoreQualifiers); } // T [integer-constant] case Type::ConstantArray: { - const ConstantArrayType *ConstantArrayArg = - S.Context.getAsConstantArrayType(Arg); - if (!ConstantArrayArg) + const auto *CAA = S.Context.getAsConstantArrayType(A), + *CAP = S.Context.getAsConstantArrayType(P); + assert(CAP); + if (!CAA || CAA->getSize() != CAP->getSize()) return Sema::TDK_NonDeducedMismatch; - const ConstantArrayType *ConstantArrayParm = - S.Context.getAsConstantArrayType(Param); - if (ConstantArrayArg->getSize() != ConstantArrayParm->getSize()) - return Sema::TDK_NonDeducedMismatch; - - unsigned SubTDF = TDF & TDF_IgnoreQualifiers; - return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, - ConstantArrayParm->getElementType(), - ConstantArrayArg->getElementType(), - Info, Deduced, SubTDF); + return DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, CAP->getElementType(), CAA->getElementType(), Info, + Deduced, TDF & TDF_IgnoreQualifiers); } // type [i] case Type::DependentSizedArray: { - const ArrayType *ArrayArg = S.Context.getAsArrayType(Arg); - if (!ArrayArg) + const auto *AA = S.Context.getAsArrayType(A); + if (!AA) return Sema::TDK_NonDeducedMismatch; - unsigned SubTDF = TDF & TDF_IgnoreQualifiers; - // Check the element type of the arrays - const DependentSizedArrayType *DependentArrayParm - = S.Context.getAsDependentSizedArrayType(Param); - if (Sema::TemplateDeductionResult Result - = DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, - DependentArrayParm->getElementType(), - ArrayArg->getElementType(), - Info, Deduced, SubTDF)) + const auto *DAP = S.Context.getAsDependentSizedArrayType(P); + assert(DAP); + if (auto Result = DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, DAP->getElementType(), AA->getElementType(), + Info, Deduced, TDF & TDF_IgnoreQualifiers)) return Result; // Determine the array bound is something we can deduce. - const NonTypeTemplateParmDecl *NTTP - = getDeducedParameterFromExpr(Info, DependentArrayParm->getSizeExpr()); + const NonTypeTemplateParmDecl *NTTP = + getDeducedParameterFromExpr(Info, DAP->getSizeExpr()); if (!NTTP) return Sema::TDK_Success; @@ -1772,20 +1714,16 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, // template parameter. assert(NTTP->getDepth() == Info.getDeducedDepth() && "saw non-type template parameter with wrong depth"); - if (const ConstantArrayType *ConstantArrayArg - = dyn_cast<ConstantArrayType>(ArrayArg)) { - llvm::APSInt Size(ConstantArrayArg->getSize()); - return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, Size, - S.Context.getSizeType(), - /*ArrayBound=*/true, - Info, Deduced); + if (const auto *CAA = dyn_cast<ConstantArrayType>(AA)) { + llvm::APSInt Size(CAA->getSize()); + return DeduceNonTypeTemplateArgument( + S, TemplateParams, NTTP, Size, S.Context.getSizeType(), + /*ArrayBound=*/true, Info, Deduced); } - if (const DependentSizedArrayType *DependentArrayArg - = dyn_cast<DependentSizedArrayType>(ArrayArg)) - if (DependentArrayArg->getSizeExpr()) - return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, - DependentArrayArg->getSizeExpr(), - Info, Deduced); + if (const auto *DAA = dyn_cast<DependentSizedArrayType>(AA)) + if (DAA->getSizeExpr()) + return DeduceNonTypeTemplateArgument( + S, TemplateParams, NTTP, DAA->getSizeExpr(), Info, Deduced); // Incomplete type does not match a dependently-sized array type return Sema::TDK_NonDeducedMismatch; @@ -1795,34 +1733,29 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, // T(*)() // T(*)(T) case Type::FunctionProto: { - unsigned SubTDF = TDF & TDF_TopLevelParameterTypeList; - const FunctionProtoType *FunctionProtoArg = - dyn_cast<FunctionProtoType>(Arg); - if (!FunctionProtoArg) + const auto *FPP = P->castAs<FunctionProtoType>(), + *FPA = A->getAs<FunctionProtoType>(); + if (!FPA) return Sema::TDK_NonDeducedMismatch; - const FunctionProtoType *FunctionProtoParam = - cast<FunctionProtoType>(Param); - - if (FunctionProtoParam->getMethodQuals() - != FunctionProtoArg->getMethodQuals() || - FunctionProtoParam->getRefQualifier() - != FunctionProtoArg->getRefQualifier() || - FunctionProtoParam->isVariadic() != FunctionProtoArg->isVariadic()) + if (FPP->getMethodQuals() != FPA->getMethodQuals() || + FPP->getRefQualifier() != FPA->getRefQualifier() || + FPP->isVariadic() != FPA->isVariadic()) return Sema::TDK_NonDeducedMismatch; // Check return types. if (auto Result = DeduceTemplateArgumentsByTypeMatch( - S, TemplateParams, FunctionProtoParam->getReturnType(), - FunctionProtoArg->getReturnType(), Info, Deduced, 0)) + S, TemplateParams, FPP->getReturnType(), FPA->getReturnType(), + Info, Deduced, 0, + /*PartialOrdering=*/false, + /*DeducedFromArrayBound=*/false)) return Result; // Check parameter types. if (auto Result = DeduceTemplateArguments( - S, TemplateParams, FunctionProtoParam->param_type_begin(), - FunctionProtoParam->getNumParams(), - FunctionProtoArg->param_type_begin(), - FunctionProtoArg->getNumParams(), Info, Deduced, SubTDF)) + S, TemplateParams, FPP->param_type_begin(), FPP->getNumParams(), + FPA->param_type_begin(), FPA->getNumParams(), Info, Deduced, + TDF & TDF_TopLevelParameterTypeList)) return Result; if (TDF & TDF_AllowCompatibleFunctionType) @@ -1831,15 +1764,15 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, // FIXME: Per core-2016/10/1019 (no corresponding core issue yet), permit // deducing through the noexcept-specifier if it's part of the canonical // type. libstdc++ relies on this. - Expr *NoexceptExpr = FunctionProtoParam->getNoexceptExpr(); + Expr *NoexceptExpr = FPP->getNoexceptExpr(); if (const NonTypeTemplateParmDecl *NTTP = - NoexceptExpr ? getDeducedParameterFromExpr(Info, NoexceptExpr) - : nullptr) { + NoexceptExpr ? getDeducedParameterFromExpr(Info, NoexceptExpr) + : nullptr) { assert(NTTP->getDepth() == Info.getDeducedDepth() && "saw non-type template parameter with wrong depth"); llvm::APSInt Noexcept(1); - switch (FunctionProtoArg->canThrow()) { + switch (FPA->canThrow()) { case CT_Cannot: Noexcept = 1; LLVM_FALLTHROUGH; @@ -1849,10 +1782,10 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, // FIXME: Should we? return DeduceNonTypeTemplateArgument( S, TemplateParams, NTTP, Noexcept, S.Context.BoolTy, - /*ArrayBound*/true, Info, Deduced); + /*DeducedFromArrayBound=*/true, Info, Deduced); case CT_Dependent: - if (Expr *ArgNoexceptExpr = FunctionProtoArg->getNoexceptExpr()) + if (Expr *ArgNoexceptExpr = FPA->getNoexceptExpr()) return DeduceNonTypeTemplateArgument( S, TemplateParams, NTTP, ArgNoexceptExpr, Info, Deduced); // Can't deduce anything from throw(T...). @@ -1870,11 +1803,6 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, case Type::InjectedClassName: // Treat a template's injected-class-name as if the template // specialization type had been used. - Param = cast<InjectedClassNameType>(Param) - ->getInjectedSpecializationType(); - assert(isa<TemplateSpecializationType>(Param) && - "injected class name is not a template specialization type"); - LLVM_FALLTHROUGH; // template-name<T> (where template-name refers to a class template) // template-name<i> @@ -1882,41 +1810,33 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, // TT<i> // TT<> case Type::TemplateSpecialization: { - const TemplateSpecializationType *SpecParam = - cast<TemplateSpecializationType>(Param); - // When Arg cannot be a derived class, we can just try to deduce template // arguments from the template-id. - const RecordType *RecordT = Arg->getAs<RecordType>(); - if (!(TDF & TDF_DerivedClass) || !RecordT) - return DeduceTemplateArguments(S, TemplateParams, SpecParam, Arg, Info, - Deduced); + if (!(TDF & TDF_DerivedClass) || !A->isRecordType()) + return DeduceTemplateSpecArguments(S, TemplateParams, P, A, Info, + Deduced); SmallVector<DeducedTemplateArgument, 8> DeducedOrig(Deduced.begin(), Deduced.end()); - Sema::TemplateDeductionResult Result = DeduceTemplateArguments( - S, TemplateParams, SpecParam, Arg, Info, Deduced); - + auto Result = + DeduceTemplateSpecArguments(S, TemplateParams, P, A, Info, Deduced); if (Result == Sema::TDK_Success) return Result; // We cannot inspect base classes as part of deduction when the type // is incomplete, so either instantiate any templates necessary to // complete the type, or skip over it if it cannot be completed. - if (!S.isCompleteType(Info.getLocation(), Arg)) + if (!S.isCompleteType(Info.getLocation(), A)) return Result; // Reset the incorrectly deduced argument from above. Deduced = DeducedOrig; // Check bases according to C++14 [temp.deduct.call] p4b3: - Sema::TemplateDeductionResult BaseResult = DeduceTemplateBases( - S, RecordT, TemplateParams, SpecParam, Info, Deduced); - - if (BaseResult != Sema::TDK_Invalid) - return BaseResult; - return Result; + auto BaseResult = DeduceTemplateBases(S, getCanonicalRD(A), + TemplateParams, P, Info, Deduced); + return BaseResult != Sema::TDK_Invalid ? BaseResult : Result; } // T type::* @@ -1929,33 +1849,27 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, // T (T::*)() // T (T::*)(T) case Type::MemberPointer: { - const MemberPointerType *MemPtrParam = cast<MemberPointerType>(Param); - const MemberPointerType *MemPtrArg = dyn_cast<MemberPointerType>(Arg); - if (!MemPtrArg) + const auto *MPP = P->castAs<MemberPointerType>(), + *MPA = A->getAs<MemberPointerType>(); + if (!MPA) return Sema::TDK_NonDeducedMismatch; - QualType ParamPointeeType = MemPtrParam->getPointeeType(); - if (ParamPointeeType->isFunctionType()) - S.adjustMemberFunctionCC(ParamPointeeType, /*IsStatic=*/true, + QualType PPT = MPP->getPointeeType(); + if (PPT->isFunctionType()) + S.adjustMemberFunctionCC(PPT, /*IsStatic=*/true, /*IsCtorOrDtor=*/false, Info.getLocation()); - QualType ArgPointeeType = MemPtrArg->getPointeeType(); - if (ArgPointeeType->isFunctionType()) - S.adjustMemberFunctionCC(ArgPointeeType, /*IsStatic=*/true, + QualType APT = MPA->getPointeeType(); + if (APT->isFunctionType()) + S.adjustMemberFunctionCC(APT, /*IsStatic=*/true, /*IsCtorOrDtor=*/false, Info.getLocation()); - if (Sema::TemplateDeductionResult Result - = DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, - ParamPointeeType, - ArgPointeeType, - Info, Deduced, - TDF & TDF_IgnoreQualifiers)) + unsigned SubTDF = TDF & TDF_IgnoreQualifiers; + if (auto Result = DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, PPT, APT, Info, Deduced, SubTDF)) return Result; - - return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, - QualType(MemPtrParam->getClass(), 0), - QualType(MemPtrArg->getClass(), 0), - Info, Deduced, - TDF & TDF_IgnoreQualifiers); + return DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, QualType(MPP->getClass(), 0), + QualType(MPA->getClass(), 0), Info, Deduced, SubTDF); } // (clang extension) @@ -1964,70 +1878,58 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, // T(^)() // T(^)(T) case Type::BlockPointer: { - const BlockPointerType *BlockPtrParam = cast<BlockPointerType>(Param); - const BlockPointerType *BlockPtrArg = dyn_cast<BlockPointerType>(Arg); - - if (!BlockPtrArg) + const auto *BPP = P->castAs<BlockPointerType>(), + *BPA = A->getAs<BlockPointerType>(); + if (!BPA) return Sema::TDK_NonDeducedMismatch; - - return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, - BlockPtrParam->getPointeeType(), - BlockPtrArg->getPointeeType(), - Info, Deduced, 0); + return DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, BPP->getPointeeType(), BPA->getPointeeType(), Info, + Deduced, 0); } // (clang extension) // // T __attribute__(((ext_vector_type(<integral constant>)))) case Type::ExtVector: { - const ExtVectorType *VectorParam = cast<ExtVectorType>(Param); - if (const ExtVectorType *VectorArg = dyn_cast<ExtVectorType>(Arg)) { + const auto *VP = P->castAs<ExtVectorType>(); + QualType ElementType; + if (const auto *VA = A->getAs<ExtVectorType>()) { // Make sure that the vectors have the same number of elements. - if (VectorParam->getNumElements() != VectorArg->getNumElements()) + if (VP->getNumElements() != VA->getNumElements()) return Sema::TDK_NonDeducedMismatch; - - // Perform deduction on the element types. - return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, - VectorParam->getElementType(), - VectorArg->getElementType(), - Info, Deduced, TDF); - } - - if (const DependentSizedExtVectorType *VectorArg - = dyn_cast<DependentSizedExtVectorType>(Arg)) { + ElementType = VA->getElementType(); + } else if (const auto *VA = A->getAs<DependentSizedExtVectorType>()) { // We can't check the number of elements, since the argument has a // dependent number of elements. This can only occur during partial // ordering. - - // Perform deduction on the element types. - return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, - VectorParam->getElementType(), - VectorArg->getElementType(), - Info, Deduced, TDF); + ElementType = VA->getElementType(); + } else { + return Sema::TDK_NonDeducedMismatch; } - - return Sema::TDK_NonDeducedMismatch; + // Perform deduction on the element types. + return DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, VP->getElementType(), ElementType, Info, Deduced, + TDF); } case Type::DependentVector: { - const auto *VectorParam = cast<DependentVectorType>(Param); + const auto *VP = P->castAs<DependentVectorType>(); - if (const auto *VectorArg = dyn_cast<VectorType>(Arg)) { + if (const auto *VA = A->getAs<VectorType>()) { // Perform deduction on the element types. - if (Sema::TemplateDeductionResult Result = - DeduceTemplateArgumentsByTypeMatch( - S, TemplateParams, VectorParam->getElementType(), - VectorArg->getElementType(), Info, Deduced, TDF)) + if (auto Result = DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, VP->getElementType(), VA->getElementType(), + Info, Deduced, TDF)) return Result; // Perform deduction on the vector size, if we can. const NonTypeTemplateParmDecl *NTTP = - getDeducedParameterFromExpr(Info, VectorParam->getSizeExpr()); + getDeducedParameterFromExpr(Info, VP->getSizeExpr()); if (!NTTP) return Sema::TDK_Success; llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false); - ArgSize = VectorArg->getNumElements(); + ArgSize = VA->getNumElements(); // Note that we use the "array bound" rules here; just like in that // case, we don't have any particular type for the vector size, but // we can provide one if necessary. @@ -2036,22 +1938,21 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, Info, Deduced); } - if (const auto *VectorArg = dyn_cast<DependentVectorType>(Arg)) { + if (const auto *VA = A->getAs<DependentVectorType>()) { // Perform deduction on the element types. - if (Sema::TemplateDeductionResult Result = - DeduceTemplateArgumentsByTypeMatch( - S, TemplateParams, VectorParam->getElementType(), - VectorArg->getElementType(), Info, Deduced, TDF)) + if (auto Result = DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, VP->getElementType(), VA->getElementType(), + Info, Deduced, TDF)) return Result; // Perform deduction on the vector size, if we can. - const NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr( - Info, VectorParam->getSizeExpr()); + const NonTypeTemplateParmDecl *NTTP = + getDeducedParameterFromExpr(Info, VP->getSizeExpr()); if (!NTTP) return Sema::TDK_Success; - return DeduceNonTypeTemplateArgument( - S, TemplateParams, NTTP, VectorArg->getSizeExpr(), Info, Deduced); + return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, + VA->getSizeExpr(), Info, Deduced); } return Sema::TDK_NonDeducedMismatch; @@ -2061,26 +1962,23 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, // // T __attribute__(((ext_vector_type(N)))) case Type::DependentSizedExtVector: { - const DependentSizedExtVectorType *VectorParam - = cast<DependentSizedExtVectorType>(Param); + const auto *VP = P->castAs<DependentSizedExtVectorType>(); - if (const ExtVectorType *VectorArg = dyn_cast<ExtVectorType>(Arg)) { + if (const auto *VA = A->getAs<ExtVectorType>()) { // Perform deduction on the element types. - if (Sema::TemplateDeductionResult Result - = DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, - VectorParam->getElementType(), - VectorArg->getElementType(), - Info, Deduced, TDF)) + if (auto Result = DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, VP->getElementType(), VA->getElementType(), + Info, Deduced, TDF)) return Result; // Perform deduction on the vector size, if we can. const NonTypeTemplateParmDecl *NTTP = - getDeducedParameterFromExpr(Info, VectorParam->getSizeExpr()); + getDeducedParameterFromExpr(Info, VP->getSizeExpr()); if (!NTTP) return Sema::TDK_Success; llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false); - ArgSize = VectorArg->getNumElements(); + ArgSize = VA->getNumElements(); // Note that we use the "array bound" rules here; just like in that // case, we don't have any particular type for the vector size, but // we can provide one if necessary. @@ -2089,25 +1987,21 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, Deduced); } - if (const DependentSizedExtVectorType *VectorArg - = dyn_cast<DependentSizedExtVectorType>(Arg)) { + if (const auto *VA = A->getAs<DependentSizedExtVectorType>()) { // Perform deduction on the element types. - if (Sema::TemplateDeductionResult Result - = DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, - VectorParam->getElementType(), - VectorArg->getElementType(), - Info, Deduced, TDF)) + if (auto Result = DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, VP->getElementType(), VA->getElementType(), + Info, Deduced, TDF)) return Result; // Perform deduction on the vector size, if we can. const NonTypeTemplateParmDecl *NTTP = - getDeducedParameterFromExpr(Info, VectorParam->getSizeExpr()); + getDeducedParameterFromExpr(Info, VP->getSizeExpr()); if (!NTTP) return Sema::TDK_Success; return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, - VectorArg->getSizeExpr(), - Info, Deduced); + VA->getSizeExpr(), Info, Deduced); } return Sema::TDK_NonDeducedMismatch; @@ -2118,62 +2012,59 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, // T __attribute__((matrix_type(<integral constant>, // <integral constant>))) case Type::ConstantMatrix: { - const ConstantMatrixType *MatrixArg = dyn_cast<ConstantMatrixType>(Arg); - if (!MatrixArg) + const auto *MP = P->castAs<ConstantMatrixType>(), + *MA = A->getAs<ConstantMatrixType>(); + if (!MA) return Sema::TDK_NonDeducedMismatch; - const ConstantMatrixType *MatrixParam = cast<ConstantMatrixType>(Param); // Check that the dimensions are the same - if (MatrixParam->getNumRows() != MatrixArg->getNumRows() || - MatrixParam->getNumColumns() != MatrixArg->getNumColumns()) { + if (MP->getNumRows() != MA->getNumRows() || + MP->getNumColumns() != MA->getNumColumns()) { return Sema::TDK_NonDeducedMismatch; } // Perform deduction on element types. return DeduceTemplateArgumentsByTypeMatch( - S, TemplateParams, MatrixParam->getElementType(), - MatrixArg->getElementType(), Info, Deduced, TDF); + S, TemplateParams, MP->getElementType(), MA->getElementType(), Info, + Deduced, TDF); } case Type::DependentSizedMatrix: { - const MatrixType *MatrixArg = dyn_cast<MatrixType>(Arg); - if (!MatrixArg) + const auto *MP = P->castAs<DependentSizedMatrixType>(); + const auto *MA = A->getAs<MatrixType>(); + if (!MA) return Sema::TDK_NonDeducedMismatch; // Check the element type of the matrixes. - const DependentSizedMatrixType *MatrixParam = - cast<DependentSizedMatrixType>(Param); - if (Sema::TemplateDeductionResult Result = - DeduceTemplateArgumentsByTypeMatch( - S, TemplateParams, MatrixParam->getElementType(), - MatrixArg->getElementType(), Info, Deduced, TDF)) + if (auto Result = DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, MP->getElementType(), MA->getElementType(), + Info, Deduced, TDF)) return Result; // Try to deduce a matrix dimension. auto DeduceMatrixArg = [&S, &Info, &Deduced, &TemplateParams]( - Expr *ParamExpr, const MatrixType *Arg, + Expr *ParamExpr, const MatrixType *A, unsigned (ConstantMatrixType::*GetArgDimension)() const, Expr *(DependentSizedMatrixType::*GetArgDimensionExpr)() const) { - const auto *ArgConstMatrix = dyn_cast<ConstantMatrixType>(Arg); - const auto *ArgDepMatrix = dyn_cast<DependentSizedMatrixType>(Arg); + const auto *ACM = dyn_cast<ConstantMatrixType>(A); + const auto *ADM = dyn_cast<DependentSizedMatrixType>(A); if (!ParamExpr->isValueDependent()) { Optional<llvm::APSInt> ParamConst = ParamExpr->getIntegerConstantExpr(S.Context); if (!ParamConst) return Sema::TDK_NonDeducedMismatch; - if (ArgConstMatrix) { - if ((ArgConstMatrix->*GetArgDimension)() == *ParamConst) + if (ACM) { + if ((ACM->*GetArgDimension)() == *ParamConst) return Sema::TDK_Success; return Sema::TDK_NonDeducedMismatch; } - Expr *ArgExpr = (ArgDepMatrix->*GetArgDimensionExpr)(); - if (!ArgExpr->isValueDependent()) - if (Optional<llvm::APSInt> ArgConst = - ArgExpr->getIntegerConstantExpr(S.Context)) - if (*ArgConst == *ParamConst) - return Sema::TDK_Success; + Expr *ArgExpr = (ADM->*GetArgDimensionExpr)(); + if (Optional<llvm::APSInt> ArgConst = + ArgExpr->getIntegerConstantExpr(S.Context)) + if (*ArgConst == *ParamConst) + return Sema::TDK_Success; return Sema::TDK_NonDeducedMismatch; } @@ -2182,27 +2073,26 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, if (!NTTP) return Sema::TDK_Success; - if (ArgConstMatrix) { + if (ACM) { llvm::APSInt ArgConst( S.Context.getTypeSize(S.Context.getSizeType())); - ArgConst = (ArgConstMatrix->*GetArgDimension)(); + ArgConst = (ACM->*GetArgDimension)(); return DeduceNonTypeTemplateArgument( S, TemplateParams, NTTP, ArgConst, S.Context.getSizeType(), /*ArrayBound=*/true, Info, Deduced); } - return DeduceNonTypeTemplateArgument( - S, TemplateParams, NTTP, (ArgDepMatrix->*GetArgDimensionExpr)(), - Info, Deduced); + return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, + (ADM->*GetArgDimensionExpr)(), + Info, Deduced); }; - auto Result = DeduceMatrixArg(MatrixParam->getRowExpr(), MatrixArg, - &ConstantMatrixType::getNumRows, - &DependentSizedMatrixType::getRowExpr); - if (Result) + if (auto Result = DeduceMatrixArg(MP->getRowExpr(), MA, + &ConstantMatrixType::getNumRows, + &DependentSizedMatrixType::getRowExpr)) return Result; - return DeduceMatrixArg(MatrixParam->getColumnExpr(), MatrixArg, + return DeduceMatrixArg(MP->getColumnExpr(), MA, &ConstantMatrixType::getNumColumns, &DependentSizedMatrixType::getColumnExpr); } @@ -2211,44 +2101,39 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, // // T __attribute__(((address_space(N)))) case Type::DependentAddressSpace: { - const DependentAddressSpaceType *AddressSpaceParam = - cast<DependentAddressSpaceType>(Param); + const auto *ASP = P->castAs<DependentAddressSpaceType>(); - if (const DependentAddressSpaceType *AddressSpaceArg = - dyn_cast<DependentAddressSpaceType>(Arg)) { + if (const auto *ASA = A->getAs<DependentAddressSpaceType>()) { // Perform deduction on the pointer type. - if (Sema::TemplateDeductionResult Result = - DeduceTemplateArgumentsByTypeMatch( - S, TemplateParams, AddressSpaceParam->getPointeeType(), - AddressSpaceArg->getPointeeType(), Info, Deduced, TDF)) + if (auto Result = DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, ASP->getPointeeType(), ASA->getPointeeType(), + Info, Deduced, TDF)) return Result; // Perform deduction on the address space, if we can. - const NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr( - Info, AddressSpaceParam->getAddrSpaceExpr()); + const NonTypeTemplateParmDecl *NTTP = + getDeducedParameterFromExpr(Info, ASP->getAddrSpaceExpr()); if (!NTTP) return Sema::TDK_Success; return DeduceNonTypeTemplateArgument( - S, TemplateParams, NTTP, AddressSpaceArg->getAddrSpaceExpr(), Info, - Deduced); + S, TemplateParams, NTTP, ASA->getAddrSpaceExpr(), Info, Deduced); } - if (isTargetAddressSpace(Arg.getAddressSpace())) { + if (isTargetAddressSpace(A.getAddressSpace())) { llvm::APSInt ArgAddressSpace(S.Context.getTypeSize(S.Context.IntTy), false); - ArgAddressSpace = toTargetAddressSpace(Arg.getAddressSpace()); + ArgAddressSpace = toTargetAddressSpace(A.getAddressSpace()); // Perform deduction on the pointer types. - if (Sema::TemplateDeductionResult Result = - DeduceTemplateArgumentsByTypeMatch( - S, TemplateParams, AddressSpaceParam->getPointeeType(), - S.Context.removeAddrSpaceQualType(Arg), Info, Deduced, TDF)) + if (auto Result = DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, ASP->getPointeeType(), + S.Context.removeAddrSpaceQualType(A), Info, Deduced, TDF)) return Result; // Perform deduction on the address space, if we can. - const NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr( - Info, AddressSpaceParam->getAddrSpaceExpr()); + const NonTypeTemplateParmDecl *NTTP = + getDeducedParameterFromExpr(Info, ASP->getAddrSpaceExpr()); if (!NTTP) return Sema::TDK_Success; @@ -2260,30 +2145,31 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, return Sema::TDK_NonDeducedMismatch; } case Type::DependentExtInt: { - const auto *IntParam = cast<DependentExtIntType>(Param); + const auto *IP = P->castAs<DependentExtIntType>(); - if (const auto *IntArg = dyn_cast<ExtIntType>(Arg)){ - if (IntParam->isUnsigned() != IntArg->isUnsigned()) + if (const auto *IA = A->getAs<ExtIntType>()) { + if (IP->isUnsigned() != IA->isUnsigned()) return Sema::TDK_NonDeducedMismatch; const NonTypeTemplateParmDecl *NTTP = - getDeducedParameterFromExpr(Info, IntParam->getNumBitsExpr()); + getDeducedParameterFromExpr(Info, IP->getNumBitsExpr()); if (!NTTP) return Sema::TDK_Success; llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false); - ArgSize = IntArg->getNumBits(); + ArgSize = IA->getNumBits(); return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, ArgSize, S.Context.IntTy, true, Info, Deduced); } - if (const auto *IntArg = dyn_cast<DependentExtIntType>(Arg)) { - if (IntParam->isUnsigned() != IntArg->isUnsigned()) + if (const auto *IA = A->getAs<DependentExtIntType>()) { + if (IP->isUnsigned() != IA->isUnsigned()) return Sema::TDK_NonDeducedMismatch; return Sema::TDK_Success; } + return Sema::TDK_NonDeducedMismatch; } @@ -2293,125 +2179,103 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, case Type::UnresolvedUsing: case Type::Decltype: case Type::UnaryTransform: - case Type::Auto: case Type::DeducedTemplateSpecialization: case Type::DependentTemplateSpecialization: case Type::PackExpansion: case Type::Pipe: // No template argument deduction for these types return Sema::TDK_Success; - } + } llvm_unreachable("Invalid Type Class!"); } static Sema::TemplateDeductionResult -DeduceTemplateArguments(Sema &S, - TemplateParameterList *TemplateParams, - const TemplateArgument &Param, - TemplateArgument Arg, +DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, + const TemplateArgument &P, TemplateArgument A, TemplateDeductionInfo &Info, SmallVectorImpl<DeducedTemplateArgument> &Deduced) { // If the template argument is a pack expansion, perform template argument // deduction against the pattern of that expansion. This only occurs during // partial ordering. - if (Arg.isPackExpansion()) - Arg = Arg.getPackExpansionPattern(); + if (A.isPackExpansion()) + A = A.getPackExpansionPattern(); - switch (Param.getKind()) { + switch (P.getKind()) { case TemplateArgument::Null: llvm_unreachable("Null template argument in parameter list"); case TemplateArgument::Type: - if (Arg.getKind() == TemplateArgument::Type) - return DeduceTemplateArgumentsByTypeMatch(S, TemplateParams, - Param.getAsType(), - Arg.getAsType(), - Info, Deduced, 0); - Info.FirstArg = Param; - Info.SecondArg = Arg; + if (A.getKind() == TemplateArgument::Type) + return DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, P.getAsType(), A.getAsType(), Info, Deduced, 0); + Info.FirstArg = P; + Info.SecondArg = A; return Sema::TDK_NonDeducedMismatch; case TemplateArgument::Template: - if (Arg.getKind() == TemplateArgument::Template) - return DeduceTemplateArguments(S, TemplateParams, - Param.getAsTemplate(), - Arg.getAsTemplate(), Info, Deduced); - Info.FirstArg = Param; - Info.SecondArg = Arg; + if (A.getKind() == TemplateArgument::Template) + return DeduceTemplateArguments(S, TemplateParams, P.getAsTemplate(), + A.getAsTemplate(), Info, Deduced); + Info.FirstArg = P; + Info.SecondArg = A; return Sema::TDK_NonDeducedMismatch; case TemplateArgument::TemplateExpansion: llvm_unreachable("caller should handle pack expansions"); case TemplateArgument::Declaration: - if (Arg.getKind() == TemplateArgument::Declaration && - isSameDeclaration(Param.getAsDecl(), Arg.getAsDecl())) + if (A.getKind() == TemplateArgument::Declaration && + isSameDeclaration(P.getAsDecl(), A.getAsDecl())) return Sema::TDK_Success; - Info.FirstArg = Param; - Info.SecondArg = Arg; + Info.FirstArg = P; + Info.SecondArg = A; return Sema::TDK_NonDeducedMismatch; case TemplateArgument::NullPtr: - if (Arg.getKind() == TemplateArgument::NullPtr && - S.Context.hasSameType(Param.getNullPtrType(), Arg.getNullPtrType())) + if (A.getKind() == TemplateArgument::NullPtr && + S.Context.hasSameType(P.getNullPtrType(), A.getNullPtrType())) return Sema::TDK_Success; - Info.FirstArg = Param; - Info.SecondArg = Arg; + Info.FirstArg = P; + Info.SecondArg = A; return Sema::TDK_NonDeducedMismatch; case TemplateArgument::Integral: - if (Arg.getKind() == TemplateArgument::Integral) { - if (hasSameExtendedValue(Param.getAsIntegral(), Arg.getAsIntegral())) + if (A.getKind() == TemplateArgument::Integral) { + if (hasSameExtendedValue(P.getAsIntegral(), A.getAsIntegral())) return Sema::TDK_Success; - - Info.FirstArg = Param; - Info.SecondArg = Arg; - return Sema::TDK_NonDeducedMismatch; - } - - if (Arg.getKind() == TemplateArgument::Expression) { - Info.FirstArg = Param; - Info.SecondArg = Arg; - return Sema::TDK_NonDeducedMismatch; } - - Info.FirstArg = Param; - Info.SecondArg = Arg; + Info.FirstArg = P; + Info.SecondArg = A; return Sema::TDK_NonDeducedMismatch; case TemplateArgument::Expression: if (const NonTypeTemplateParmDecl *NTTP = - getDeducedParameterFromExpr(Info, Param.getAsExpr())) { - if (Arg.getKind() == TemplateArgument::Integral) - return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, - Arg.getAsIntegral(), - Arg.getIntegralType(), - /*ArrayBound=*/false, - Info, Deduced); - if (Arg.getKind() == TemplateArgument::NullPtr) + getDeducedParameterFromExpr(Info, P.getAsExpr())) { + if (A.getKind() == TemplateArgument::Integral) + return DeduceNonTypeTemplateArgument( + S, TemplateParams, NTTP, A.getAsIntegral(), A.getIntegralType(), + /*ArrayBound=*/false, Info, Deduced); + if (A.getKind() == TemplateArgument::NullPtr) return DeduceNullPtrTemplateArgument(S, TemplateParams, NTTP, - Arg.getNullPtrType(), - Info, Deduced); - if (Arg.getKind() == TemplateArgument::Expression) - return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, - Arg.getAsExpr(), Info, Deduced); - if (Arg.getKind() == TemplateArgument::Declaration) + A.getNullPtrType(), Info, Deduced); + if (A.getKind() == TemplateArgument::Expression) return DeduceNonTypeTemplateArgument(S, TemplateParams, NTTP, - Arg.getAsDecl(), - Arg.getParamTypeForDecl(), - Info, Deduced); + A.getAsExpr(), Info, Deduced); + if (A.getKind() == TemplateArgument::Declaration) + return DeduceNonTypeTemplateArgument( + S, TemplateParams, NTTP, A.getAsDecl(), A.getParamTypeForDecl(), + Info, Deduced); - Info.FirstArg = Param; - Info.SecondArg = Arg; + Info.FirstArg = P; + Info.SecondArg = A; return Sema::TDK_NonDeducedMismatch; } // Can't deduce anything, but that's okay. return Sema::TDK_Success; - case TemplateArgument::Pack: llvm_unreachable("Argument packs should be expanded by the caller!"); } @@ -2464,8 +2328,8 @@ static bool hasPackExpansionBeforeEnd(ArrayRef<TemplateArgument> Args) { static Sema::TemplateDeductionResult DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, - ArrayRef<TemplateArgument> Params, - ArrayRef<TemplateArgument> Args, + ArrayRef<TemplateArgument> Ps, + ArrayRef<TemplateArgument> As, TemplateDeductionInfo &Info, SmallVectorImpl<DeducedTemplateArgument> &Deduced, bool NumberOfArgumentsMustMatch) { @@ -2473,7 +2337,7 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, // If the template argument list of P contains a pack expansion that is not // the last template argument, the entire template argument list is a // non-deduced context. - if (hasPackExpansionBeforeEnd(Params)) + if (hasPackExpansionBeforeEnd(Ps)) return Sema::TDK_Success; // C++0x [temp.deduct.type]p9: @@ -2481,12 +2345,13 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, // respective template argument list P is compared with the corresponding // argument Ai of the corresponding template argument list of A. unsigned ArgIdx = 0, ParamIdx = 0; - for (; hasTemplateArgumentForDeduction(Params, ParamIdx); ++ParamIdx) { - if (!Params[ParamIdx].isPackExpansion()) { + for (; hasTemplateArgumentForDeduction(Ps, ParamIdx); ++ParamIdx) { + const TemplateArgument &P = Ps[ParamIdx]; + if (!P.isPackExpansion()) { // The simple case: deduce template arguments by matching Pi and Ai. // Check whether we have enough arguments. - if (!hasTemplateArgumentForDeduction(Args, ArgIdx)) + if (!hasTemplateArgumentForDeduction(As, ArgIdx)) return NumberOfArgumentsMustMatch ? Sema::TDK_MiscellaneousDeductionFailure : Sema::TDK_Success; @@ -2494,14 +2359,12 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, // C++1z [temp.deduct.type]p9: // During partial ordering, if Ai was originally a pack expansion [and] // Pi is not a pack expansion, template argument deduction fails. - if (Args[ArgIdx].isPackExpansion()) + if (As[ArgIdx].isPackExpansion()) return Sema::TDK_MiscellaneousDeductionFailure; // Perform deduction for this Pi/Ai pair. - if (Sema::TemplateDeductionResult Result - = DeduceTemplateArguments(S, TemplateParams, - Params[ParamIdx], Args[ArgIdx], - Info, Deduced)) + if (auto Result = DeduceTemplateArguments(S, TemplateParams, P, + As[ArgIdx], Info, Deduced)) return Result; // Move to the next argument. @@ -2516,7 +2379,7 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, // each remaining argument in the template argument list of A. Each // comparison deduces template arguments for subsequent positions in the // template parameter packs expanded by Pi. - TemplateArgument Pattern = Params[ParamIdx].getPackExpansionPattern(); + TemplateArgument Pattern = P.getPackExpansionPattern(); // Prepare to deduce the packs within the pattern. PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern); @@ -2524,13 +2387,12 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, // Keep track of the deduced template arguments for each parameter pack // expanded by this pack expansion (the outer index) and for each // template argument (the inner SmallVectors). - for (; hasTemplateArgumentForDeduction(Args, ArgIdx) && + for (; hasTemplateArgumentForDeduction(As, ArgIdx) && PackScope.hasNextElement(); ++ArgIdx) { // Deduce template arguments from the pattern. - if (Sema::TemplateDeductionResult Result - = DeduceTemplateArguments(S, TemplateParams, Pattern, Args[ArgIdx], - Info, Deduced)) + if (auto Result = DeduceTemplateArguments(S, TemplateParams, Pattern, + As[ArgIdx], Info, Deduced)) return Result; PackScope.nextPackElement(); @@ -2546,15 +2408,14 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, } static Sema::TemplateDeductionResult -DeduceTemplateArguments(Sema &S, - TemplateParameterList *TemplateParams, +DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, const TemplateArgumentList &ParamList, const TemplateArgumentList &ArgList, TemplateDeductionInfo &Info, SmallVectorImpl<DeducedTemplateArgument> &Deduced) { return DeduceTemplateArguments(S, TemplateParams, ParamList.asArray(), ArgList.asArray(), Info, Deduced, - /*NumberOfArgumentsMustMatch*/false); + /*NumberOfArgumentsMustMatch=*/false); } /// Determine whether two template arguments are the same. @@ -2858,9 +2719,24 @@ static Sema::TemplateDeductionResult ConvertDeducedTemplateArguments( return Sema::TDK_Incomplete; } - TemplateArgumentLoc DefArg = S.SubstDefaultTemplateArgumentIfAvailable( - TD, TD->getLocation(), TD->getSourceRange().getEnd(), Param, Builder, - HasDefaultArg); + TemplateArgumentLoc DefArg; + { + Qualifiers ThisTypeQuals; + CXXRecordDecl *ThisContext = nullptr; + if (auto *Rec = dyn_cast<CXXRecordDecl>(TD->getDeclContext())) + if (Rec->isLambda()) + if (auto *Method = dyn_cast<CXXMethodDecl>(Rec->getDeclContext())) { + ThisContext = Method->getParent(); + ThisTypeQuals = Method->getMethodQualifiers(); + } + + Sema::CXXThisScopeRAII ThisScope(S, ThisContext, ThisTypeQuals, + S.getLangOpts().CPlusPlus17); + + DefArg = S.SubstDefaultTemplateArgumentIfAvailable( + TD, TD->getLocation(), TD->getSourceRange().getEnd(), Param, Builder, + HasDefaultArg); + } // If there was no default argument, deduction is incomplete. if (DefArg.getArgument().isNull()) { @@ -2964,14 +2840,13 @@ FinishTemplateArgumentDeduction( auto *Template = Partial->getSpecializedTemplate(); const ASTTemplateArgumentListInfo *PartialTemplArgInfo = Partial->getTemplateArgsAsWritten(); - const TemplateArgumentLoc *PartialTemplateArgs = - PartialTemplArgInfo->getTemplateArgs(); TemplateArgumentListInfo InstArgs(PartialTemplArgInfo->LAngleLoc, PartialTemplArgInfo->RAngleLoc); - if (S.Subst(PartialTemplateArgs, PartialTemplArgInfo->NumTemplateArgs, - InstArgs, MultiLevelTemplateArgumentList(*DeducedArgumentList))) { + if (S.SubstTemplateArguments( + PartialTemplArgInfo->arguments(), + MultiLevelTemplateArgumentList(*DeducedArgumentList), InstArgs)) { unsigned ArgIdx = InstArgs.size(), ParamIdx = ArgIdx; if (ParamIdx >= Partial->getTemplateParameters()->size()) ParamIdx = Partial->getTemplateParameters()->size() - 1; @@ -2979,7 +2854,7 @@ FinishTemplateArgumentDeduction( Decl *Param = const_cast<NamedDecl *>( Partial->getTemplateParameters()->getParam(ParamIdx)); Info.Param = makeTemplateParameter(Param); - Info.FirstArg = PartialTemplateArgs[ArgIdx].getArgument(); + Info.FirstArg = (*PartialTemplArgInfo)[ArgIdx].getArgument(); return Sema::TDK_SubstitutionFailure; } @@ -3879,8 +3754,9 @@ static bool AdjustFunctionParmAndArgTypesForDeduction( // "lvalue reference to A" is used in place of A for type deduction. if (isForwardingReference(QualType(ParamRefType, 0), FirstInnerIndex) && Arg->isLValue()) { - if (S.getLangOpts().OpenCL && !ArgType.hasAddressSpace()) - ArgType = S.Context.getAddrSpaceQualType(ArgType, LangAS::opencl_generic); + if (S.getLangOpts().OpenCL && !ArgType.hasAddressSpace()) + ArgType = S.Context.getAddrSpaceQualType( + ArgType, S.Context.getDefaultOpenCLPointeeAddrSpace()); ArgType = S.Context.getLValueReferenceType(ArgType); } } else { @@ -4342,11 +4218,11 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( bool HasDeducedReturnType = false; if (getLangOpts().CPlusPlus14 && IsAddressOfFunction && Function->getReturnType()->getContainedAutoType()) { - FunctionType = SubstAutoType(FunctionType, Context.DependentTy); + FunctionType = SubstAutoTypeDependent(FunctionType); HasDeducedReturnType = true; } - if (!ArgFunctionType.isNull()) { + if (!ArgFunctionType.isNull() && !FunctionType.isNull()) { unsigned TDF = TDF_TopLevelParameterTypeList | TDF_AllowCompatibleFunctionType; // Deduce template arguments from the function type. @@ -4776,12 +4652,8 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, ExprResult ER = CheckPlaceholderExpr(Init); if (ER.isInvalid()) return DAR_FailedAlreadyDiagnosed; - Init = ER.get(); - QualType Deduced = BuildDecltypeType(Init, Init->getBeginLoc(), false); - if (Deduced.isNull()) - return DAR_FailedAlreadyDiagnosed; - // FIXME: Support a non-canonical deduced type for 'auto'. - Deduced = Context.getCanonicalType(Deduced); + QualType Deduced = getDecltypeForExpr(ER.get()); + assert(!Deduced.isNull()); if (AT->isConstrained() && !IgnoreConstraints) { auto ConstraintsResult = CheckDeducedPlaceholderConstraints(*this, *AT, @@ -4816,7 +4688,7 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, Context, Loc, Loc, TemplParamPtr, Loc, nullptr); QualType FuncParam = - SubstituteDeducedTypeTransform(*this, TemplArg, /*UseTypeSugar*/false) + SubstituteDeducedTypeTransform(*this, TemplArg, /*UseTypeSugar*/ true) .Apply(Type); assert(!FuncParam.isNull() && "substituting template parameter for 'auto' failed"); @@ -4930,27 +4802,29 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, QualType Sema::SubstAutoType(QualType TypeWithAuto, QualType TypeToReplaceAuto) { - if (TypeToReplaceAuto->isDependentType()) - return SubstituteDeducedTypeTransform( - *this, DependentAuto{ - TypeToReplaceAuto->containsUnexpandedParameterPack()}) - .TransformType(TypeWithAuto); + assert(TypeToReplaceAuto != Context.DependentTy); return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto) .TransformType(TypeWithAuto); } TypeSourceInfo *Sema::SubstAutoTypeSourceInfo(TypeSourceInfo *TypeWithAuto, QualType TypeToReplaceAuto) { - if (TypeToReplaceAuto->isDependentType()) - return SubstituteDeducedTypeTransform( - *this, - DependentAuto{ - TypeToReplaceAuto->containsUnexpandedParameterPack()}) - .TransformType(TypeWithAuto); + assert(TypeToReplaceAuto != Context.DependentTy); return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto) .TransformType(TypeWithAuto); } +QualType Sema::SubstAutoTypeDependent(QualType TypeWithAuto) { + return SubstituteDeducedTypeTransform(*this, DependentAuto{false}) + .TransformType(TypeWithAuto); +} + +TypeSourceInfo * +Sema::SubstAutoTypeSourceInfoDependent(TypeSourceInfo *TypeWithAuto) { + return SubstituteDeducedTypeTransform(*this, DependentAuto{false}) + .TransformType(TypeWithAuto); +} + QualType Sema::ReplaceAutoType(QualType TypeWithAuto, QualType TypeToReplaceAuto) { return SubstituteDeducedTypeTransform(*this, TypeToReplaceAuto, @@ -5145,6 +5019,7 @@ static bool isAtLeastAsSpecializedAs(Sema &S, Args2.resize(NumComparedArguments); if (Reversed) std::reverse(Args2.begin(), Args2.end()); + if (DeduceTemplateArguments(S, TemplateParams, Args2.data(), Args2.size(), Args1.data(), Args1.size(), Info, Deduced, TDF_None, /*PartialOrdering=*/true)) |
