4. The Transforms
This section describes each of the transforms in the CPPX transform engine.
4.1 Transform Order
The transforms are applied in the following order:
gd_reduce gd_builtin namespace aggregate gd_filter
gd_alias funct_type
gd_derived gd_enum gd_objects gd_func gd_literals
gd_operators gd_actuals
gd_break gd_goto gd_return gd_labels gd_for gd_while
gd_if gd_switch gd_block
gd_statements gd_nameref classes gd_typedecls ordinals
gd_filter merge_builtin
zap_builtin zap_other gd_filter
4.4 General Transform Approach
While some of the transforms will walk the graph, most do a simple linear
pass over the nodes, and only do limited graph traversals. Thus a
typical algorithm might be:
for each node in the graph
if the node type is the one
I want
-- do something.
This leads to very fast transforms. However, it also means that the
garbage collector needs to be invoked on a more frequent basis, because
nodes cut off from the main graph retain thier node type and may influence
part of a transform unless specifically collected by the gd_filter.
4.3 Transforms
-
gd_reduce - this transform is applied at the very beginning. It removes
the unused built in types and predefined functions from the GD graph. These
include built in types for fortran and java.
-
gd_filter - a general garbage collector. This filter walks the graph marking
reachable nodes and marks all other nodes as deleted. This filter is applied
more than once during the transforms
-
namespace - changes the representation of namespace
-
gd_builtin - changes gcc declarations for the builtin types to datrix built_in
type nodes.
-
aggregate - converts the type nodes for classes, struct and unions
-
gd_derived - converts derived types (pointers, arrays, etc)
-
funct_type - converts function types in GCC. This does not include function
definitions, on the types. For function definitions, these nodes
will be deleted, but retained for external function declarations
-
gd_enum - handle enumerated types
-
gd_alias - handles typedef
-
gd_objects - fields of structures, untions and classes, definitions of
local variables, parameters
-
gd_func - handles function declarations
-
gd_literals - conversion of nodes representing literals
-
gd_operators - handles expressions
-
gd_acutals - arguments in procedure and function calls
-
gd_statements - handles most simple statements
-
gd_break - converts the break statement
-
gd_label - converts label statements
-
gd_for - the for statement, handles conversion of internal blocks
-
gd_while - the while statement, converts internal blocks
-
gd_if - the if statement, converts internal blocks
-
gd_switch - the switch statement, case labels and linkage of internal statements
-
gd_block - handles statement blocks (delimited by '{ and "})
-
gd_classes - follows class inheritance
-
gd_nameref - inserts namerefs into object references. GCC refers directly
to the definition of the field, Datrix requires a nameref node as a place
holder
-
gd_typedecls - GCC uses two nodes for each type declaration. We conver
the second node, This node traverses the graph and removes the extra nodes
-
ordinals - the gd representation implicitly represents the position of
nodes within the graph. This pass adds the ordinal attribute for output.
-
zap_builtin - zaps any unused builtin nodes. These are nodes not removed
by gd_reduce because they were used by parts of the graph that have since
been removed.
-
zap_other - the other_ptr in the base node structure is used for some house
keeping. By the end any housekeeping used by that pointer is finished.
null the pointer so the final garbage collect removes all but relevant
nodes.
4.3 Auxilary Files
There are several auxilary files:
-
gd_utils.c - This file provides several simple utility routines and a definition
of some static data. The most usefull routine is the newNode routine which
allocates a new node in the data structure.
-
gd_walkers.c - This file provides a walking algorithm that calls a callback
routine for each node_ptr in the graph structure. It permits general moving
of pointers.
-
gd_next.c - finds (or sets) the 'next' node using some general criteria.
Used for walking statement lists, etc. Not all of the transforms use this
file, some have thier own copies (and should be fixed to use the single
central copy). The other_node pointer in the common block is used
to chain Datrix statments in GCC node sequences before the block containing
the current statement has been fixed.