Am Montag, dem 28.07.2025 um 16:01 -0700 schrieb Bill Wendling:
> On Mon, Jul 28, 2025 at 2:39 PM Martin Uecker <ma.uec...@gmail.com> wrote:
> > Yes, forwards declarations are this simplest solution.
> > 
> Forward declarations work until you get something complex. For
> example, if we want to support substructure fields in the attribute,
> you'd have to replicate the whole substructure's declaration in the
> forward decl. That becomes unwieldy when the substructure is very big:
> 
> struct foo {
>     char *buf __counted_by_expr(struct bar { ... } sub; sub.a.b);
>     struct bar {
>         int x, y;
>         struct baz {
>             int b;
>             /* 20 other elements */
>         } a;
>         unsigned b1 : 1;
>         unsigned b2 : 4;
>         unsigned : 8;
>         unsigned b3 : 2;
>         /* and on and on... */
>     } sub;
> };

You could write it like this:

struct bar {
        int x, y;
        struct baz {
            int b;
            /* 20 other elements */
        } a;
        unsigned b1 : 1;
        unsigned b2 : 4;
        unsigned : 8;
        unsigned b3 : 2;
        /* and on and on... */
};

struct foo {
    char *buf __counted_by_expr(struct bar sub; sub.a.b);
    struct bar sub;
};

Martin


> 
> However, with delayed parsing, we wouldn't have to worry about forward
> declaring all of 'struct bar'

> 
> -bw
> 
> > Another idea I mentioned before is to let __self.N have type
> > int, and then emit an error later if it has  a type that
> > would change the type / meaning of the immediate
> > parent expression.
> > 
> > This would allow all of the following:
> > 
> > struct foo {
> >         char * __counted_by_expr(__self.N) buf;
> >         int N;
> > };
> > struct foo {
> >         char * __counted_by_expr(__self.N + 1L) buf;
> >         long N;
> > };
> > struct foo {
> >         char * __counted_by_expr(__self.N * 2) buf;
> >         int N;
> > };
> > struct foo {
> >         char * __counted_by_expr(__self.N + 2) buf;
> >         char N;
> > };
> > struct foo {
> >         char * __counted_by_expr(__self.N + .M) buf;
> >         int N; int M;
> > };
> > struct foo {
> >         char * __counted_by_expr((int)__self.N) buf;
> >         double N;
> > };
> > struct foo {
> >         char * __counted_by_expr(3 * sizeof(__self.buf2)) buf;
> >         char buf2[5];
> > };
> > struct foo {
> >         char * __counted_by_expr(((struct bar *)__self.x)->z) buf;
> >         struct bar *x;
> > };
> > 
> > 
> > It would *not* allow:
> > 
> > struct foo {
> >         char * __counted_by_expr(__self.N + 1) buf;
> >         long N;
> > };
> > struct foo {
> >         char * __counted_by_expr(__self.x->z) buf;
> >         struct foo *x;
> > };
> > 
> > 
> > But in this case you would get an explicit error:
> > 
> > xyz:13.4: Type of `__self.N' needs to be known.  Did you forget to
> > add a cast `(long)__self.N'?
> > 
> > 
> > 
> > Martin
> > 
> > 
> > 
> > 
> > 
> > 

Reply via email to