[clang] [WIP] Turn 'counted_by' into a type attribute and parse it into 'CountAttributedType' (PR #78000)

via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 12 16:12:58 PST 2024


github-actions[bot] wrote:

<!--LLVM CODE FORMAT COMMENT: {clang-format}-->


:warning: C/C++ code formatter, clang-format found issues in your code. :warning:

<details>
<summary>
You can test this locally with the following command:
</summary>

``````````bash
git-clang-format --diff 3bbc912d37f03d9ad3be330b81d91c2eaf6c37f2 e65a99a00faba70960e75b4b8edb5acecb675197 -- clang/include/clang/AST/ASTContext.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/AST/Type.h clang/include/clang/AST/TypeLoc.h clang/include/clang/Parse/Parser.h clang/include/clang/Sema/Sema.h clang/include/clang/Serialization/ASTRecordReader.h clang/include/clang/Serialization/ASTRecordWriter.h clang/lib/AST/ASTContext.cpp clang/lib/AST/ASTImporter.cpp clang/lib/AST/ASTStructuralEquivalence.cpp clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/Type.cpp clang/lib/AST/TypeLoc.cpp clang/lib/AST/TypePrinter.cpp clang/lib/CodeGen/CGDebugInfo.cpp clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CodeGenFunction.cpp clang/lib/Parse/ParseDecl.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaDeclAttr.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaType.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/tools/libclang/CIndex.cpp
``````````

</details>

<details>
<summary>
View the diff from clang-format here.
</summary>

``````````diff
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index f88191ef5f..65f2e67fe7 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -3055,10 +3055,8 @@ private:
                                  ParsedAttr::Form Form);
 
   void ParseBoundsAttribute(IdentifierInfo &AttrName,
-                            SourceLocation AttrNameLoc,
-                            ParsedAttributes &Attrs,
-                            IdentifierInfo *ScopeName,
-                            SourceLocation ScopeLoc,
+                            SourceLocation AttrNameLoc, ParsedAttributes &Attrs,
+                            IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
                             ParsedAttr::Form Form);
 
   void ParseTypeofSpecifier(DeclSpec &DS);
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 027afb5d70..849692079c 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -1341,7 +1341,10 @@ public:
     /// \brief Describes whether we are in an expression constext which we have
     /// to handle differently.
     enum ExpressionKind {
-      EK_Decltype, EK_TemplateArgument, EK_BoundsAttrArgument, EK_Other
+      EK_Decltype,
+      EK_TemplateArgument,
+      EK_BoundsAttrArgument,
+      EK_Other
     } ExprContext;
 
     // A context can be nested in both a discarded statement context and
@@ -1437,11 +1440,11 @@ public:
   getCurrentMangleNumberContext(const DeclContext *DC);
 
   bool isBoundsAttrArgument() const {
-    return ExprEvalContexts.back().ExprContext == 
-        ExpressionEvaluationContextRecord::ExpressionKind::EK_BoundsAttrArgument; 
+    return ExprEvalContexts.back().ExprContext ==
+           ExpressionEvaluationContextRecord::ExpressionKind::
+               EK_BoundsAttrArgument;
   }
 
-
   /// SpecialMemberOverloadResult - The overloading result for a special member
   /// function.
   ///
@@ -2617,8 +2620,9 @@ public:
   QualType BuiltinChangeSignedness(QualType BaseType, UTTKind UKind,
                                    SourceLocation Loc);
 
-  QualType BuildCountAttributedArrayType(QualType WrappedTy, Expr *CountExpr,
-                              const llvm::SmallVector<TypeCoupledDeclRefInfo, 1> &Decls);
+  QualType BuildCountAttributedArrayType(
+      QualType WrappedTy, Expr *CountExpr,
+      const llvm::SmallVector<TypeCoupledDeclRefInfo, 1> &Decls);
 
   //===--------------------------------------------------------------------===//
   // Symbol table / Decl tracking callbacks: SemaDecl.cpp.
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 1bbccfd47c..83a1e09ebd 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -630,8 +630,8 @@ void Parser::ParseGNUAttributeArgs(
                               ScopeLoc, Form);
     return;
   } else if (AttrKind == ParsedAttr::AT_CountedBy) {
-    ParseBoundsAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName,
-                         ScopeLoc, Form);
+    ParseBoundsAttribute(*AttrName, AttrNameLoc, Attrs, ScopeName, ScopeLoc,
+                         Form);
     return;
   }
 
@@ -3167,11 +3167,14 @@ void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,
 
 /// Bounds attributes (e.g., counted_by):
 ///   AttrName '(' expression ')'
-void Parser::ParseBoundsAttribute(IdentifierInfo &AttrName, SourceLocation AttrNameLoc, ParsedAttributes &Attrs, IdentifierInfo *ScopeName,
-                                       SourceLocation ScopeLoc,
-                                       ParsedAttr::Form Form) {
+void Parser::ParseBoundsAttribute(IdentifierInfo &AttrName,
+                                  SourceLocation AttrNameLoc,
+                                  ParsedAttributes &Attrs,
+                                  IdentifierInfo *ScopeName,
+                                  SourceLocation ScopeLoc,
+                                  ParsedAttr::Form Form) {
   assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
- 
+
   BalancedDelimiterTracker Parens(*this, tok::l_paren);
   Parens.consumeOpen();
 
@@ -3207,8 +3210,7 @@ void Parser::ParseBoundsAttribute(IdentifierInfo &AttrName, SourceLocation AttrN
       Ctx.getSizeType(), SourceLocation()));
 
   Attrs.addNew(&AttrName, SourceRange(AttrNameLoc, Parens.getCloseLocation()),
-               ScopeName, ScopeLoc, ArgExprs.data(),
-               ArgExprs.size(), Form);
+               ScopeName, ScopeLoc, ArgExprs.data(), ArgExprs.size(), Form);
 }
 
 ExprResult Parser::ParseExtIntegerArgument() {
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index eb4cd97350..d87fb83056 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -8460,7 +8460,6 @@ static void handleZeroCallUsedRegsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   D->addAttr(ZeroCallUsedRegsAttr::Create(S.Context, Kind, AL));
 }
 
-
 static const RecordDecl *GetEnclosingNamedOrTopAnonRecord(const FieldDecl *FD) {
   const auto *RD = FD->getParent();
   while (RD && RD->isAnonymousStructOrUnion()) {
@@ -8472,17 +8471,18 @@ static const RecordDecl *GetEnclosingNamedOrTopAnonRecord(const FieldDecl *FD) {
   return RD;
 }
 
-static bool CheckCountExpr(Sema &S, FieldDecl *FD, Expr *E,
-                           llvm::SmallVector<TypeCoupledDeclRefInfo, 1> &Decls) {
+static bool
+CheckCountExpr(Sema &S, FieldDecl *FD, Expr *E,
+               llvm::SmallVector<TypeCoupledDeclRefInfo, 1> &Decls) {
   if (FD->getParent()->isUnion()) {
-    S.Diag(FD->getBeginLoc(), diag::err_counted_by_attr_in_union) << FD->getSourceRange();
+    S.Diag(FD->getBeginLoc(), diag::err_counted_by_attr_in_union)
+        << FD->getSourceRange();
     return true;
   }
 
   if (!E->getType()->isIntegerType() || E->getType()->isBooleanType()) {
-    S.Diag(E->getBeginLoc(),
-           diag::err_counted_by_attr_argument_not_integer)
-           << E->getSourceRange();
+    S.Diag(E->getBeginLoc(), diag::err_counted_by_attr_argument_not_integer)
+        << E->getSourceRange();
     return true;
   }
 
@@ -8493,16 +8493,17 @@ static bool CheckCountExpr(Sema &S, FieldDecl *FD, Expr *E,
                                        StrictFlexArraysLevel, true)) {
     // The "counted_by" attribute must be on a flexible array member.
     SourceRange SR = FD->getLocation();
-    S.Diag(SR.getBegin(), diag::err_counted_by_attr_not_on_flexible_array_member)
+    S.Diag(SR.getBegin(),
+           diag::err_counted_by_attr_not_on_flexible_array_member)
         << SR;
     return true;
   }
 
-  auto *DRE = dyn_cast<DeclRefExpr>(E); 
+  auto *DRE = dyn_cast<DeclRefExpr>(E);
   if (!DRE) {
     S.Diag(E->getBeginLoc(),
            diag::err_counted_by_attr_only_support_simple_decl_reference)
-           << E->getSourceRange();
+        << E->getSourceRange();
     return true;
   }
 
@@ -8513,32 +8514,35 @@ static bool CheckCountExpr(Sema &S, FieldDecl *FD, Expr *E,
   }
   if (!CountFD) {
     S.Diag(E->getBeginLoc(), diag::err_counted_by_must_be_in_structure)
-      << CountDecl << E->getSourceRange();
-    
-    S.Diag(CountDecl->getBeginLoc(), diag::note_flexible_array_counted_by_attr_field)
-            << CountDecl << CountDecl->getSourceRange();
+        << CountDecl << E->getSourceRange();
+
+    S.Diag(CountDecl->getBeginLoc(),
+           diag::note_flexible_array_counted_by_attr_field)
+        << CountDecl << CountDecl->getSourceRange();
     return true;
   }
 
   if (FD->getParent() != CountFD->getParent()) {
     if (CountFD->getParent()->isUnion()) {
       S.Diag(CountFD->getBeginLoc(), diag::err_counted_by_attr_refer_to_union)
-            << CountFD->getSourceRange();
+          << CountFD->getSourceRange();
       return true;
     }
-    // FIXME: whether CountRD is an anonymous struct is not determined at this point.
-    // check later if `FD` and `CountFD` are in the same enclosing named struct.
+    // FIXME: whether CountRD is an anonymous struct is not determined at this
+    // point. check later if `FD` and `CountFD` are in the same enclosing named
+    // struct.
     auto *RD = GetEnclosingNamedOrTopAnonRecord(FD);
     auto *CountRD = GetEnclosingNamedOrTopAnonRecord(CountFD);
 
     if (RD != CountRD) {
-      S.Diag(CountFD->getBeginLoc(), diag::err_flexible_array_count_not_in_same_struct)
+      S.Diag(CountFD->getBeginLoc(),
+             diag::err_flexible_array_count_not_in_same_struct)
           << CountFD << CountFD->getSourceRange();
       return true;
     }
   }
 
-  Decls.push_back(TypeCoupledDeclRefInfo(FD, /*IsDref*/false));
+  Decls.push_back(TypeCoupledDeclRefInfo(FD, /*IsDref*/ false));
   return false;
 }
 
@@ -8554,7 +8558,8 @@ static void handleCountedByAttrField(Sema &S, Decl *D, const ParsedAttr &AL) {
   if (CheckCountExpr(S, FD, CountExpr, Decls))
     return;
 
-  QualType CAT = S.BuildCountAttributedArrayType(FD->getType(), CountExpr, Decls);
+  QualType CAT =
+      S.BuildCountAttributedArrayType(FD->getType(), CountExpr, Decls);
   FD->setType(CAT);
 }
 
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index fac27fd625..b20828e6a9 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2910,7 +2910,8 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS,
   // to get this right here so that we don't end up making a
   // spuriously dependent expression if we're inside a dependent
   // instance method.
-  if (getLangOpts().CPlusPlus && !R.empty() && (*R.begin())->isCXXClassMember()) {
+  if (getLangOpts().CPlusPlus && !R.empty() &&
+      (*R.begin())->isCXXClassMember()) {
     bool MightBeImplicitMember;
     if (!IsAddressOfOperand)
       MightBeImplicitMember = true;
@@ -3566,8 +3567,8 @@ ExprResult Sema::BuildDeclarationNameExpr(
   case Decl::Field:
   case Decl::IndirectField:
   case Decl::ObjCIvar:
-    assert((getLangOpts().CPlusPlus || isBoundsAttrArgument())
-           && "building reference to field in C?");
+    assert((getLangOpts().CPlusPlus || isBoundsAttrArgument()) &&
+           "building reference to field in C?");
 
     // These can't have reference type in well-formed programs, but
     // for internal consistency we do this anyway.
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index e613f9d2f9..87ff9f79be 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -9606,14 +9606,15 @@ QualType Sema::BuildTypeofExprType(Expr *E, TypeOfKind Kind) {
   return Context.getTypeOfExprType(E, Kind);
 }
 
-QualType Sema::BuildCountAttributedArrayType(QualType WrappedTy, Expr *CountExpr,
-                                             const llvm::SmallVector<TypeCoupledDeclRefInfo, 1> &Decls) {
+QualType Sema::BuildCountAttributedArrayType(
+    QualType WrappedTy, Expr *CountExpr,
+    const llvm::SmallVector<TypeCoupledDeclRefInfo, 1> &Decls) {
   assert(WrappedTy->isIncompleteArrayType());
 
   /// When the resulting expression is invalid, we still create the AST using
   /// the original count expression for the sake of AST dump.
   return Context.getCountAttributedType(
-      WrappedTy, CountExpr, /*CountInBytes*/false, /*OrNull*/false,
+      WrappedTy, CountExpr, /*CountInBytes*/ false, /*OrNull*/ false,
       llvm::ArrayRef(Decls.begin(), Decls.end()));
 }
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/78000


More information about the cfe-commits mailing list