A variable declaration with the form:
[loc|heap] amode defining identifier [:= unit];
Is in principle equivalent to the identity declaration:
ref amode defining identifier = [loc|heap] amode;
In both cases the object ascribed to the defining identifier is of
mode ref amode. The ascribed object is a name which is
created by a generator implied in the actual declarer in the variable
declaration case, and an explicit generator in the initialization
expression in the identity declaration case.
However, in this compiler these two cases are handled differently in order to reduce the amount of both indirect addressing and of storage:
[loc|heap] amode foo
lowers into a VAR_DECL with type CTYPE (amode) provided
that the generator is loc and that the type contains no
rows. Accessing the variable will then involve direct addressing, and
when its address is required an ADDR_EXPR shall be used.
ref amode foo = loc
amode lowers into a VAR_DECL with type *CTYPE
(amode). Accessing the variable will then involve indirect
addressing: it is effectively a pointer.
This optimization introduces the complication that an expression (the
VAR_DECL) whose type is TYPE can appear in a place where *TYPE
is expected, depending on the context and the r-value and l-value
interpretation of the VAR_DECL. The function
a68_consolidate_ref is used in several parts of the lowering
pass to guarantee a given name is an address regardless of how it was
initialized.