diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp | 279 |
1 files changed, 233 insertions, 46 deletions
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp b/contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp index 1e321d637910..5392be57a3aa 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -355,7 +355,7 @@ checkDeducedTemplateArguments(ASTContext &Context, TemplateArgument Merged = checkDeducedTemplateArguments( Context, DeducedTemplateArgument(*XA, X.wasDeducedFromArrayBound()), DeducedTemplateArgument(*YA, Y.wasDeducedFromArrayBound())); - if (Merged.isNull()) + if (Merged.isNull() && !(XA->isNull() && YA->isNull())) return DeducedTemplateArgument(); NewPack.push_back(Merged); } @@ -738,8 +738,9 @@ private: // type, so we need to collect the pending deduced values for those packs. if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>( TemplateParams->getParam(Index))) { - if (auto *Expansion = dyn_cast<PackExpansionType>(NTTP->getType())) - ExtraDeductions.push_back(Expansion->getPattern()); + if (!NTTP->isExpandedParameterPack()) + if (auto *Expansion = dyn_cast<PackExpansionType>(NTTP->getType())) + ExtraDeductions.push_back(Expansion->getPattern()); } // FIXME: Also collect the unexpanded packs in any type and template // parameter packs that are pack expansions. @@ -1515,6 +1516,7 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, case Type::ObjCObject: case Type::ObjCInterface: case Type::ObjCObjectPointer: + case Type::ExtInt: if (TDF & TDF_SkipNonDependent) return Sema::TDK_Success; @@ -2056,6 +2058,101 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, // (clang extension) // + // T __attribute__((matrix_type(<integral constant>, + // <integral constant>))) + case Type::ConstantMatrix: { + const ConstantMatrixType *MatrixArg = dyn_cast<ConstantMatrixType>(Arg); + if (!MatrixArg) + 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()) { + return Sema::TDK_NonDeducedMismatch; + } + // Perform deduction on element types. + return DeduceTemplateArgumentsByTypeMatch( + S, TemplateParams, MatrixParam->getElementType(), + MatrixArg->getElementType(), Info, Deduced, TDF); + } + + case Type::DependentSizedMatrix: { + const MatrixType *MatrixArg = dyn_cast<MatrixType>(Arg); + if (!MatrixArg) + 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)) + return Result; + + // Try to deduce a matrix dimension. + auto DeduceMatrixArg = + [&S, &Info, &Deduced, &TemplateParams]( + Expr *ParamExpr, const MatrixType *Arg, + unsigned (ConstantMatrixType::*GetArgDimension)() const, + Expr *(DependentSizedMatrixType::*GetArgDimensionExpr)() const) { + const auto *ArgConstMatrix = dyn_cast<ConstantMatrixType>(Arg); + const auto *ArgDepMatrix = dyn_cast<DependentSizedMatrixType>(Arg); + if (!ParamExpr->isValueDependent()) { + llvm::APSInt ParamConst( + S.Context.getTypeSize(S.Context.getSizeType())); + if (!ParamExpr->isIntegerConstantExpr(ParamConst, S.Context)) + return Sema::TDK_NonDeducedMismatch; + + if (ArgConstMatrix) { + if ((ArgConstMatrix->*GetArgDimension)() == ParamConst) + return Sema::TDK_Success; + return Sema::TDK_NonDeducedMismatch; + } + + Expr *ArgExpr = (ArgDepMatrix->*GetArgDimensionExpr)(); + llvm::APSInt ArgConst( + S.Context.getTypeSize(S.Context.getSizeType())); + if (!ArgExpr->isValueDependent() && + ArgExpr->isIntegerConstantExpr(ArgConst, S.Context) && + ArgConst == ParamConst) + return Sema::TDK_Success; + return Sema::TDK_NonDeducedMismatch; + } + + NonTypeTemplateParmDecl *NTTP = + getDeducedParameterFromExpr(Info, ParamExpr); + if (!NTTP) + return Sema::TDK_Success; + + if (ArgConstMatrix) { + llvm::APSInt ArgConst( + S.Context.getTypeSize(S.Context.getSizeType())); + ArgConst = (ArgConstMatrix->*GetArgDimension)(); + return DeduceNonTypeTemplateArgument( + S, TemplateParams, NTTP, ArgConst, S.Context.getSizeType(), + /*ArrayBound=*/true, Info, Deduced); + } + + return DeduceNonTypeTemplateArgument( + S, TemplateParams, NTTP, (ArgDepMatrix->*GetArgDimensionExpr)(), + Info, Deduced); + }; + + auto Result = DeduceMatrixArg(MatrixParam->getRowExpr(), MatrixArg, + &ConstantMatrixType::getNumRows, + &DependentSizedMatrixType::getRowExpr); + if (Result) + return Result; + + return DeduceMatrixArg(MatrixParam->getColumnExpr(), MatrixArg, + &ConstantMatrixType::getNumColumns, + &DependentSizedMatrixType::getColumnExpr); + } + + // (clang extension) + // // T __attribute__(((address_space(N)))) case Type::DependentAddressSpace: { const DependentAddressSpaceType *AddressSpaceParam = @@ -2106,6 +2203,33 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S, return Sema::TDK_NonDeducedMismatch; } + case Type::DependentExtInt: { + const auto *IntParam = cast<DependentExtIntType>(Param); + + if (const auto *IntArg = dyn_cast<ExtIntType>(Arg)){ + if (IntParam->isUnsigned() != IntArg->isUnsigned()) + return Sema::TDK_NonDeducedMismatch; + + NonTypeTemplateParmDecl *NTTP = + getDeducedParameterFromExpr(Info, IntParam->getNumBitsExpr()); + if (!NTTP) + return Sema::TDK_Success; + + llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false); + ArgSize = IntArg->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()) + return Sema::TDK_NonDeducedMismatch; + return Sema::TDK_Success; + } + return Sema::TDK_NonDeducedMismatch; + } case Type::TypeOfExpr: case Type::TypeOf: @@ -2747,8 +2871,8 @@ CheckDeducedArgumentConstraints(Sema& S, TemplateDeclT *Template, /// Complete template argument deduction for a partial specialization. template <typename T> -static typename std::enable_if<IsPartialSpecialization<T>::value, - Sema::TemplateDeductionResult>::type +static std::enable_if_t<IsPartialSpecialization<T>::value, + Sema::TemplateDeductionResult> FinishTemplateArgumentDeduction( Sema &S, T *Partial, bool IsPartialOrdering, const TemplateArgumentList &TemplateArgs, @@ -2917,8 +3041,13 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, if (Trap.hasErrorOccurred()) return Sema::TDK_SubstitutionFailure; - return ::FinishTemplateArgumentDeduction( - *this, Partial, /*IsPartialOrdering=*/false, TemplateArgs, Deduced, Info); + TemplateDeductionResult Result; + runWithSufficientStackSpace(Info.getLocation(), [&] { + Result = ::FinishTemplateArgumentDeduction(*this, Partial, + /*IsPartialOrdering=*/false, + TemplateArgs, Deduced, Info); + }); + return Result; } /// Perform template argument deduction to determine whether @@ -2958,8 +3087,13 @@ Sema::DeduceTemplateArguments(VarTemplatePartialSpecializationDecl *Partial, if (Trap.hasErrorOccurred()) return Sema::TDK_SubstitutionFailure; - return ::FinishTemplateArgumentDeduction( - *this, Partial, /*IsPartialOrdering=*/false, TemplateArgs, Deduced, Info); + TemplateDeductionResult Result; + runWithSufficientStackSpace(Info.getLocation(), [&] { + Result = ::FinishTemplateArgumentDeduction(*this, Partial, + /*IsPartialOrdering=*/false, + TemplateArgs, Deduced, Info); + }); + return Result; } /// Determine whether the given type T is a simple-template-id type. @@ -3908,13 +4042,12 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( SmallVector<QualType, 8> ParamTypes; unsigned NumExplicitlySpecified = 0; if (ExplicitTemplateArgs) { - TemplateDeductionResult Result = - SubstituteExplicitTemplateArguments(FunctionTemplate, - *ExplicitTemplateArgs, - Deduced, - ParamTypes, - nullptr, - Info); + TemplateDeductionResult Result; + runWithSufficientStackSpace(Info.getLocation(), [&] { + Result = SubstituteExplicitTemplateArguments( + FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes, nullptr, + Info); + }); if (Result) return Result; @@ -4016,12 +4149,16 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( // that is needed when the accessibility of template arguments is checked. DeclContext *CallingCtx = CurContext; - return FinishTemplateArgumentDeduction( - FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info, - &OriginalCallArgs, PartialOverloading, [&, CallingCtx]() { - ContextRAII SavedContext(*this, CallingCtx); - return CheckNonDependent(ParamTypesForArgChecking); - }); + TemplateDeductionResult Result; + runWithSufficientStackSpace(Info.getLocation(), [&] { + Result = FinishTemplateArgumentDeduction( + FunctionTemplate, Deduced, NumExplicitlySpecified, Specialization, Info, + &OriginalCallArgs, PartialOverloading, [&, CallingCtx]() { + ContextRAII SavedContext(*this, CallingCtx); + return CheckNonDependent(ParamTypesForArgChecking); + }); + }); + return Result; } QualType Sema::adjustCCAndNoReturn(QualType ArgFunctionType, @@ -4107,11 +4244,13 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( unsigned NumExplicitlySpecified = 0; SmallVector<QualType, 4> ParamTypes; if (ExplicitTemplateArgs) { - if (TemplateDeductionResult Result - = SubstituteExplicitTemplateArguments(FunctionTemplate, - *ExplicitTemplateArgs, - Deduced, ParamTypes, - &FunctionType, Info)) + TemplateDeductionResult Result; + runWithSufficientStackSpace(Info.getLocation(), [&] { + Result = SubstituteExplicitTemplateArguments( + FunctionTemplate, *ExplicitTemplateArgs, Deduced, ParamTypes, + &FunctionType, Info); + }); + if (Result) return Result; NumExplicitlySpecified = Deduced.size(); @@ -4153,10 +4292,13 @@ Sema::TemplateDeductionResult Sema::DeduceTemplateArguments( return Result; } - if (TemplateDeductionResult Result - = FinishTemplateArgumentDeduction(FunctionTemplate, Deduced, - NumExplicitlySpecified, - Specialization, Info)) + TemplateDeductionResult Result; + runWithSufficientStackSpace(Info.getLocation(), [&] { + Result = FinishTemplateArgumentDeduction(FunctionTemplate, Deduced, + NumExplicitlySpecified, + Specialization, Info); + }); + if (Result) return Result; // If the function has a deduced return type, deduce it now, so we can check @@ -4313,9 +4455,11 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *ConversionTemplate, LocalInstantiationScope InstScope(*this); // Finish template argument deduction. FunctionDecl *ConversionSpecialized = nullptr; - TemplateDeductionResult Result - = FinishTemplateArgumentDeduction(ConversionTemplate, Deduced, 0, - ConversionSpecialized, Info); + TemplateDeductionResult Result; + runWithSufficientStackSpace(Info.getLocation(), [&] { + Result = FinishTemplateArgumentDeduction(ConversionTemplate, Deduced, 0, + ConversionSpecialized, Info); + }); Specialization = cast_or_null<CXXConversionDecl>(ConversionSpecialized); return Result; } @@ -4532,6 +4676,8 @@ Sema::DeduceAutoResult Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, Optional<unsigned> DependentDeductionDepth, bool IgnoreConstraints) { + if (Init->containsErrors()) + return DAR_FailedAlreadyDiagnosed; if (Init->getType()->isNonOverloadPlaceholderType()) { ExprResult NonPlaceholder = CheckPlaceholderExpr(Init); if (NonPlaceholder.isInvalid()) @@ -4850,7 +4996,10 @@ static bool isAtLeastAsSpecializedAs(Sema &S, FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, TemplatePartialOrderingContext TPOC, - unsigned NumCallArguments1) { + unsigned NumCallArguments1, + bool Reversed) { + assert(!Reversed || TPOC == TPOC_Call); + FunctionDecl *FD1 = FT1->getTemplatedDecl(); FunctionDecl *FD2 = FT2->getTemplatedDecl(); const FunctionProtoType *Proto1 = FD1->getType()->getAs<FunctionProtoType>(); @@ -4899,6 +5048,12 @@ static bool isAtLeastAsSpecializedAs(Sema &S, } else if (!Method1 && Method2 && !Method2->isStatic()) { // Compare 'this' from Method2 against first parameter from Method1. AddImplicitObjectParameterType(S.Context, Method2, Args2); + } else if (Method1 && Method2 && Reversed) { + // Compare 'this' from Method1 against second parameter from Method2 + // and 'this' from Method2 against second parameter from Method1. + AddImplicitObjectParameterType(S.Context, Method1, Args1); + AddImplicitObjectParameterType(S.Context, Method2, Args2); + ++NumComparedArguments; } Args1.insert(Args1.end(), Proto1->param_type_begin(), @@ -4913,6 +5068,8 @@ static bool isAtLeastAsSpecializedAs(Sema &S, Args1.resize(NumComparedArguments); if (Args2.size() > NumComparedArguments) 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)) @@ -5031,6 +5188,10 @@ static bool isVariadicFunctionTemplate(FunctionTemplateDecl *FunTmpl) { /// \param NumCallArguments2 The number of arguments in the call to FT2, used /// only when \c TPOC is \c TPOC_Call. /// +/// \param Reversed If \c true, exactly one of FT1 and FT2 is an overload +/// candidate with a reversed parameter order. In this case, the corresponding +/// P/A pairs between FT1 and FT2 are reversed. +/// /// \returns the more specialized function template. If neither /// template is more specialized, returns NULL. FunctionTemplateDecl * @@ -5039,7 +5200,8 @@ Sema::getMoreSpecializedTemplate(FunctionTemplateDecl *FT1, SourceLocation Loc, TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1, - unsigned NumCallArguments2) { + unsigned NumCallArguments2, + bool Reversed) { auto JudgeByConstraints = [&] () -> FunctionTemplateDecl * { llvm::SmallVector<const Expr *, 3> AC1, AC2; @@ -5056,9 +5218,9 @@ Sema::getMoreSpecializedTemplate(FunctionTemplateDecl *FT1, }; bool Better1 = isAtLeastAsSpecializedAs(*this, Loc, FT1, FT2, TPOC, - NumCallArguments1); + NumCallArguments1, Reversed); bool Better2 = isAtLeastAsSpecializedAs(*this, Loc, FT2, FT1, TPOC, - NumCallArguments2); + NumCallArguments2, Reversed); if (Better1 != Better2) // We have a clear winner return Better1 ? FT1 : FT2; @@ -5237,14 +5399,15 @@ static bool isAtLeastAsSpecializedAs(Sema &S, QualType T1, QualType T2, Sema::InstantiatingTemplate Inst(S, Info.getLocation(), P2, DeducedArgs, Info); auto *TST1 = T1->castAs<TemplateSpecializationType>(); - if (FinishTemplateArgumentDeduction( - S, P2, /*IsPartialOrdering=*/true, - TemplateArgumentList(TemplateArgumentList::OnStack, - TST1->template_arguments()), - Deduced, Info)) - return false; - - return true; + bool AtLeastAsSpecialized; + S.runWithSufficientStackSpace(Info.getLocation(), [&] { + AtLeastAsSpecialized = !FinishTemplateArgumentDeduction( + S, P2, /*IsPartialOrdering=*/true, + TemplateArgumentList(TemplateArgumentList::OnStack, + TST1->template_arguments()), + Deduced, Info); + }); + return AtLeastAsSpecialized; } /// Returns the more specialized class template partial specialization @@ -5679,6 +5842,24 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T, break; } + case Type::ConstantMatrix: { + const ConstantMatrixType *MatType = cast<ConstantMatrixType>(T); + MarkUsedTemplateParameters(Ctx, MatType->getElementType(), OnlyDeduced, + Depth, Used); + break; + } + + case Type::DependentSizedMatrix: { + const DependentSizedMatrixType *MatType = cast<DependentSizedMatrixType>(T); + MarkUsedTemplateParameters(Ctx, MatType->getElementType(), OnlyDeduced, + Depth, Used); + MarkUsedTemplateParameters(Ctx, MatType->getRowExpr(), OnlyDeduced, Depth, + Used); + MarkUsedTemplateParameters(Ctx, MatType->getColumnExpr(), OnlyDeduced, + Depth, Used); + break; + } + case Type::FunctionProto: { const FunctionProtoType *Proto = cast<FunctionProtoType>(T); MarkUsedTemplateParameters(Ctx, Proto->getReturnType(), OnlyDeduced, Depth, @@ -5834,6 +6015,11 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T, cast<DeducedType>(T)->getDeducedType(), OnlyDeduced, Depth, Used); break; + case Type::DependentExtInt: + MarkUsedTemplateParameters(Ctx, + cast<DependentExtIntType>(T)->getNumBitsExpr(), + OnlyDeduced, Depth, Used); + break; // None of these types have any template parameters in them. case Type::Builtin: @@ -5846,6 +6032,7 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T, case Type::ObjCObjectPointer: case Type::UnresolvedUsing: case Type::Pipe: + case Type::ExtInt: #define TYPE(Class, Base) #define ABSTRACT_TYPE(Class, Base) #define DEPENDENT_TYPE(Class, Base) |