llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Vlad Serebrennikov (Endilll) <details> <summary>Changes</summary> This patch moves `Sema` functions that handle C++20 concepts into the new `SemaConcept` class. This continues previous efforts to split `Sema` up. Additional context can be found in #<!-- -->84184. This patch has 3 commits: the first one covers what already was in `SemaConcept.cpp`, the second one moves quite a lot of concepts-related functions from `Sema` into `SemaConcept`. The third one, as usual, contains formatting changes. --- Patch is 177.69 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/92672.diff 21 Files Affected: - (modified) clang/include/clang/Sema/Sema.h (+26-381) - (modified) clang/include/clang/Sema/SemaConcept.h (+388-2) - (modified) clang/lib/Parse/ParseDecl.cpp (+4-2) - (modified) clang/lib/Parse/ParseDeclCXX.cpp (+3-3) - (modified) clang/lib/Parse/ParseExpr.cpp (+5-4) - (modified) clang/lib/Parse/ParseExprCXX.cpp (+16-14) - (modified) clang/lib/Parse/ParseTemplate.cpp (+13-10) - (modified) clang/lib/Sema/Sema.cpp (+3-9) - (modified) clang/lib/Sema/SemaChecking.cpp (-6) - (modified) clang/lib/Sema/SemaConcept.cpp (+809-171) - (modified) clang/lib/Sema/SemaDecl.cpp (+7-6) - (modified) clang/lib/Sema/SemaDeclCXX.cpp (+4-36) - (modified) clang/lib/Sema/SemaExpr.cpp (+4-3) - (modified) clang/lib/Sema/SemaExprCXX.cpp (+1-227) - (modified) clang/lib/Sema/SemaOverload.cpp (+25-23) - (modified) clang/lib/Sema/SemaTemplate.cpp (+31-392) - (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+17-44) - (modified) clang/lib/Sema/SemaTemplateInstantiate.cpp (+41-3) - (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+4-2) - (modified) clang/lib/Sema/SemaType.cpp (+4-3) - (modified) clang/lib/Sema/TreeTransform.h (+12-13) ``````````diff diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index d4d4a82525a02..be4aebf1d04e2 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -168,6 +168,7 @@ class PseudoDestructorTypeStorage; class PseudoObjectExpr; class QualType; class SemaCodeCompletion; +class SemaConcept; class SemaCUDA; class SemaHLSL; class SemaObjC; @@ -181,6 +182,7 @@ class SwitchStmt; class TemplateArgument; class TemplateArgumentList; class TemplateArgumentLoc; +class TemplateCompareNewDeclInfo; class TemplateDecl; class TemplateInstantiationCallback; class TemplateParameterList; @@ -989,6 +991,11 @@ class Sema final : public SemaBase { return *CodeCompletionPtr; } + SemaConcept &Concept() { + assert(ConceptPtr); + return *ConceptPtr; + } + SemaCUDA &CUDA() { assert(CUDAPtr); return *CUDAPtr; @@ -1050,6 +1057,7 @@ class Sema final : public SemaBase { mutable IdentifierInfo *Ident_super; std::unique_ptr<SemaCodeCompletion> CodeCompletionPtr; + std::unique_ptr<SemaConcept> ConceptPtr; std::unique_ptr<SemaCUDA> CUDAPtr; std::unique_ptr<SemaHLSL> HLSLPtr; std::unique_ptr<SemaObjC> ObjCPtr; @@ -2028,8 +2036,6 @@ class Sema final : public SemaBase { void CheckTCBEnforcement(const SourceLocation CallExprLoc, const NamedDecl *Callee); - void CheckConstrainedAuto(const AutoType *AutoT, SourceLocation Loc); - private: void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, const ArraySubscriptExpr *ASE = nullptr, @@ -4727,9 +4733,6 @@ class Sema final : public SemaBase { void SetFunctionBodyKind(Decl *D, SourceLocation Loc, FnBodyKind BodyKind, StringLiteral *DeletedMessage = nullptr); - void ActOnStartTrailingRequiresClause(Scope *S, Declarator &D); - ExprResult ActOnFinishTrailingRequiresClause(ExprResult ConstraintExpr); - ExprResult ActOnRequiresClause(ExprResult ConstraintExpr); NamedDecl * ActOnDecompositionDeclarator(Scope *S, Declarator &D, @@ -6811,45 +6814,6 @@ class Sema final : public SemaBase { bool IsIfExists, CXXScopeSpec &SS, UnqualifiedId &Name); - RequiresExprBodyDecl * - ActOnStartRequiresExpr(SourceLocation RequiresKWLoc, - ArrayRef<ParmVarDecl *> LocalParameters, - Scope *BodyScope); - void ActOnFinishRequiresExpr(); - concepts::Requirement *ActOnSimpleRequirement(Expr *E); - concepts::Requirement *ActOnTypeRequirement(SourceLocation TypenameKWLoc, - CXXScopeSpec &SS, - SourceLocation NameLoc, - const IdentifierInfo *TypeName, - TemplateIdAnnotation *TemplateId); - concepts::Requirement *ActOnCompoundRequirement(Expr *E, - SourceLocation NoexceptLoc); - concepts::Requirement *ActOnCompoundRequirement( - Expr *E, SourceLocation NoexceptLoc, CXXScopeSpec &SS, - TemplateIdAnnotation *TypeConstraint, unsigned Depth); - concepts::Requirement *ActOnNestedRequirement(Expr *Constraint); - concepts::ExprRequirement *BuildExprRequirement( - Expr *E, bool IsSatisfied, SourceLocation NoexceptLoc, - concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement); - concepts::ExprRequirement *BuildExprRequirement( - concepts::Requirement::SubstitutionDiagnostic *ExprSubstDiag, - bool IsSatisfied, SourceLocation NoexceptLoc, - concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement); - concepts::TypeRequirement *BuildTypeRequirement(TypeSourceInfo *Type); - concepts::TypeRequirement *BuildTypeRequirement( - concepts::Requirement::SubstitutionDiagnostic *SubstDiag); - concepts::NestedRequirement *BuildNestedRequirement(Expr *E); - concepts::NestedRequirement * - BuildNestedRequirement(StringRef InvalidConstraintEntity, - const ASTConstraintSatisfaction &Satisfaction); - ExprResult ActOnRequiresExpr(SourceLocation RequiresKWLoc, - RequiresExprBodyDecl *Body, - SourceLocation LParenLoc, - ArrayRef<ParmVarDecl *> LocalParameters, - SourceLocation RParenLoc, - ArrayRef<concepts::Requirement *> Requirements, - SourceLocation ClosingBraceLoc); - private: ExprResult BuiltinOperatorNewDeleteOverloaded(ExprResult TheCallResult, bool IsDelete); @@ -8847,30 +8811,6 @@ class Sema final : public SemaBase { unsigned Position, SourceLocation EqualLoc, ParsedType DefaultArg, bool HasTypeConstraint); - bool CheckTypeConstraint(TemplateIdAnnotation *TypeConstraint); - - bool ActOnTypeConstraint(const CXXScopeSpec &SS, - TemplateIdAnnotation *TypeConstraint, - TemplateTypeParmDecl *ConstrainedParameter, - SourceLocation EllipsisLoc); - bool BuildTypeConstraint(const CXXScopeSpec &SS, - TemplateIdAnnotation *TypeConstraint, - TemplateTypeParmDecl *ConstrainedParameter, - SourceLocation EllipsisLoc, - bool AllowUnexpandedPack); - - bool AttachTypeConstraint(NestedNameSpecifierLoc NS, - DeclarationNameInfo NameInfo, - ConceptDecl *NamedConcept, NamedDecl *FoundDecl, - const TemplateArgumentListInfo *TemplateArgs, - TemplateTypeParmDecl *ConstrainedParameter, - SourceLocation EllipsisLoc); - - bool AttachTypeConstraint(AutoTypeLoc TL, - NonTypeTemplateParmDecl *NewConstrainedParm, - NonTypeTemplateParmDecl *OrigConstrainedParm, - SourceLocation EllipsisLoc); - bool RequireStructuralType(QualType T, SourceLocation Loc); QualType CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI, @@ -8974,12 +8914,6 @@ class Sema final : public SemaBase { SourceLocation TemplateLoc, const TemplateArgumentListInfo *TemplateArgs); - ExprResult - CheckConceptTemplateId(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, - const DeclarationNameInfo &ConceptNameInfo, - NamedDecl *FoundDecl, ConceptDecl *NamedConcept, - const TemplateArgumentListInfo *TemplateArgs); - void diagnoseMissingTemplateArguments(TemplateName Name, SourceLocation Loc); ExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS, @@ -9198,46 +9132,6 @@ class Sema final : public SemaBase { TPL_TemplateParamsEquivalent, }; - // A struct to represent the 'new' declaration, which is either itself just - // the named decl, or the important information we need about it in order to - // do constraint comparisons. - class TemplateCompareNewDeclInfo { - const NamedDecl *ND = nullptr; - const DeclContext *DC = nullptr; - const DeclContext *LexicalDC = nullptr; - SourceLocation Loc; - - public: - TemplateCompareNewDeclInfo(const NamedDecl *ND) : ND(ND) {} - TemplateCompareNewDeclInfo(const DeclContext *DeclCtx, - const DeclContext *LexicalDeclCtx, - SourceLocation Loc) - - : DC(DeclCtx), LexicalDC(LexicalDeclCtx), Loc(Loc) { - assert(DC && LexicalDC && - "Constructor only for cases where we have the information to put " - "in here"); - } - - // If this was constructed with no information, we cannot do substitution - // for constraint comparison, so make sure we can check that. - bool isInvalid() const { return !ND && !DC; } - - const NamedDecl *getDecl() const { return ND; } - - bool ContainsDecl(const NamedDecl *ND) const { return this->ND == ND; } - - const DeclContext *getLexicalDeclContext() const { - return ND ? ND->getLexicalDeclContext() : LexicalDC; - } - - const DeclContext *getDeclContext() const { - return ND ? ND->getDeclContext() : DC; - } - - SourceLocation getLocation() const { return ND ? ND->getLocation() : Loc; } - }; - bool TemplateParameterListsAreEqual( const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New, const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain, @@ -9361,15 +9255,6 @@ class Sema final : public SemaBase { void CheckDeductionGuideTemplate(FunctionTemplateDecl *TD); - Decl *ActOnConceptDefinition(Scope *S, - MultiTemplateParamsArg TemplateParameterLists, - const IdentifierInfo *Name, - SourceLocation NameLoc, Expr *ConstraintExpr, - const ParsedAttributesView &Attrs); - - void CheckConceptRedefinition(ConceptDecl *NewDecl, LookupResult &Previous, - bool &AddToScope); - TypeResult ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK, const CXXScopeSpec &SS, const IdentifierInfo *Name, @@ -9386,6 +9271,9 @@ class Sema final : public SemaBase { void checkSpecializationVisibility(SourceLocation Loc, NamedDecl *Spec); void checkSpecializationReachability(SourceLocation Loc, NamedDecl *Spec); + TemplateArgumentListInfo + makeTemplateArgumentListInfo(TemplateIdAnnotation &TemplateId); + ///@} // @@ -9653,9 +9541,6 @@ class Sema final : public SemaBase { const PartialDiagnostic &CandidateDiag, bool Complain = true, QualType TargetType = QualType()); - FunctionDecl *getMoreConstrainedFunction(FunctionDecl *FD1, - FunctionDecl *FD2); - ///@} // @@ -10402,6 +10287,14 @@ class Sema final : public SemaBase { return CodeSynthesisContexts.size() > NonInstantiationEntries; } +private: + /// Introduce the instantiated captures of the lambda into the local + /// instantiation scope. + bool addInstantiatedCapturesToScope( + FunctionDecl *Function, const FunctionDecl *PatternDecl, + LocalInstantiationScope &Scope, + const MultiLevelTemplateArgumentList &TemplateArgs); + ///@} // @@ -10638,12 +10531,6 @@ class Sema final : public SemaBase { const DeclContext *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs); -private: - /// Introduce the instantiated local variables into the local - /// instantiation scope. - void addInstantiatedLocalVarsToScope(FunctionDecl *Function, - const FunctionDecl *PatternDecl, - LocalInstantiationScope &Scope); /// Introduce the instantiated function parameters into the local /// instantiation scope, and set the parameter names to those used /// in the template. @@ -10652,6 +10539,13 @@ class Sema final : public SemaBase { LocalInstantiationScope &Scope, const MultiLevelTemplateArgumentList &TemplateArgs); +private: + /// Introduce the instantiated local variables into the local + /// instantiation scope. + void addInstantiatedLocalVarsToScope(FunctionDecl *Function, + const FunctionDecl *PatternDecl, + LocalInstantiationScope &Scope); + int ParsingClassDepth = 0; class SavePendingParsedClassStateRAII { @@ -11092,255 +10986,6 @@ class Sema final : public SemaBase { // // - /// \name Constraints and Concepts - /// Implementations are in SemaConcept.cpp - ///@{ - -public: - void PushSatisfactionStackEntry(const NamedDecl *D, - const llvm::FoldingSetNodeID &ID) { - const NamedDecl *Can = cast<NamedDecl>(D->getCanonicalDecl()); - SatisfactionStack.emplace_back(Can, ID); - } - - void PopSatisfactionStackEntry() { SatisfactionStack.pop_back(); } - - bool SatisfactionStackContains(const NamedDecl *D, - const llvm::FoldingSetNodeID &ID) const { - const NamedDecl *Can = cast<NamedDecl>(D->getCanonicalDecl()); - return llvm::find(SatisfactionStack, SatisfactionStackEntryTy{Can, ID}) != - SatisfactionStack.end(); - } - - using SatisfactionStackEntryTy = - std::pair<const NamedDecl *, llvm::FoldingSetNodeID>; - - // Resets the current SatisfactionStack for cases where we are instantiating - // constraints as a 'side effect' of normal instantiation in a way that is not - // indicative of recursive definition. - class SatisfactionStackResetRAII { - llvm::SmallVector<SatisfactionStackEntryTy, 10> BackupSatisfactionStack; - Sema &SemaRef; - - public: - SatisfactionStackResetRAII(Sema &S) : SemaRef(S) { - SemaRef.SwapSatisfactionStack(BackupSatisfactionStack); - } - - ~SatisfactionStackResetRAII() { - SemaRef.SwapSatisfactionStack(BackupSatisfactionStack); - } - }; - - void SwapSatisfactionStack( - llvm::SmallVectorImpl<SatisfactionStackEntryTy> &NewSS) { - SatisfactionStack.swap(NewSS); - } - - /// Check whether the given expression is a valid constraint expression. - /// A diagnostic is emitted if it is not, false is returned, and - /// PossibleNonPrimary will be set to true if the failure might be due to a - /// non-primary expression being used as an atomic constraint. - bool CheckConstraintExpression(const Expr *CE, Token NextToken = Token(), - bool *PossibleNonPrimary = nullptr, - bool IsTrailingRequiresClause = false); - - /// \brief Check whether the given list of constraint expressions are - /// satisfied (as if in a 'conjunction') given template arguments. - /// \param Template the template-like entity that triggered the constraints - /// check (either a concept or a constrained entity). - /// \param ConstraintExprs a list of constraint expressions, treated as if - /// they were 'AND'ed together. - /// \param TemplateArgLists the list of template arguments to substitute into - /// the constraint expression. - /// \param TemplateIDRange The source range of the template id that - /// caused the constraints check. - /// \param Satisfaction if true is returned, will contain details of the - /// satisfaction, with enough information to diagnose an unsatisfied - /// expression. - /// \returns true if an error occurred and satisfaction could not be checked, - /// false otherwise. - bool CheckConstraintSatisfaction( - const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs, - const MultiLevelTemplateArgumentList &TemplateArgLists, - SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction) { - llvm::SmallVector<Expr *, 4> Converted; - return CheckConstraintSatisfaction(Template, ConstraintExprs, Converted, - TemplateArgLists, TemplateIDRange, - Satisfaction); - } - - /// \brief Check whether the given list of constraint expressions are - /// satisfied (as if in a 'conjunction') given template arguments. - /// Additionally, takes an empty list of Expressions which is populated with - /// the instantiated versions of the ConstraintExprs. - /// \param Template the template-like entity that triggered the constraints - /// check (either a concept or a constrained entity). - /// \param ConstraintExprs a list of constraint expressions, treated as if - /// they were 'AND'ed together. - /// \param ConvertedConstraints a out parameter that will get populated with - /// the instantiated version of the ConstraintExprs if we successfully checked - /// satisfaction. - /// \param TemplateArgList the multi-level list of template arguments to - /// substitute into the constraint expression. This should be relative to the - /// top-level (hence multi-level), since we need to instantiate fully at the - /// time of checking. - /// \param TemplateIDRange The source range of the template id that - /// caused the constraints check. - /// \param Satisfaction if true is returned, will contain details of the - /// satisfaction, with enough information to diagnose an unsatisfied - /// expression. - /// \returns true if an error occurred and satisfaction could not be checked, - /// false otherwise. - bool CheckConstraintSatisfaction( - const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs, - llvm::SmallVectorImpl<Expr *> &ConvertedConstraints, - const MultiLevelTemplateArgumentList &TemplateArgList, - SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction); - - /// \brief Check whether the given non-dependent constraint expression is - /// satisfied. Returns false and updates Satisfaction with the satisfaction - /// verdict if successful, emits a diagnostic and returns true if an error - /// occurred and satisfaction could not be determined. - /// - /// \returns true if an error occurred, false otherwise. - bool CheckConstraintSatisfaction(const Expr *ConstraintExpr, - ConstraintSatisfaction &Satisfaction); - - /// Check whether the given function decl's trailing requires clause is - /// satisfied, if any. Returns false and updates Satisfaction with the - /// satisfaction verdict if successful, emits a diagnostic and returns true if - /// an error occurred and satisfaction could not be determined. - /// - /// \returns true if an error occurred, false otherwise. - bool CheckFunctionConstraints(const FunctionDecl *FD, - ConstraintSatisfaction &Satisfaction, - SourceLocation UsageLoc = SourceLocation(), - bool ForOverloadResolution = false); - - // Calculates whether two constraint expressions are equal irrespective of a - // difference in 'depth'. This takes a pair of optional 'NamedDecl's 'Old' and - // 'New', which are the "source" of the constraint, since this is necessary - // for figuring out the relative 'depth' of the constraint. The depth of the - // 'primary template' and the 'instantiated from' templates aren't necessarily - // the same, such as a case when one is a 'friend' defined in a class. - bool AreConstraintExpressionsEqual(const NamedDecl *Old, - const Expr *OldConstr, - const TemplateCompareNewDeclInfo &New, - const Expr *NewConstr); - - // Calculates whether the friend function depends on an enclosing template for - // the purposes of [temp.friend] p9. - bool FriendConstraintsDependOnEnclosingTemplate(const FunctionDecl *FD); - - /// \brief Ensure that the given template arguments satisfy the constraints - /// associated with the given template, emitting a diagnostic if they do not. - /// - /// \param Template The template to which the template arguments are being - /// provided. - /// - /// \param TemplateArgs The converted, canonicalized template arguments. - /// - /// \param TemplateIDRange The source range of the template id that - /// caused the constraints check. - /// - /// \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, - const MultiLevelTemplateArgumentList &TemplateArgs, - SourceRange TemplateIDRange); - - bool CheckInstantiatedFunctionTemplateConstraints( - SourceLocation PointOfInstantiation, FunctionDecl *Decl, - ArrayRef<TemplateArgument> TemplateArgs, - ConstraintSatisfaction &Satisfaction); - - /// \brief Emit diagnostics explaining why a constraint expression was deemed - /// unsatisfied. - /// \param First whether this is the... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/92672 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits