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 > > > > > > > > > > > >