Go to the previous, next section.

Features Shared By All Types

The base type_node class defines some common features of all types. This section describes the methods from this base class along with some comments about conventions for using types. Besides the things covered here, each type_node contains an ID number that uniquely identifies it within a particular context. See section Numbering Types and Symbols.

New types can be created as necessary, but once a type has been entered in a symbol table it should generally not be changed. This helps to avoid duplicate types and to prevent unintended side effects when a type is used in multiple places. Instead, the copy method can be used to get a new type that is the same as the existing type, except that it does not copy annotations. The copy can then be freely modified and installed in a symbol table. If necessary, annotations on the type can be copied separately using the copy_annotes method. See section SUIF Objects.

When a type is entered in a symbol table, it automatically records a pointer to that parent table. Similarly, when the type is removed from the symbol table, its parent pointer is cleared. The parent method retrieves this parent pointer.

Each type has a size method that returns the number of bits used to store values of that type. (That is not very meaningful for function types, so they always have a fixed size of zero.) The size for a type may or may not be set directly, depending on the type operator. The sizes for type nodes from each of the derived classes are described in the appropriate sections below.

Structures, unions, and enumerated types are all given names. The is_named method checks to see if a type_node is one of these types. The name of a type should be unique within the symbol table where it is defined, but the type name space is separate from the names for symbols. Because the type names are automatically entered in the lexicon (see section Lexicon) when the types are created, they can be compared as pointers without doing string comparisons.

More than one type_node can represent the same type. That is, types may be equivalent even if they are represented by different type nodes. Given that, the only reason to reuse existing types is to keep the symbol tables from getting too big. The is_same method is provided to check if two types are equivalent, so that the symbol tables can be kept to a reasonable size. However, is_same is only intended to help get rid of duplicates. Because it assumes that duplicate types are still perfectly legal, it may potentially return false negatives to avoid the expense of comparing annotations on type nodes (5). For named types, the is_same method assumes that all type nodes are unique; it does not check for structural equivalence. In most cases, is_same need not be called directly. Instead, the symbol table install_type method (see section Adding and Removing Entries), which uses is_same to detect and avoid duplicate types, is the recommended way to add new types to a symbol table.

SUIF has its own definition of type compatibility. Two types do not need to be strictly equivalent to be compatible. Besides the rules for type equivalence, the following conditions define which types are compatible:

The compatible method is included in the type_node class to determine if two types are compatible according to these rules.

There are three different methods for printing SUIF types. The print_abbrev method is used when printing the result types of instructions. It prints the type ID number along with a single character to identify the type operator followed by a period and the size (e.g. `i.32' for a 32-bit integer). The print method shows the ID number prefixed with `t:' to identify it as a type. The print_full method prints all of the type information and is used when listing symbol tables. It's optional depth parameter can be used to specify the indentation level.

Many kinds of type nodes contain fields that refer to other types. Moreover, each type may contain annotations that include references to other types. With one exception, however, recursive type references are not allowed. In other words, if the type nodes are viewed as a directed graph with the references between them forming the edges, there can be no cycles. To support recursive data structures, we allow an exception to this rule: types within a field of a structure or union may refer back to the structure or union type.

Go to the previous, next section.