aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp279
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)