Author: Erich Keane Date: 2022-07-29T05:54:04-07:00 New Revision: b25902736c2e330429278e1929cc5afd2201fb77
URL: https://github.com/llvm/llvm-project/commit/b25902736c2e330429278e1929cc5afd2201fb77 DIFF: https://github.com/llvm/llvm-project/commit/b25902736c2e330429278e1929cc5afd2201fb77.diff LOG: [NFCI] Propagate MLTAL through more concepts in prep of deferred inst. In preperation of the deferred instantation progress, this patch propagates the multi-level template argument lists further through the API to reduce the size of that patch. Added: Modified: clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaConcept.cpp clang/lib/Sema/SemaTemplate.cpp clang/lib/Sema/SemaTemplateDeduction.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 62023fe42a218..b84ad1283173d 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -7153,7 +7153,7 @@ class Sema final { /// false otherwise. bool CheckConstraintSatisfaction( const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs, - ArrayRef<TemplateArgument> TemplateArgs, + const MultiLevelTemplateArgumentList &TemplateArgLists, SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction); /// \brief Check whether the given non-dependent constraint expression is @@ -7189,9 +7189,10 @@ class Sema final { /// /// \returns true if the constrains are not satisfied or could not be checked /// for satisfaction, false if the constraints are satisfied. - bool EnsureTemplateArgumentListConstraints(TemplateDecl *Template, - ArrayRef<TemplateArgument> TemplateArgs, - SourceRange TemplateIDRange); + bool EnsureTemplateArgumentListConstraints( + TemplateDecl *Template, + const MultiLevelTemplateArgumentList &TemplateArgs, + SourceRange TemplateIDRange); /// \brief Emit diagnostics explaining why a constraint expression was deemed /// unsatisfied. diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index 239e5dc4394c3..f0ccc0710cfb4 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -199,9 +199,9 @@ calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr, } static bool calculateConstraintSatisfaction( - Sema &S, const NamedDecl *Template, ArrayRef<TemplateArgument> TemplateArgs, - SourceLocation TemplateNameLoc, MultiLevelTemplateArgumentList &MLTAL, - const Expr *ConstraintExpr, ConstraintSatisfaction &Satisfaction) { + Sema &S, const NamedDecl *Template, SourceLocation TemplateNameLoc, + const MultiLevelTemplateArgumentList &MLTAL, const Expr *ConstraintExpr, + ConstraintSatisfaction &Satisfaction) { return calculateConstraintSatisfaction( S, ConstraintExpr, Satisfaction, [&](const Expr *AtomicExpr) { EnterExpressionEvaluationContext ConstantEvaluated( @@ -268,36 +268,35 @@ static bool calculateConstraintSatisfaction( }); } -static bool CheckConstraintSatisfaction(Sema &S, const NamedDecl *Template, - ArrayRef<const Expr *> ConstraintExprs, - ArrayRef<TemplateArgument> TemplateArgs, - SourceRange TemplateIDRange, - ConstraintSatisfaction &Satisfaction) { +static bool CheckConstraintSatisfaction( + Sema &S, const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs, + const MultiLevelTemplateArgumentList &TemplateArgsLists, + SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction) { if (ConstraintExprs.empty()) { Satisfaction.IsSatisfied = true; return false; } - for (auto& Arg : TemplateArgs) - if (Arg.isInstantiationDependent()) { - // No need to check satisfaction for dependent constraint expressions. - Satisfaction.IsSatisfied = true; - return false; - } + if (TemplateArgsLists.isAnyArgInstantiationDependent()) { + // No need to check satisfaction for dependent constraint expressions. + Satisfaction.IsSatisfied = true; + return false; + } + ArrayRef<TemplateArgument> TemplateArgs = + TemplateArgsLists.getNumSubstitutedLevels() > 0 + ? TemplateArgsLists.getOutermost() + : ArrayRef<TemplateArgument> {}; Sema::InstantiatingTemplate Inst(S, TemplateIDRange.getBegin(), Sema::InstantiatingTemplate::ConstraintsCheck{}, const_cast<NamedDecl *>(Template), TemplateArgs, TemplateIDRange); if (Inst.isInvalid()) return true; - MultiLevelTemplateArgumentList MLTAL; - MLTAL.addOuterTemplateArguments(TemplateArgs); - for (const Expr *ConstraintExpr : ConstraintExprs) { - if (calculateConstraintSatisfaction(S, Template, TemplateArgs, - TemplateIDRange.getBegin(), MLTAL, - ConstraintExpr, Satisfaction)) + if (calculateConstraintSatisfaction(S, Template, TemplateIDRange.getBegin(), + TemplateArgsLists, ConstraintExpr, + Satisfaction)) return true; if (!Satisfaction.IsSatisfied) // [temp.constr.op] p2 @@ -311,28 +310,37 @@ static bool CheckConstraintSatisfaction(Sema &S, const NamedDecl *Template, bool Sema::CheckConstraintSatisfaction( const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs, - ArrayRef<TemplateArgument> TemplateArgs, SourceRange TemplateIDRange, - ConstraintSatisfaction &OutSatisfaction) { + const MultiLevelTemplateArgumentList &TemplateArgsLists, + SourceRange TemplateIDRange, ConstraintSatisfaction &OutSatisfaction) { if (ConstraintExprs.empty()) { OutSatisfaction.IsSatisfied = true; return false; } if (!Template) { return ::CheckConstraintSatisfaction(*this, nullptr, ConstraintExprs, - TemplateArgs, TemplateIDRange, + TemplateArgsLists, TemplateIDRange, OutSatisfaction); } + + // A list of the template argument list flattened in a predictible manner for + // the purposes of caching. The ConstraintSatisfaction type is in AST so it + // has no access to the MultiLevelTemplateArgumentList, so this has to happen + // here. + llvm::SmallVector<TemplateArgument, 4> FlattenedArgs; + for (ArrayRef<TemplateArgument> List : TemplateArgsLists) + FlattenedArgs.insert(FlattenedArgs.end(), List.begin(), List.end()); + llvm::FoldingSetNodeID ID; - ConstraintSatisfaction::Profile(ID, Context, Template, TemplateArgs); + ConstraintSatisfaction::Profile(ID, Context, Template, FlattenedArgs); void *InsertPos; if (auto *Cached = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos)) { OutSatisfaction = *Cached; return false; } auto Satisfaction = - std::make_unique<ConstraintSatisfaction>(Template, TemplateArgs); + std::make_unique<ConstraintSatisfaction>(Template, FlattenedArgs); if (::CheckConstraintSatisfaction(*this, Template, ConstraintExprs, - TemplateArgs, TemplateIDRange, + TemplateArgsLists, TemplateIDRange, *Satisfaction)) { return true; } @@ -379,12 +387,12 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD, } bool Sema::EnsureTemplateArgumentListConstraints( - TemplateDecl *TD, ArrayRef<TemplateArgument> TemplateArgs, + TemplateDecl *TD, const MultiLevelTemplateArgumentList &TemplateArgsLists, SourceRange TemplateIDRange) { ConstraintSatisfaction Satisfaction; llvm::SmallVector<const Expr *, 3> AssociatedConstraints; TD->getAssociatedConstraints(AssociatedConstraints); - if (CheckConstraintSatisfaction(TD, AssociatedConstraints, TemplateArgs, + if (CheckConstraintSatisfaction(TD, AssociatedConstraints, TemplateArgsLists, TemplateIDRange, Satisfaction)) return true; @@ -392,7 +400,8 @@ bool Sema::EnsureTemplateArgumentListConstraints( SmallString<128> TemplateArgString; TemplateArgString = " "; TemplateArgString += getTemplateArgumentBindingsText( - TD->getTemplateParameters(), TemplateArgs.data(), TemplateArgs.size()); + TD->getTemplateParameters(), TemplateArgsLists.getInnermost().data(), + TemplateArgsLists.getInnermost().size()); Diag(TemplateIDRange.getBegin(), diag::err_template_arg_list_constraints_not_satisfied) @@ -423,6 +432,10 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints( // PushDeclContext because we don't have a scope. Sema::ContextRAII savedContext(*this, Decl); LocalInstantiationScope Scope(*this); + MultiLevelTemplateArgumentList MLTAL; + // FIXME: This will be replaced with some logic to get all the template + // arguments when we switch to deferred template instantiation. + MLTAL.addOuterTemplateArguments(TemplateArgs); // If this is not an explicit specialization - we need to get the instantiated // version of the template arguments and add them to scope for the @@ -446,7 +459,7 @@ bool Sema::CheckInstantiatedFunctionTemplateConstraints( Record = Method->getParent(); } CXXThisScopeRAII ThisScope(*this, Record, ThisQuals, Record != nullptr); - return CheckConstraintSatisfaction(Template, TemplateAC, TemplateArgs, + return CheckConstraintSatisfaction(Template, TemplateAC, MLTAL, PointOfInstantiation, Satisfaction); } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 6f3c5d1847cd8..ec1d5421ff51b 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -4751,9 +4751,12 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS, bool AreArgsDependent = TemplateSpecializationType::anyDependentTemplateArguments(*TemplateArgs, Converted); + MultiLevelTemplateArgumentList MLTAL; + MLTAL.addOuterTemplateArguments(Converted); + LocalInstantiationScope Scope(*this); if (!AreArgsDependent && CheckConstraintSatisfaction( - NamedConcept, {NamedConcept->getConstraintExpr()}, Converted, + NamedConcept, {NamedConcept->getConstraintExpr()}, MLTAL, SourceRange(SS.isSet() ? SS.getBeginLoc() : ConceptNameInfo.getLoc(), TemplateArgs->getRAngleLoc()), Satisfaction)) @@ -5970,13 +5973,18 @@ bool Sema::CheckTemplateArgumentList( if (UpdateArgsWithConversions) TemplateArgs = std::move(NewArgs); - if (!PartialTemplateArgs && - EnsureTemplateArgumentListConstraints( - Template, Converted, SourceRange(TemplateLoc, - TemplateArgs.getRAngleLoc()))) { - if (ConstraintsNotSatisfied) - *ConstraintsNotSatisfied = true; - return true; + if (!PartialTemplateArgs) { + // FIXME: This will be changed a bit once deferred concept instantiation is + // implemented. + MultiLevelTemplateArgumentList MLTAL; + MLTAL.addOuterTemplateArguments(Converted); + if (EnsureTemplateArgumentListConstraints( + Template, MLTAL, + SourceRange(TemplateLoc, TemplateArgs.getRAngleLoc()))) { + if (ConstraintsNotSatisfied) + *ConstraintsNotSatisfied = true; + return true; + } } return false; diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 9ec33e8981983..144a240089ccb 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -2791,8 +2791,13 @@ CheckDeducedArgumentConstraints(Sema& S, TemplateDeclT *Template, TemplateDeductionInfo& Info) { llvm::SmallVector<const Expr *, 3> AssociatedConstraints; Template->getAssociatedConstraints(AssociatedConstraints); + // FIXME: This will change quite a bit once deferred concept instantiation is + // implemented. + MultiLevelTemplateArgumentList MLTAL; + MLTAL.addOuterTemplateArguments(DeducedArgs); + if (S.CheckConstraintSatisfaction(Template, AssociatedConstraints, - DeducedArgs, Info.getLocation(), + MLTAL, Info.getLocation(), Info.AssociatedConstraintsSatisfaction) || !Info.AssociatedConstraintsSatisfaction.IsSatisfied) { Info.reset(TemplateArgumentList::CreateCopy(S.Context, DeducedArgs)); @@ -4572,8 +4577,10 @@ CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type, if (S.CheckTemplateArgumentList(Concept, SourceLocation(), TemplateArgs, /*PartialTemplateArgs=*/false, Converted)) return Sema::DAR_FailedAlreadyDiagnosed; + MultiLevelTemplateArgumentList MLTAL; + MLTAL.addOuterTemplateArguments(Converted); if (S.CheckConstraintSatisfaction(Concept, {Concept->getConstraintExpr()}, - Converted, TypeLoc.getLocalSourceRange(), + MLTAL, TypeLoc.getLocalSourceRange(), Satisfaction)) return Sema::DAR_FailedAlreadyDiagnosed; if (!Satisfaction.IsSatisfied) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits