Procedure symbols are represented by objects of the proc_sym
class. SUIF does not support nested procedures, so these symbols may
only be entered in global and file symbol tables. The fields in a
procedure symbol hold information about the procedure, including a
pointer to the body if it is in memory. The proc_sym
class also
provides methods to read procedure bodies from input files, write them
to the output files, and flush them from memory.
Each procedure symbol contains a field to record the source language for
the procedure. The src_lang
and set_src_lang
methods
access this field, which holds a value from src_lang_type
enumeration: src_unknown
, src_c
, src_fortran
, or
src_verilog
. Other values may be added in the future.
A procedure symbol also has a field that specifies the type of the
procedure. The type
and set_type
methods retrieve and
change this field. The type must be a function type. See section Function Types.
The body of a procedure is represented by its abstract syntax tree.
See section Abstract Syntax Trees. The procedure symbol contains a pointer to the root node
of this tree. The block
and set_block
methods access this
pointer. If the body is not in memory, the block
pointer will be
NULL
; the is_in_memory
method is provided to check this
condition.
The proc_sym
class contains the methods to read procedure bodies
from binary SUIF files and to write them out again. The details of SUIF
I/O are thus hidden from users; only entire procedures can be read and
written. If one of the input files contains the body for a procedure, a
pointer to the file set entry (see section File Set Entries) is recorded in
the procedure symbol. The file
method retrieves this pointer for
a particular proc_sym
. The same procedure can be read in and
flushed from memory many times, but once it has been written out it can
no longer be read or written again. The procedure symbol contains a
flag to indicate if it has been written out yet. The is_written
method returns the value of this flag. The is_readable
method
checks if the procedure body exists in one of the input files and if it
has not yet been written out. If this method returns TRUE
, the
read_proc
method can be used to read the body of the procedure.
By default, read_proc
also converts the procedure to expression
tree form (see section Expression Trees) but it does not convert to Fortran
form (see section Features for Compiling Fortran). The exp_trees
and
use_fortran_form
parameters to read_proc
can be used to
override these defaults.
After a procedure body has been read in and possibly modified, it can be
written to the output file using the procedure symbol's
write_proc
method. You must specify the file set entry to which
the procedure should be written. In most cases, the input and output
file set entry will be the same, and you will just use the file
method to determine the output file set entry. As mentioned above, once
a procedure has been written out it cannot be rewritten or read in
again. Obviously, it should not be changed after that point because the
changes could not be saved. Besides avoiding changes directly to the
procedure, however, you must also be careful to avoid certain changes to
the global symbol tables. The symbols and types within the procedure
are written out using their ID numbers. See section Numbering Types and Symbols. Thus, you must not do anything to the global symbol tables
that would cause the ID numbers for those symbols and types to change.
For example, moving a symbol from a file symbol table to the global
symbol table would require that its ID number change. The best solution
to this is to not write out the procedures until you are certain that
such changes to the symbol tables will not be needed.
When a procedure body is no longer needed, typically after it has been
written out, call the flush_proc
method for the procedure symbol
to deallocate the storage used by the procedure. In some cases, you may
want to flush the procedure before it is written. For example,
interprocedural analysis requires that all procedures be read in and
analyzed together. To save space, the procedures can be summarized for
the purpose of the particular analysis and then flushed. After the
analysis is complete, they can be re-read and the results can be
attached to the code.