Skip to content

Check Uses

Rob Bocchino edited this page Feb 11, 2026 · 16 revisions

This algorithm traverses a source model and checks that each use refers to definition. It also constructs the use-def map.

Input

  1. A list tul of translation units.

  2. An analysis data structure a representing the results of analysis so far.

Output

  1. An analysis data structure a with updated use-def map.

Procedure

  1. Translation unit lists: Visit each translation unit tu in tul in order.

  2. Translation units: Visit a translation unit tu by visiting its members tum.

  3. Translation unit members: Visit a translation unit member tum as follows:

    1. Module definitions: If tum is a module definition d with name n, then

      1. Look up the module symbol sym associated with the unqualified name n as described in Expressions below.

      2. Look up the mapping from sym to s in the symbol-scope map of a. If no such mapping exists, then throw an internal error.

      3. Push s onto the nested scope of a.

      4. Visit each translation unit member of d.

      5. Pop s off the nested scope of a.

    2. Enum definitions: If tum is an enum definition d with name n, then

      1. Visit the type of d if it is present.

      2. Construct the unique enum symbol sym corresponding to d.

      3. Look up the mapping from sym to s in the symbol-scope map of a. If no such mapping exists, then throw an internal error.

      4. Push s onto the nested scope of a.

      5. Visit each enumerated constant definition of d.

      6. Pop s off the nested scope of a.

    3. Component definitions: If tum is a component definition d with name n, then

      1. Construct the unique component symbol sym corresponding to d.

      2. Look up the mapping from sym to s in the symbol-scope map of a. If no such mapping exists, then throw an internal error.

      3. Push s onto the nested scope of a.

      4. Visit each member of d.

      5. Pop s off the nested scope of a.

    4. Interface definitions: If tum is a component instance definition, then visit all the expressions, and port uses uses appearing in tum.

    5. Component instance definitions: If tum is a component instance definition, then visit all the type names, expressions, and component uses appearing in tum.

    6. Topology definitions: If tum is a topology definition, then

      1. Visit all the implied uses of tum.

      2. Visit all the type names, expressions, and component instance uses appearing in tum.

    7. Other definitions: If tum is an abstract type, array, constant, or port definition, then visit all the type names and expressions appearing in tum.

  4. Enumerated constant definitions: Visit an enumerated constant definition d as follows:

    1. If d contains an expression e, then visit e.

  5. Component members: Visit a component member cm as follows:

    1. If cm corresponds to a translation member tum, then visit cm in the same manner as tum.

    2. Otherwise visit all the expressions, types, port uses, implied uses, and state machine uses appearing in cm.

  6. Expressions: Visit an expression e as follows:

    1. Unqualified names: If e is an unqualified name n, then

      1. Look up the mapping from n to sym in the innermost nested scope of a in the value name group. If no such mapping exists, then throw a semantic error.

      2. Record the mapping from e to sym in the use-def map of a.

    2. Dot expressions: Otherwise if e is a dot expression e'.n, then

      1. Visit e'.

      2. Look up the mapping of e' to sym' in the use-def map

        1. If sym' does not exist or sym' exists and is a constant symbol, this dot expression selects a member of the constant and therefore does not introduce an additional use. Exit this visitor.

        2. Otherwise if sym' exists, get the mapping from sym' to s in the symbol-scope map of a. If no such mapping exists, then throw an internal error.

        3. Look up the mapping from n to sym in s. If no such mapping exists, then throw a semantic error.

        4. Record the mapping from e to sym in the use-def map of a.

    3. Other expressions: Otherwise visit each expression and type appearing in e.

  7. Type names: Visit a type name tn as follows:

    1. Unqualified names: Use the same algorithm as for unqualified name expressions, but use the type name group instead of the value name group.

    2. Qualified names: Use the same algorithm as for dot expressions, but use the type name group instead of the value name group.

    3. Other types: Nothing to do.

  8. Port uses: A port use pu is a qualified or unqualified name. Visit pu in the same way as a qualified or unqualified type name, but use the port name group instead of the type name group.

  9. Component instance uses: A component instance use ciu is a qualified or unqualified name. Visit ciu in the same way as for a port use, but use the component instance name group instead of the port name group.

  10. Implied uses: An implied use iu is a qualified or unqualified name provided by the implied use map. Visit iu like a constant expression, a type use, or a port use.

Clone this wiki locally