[clang] [Clang] Add __builtin_get_counted_by builtin (PR #102549)

Bill Wendling via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 14 14:04:40 PDT 2024


================
@@ -222,6 +222,49 @@ bool Expr::isFlexibleArrayMemberLike(
                                          IgnoreTemplateOrMacroSubstitution);
 }
 
+namespace {
+
+/// MemberExprVisitor - Find the MemberExpr through all of the casts, array
+/// subscripts, and unary ops. This intentionally avoids all of them because
+/// we're interested only in the MemberExpr to check if it's a flexible array
+/// member.
+class MemberExprVisitor
+    : public ConstStmtVisitor<MemberExprVisitor, const Expr *> {
+public:
+  //===--------------------------------------------------------------------===//
+  //                            Visitor Methods
+  //===--------------------------------------------------------------------===//
+
+  const Expr *Visit(const Expr *E) {
+    return ConstStmtVisitor<MemberExprVisitor, const Expr *>::Visit(E);
+  }
+  const Expr *VisitStmt(const Stmt *S) { return nullptr; }
+
+  const Expr *VisitMemberExpr(const MemberExpr *E) { return E; }
+
+  const Expr *VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
+    return Visit(E->getBase());
+  }
+  const Expr *VisitCastExpr(const CastExpr *E) {
+    return Visit(E->getSubExpr());
+  }
+  const Expr *VisitParenExpr(const ParenExpr *E) {
+    return Visit(E->getSubExpr());
+  }
+  const Expr *VisitUnaryAddrOf(const UnaryOperator *E) {
+    return Visit(E->getSubExpr());
+  }
+  const Expr *VisitUnaryDeref(const UnaryOperator *E) {
+    return Visit(E->getSubExpr());
+  }
----------------
bwendling wrote:

I worry about making assumptions of uses within C. :-) I'm sure that 99.999% of the time, either `foo->x` or `&foo->x[0]` will be the argument. But in the marginal case where it's "hidden" by casts (et al) it worries me that the behavior becomes unknowable. Maybe I'm being too paranoid? How do other places in the front-end handle looking down to the underlying object? Is it mainly through the `Ignore.*` methods?

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


More information about the cfe-commits mailing list