Repository navigation
Evaluate Constant Expressions
This algorithm traverses the source model and computes the values of constant symbols and expressions.
-
A list tul of translation units.
-
An analysis data structure a representing the results of analysis so far. Evaluate Implied Enum Constants must have already been run.
-
The analysis a with an updated value map, if the check passes; otherwise an error.
-
Visit each translation unit in tul with input a, yielding either a new analysis a' or an error.
Each method accepts an analysis data structure a as input and yields either a new analysis data structure a' or an error as output.
For each constant definition d:
-
If d is not in the value map of a, then
-
Visit each expression appearing in d, threading the analysis through the visits. Let a' be the resulting analysis.
-
Use the value map of a' to compute the value v of d.
-
Let a'' be the analysis data structure that results from adding the mapping from d to v to the value map of a'.
-
Yield a'' as the result.
-
-
Otherwise we have already visited d; yield a as the result.
For each enum definition d, check that the enumerated constants of d all have different values.
For each template expansion specifier n:
-
For each constant parameter symbol of n, with parameter type name t and argument p:
-
Visit the expression p, so that it has a value v in the value map of a.
-
Run Finalize Type Definitions on t, and let T be the resulting type of t in the type map of a.
-
Convert v to T, yielding v'. If the conversion is not possible, then report a type mismatch error.
-
Let a' be the analysis data structure that results from adding the mapping from p to T in the type map of a and the mapping from p to v' in the value map of a. The type and the value of a bound parameter symbol are the ones recorded for its argument.
-
Yield a' as the result.
-
-
For each type parameter symbol of n with argument p, visit the type name p.
-
Visit all the member nodes of n.
For each AST node n that represents an expression, if n is not already in the value map of a:
-
Compute the value v of n:
-
If the value of n is directly available (for example, the value of the integer literal
1is 1), then use that as v. -
Otherwise if n represents a use, then
-
Look in the use-def map of n to get the symbol s corresponding to n. Throw an internal error if it is not there.
-
If s is a constant parameter symbol with argument p, then if p is not already in the value map of a, apply the rules stated above for the constant parameters of a template expansion specifier.
-
Otherwise visit the definition corresponding to s.
-
Look in the value map of a to get the value v of s. Throw an internal error if it is not there.
-
Use v as the value of n.
-
-
Otherwise if n is an expression
sizeoftypename, then-
Visit the child expressions of n.
-
Let t be the type assigned to typename in the type map.
-
Finalize t: if t has a definition d and d has not yet been visited by Finalize Type Definitions, then
-
Visit d.
-
Recursively finalize the member types of d.
-
Run Finalize Type Definitions on d.
-
-
Let t' be the finalized type of typename. If t has a definition d, then t' is the type assigned to d in the type map. Otherwise t' is t.
-
Compute the size v of t'.
-
-
Otherwise
-
Visit the child expressions of n.
-
If possible, use the child values to compute the value v of n. If this is not possible (for example, because an array index is out of bounds), then report an error.
-
-
-
Update the value map with the mapping of n to v.