next up previous
Next: Enumeration specifiers Up: Declarations Previous: Declarations

Struct and union specifiers

Structure and union specifiers have the same form, being distinguished only by the appearance of the keyword struct or the keyword union. The presence of a bracketed list declares a new type, which may or may not be given a tag. TagDef represents the context in which a tag is given to a new type.

When a bracketed list is not present, the situation is much more complex. Because of the need to declare types that are related cyclically by pointers, tags may be used before they are given specific types. ForwardDef (Section 2.4, above) represents a context in which a forward reference represents a type declared in the current scope. ForwardUse represents a reference that may be forward (if the identifier appears in a later TagDef or ForwardDef context in the same scope) or may not (if the identifier does not appear in such a context but has previously appeared in a TagDef or ForwardDef context visible at this point).

An additional consideration is that the identifier may never appear in a TagDef or ForwardDef context visible atthis point. That situation is not necessarily an error. The type represented by the tag is incomplete (Section of the standard), and as such it may be legally used in any situation that does not require its size.

Clearly the semantics of TagDef, ForwardDef, and ForwardUse are quite different. Representing them by distinct contexts in the tree simplifies the semantic analysis task.

AST nodes[11]:

RULE: struct_or_union_specifier
                         ::= struct_or_union TagDef
                                    '{' struct_declaration_list '}'   END;
RULE: struct_or_union_specifier
                         ::= struct_or_union
                                    '{' struct_declaration_list '}'   END;
RULE: struct_or_union_specifier
                         ::= struct_or_union ForwardUse               END;

RULE: struct_or_union    ::=    'struct'                              END;
RULE: struct_or_union    ::=    'union'                               END;

RULE: struct_declaration_list
                         LISTOF struct_declaration                    END;

RULE: struct_declaration ::=    Specifiers struct_declarator_list ';' END;

RULE: struct_declarator_list
                         LISTOF struct_declarator                     END;

RULE: struct_declarator  ::=    member_declarator                     END;
RULE: struct_declarator  ::=    member_declarator ':' constant_expression END;
RULE: struct_declarator  ::=                      ':' constant_expression END;

RULE: member_declarator ::= member_pointer_declarator END;
RULE: member_declarator ::= MemberIdDef END;
RULE: member_declarator ::= member_array_declarator END;
RULE: member_declarator ::= member_function_declarator END;
RULE: member_pointer_declarator ::= '*' Specifiers member_declarator END;
RULE: member_array_declarator ::= member_declarator '[' constant_expression ']' END;
RULE: member_function_declarator ::= member_declarator '(' parameter_type_list ')' END;
This macro is defined in definitions 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, and 18.
This macro is invoked in definition 1.

next up previous
Next: Enumeration specifiers Up: Declarations Previous: Declarations