Dimb-amb-declor/absdeclor
Disambiguate an ambiguous declarator or abstract declarator.
- Signature
(dimb-amb-declor/absdeclor declor/absdeclor table)
→
(mv erp declor-or-absdeclor ident? new-table)
- Arguments
- declor/absdeclor — Guard (amb-declor/absdeclor-p declor/absdeclor).
- table — Guard (dimb-tablep table).
- Returns
- declor-or-absdeclor — Type (declor/absdeclor-p declor-or-absdeclor).
- ident? — Type (ident-optionp ident?).
- new-table — Type (dimb-tablep new-table).
An ambiguous declarator or abstract declarator is represented as
a pair of a declarator and an abstract declarator
(with the same concrete syntax appearance).
We attempt to disambiguate
both the declarator and the abstract declarator,
independently from each other.
If both fail, the code is invalid.
If one of them succeeds while the other fails,
we have a disambiguation.
There are cases in which both can succeed,
for instance in void f(int(x));
the (x) could be a parenthesized declarator for identifier x,
but if a typedef for x is in scope,
it could be also an abstract function declarator,
where x is the type of the (inner) parameter.
[C:6.7.6.3/11] says that in this case
the typedef interpretation takes priority.
Thus, in general,
if both attempted disambiguations
(as declarator and as abstract declarator)
succeed, we check if
the identifier returned by the successful disambiguation as declarator
denotes a typedef name:
if the check succeeds,
we keep the disambiguation as abstract declarator
and discard the one as declarator.
If instead the check fails, we return an error:
we conjecture that this should only happen if the code is invalid,
but this needs further investigation.
If the ambiguous declarator or abstract declarator
turns out to be a declarator,
we also return the identifier it declares.
If it turns out to be an abstract declarator instead,
we return nil.
So, in general, this function returns an optional identifier,
besides the disambiguated declarator or abstract declarator.
In the call of dimb-declor
we pass nil as the fundefp flag,
because if we are disambiguating a declarator or abstract declarator,
it means that we are disambiguating a parameter declarator,
and not the declarator of a defined function.