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

Reply via email to