Rectangles represent structs. Each division of a rectangle is an attribute of the struct. The content of a division is the value of the attribute. An arrow represents a pointer (to the struct pointed to by the arrow) The division the arrow originates at is a pointer-valued attribute, whose value is that pointer. Divisions with a diagonal line through them are pointer-valued attributes that happen to have value NULL. When the value is in quotes, the attribute is string-valued. If not, then it's just an enum value. The names on top of divisions of a rectangle are the names of the attribures. The names next to or underneath rectangles are the type names of the struct. Divisions of rectangles that are empty indicate that the value of this attribute is irrelevant (and perhaps also undefined).
Nodes sometimes can represent different things, eg a simpletype node can represent a constant value, a variable or a token (constant placeholder). In the absence of inheritance, we use a "kind" attribute in these cases to indicate for each instance of these nodes, what they actually hold. Depending on what "kind" a node is, some of the attibutes may be "irrelevant", eg the "var" attribute of a simpletype when the node is of kind "constant". Kind nodes have enum types, listing their possible values.
Sets are represented with lists of pointers to the members of the set. So, an member of the set is accessed thru a "list" object, that generally consists of a pointer to the member of the set and a pointer to the next list object.