Skip to content

Check Uses

Rob Bocchino edited this page Jul 17, 2024 · 6 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. Component instance definitions: If tum is a component instance definition, then visit all the type names, expressions, and component uses appearing in tum.

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

    6. 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, and port 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 from e' to sym' in the use-def map of a. If no such mapping exists, then throw an internal error.

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

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

      5. 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.