Validate a direct declarator.
(valid-dirdeclor dirdeclor fundef-params-p type table ienv) → (mv erp new-dirdeclor new-type ident return-types new-table)
The type passed as input is the one resulting from the validation of the list of declaration specifiers or the list of specifiers and qualifiers that precedes the declarator of which the direct declarator is part. This type is refined according to the direct declarator, and we return the refined type, along with the declared identifier.
The meaning of the
If the direct declarator is just an identifier, the type is not further refined by this direct declarator.
If the direct declarator is a parenthesized declarator, we recursively validate the declarator.
If the direct declarator is one of the array kinds,
we refine the type to an array type [C17:6.7.6.2/3]
derived from the input type,
and we recursively validate the enclosed direct declarator.
Then we validate the index expression (if present),
ensuring that it has integer type.
For now we do not check that, if these expressions are constant,
their values are greater than 0 [C17:6.7.6.2/1].
Currently we do not need to do anything
with type qualifiers and attributes.
The
If the direct declarator is one of the function kinds, we ensure that the input type, which is the function return type, is not a function or array type [C17:6.7.6.3/1]. We refine the input type to a function type (which in our current type system means we override it), and we validate the declarator. Then things differ between the kinds of function declarators.
In a function declarator with a parameter type list,
we push a new scope for the parameters.
If
To check whether the parameter type list in the current direct declarator represents the parameters of the current function definition, we check if the enclosed direct declarator contains function parameters. If so, this enclosed direct declarator contains the definition parameters; the parameter type list of the outer direct declarator does not correspond to the definition. To make things clearer, consider a function definition
void (*f(int x, int y))(int z) { ... }which defines a function
In any case, when the current function declarator
is the one whose parameters are for the function definition,
after validating the parameters, which pushes a new scope with them,
we return the validation table as such,
so that when we later validate the function body,
we already have the top-level scope for the body.
If instead
For the function declarator with a parameter type list,
we handle the special case of a single
A function declarator with a non-empty name list can only occur
as the parameters of a function being defined [C17:6.7.6.3/3]
Thus, we raise an error when the list is nonempty
and