next up previous
Next: Identifier occurrences Up: Name Analysis Previous: Name Analysis

Name spaces and scopes

Section of the standard defines four name spaces for identifiers in C, and therefore we use four instances of the necessary environment modules:

Instantiate modules[3]:

$/Name/AlgScope.gnrc      +instance=Label  :inst
$/Name/AlgScope.gnrc      +instance=Tag    :inst
$/Name/AlgRangeSeq.gnrc   +instance=Tag    :inst
$/Name/AlgScope.gnrc      +instance=Member :inst
$/Name/ScopeProp.gnrc     +instance=Member :inst
$/Name/CScope.gnrc                         :inst
$/Name/CRangeSeq.gnrc                      :inst
This macro is defined in definitions 3 and 9.
This macro is invoked in definition 2.

(The unnamed instances implement the name space of ``ordinary identifiers''. An ordinary identifier is any identifier that does not belong to one of the other name spaces.)

Label identifiers obey ALGOL-like scope rules because Section of the standard states explicitly that the scope of a label identifier is the entire function in which it appears.

Section of the standard describes the behavior of tags, and although that description is couched in terms of the sequence in which constructs appear in the program, the overall effect is that tags obey ALGOL-like scope rules.

Member identifier declarations do not interact with any other identifier occurrences in their scopes. Similarly, applied occurrences of member identifiers don't interact with any other identifier occurrences. Thus member identifiers could be considered to obey either ALGOL-like or C-like scope rules. We chose to use ALGOL-like scope rules for compatibility with the ScopeProp module.

Ordinary identifiers obey C-like scope rules, in which the scope begins with the declaration of the identifier and ends at the end of some source language construct.

Section of the standard defines the points at which the scopes of various identifiers terminate, and then states that two identifiers have the same scope if and only if their scopes terminate at the same point. Certain symbols of Section 2's abstract syntax tree correspond to constructs ending at those termination points and encompassing all of the possible points at which the scope of an identifier could begin. Each of these symbols inherits the RangeScope role of the corresponding name space module.

Identifiers appearing within the list of parameter declarations in a function definition have block scope terminating at the } that closes the function body. Although the parameter list and the function body are represented by nodes that have a common parent (function_definition), there are intervening nodes. This requires use of the range sequence module, with function_definition inheriting the RangeSequence role and the parameter list and function body each inheriting the RangeElement role. The definition of the range sequence module requires that RangeElement be inherited by a node belonging to a subtree rooted in a node that inherits RangeSequence.

The parameters node, which represents the parameter list of a function definition, is a component of a declarator, which occurs in contexts other than function definitions. When declarator occurs a context other than a function definition, parameters represents a function prototype scope. There is no practical way to make a syntactic distinction between the use of a declarator in a function definition and the use of a declarator in other contexts.

Since parameters must inherit RangeElement in order to implement the block scope of a function definition, it must always appear in a subtree rooted in a node inheriting RangeSequence. Thus several other nodes that would not normally be considered to represent constructs significant for name analysis inherit that role.

Regions of text encompassing identifier scopes[4]:

SYMBOL function_body           INHERITS LabelRangeScope                 END;

SYMBOL function_definition     INHERITS TagRangeSequence                END;
SYMBOL parameters              INHERITS TagRangeElement                 END;
SYMBOL function_body           INHERITS TagRangeElement                 END;
SYMBOL compound_statement      INHERITS TagRangeScope                   END;
SYMBOL Prototype               INHERITS TagRangeScope                   END;

SYMBOL struct_declaration_list INHERITS MemberExportRange               END;

SYMBOL function_definition     INHERITS RangeSequence                   END;
SYMBOL parameters              INHERITS RangeElement                    END;
SYMBOL declaration_list        INHERITS RangeElement                    END;
SYMBOL function_body           INHERITS RangeElement                    END;
SYMBOL compound_statement      INHERITS RangeScope                      END;
SYMBOL parameter_type_list     INHERITS RangeScope                      END;

SYMBOL init_declarator         INHERITS RangeSequence, TagRangeSequence END;
SYMBOL parameter_declaration   INHERITS RangeSequence, TagRangeSequence END;
This macro is invoked in definition 1.

next up previous
Next: Identifier occurrences Up: Name Analysis Previous: Name Analysis