DWARF procedures generation
DWARF expressions (aka. location descriptions) are used to encode variable
things such as sizes or offsets. Such computations can have redundant parts
that can be factorized in order to reduce the size of the output debug
information. This is the whole point of DWARF procedures.
Thanks to stor-layout.cc, size and offset expressions in GENERIC trees are
already factorized into functions ("size functions") in order to handle very
big and complex types. Such functions are quite simple: they have integral
arguments, they return an integral result and their body contains only a
return statement with arithmetic expressions. This is the only kind of
function we are interested in translating into DWARF procedures, here.
DWARF expressions and DWARF procedure are executed using a stack, so we have
to define some calling convention for them to interact. Let's say that:
- Before calling a DWARF procedure, DWARF expressions must push on the stack
all arguments in reverse order (right-to-left) so that when the DWARF
procedure execution starts, the first argument is the top of the stack.
- Then, when returning, the DWARF procedure must have consumed all arguments
on the stack, must have pushed the result and touched nothing else.
- Each integral argument and the result are integral types can be hold in a
single stack slot.
- We call "frame offset" the number of stack slots that are "under DWARF
procedure control": it includes the arguments slots, the temporaries and
the result slot. Thus, it is equal to the number of arguments when the
procedure execution starts and must be equal to one (the result) when it
returns.
Helper structure used when generating operations for a DWARF procedure.