Skip to content

Enter Template Symbols

Andrei Tumbar edited this page Sep 24, 2026 · 3 revisions

This algorithm traverses a source model in which templates have been expanded and enters into their scopes the symbols produced by each template expansion. It also checks that the arguments of each expansion match the parameters of the template it expands, and it records each expansion in the template expansion map.

Input

  1. A list tul of translation units with templates expanded.

  2. An analysis data structure a representing the results of analysis so far. The symbols of tul must already be entered, and templates must already be expanded.

Output

  1. An updated analysis data structure a with the symbols produced by template expansions entered and the template expansion map filled in.

Bound Parameter Symbols

For each parameter q of the expanded template and each corresponding argument p, this algorithm constructs a bound parameter symbol representing the bound parameter definition \$(q, p)\$. A constant parameter yields a constant parameter symbol, which resides in the value name group; a type parameter yields a type parameter symbol, in the type name group; and an instance parameter yields a port interface instance parameter symbol, in the port interface instance name group. The unqualified name of the symbol is the name of q, and its AST node is the node of p.

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, then visit it using the same rules as described in the enter symbols algorithm, visiting the members of the module so that expansions appearing inside it are reached. In particular, if a module symbol with the same name already exists at the current level, then reopen its scope instead of creating a new one.

    2. Template expansion specifiers: If tum is a template expansion specifier te, then

      1. If the template expansion map of a already has an entry e for te, then

        1. Push the definition scope of e onto the nested scope of a.

        2. Visit the members of te with this algorithm.

        3. Pop the resulting scope s off the nested scope of a and replace the definition scope of e with s in the template expansion map.

      2. Otherwise let t be the module template definition that the template name of te refers to in the use-def map of a, let P be the parameters of t, and let A be the arguments of te. Throw an internal error if the template name does not resolve to a template symbol. Then

        1. If the number of arguments in A does not equal the number of parameters in P, report an error.

        2. For each argument p in A paired with its corresponding parameter q in P:

          1. If the kind of p (constant, type, or instance) does not match the kind of q, report an error.

          2. Otherwise construct the bound parameter symbol binding q to p.

        3. Create a fresh scope sp for the parameters. For each bound parameter symbol, add the mapping from its name to the symbol in sp, in the single name group determined by the kind of the parameter. Report an error if the name is already present in that name group. Two parameters with the same name in different name groups are allowed.

        4. Create a fresh scope sd for the expanded definitions. Push sd onto the nested scope of a, and enter the symbols for the members of te using the enter symbols algorithm, yielding a scope sd'. Pop sd' off the nested scope of a.

        5. Compute the local scope map of the expansion: starting from the module symbols bound in sd', map each such symbol to its scope in the symbol-scope map of a, and repeat transitively for the module symbols bound in those scopes.

        6. For each bound parameter symbol, check that its name is not bound in sd' in the name group of the parameter. If it is, report an error for a template parameter conflict.

        7. Merge sd' into the innermost nested scope s of a. For each name group g and each mapping from a name n to a symbol sym in sd':

          1. If n is already mapped to sym in g in s, then do nothing.

          2. Otherwise if n is mapped in g in s to a module symbol sym' and sym is also a module symbol, then recursively merge their scopes and map both symbols to the merged scope in the symbol-scope map of a, keeping the mapping already in s.

          3. Otherwise add the mapping from n to sym in g in s, and report an error if n is already mapped in g in s to some other symbol.

        8. Construct a template expansion consisting of t, te, the map from parameter keys to bound parameter symbols, the parameter scope sp, the definition scope sd', and the local scope map. Add the mapping from te to this expansion in the template expansion map of a.

        9. Visit the members of te with this algorithm.

    3. Otherwise do nothing. In particular, the body of a module template definition is not visited.

Clone this wiki locally