Right, that is a great insight. In the implementation, we’ve added a name lookup for struct members referred to by attributes within the struct’s scope. The name lookup is performed after parsing the struct body, ensuring the field declarations of the same struct are always seen first (not a global declaration of the same name). Another challenge was creating count expressions from struct fields (e.g., __counted_by(n+1)
in the example below) without instantiation and without the notion of this
in C. This means that the expressions won’t have a base required to create MemberExpr
. Therefore, we had to create a DeclRef
directly referring to the struct field to represent the expression passed to the bounds annotations, which isn’t something allowed in C. I envision this as an extended behavior limited to expressions, passed to attributes only. It should be generally beneficial for other attributes that require more expressiveness from C, such as the guarded_by
attribute you mentioned.
struct S {
int n;
// Allowed: Counted by a member variable
int *__counted_by(n+1) ptr;
};
Thank you! We will wait until we will have better understanding on the direction.
Yes, this makes a lot of sense. We will keep the late parsing logic in a separate flag.
This will only involve id expressions. Member accesses will not be allowed.