Constant expressions (GNU Compiler Collection (GCC) Internals)

#### 11.6.1 Constant expressions ¶

The table below begins with constants, moves on to unary expressions, then proceeds to binary expressions, and concludes with various other kinds of expressions:

`INTEGER_CST`

  These nodes represent integer constants. Note that the type of these constants is obtained with `TREE_TYPE`; they are not always of type `int`. In particular, `char` constants are represented with `INTEGER_CST` nodes. The value of the integer constant `e` is represented in an array of HOST_WIDE_INT. There are enough elements in the array to represent the value without taking extra elements for redundant 0s or -1. The number of elements used to represent `e` is available via `TREE_INT_CST_NUNITS`. Element `i` can be extracted by using `TREE_INT_CST_ELT (e, i)`. `TREE_INT_CST_LOW` is a shorthand for `TREE_INT_CST_ELT (e, 0)`.

  The functions `tree_fits_shwi_p` and `tree_fits_uhwi_p` can be used to tell if the value is small enough to fit in a signed HOST_WIDE_INT or an unsigned HOST_WIDE_INT respectively. The value can then be extracted using `tree_to_shwi` and `tree_to_uhwi`.

`REAL_CST`

  FIXME: Talk about how to obtain representations of this constant, do comparisons, and so forth.

`FIXED_CST`

  These nodes represent fixed-point constants. The type of these constants is obtained with `TREE_TYPE`. `TREE_FIXED_CST_PTR` points to a `struct fixed_value`; `TREE_FIXED_CST` returns the structure itself. `struct fixed_value` contains `data` with the size of two `HOST_BITS_PER_WIDE_INT` and `mode` as the associated fixed-point machine mode for `data`.

`COMPLEX_CST`

  These nodes are used to represent complex number constants, that is a `__complex__` whose parts are constant nodes. The `TREE_REALPART` and `TREE_IMAGPART` return the real and the imaginary parts respectively.

`VECTOR_CST`

  These nodes are used to represent vector constants. Each vector constant v is treated as a specific instance of an arbitrary-length sequence that itself contains ‘`VECTOR_CST_NPATTERNS (v)`’ interleaved patterns. Each pattern has the form:

      { base0, base1, base1 + step, base1 + step * 2, ... }

  The first three elements in each pattern are enough to determine the values of the other elements. However, if all steps are zero, only the first two elements are needed. If in addition each base1 is equal to the corresponding base0, only the first element in each pattern is needed. The number of encoded elements per pattern is given by ‘`VECTOR_CST_NELTS_PER_PATTERN (v)`’.

  For example, the constant:

      { 0, 1, 2, 6, 3, 8, 4, 10, 5, 12, 6, 14, 7, 16, 8, 18 }

  is interpreted as an interleaving of the sequences:

      { 0, 2, 3, 4, 5, 6, 7, 8 }
      { 1, 6, 8, 10, 12, 14, 16, 18 }

  where the sequences are represented by the following patterns:

      base0 == 0, base1 == 2, step == 1
      base0 == 1, base1 == 6, step == 2

  In this case:

      VECTOR_CST_NPATTERNS (v) == 2
      VECTOR_CST_NELTS_PER_PATTERN (v) == 3

  The vector is therefore encoded using the first 6 elements (‘`{ 0, 1, 2, 6, 3, 8 }`’), with the remaining 10 elements being implicit extensions of them.

  Sometimes this scheme can create two possible encodings of the same vector. For example { 0, 1 } could be seen as two patterns with one element each or one pattern with two elements (base0 and base1). The canonical encoding is always the one with the fewest patterns or (if both encodings have the same number of patterns) the one with the fewest encoded elements.

  ‘`vector_cst_encoding_nelts (v)`’ gives the total number of encoded elements in v, which is 6 in the example above. `VECTOR_CST_ENCODED_ELTS (v)` gives a pointer to the elements encoded in v and `VECTOR_CST_ENCODED_ELT (v, i)` accesses the value of encoded element i.

  ‘`VECTOR_CST_DUPLICATE_P (v)`’ is true if v simply contains repeated instances of ‘`VECTOR_CST_NPATTERNS (v)`’ values. This is a shorthand for testing ‘`VECTOR_CST_NELTS_PER_PATTERN (v) == 1`’.

  ‘`VECTOR_CST_STEPPED_P (v)`’ is true if at least one pattern in v has a nonzero step. This is a shorthand for testing ‘`VECTOR_CST_NELTS_PER_PATTERN (v) == 3`’.

  The utility function `vector_cst_elt` gives the value of an arbitrary index as a `tree`. `vector_cst_int_elt` gives the same value as a `wide_int`.

`STRING_CST`

  These nodes represent string-constants. The `TREE_STRING_LENGTH` returns the length of the string, as an `int`. The `TREE_STRING_POINTER` is a `char*` containing the string itself. The string may not be `NUL`-terminated, and it may contain embedded `NUL` characters. Therefore, the `TREE_STRING_LENGTH` includes the trailing `NUL` if it is present.

  For wide string constants, the `TREE_STRING_LENGTH` is the number of bytes in the string, and the `TREE_STRING_POINTER` points to an array of the bytes of the string, as represented on the target system (that is, as integers in the target endianness). Wide and non-wide string constants are distinguished only by the `TREE_TYPE` of the `STRING_CST`.

  FIXME: The formats of string constants are not well-defined when the target system bytes are not the same width as host system bytes.

`POLY_INT_CST`

  These nodes represent invariants that depend on some target-specific runtime parameters. They consist of `NUM_POLY_INT_COEFFS` coefficients, with the first coefficient being the constant term and the others being multipliers that are applied to the runtime parameters.

  `POLY_INT_CST_ELT (x, i)` references coefficient number i of `POLY_INT_CST` node x. Each coefficient is an `INTEGER_CST`.