diff options
author | Vedant Kumar <vsk@apple.com> | 2019-12-18 14:52:51 -0800 |
---|---|---|
committer | Vedant Kumar <vsk@apple.com> | 2019-12-18 15:02:39 -0800 |
commit | 5094e6dad64c755be1bb797b0307c54dbae8871d (patch) | |
tree | e69dc554593934e48240b90458911b6098ae0862 /clang/lib/Sema/SemaTemplateDeduction.cpp | |
parent | f0df4218b67d0abe96867804b8932b9b88998f51 (diff) | |
download | bcm5719-llvm-5094e6dad64c755be1bb797b0307c54dbae8871d.tar.gz bcm5719-llvm-5094e6dad64c755be1bb797b0307c54dbae8871d.zip |
Revert concepts changes from D41910
These changes caused LibcxxVariantDataFormatterTestCase in lldb to fail
with an assert:
Assertion failed: (Idx < size() && "Out-of-bounds Bit access."),
function operator[], file
/Users/buildslave/jenkins/workspace/lldb-cmake/llvm-project/llvm/include/llvm/ADT/SmallBitVector.h,
line 452.
In:
7 clang-10 0x00000001094b79d9 isAtLeastAsSpecializedAs(clang::Sema&, clang::SourceLocation, clang::FunctionTemplateDecl*, clang::FunctionTemplateDecl*, clang::TemplatePartialOrderingContext, unsigned int) + 1865
8 clang-10 0x00000001094b7111 clang::Sema::getMoreSpecializedTemplate(clang::FunctionTemplateDecl*, clang::FunctionTemplateDecl*, clang::SourceLocation, clang::TemplatePartialOrderingContext, unsigned int, unsigned int) + 97
9 clang-10 0x000000010939bf88 clang::isBetterOverloadCandidate(clang::Sema&, clang::OverloadCandidate const&, clang::OverloadCandidate const&, clang::SourceLocation, clang::OverloadCandidateSet::CandidateSetKind) + 1128
Revert "[Concepts] Fix incorrect move out of temporary in D41910"
This reverts commit 11d5fa6e87e3584f72056ecc2b17f88c58323dde.
Revert "[Concepts] Fix crash in D41910"
This reverts commit 12038be20ee6a903cdbd3fddce65535ef683e31d.
Revert "[Concepts] Constrained partial specializations and function overloads."
This reverts commit fc0731b98a67c793862288f8ae334322666214dc.
Diffstat (limited to 'clang/lib/Sema/SemaTemplateDeduction.cpp')
-rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 231 |
1 files changed, 37 insertions, 194 deletions
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index df4f6f647b2..327447746c3 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -24,7 +24,6 @@ #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/NestedNameSpecifier.h" -#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" @@ -2502,30 +2501,6 @@ Sema::getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, llvm_unreachable("Invalid TemplateArgument Kind!"); } -TemplateArgumentLoc -Sema::getIdentityTemplateArgumentLoc(Decl *TemplateParm, - SourceLocation Location) { - if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParm)) - return getTrivialTemplateArgumentLoc( - TemplateArgument( - Context.getTemplateTypeParmType(TTP->getDepth(), TTP->getIndex(), - TTP->isParameterPack(), TTP)), - QualType(), Location.isValid() ? Location : TTP->getLocation()); - else if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParm)) - return getTrivialTemplateArgumentLoc(TemplateArgument(TemplateName(TTP)), - QualType(), - Location.isValid() ? Location : - TTP->getLocation()); - auto *NTTP = cast<NonTypeTemplateParmDecl>(TemplateParm); - CXXScopeSpec SS; - DeclarationNameInfo Info(NTTP->getDeclName(), - Location.isValid() ? Location : NTTP->getLocation()); - Expr *E = BuildDeclarationNameExpr(SS, Info, NTTP).get(); - return getTrivialTemplateArgumentLoc(TemplateArgument(E), NTTP->getType(), - Location.isValid() ? Location : - NTTP->getLocation()); -} - /// Convert the given deduced template argument and add it to the set of /// fully-converted template arguments. static bool @@ -2616,6 +2591,23 @@ ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param, return ConvertArg(Arg, 0); } +template<typename TemplateDeclT> +static Sema::TemplateDeductionResult +CheckDeducedArgumentConstraints(Sema& S, TemplateDeclT *Template, + ArrayRef<TemplateArgument> DeducedArgs, + TemplateDeductionInfo &Info) { + llvm::SmallVector<const Expr *, 3> AssociatedConstraints; + Template->getAssociatedConstraints(AssociatedConstraints); + if (S.CheckConstraintSatisfaction(Template, AssociatedConstraints, + DeducedArgs, Info.getLocation(), + Info.AssociatedConstraintsSatisfaction) || + !Info.AssociatedConstraintsSatisfaction.IsSatisfied) { + Info.reset(TemplateArgumentList::CreateCopy(S.Context, DeducedArgs)); + return Sema::TDK_ConstraintsNotSatisfied; + } + return Sema::TDK_Success; +} + // FIXME: This should not be a template, but // ClassTemplatePartialSpecializationDecl sadly does not derive from // TemplateDecl. @@ -2713,6 +2705,10 @@ static Sema::TemplateDeductionResult ConvertDeducedTemplateArguments( // If we get here, we successfully used the default template argument. } + if (Sema::TemplateDeductionResult Result + = CheckDeducedArgumentConstraints(S, Template, Builder, Info)) + return Result; + return Sema::TDK_Success; } @@ -2734,23 +2730,6 @@ struct IsPartialSpecialization<VarTemplatePartialSpecializationDecl> { static constexpr bool value = true; }; -template<typename TemplateDeclT> -static Sema::TemplateDeductionResult -CheckDeducedArgumentConstraints(Sema& S, TemplateDeclT *Template, - ArrayRef<TemplateArgument> DeducedArgs, - TemplateDeductionInfo& Info) { - llvm::SmallVector<const Expr *, 3> AssociatedConstraints; - Template->getAssociatedConstraints(AssociatedConstraints); - if (S.CheckConstraintSatisfaction(Template, AssociatedConstraints, - DeducedArgs, Info.getLocation(), - Info.AssociatedConstraintsSatisfaction) || - !Info.AssociatedConstraintsSatisfaction.IsSatisfied) { - Info.reset(TemplateArgumentList::CreateCopy(S.Context, DeducedArgs)); - return Sema::TDK_ConstraintsNotSatisfied; - } - return Sema::TDK_Success; -} - /// Complete template argument deduction for a partial specialization. template <typename T> static typename std::enable_if<IsPartialSpecialization<T>::value, @@ -2832,9 +2811,6 @@ FinishTemplateArgumentDeduction( if (Trap.hasErrorOccurred()) return Sema::TDK_SubstitutionFailure; - if (auto Result = CheckDeducedArgumentConstraints(S, Partial, Builder, Info)) - return Result; - return Sema::TDK_Success; } @@ -2877,10 +2853,6 @@ static Sema::TemplateDeductionResult FinishTemplateArgumentDeduction( if (Trap.hasErrorOccurred()) return Sema::TDK_SubstitutionFailure; - if (auto Result = CheckDeducedArgumentConstraints(S, Template, Builder, - Info)) - return Result; - return Sema::TDK_Success; } @@ -3392,11 +3364,6 @@ Sema::TemplateDeductionResult Sema::FinishTemplateArgumentDeduction( PartialOverloading)) return Result; - if (TemplateDeductionResult Result - = CheckDeducedArgumentConstraints(*this, FunctionTemplate, Builder, - Info)) - return Result; - // C++ [temp.deduct.call]p10: [DR1391] // If deduction succeeds for all parameters that contain // template-parameters that participate in template argument deduction, @@ -4962,21 +4929,6 @@ Sema::getMoreSpecializedTemplate(FunctionTemplateDecl *FT1, TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1, unsigned NumCallArguments2) { - - auto JudgeByConstraints = [&] () -> FunctionTemplateDecl * { - llvm::SmallVector<const Expr *, 3> AC1, AC2; - FT1->getAssociatedConstraints(AC1); - FT2->getAssociatedConstraints(AC2); - bool AtLeastAsConstrained1, AtLeastAsConstrained2; - if (IsAtLeastAsConstrained(FT1, AC1, FT2, AC2, AtLeastAsConstrained1)) - return nullptr; - if (IsAtLeastAsConstrained(FT2, AC2, FT1, AC1, AtLeastAsConstrained2)) - return nullptr; - if (AtLeastAsConstrained1 == AtLeastAsConstrained2) - return nullptr; - return AtLeastAsConstrained1 ? FT1 : FT2; - }; - bool Better1 = isAtLeastAsSpecializedAs(*this, Loc, FT1, FT2, TPOC, NumCallArguments1); bool Better2 = isAtLeastAsSpecializedAs(*this, Loc, FT2, FT1, TPOC, @@ -4986,7 +4938,7 @@ Sema::getMoreSpecializedTemplate(FunctionTemplateDecl *FT1, return Better1 ? FT1 : FT2; if (!Better1 && !Better2) // Neither is better than the other - return JudgeByConstraints(); + return nullptr; // FIXME: This mimics what GCC implements, but doesn't match up with the // proposed resolution for core issue 692. This area needs to be sorted out, @@ -4996,7 +4948,7 @@ Sema::getMoreSpecializedTemplate(FunctionTemplateDecl *FT1, if (Variadic1 != Variadic2) return Variadic1? FT2 : FT1; - return JudgeByConstraints(); + return nullptr; } /// Determine if the two templates are equivalent. @@ -5121,6 +5073,7 @@ template<typename TemplateLikeDecl> static bool isAtLeastAsSpecializedAs(Sema &S, QualType T1, QualType T2, TemplateLikeDecl *P2, TemplateDeductionInfo &Info) { + // TODO: Concepts: Regard constraints // C++ [temp.class.order]p1: // For two class template partial specializations, the first is at least as // specialized as the second if, given the following rewrite to two @@ -5191,21 +5144,8 @@ Sema::getMoreSpecializedPartialSpecialization( bool Better1 = isAtLeastAsSpecializedAs(*this, PT1, PT2, PS2, Info); bool Better2 = isAtLeastAsSpecializedAs(*this, PT2, PT1, PS1, Info); - if (!Better1 && !Better2) - return nullptr; - if (Better1 && Better2) { - llvm::SmallVector<const Expr *, 3> AC1, AC2; - PS1->getAssociatedConstraints(AC1); - PS2->getAssociatedConstraints(AC2); - bool AtLeastAsConstrained1, AtLeastAsConstrained2; - if (IsAtLeastAsConstrained(PS1, AC1, PS2, AC2, AtLeastAsConstrained1)) - return nullptr; - if (IsAtLeastAsConstrained(PS2, AC2, PS1, AC1, AtLeastAsConstrained2)) - return nullptr; - if (AtLeastAsConstrained1 == AtLeastAsConstrained2) - return nullptr; - return AtLeastAsConstrained1 ? PS1 : PS2; - } + if (Better1 == Better2) + return nullptr; return Better1 ? PS1 : PS2; } @@ -5217,22 +5157,11 @@ bool Sema::isMoreSpecializedThanPrimary( QualType PartialT = Spec->getInjectedSpecializationType(); if (!isAtLeastAsSpecializedAs(*this, PartialT, PrimaryT, Primary, Info)) return false; - if (!isAtLeastAsSpecializedAs(*this, PrimaryT, PartialT, Spec, Info)) - return true; - Info.clearSFINAEDiagnostic(); - llvm::SmallVector<const Expr *, 3> PrimaryAC, SpecAC; - Primary->getAssociatedConstraints(PrimaryAC); - Spec->getAssociatedConstraints(SpecAC); - bool AtLeastAsConstrainedPrimary, AtLeastAsConstrainedSpec; - if (IsAtLeastAsConstrained(Spec, SpecAC, Primary, PrimaryAC, - AtLeastAsConstrainedSpec)) - return false; - if (!AtLeastAsConstrainedSpec) - return false; - if (IsAtLeastAsConstrained(Primary, PrimaryAC, Spec, SpecAC, - AtLeastAsConstrainedPrimary)) + if (isAtLeastAsSpecializedAs(*this, PrimaryT, PartialT, Spec, Info)) { + Info.clearSFINAEDiagnostic(); return false; - return !AtLeastAsConstrainedPrimary; + } + return true; } VarTemplatePartialSpecializationDecl * @@ -5255,22 +5184,8 @@ Sema::getMoreSpecializedPartialSpecialization( bool Better1 = isAtLeastAsSpecializedAs(*this, PT1, PT2, PS2, Info); bool Better2 = isAtLeastAsSpecializedAs(*this, PT2, PT1, PS1, Info); - if (!Better1 && !Better2) + if (Better1 == Better2) return nullptr; - if (Better1 && Better2) { - llvm::SmallVector<const Expr *, 3> AC1, AC2; - PS1->getAssociatedConstraints(AC1); - PS2->getAssociatedConstraints(AC2); - bool AtLeastAsConstrained1, AtLeastAsConstrained2; - if (IsAtLeastAsConstrained(PS1, AC1, PS2, AC2, AtLeastAsConstrained1)) - return nullptr; - if (IsAtLeastAsConstrained(PS2, AC2, PS1, AC1, AtLeastAsConstrained2)) - return nullptr; - if (AtLeastAsConstrained1 == AtLeastAsConstrained2) { - return nullptr; - } - return AtLeastAsConstrained1 ? PS1 : PS2; - } return Better1 ? PS1 : PS2; } @@ -5290,25 +5205,13 @@ bool Sema::isMoreSpecializedThanPrimary( CanonTemplate, PrimaryArgs); QualType PartialT = Context.getTemplateSpecializationType( CanonTemplate, Spec->getTemplateArgs().asArray()); - if (!isAtLeastAsSpecializedAs(*this, PartialT, PrimaryT, Primary, Info)) return false; - if (!isAtLeastAsSpecializedAs(*this, PrimaryT, PartialT, Spec, Info)) - return true; - Info.clearSFINAEDiagnostic(); - llvm::SmallVector<const Expr *, 3> PrimaryAC, SpecAC; - Primary->getAssociatedConstraints(PrimaryAC); - Spec->getAssociatedConstraints(SpecAC); - bool AtLeastAsConstrainedPrimary, AtLeastAsConstrainedSpec; - if (IsAtLeastAsConstrained(Spec, SpecAC, Primary, PrimaryAC, - AtLeastAsConstrainedSpec)) - return false; - if (!AtLeastAsConstrainedSpec) + if (isAtLeastAsSpecializedAs(*this, PrimaryT, PartialT, Spec, Info)) { + Info.clearSFINAEDiagnostic(); return false; - if (IsAtLeastAsConstrained(Primary, PrimaryAC, Spec, SpecAC, - AtLeastAsConstrainedPrimary)) - return false; - return !AtLeastAsConstrainedPrimary; + } + return true; } bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs( @@ -5374,49 +5277,6 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs( return isAtLeastAsSpecializedAs(*this, PType, AType, AArg, Info); } -struct OccurringTemplateParameterFinder : - RecursiveASTVisitor<OccurringTemplateParameterFinder> { - llvm::SmallBitVector &OccurringIndices; - - OccurringTemplateParameterFinder(llvm::SmallBitVector &OccurringIndices) - : OccurringIndices(OccurringIndices) { } - - bool VisitTemplateTypeParmType(TemplateTypeParmType *T) { - assert(T->getDepth() == 0 && "This assumes that we allow concepts at " - "namespace scope only"); - noteParameter(T->getIndex()); - return true; - } - - bool TraverseTemplateName(TemplateName Template) { - if (auto *TTP = - dyn_cast<TemplateTemplateParmDecl>(Template.getAsTemplateDecl())) { - assert(TTP->getDepth() == 0 && "This assumes that we allow concepts at " - "namespace scope only"); - noteParameter(TTP->getIndex()); - } - RecursiveASTVisitor<OccurringTemplateParameterFinder>:: - TraverseTemplateName(Template); - return true; - } - - bool VisitDeclRefExpr(DeclRefExpr *E) { - if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(E->getDecl())) { - assert(NTTP->getDepth() == 0 && "This assumes that we allow concepts at " - "namespace scope only"); - noteParameter(NTTP->getIndex()); - } - return true; - } - -protected: - void noteParameter(unsigned Index) { - if (OccurringIndices.size() >= Index) - OccurringIndices.resize(Index + 1, false); - OccurringIndices.set(Index); - } -}; - /// Mark the template parameters that are used by the given /// expression. static void @@ -5425,11 +5285,6 @@ MarkUsedTemplateParameters(ASTContext &Ctx, bool OnlyDeduced, unsigned Depth, llvm::SmallBitVector &Used) { - if (!OnlyDeduced) { - OccurringTemplateParameterFinder(Used).TraverseStmt(const_cast<Expr *>(E)); - return; - } - // We can deduce from a pack expansion. if (const PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(E)) E = Expansion->getPattern(); @@ -5448,6 +5303,8 @@ MarkUsedTemplateParameters(ASTContext &Ctx, break; } + // FIXME: if !OnlyDeduced, we have to walk the whole subexpression to + // find other occurrences of template parameters. const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E); if (!DRE) return; @@ -5827,20 +5684,6 @@ MarkUsedTemplateParameters(ASTContext &Ctx, } } -/// Mark which template parameters are used in a given expression. -/// -/// \param E the expression from which template parameters will be deduced. -/// -/// \param Used a bit vector whose elements will be set to \c true -/// to indicate when the corresponding template parameter will be -/// deduced. -void -Sema::MarkUsedTemplateParameters(const Expr *E, bool OnlyDeduced, - unsigned Depth, - llvm::SmallBitVector &Used) { - ::MarkUsedTemplateParameters(Context, E, OnlyDeduced, Depth, Used); -} - /// Mark which template parameters can be deduced from a given /// template argument list. /// |