# dmd.expression

Defines the bulk of the classes which represent the AST at the `expression` level.

Specification: ($LINK2 https://dlang.org/spec/expression.html, Expressions)

#### Authors

Walter Bright

#### License

Boost License 1.0

Source: expression.d

Documentation: https://dlang.org/phobos/dmd_expression.html

Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/expression.d

- `Modifiable`

  #### Declaration

  `enum `Modifiable`: int;`

  Return value for `checkModifiable`

  - `no`

    #### Declaration

    ``no``

    Not modifiable

  - `yes`

    #### Declaration

    ``yes``

    Modifiable (the type is mutable)

  - `initialization`

    #### Declaration

    ``initialization``

    Modifiable because it is `initialization`

- `ModifyFlags`

  #### Declaration

  `enum `ModifyFlags`: int;`

  Specifies how the checkModify deals with certain situations

  - `none`

    #### Declaration

    ``none``

    Issue error messages on invalid modifications of the variable

  - `noError`

    #### Declaration

    ``noError``

    No errors are emitted for invalid modifications

  - `fieldAssign`

    #### Declaration

    ``fieldAssign``

    The modification occurs for a subfield of the current variable

- `firstComma`

  #### Declaration

  `inout(Expression) `firstComma`(inout Expression `e`);`

  Find the first non-comma expression.

  #### Parameters

  `Expression `e`` | Expressions connected by commas

  #### Return Value

  left-most non-comma expression

- `lastComma`

  #### Declaration

  `inout(Expression) `lastComma`(inout Expression `e`);`

  Find the last non-comma expression.

  #### Parameters

  `Expression `e`` | Expressions connected by commas

  #### Return Value

  right-most non-comma expression

- `hasThis`

  #### Declaration

  `FuncDeclaration `hasThis`(Scope* `sc`);`

  Determine if `this` is available by walking up the enclosing scopes until a function is found.

  #### Parameters

  `Scope* `sc`` | where to start looking for the enclosing function

  #### Return Value

  Found function if it satisfies `isThis()`, otherwise `null`

- `isNeedThisScope`

  #### Declaration

  `bool `isNeedThisScope`(Scope* `sc`, Declaration `d`);`

  Determine if a `this` is needed to access ``d``.

  #### Parameters

  `Scope* `sc`` | context
  `Declaration `d`` | declaration to check

  #### Return Value

  `true` means a `this` is needed

- `isDotOpDispatch`

  #### Declaration

  `bool `isDotOpDispatch`(Expression `e`);`

  check `e` is exp.opDispatch!(tiargs) or not It's used to switch to UFCS the semantic analysis path

- `expandTuples`

  #### Declaration

  `void `expandTuples`(Expressions* `exps`, Identifiers* `names` = null);`

  Expand tuples in-place.

  Example: When there's a call `f(10, pair: AliasSeq!(20, 30), single: 40)`, the input is: ``exps` = [10, (20, 30), 40]` ``names` = [null, "pair", "single"]` The arrays will be modified to: ``exps` = [10, 20, 30, 40]` ``names` = [null, "pair", null, "single"]`

  #### Parameters

  `Expressions* `exps`` | array of Expressions
  `Identifiers* `names`` | optional array of `names` corresponding to Expressions

- `isAliasThisTuple`

  #### Declaration

  `TupleDeclaration `isAliasThisTuple`(Expression `e`);`

  Expand alias this tuples.

- `getFuncTemplateDecl`

  #### Declaration

  `TemplateDeclaration `getFuncTemplateDecl`(Dsymbol `s`);`

  If ``s`` is a function template, i.e. the only member of a template and that member is a function, return that template.

  #### Parameters

  `Dsymbol `s`` | symbol that might be a function template

  #### Return Value

  template for that function, otherwise `null`

- `valueNoDtor`

  #### Declaration

  `Expression `valueNoDtor`(Expression `e`);`

  If we want the value of this expression, but do not want to call the destructor on it.

- `doCopyOrMove`

  #### Declaration

  `Expression `doCopyOrMove`(Scope* `sc`, Expression `e`, Type `t` = null);`

  Handle the postblit call on lvalue, or the move of rvalue.

  #### Parameters

  `Scope* `sc`` | the scope where the expression is encountered
  `Expression `e`` | the expression the needs to be moved or copied (source)
  `Type `t`` | if the struct defines a copy constructor, the type of the destination

  #### Return Value

  The expression that copy constructs or moves the value.

- `UnionExp`

  #### Declaration

  `struct `UnionExp`;`

- `RealIdentical`

  #### Declaration

  `bool `RealIdentical`(real_t `x1`, real_t `x2`);`

  Test to see if two reals are the same. Regard NaN's as equivalent. Regard +0 and -0 as different.

  #### Parameters

  `real_t `x1`` | first operand
  `real_t `x2`` | second operand

  #### Return Value

  `true` if `x1` is `x2` else `false`

- `typeDotIdExp`

  #### Declaration

  `DotIdExp `typeDotIdExp`(const ref Loc `loc`, Type `type`, Identifier `ident`);`

  TypeDotIdExp

- `expToVariable`

  #### Declaration

  `VarDeclaration `expToVariable`(Expression `e`);`

  Given an Expression, find the variable it really is.

  #### Discussion

  For example, `a[index]` is really `a`, and `s.f` is really `s`.

  #### Parameters

  `Expression `e`` | Expression to look at

  #### Return Value

  variable if there is one, `null` if not

- `Expression`

  #### Declaration

  `abstract class `Expression`: dmd.ast_node.ASTNode;`

  https://dlang.org/spec/expression.html#expression

  - `deinitialize`

    #### Declaration

    `static void `deinitialize`();`

    Deinitializes the global state of the compiler.

    #### Discussion

    This can be used to restore the state set by `_init` to its original state.

  - `copy`

    #### Declaration

    `final Expression `copy`();`

    Does not do a deep `copy`.

  - `combine`

    #### Declaration

    `static Expression `combine`(Expression `e1`, Expression `e2`);`

    Combine `e1` and `e2` by CommaExp if both are not NULL.

  - `extractLast`

    #### Declaration

    `static Expression `extractLast`(Expression `e`, out Expression `e0`);`

    If '`e`' is a tree of commas, returns the rightmost expression by stripping off it from the tree. The remained part of the tree is returned via `e0`. Otherwise '`e`' is directly returned and `e0` is set to NULL.

  - `isLvalue`

    #### Declaration

    `bool `isLvalue`();`

    Return !=0 if expression is an lvalue.

  - `toLvalue`

    #### Declaration

    `Expression `toLvalue`(Scope* `sc`, Expression `e`);`

    Give error if we're not an lvalue. If we can, convert expression to be an lvalue.

  - `resolveLoc`

    #### Declaration

    `Expression `resolveLoc`(const ref Loc `loc`, Scope* `sc`);`

    Resolve __FILE__, __LINE__, __MODULE__, __FUNCTION__, __PRETTY_FUNCTION__, _FILE_FULL_PATH__ to `loc`.

  - `checkType`

    #### Declaration

    `bool `checkType`();`

    Check that the expression has a valid type. If not, generates an error "... has no type".

    #### Return Value

    `true` if the expression is not valid.

    Note: When this function returns `true`, `checkValue()` should also return `true`.

  - `checkValue`

    #### Declaration

    `bool `checkValue`();`

    Check that the expression has a valid value. If not, generates an error "... has no value".

    #### Return Value

    `true` if the expression is not valid or has void type.

  - `checkPurity`

    #### Declaration

    `final bool `checkPurity`(Scope* `sc`, FuncDeclaration `f`);`

    Calling function `f`. Check the purity, i.e. if we're in a pure function we can only call other pure functions. Returns `true` if error occurs.

  - `checkOverridenDtor`

    #### Declaration

    `final void `checkOverridenDtor`(Scope* `sc`, FuncDeclaration `f`, scope bool function(DtorDeclaration) `check`, const string `checkName`);`

    Checks whether ``f`` is a generated `DtorDeclaration` that hides a user-defined one which passes ``check`` while ``f`` doesn't (e.g. when the user defined dtor is pure but the generated dtor is not). In that case the method will identify and print all members causing the attribute missmatch.

    #### Parameters

    `Scope* `sc`` | scope
    `FuncDeclaration `f`` | potential `DtorDeclaration`
    `bool function(DtorDeclaration) `check`` | current `check` (e.g. whether it's pure)
    `string `checkName`` | the kind of `check` (e.g. `"pure"`)

  - `checkPurity`

    #### Declaration

    `final bool `checkPurity`(Scope* `sc`, VarDeclaration `v`);`

    Accessing variable `v`. Check for purity and safety violations. Returns `true` if error occurs.

  - `checkSafety`

    #### Declaration

    `final bool `checkSafety`(Scope* `sc`, FuncDeclaration `f`);`

    Calling function `f`. Check the safety, i.e. if we're in a @safe function we can only call @safe or @trusted functions. Returns `true` if error occurs.

  - `checkNogc`

    #### Declaration

    `final bool `checkNogc`(Scope* `sc`, FuncDeclaration `f`);`

    Calling function `f`. Check the @nogc-ness, i.e. if we're in a @nogc function we can only call other @nogc functions. Returns `true` if error occurs.

  - `checkPostblit`

    #### Declaration

    `final bool `checkPostblit`(Scope* `sc`, Type `t`);`

    Check that the postblit is callable if `t` is an array of structs. Returns `true` if error happens.

  - `checkReadModifyWrite`

    #### Declaration

    `final bool `checkReadModifyWrite`(EXP `rmwOp`, Expression `ex` = null);`

    Check whether the expression allows RMW operations, error with rmw operator diagnostic if not. `ex` is the RHS expression, or NULL if ++/-- is used (for diagnostics) Returns `true` if error occurs.

  - `addDtorHook`

    #### Declaration

    `Expression `addDtorHook`(Scope* `sc`);`

    Destructors are attached to VarDeclarations. Hence, if expression returns a temp that needs a destructor, make sure and create a VarDeclaration for that temp.

  - `addressOf`

    #### Declaration

    `final Expression `addressOf`();`

    Take address of expression.

  - `deref`

    #### Declaration

    `final Expression `deref`();`

    If this is a reference, dereference it.

  - `isIdentical`

    #### Declaration

    `const bool `isIdentical`(const Expression `e`);`

    Identical, not just equal. I.`e`. NaNs with different bit patterns are not identical

  - `toBool`

    #### Declaration

    `Optional!bool `toBool`();`

    Statically evaluate this expression to a `bool` if possible

    #### Return Value

    an optional thath either contains the value or is empty

- `IntegerExp`

  #### Declaration

  `class `IntegerExp`: dmd.expression.Expression;`

  A compile-time known integer value

  - `literal`

    #### Declaration

    `IntegerExp `literal`(int v)();`

    Use this instead of creating new instances for commonly used literals such as 0 or 1.

    Parameters: v = The value of the expression

    #### Return Value

    A static instance of the expression, typed as `Tint32`.

  - `createBool`

    #### Declaration

    `static IntegerExp `createBool`(bool `b`);`

    Use this instead of creating new instances for commonly used bools.

    Parameters: `b` = The value of the expression

    #### Return Value

    A static instance of the expression, typed as `Type.tbool`.

- `ErrorExp`

  #### Declaration

  `class `ErrorExp`: dmd.expression.Expression;`

  Use this expression for error recovery.

  #### Discussion

  It should behave as a 'sink' to prevent further cascaded error messages.

- `VoidInitExp`

  #### Declaration

  `class `VoidInitExp`: dmd.expression.Expression;`

  An uninitialized value, generated from void initializers.

  #### Discussion

  https://dlang.org/spec/declaration.html#void_init

  - `var`

    #### Declaration

    `VarDeclaration `var`;`

    the variable from where the void value came from, `null` if not known

  - `this`

    #### Declaration

    `this(VarDeclaration `var`);`

    Useful for error messages

- `RealExp`

  #### Declaration

  `class `RealExp`: dmd.expression.Expression;`

  A compile-time known floating point number

- `ComplexExp`

  #### Declaration

  `class `ComplexExp`: dmd.expression.Expression;`

  A compile-time complex number (deprecated)

- `IdentifierExp`

  #### Declaration

  `class `IdentifierExp`: dmd.expression.Expression;`

  An identifier in the context of an expression (as opposed to a declaration)

  #### Discussion

  1. `int x; // VarDeclaration with Identifier x++; // PostExp with IdentifierExp`
- `DollarExp`

  #### Declaration

  `class `DollarExp`: dmd.expression.IdentifierExp;`

  The dollar operator used when indexing or slicing an array. E.g `a[$]`, `a[1 .. $]` etc.

  #### Discussion

  https://dlang.org/spec/arrays.html#array-length

- `DsymbolExp`

  #### Declaration

  `class `DsymbolExp`: dmd.expression.Expression;`

  Won't be generated by parser.

- `ThisExp`

  #### Declaration

  `class `ThisExp`: dmd.expression.Expression;`

  https://dlang.org/spec/expression.html#this

- `SuperExp`

  #### Declaration

  `class `SuperExp`: dmd.expression.ThisExp;`

  https://dlang.org/spec/expression.html#super

- `NullExp`

  #### Declaration

  `class `NullExp`: dmd.expression.Expression;`

  A compile-time known `null` value

  #### Discussion

  https://dlang.org/spec/expression.html#null

- `StringExp`

  #### Declaration

  `class `StringExp`: dmd.expression.Expression;`

  https://dlang.org/spec/expression.html#string_literals

  - `numberOfCodeUnits`

    #### Declaration

    `const size_t `numberOfCodeUnits`(int `tynto` = 0);`

    Return the number of code units the string would be if it were re-encoded as `tynto`.

    #### Parameters

    `int `tynto`` | code unit type of the target encoding

    #### Return Value

    number of code units

  - `writeTo`

    #### Declaration

    `const void `writeTo`(void* `dest`, bool `zero`, int `tyto` = 0);`

    Write the contents of the string to `dest`. Use numberOfCodeUnits() to determine size of result.

    #### Parameters

    `void* `dest`` | destination
    `int `tyto`` | encoding type of the result
    `bool `zero`` | add terminating 0

  - `getCodeUnit`

    #### Declaration

    `const pure dchar `getCodeUnit`(size_t `i`);`

    Get the code unit at index `i`

    #### Parameters

    `size_t `i`` | index

    #### Return Value

    code unit at index `i`

  - `setCodeUnit`

    #### Declaration

    `void `setCodeUnit`(size_t `i`, dchar `c`);`

    Set the code unit at index `i` to `c`

    #### Parameters

    `size_t `i`` | index
    `dchar `c`` | code unit to set it to

  - `toUTF8`

    #### Declaration

    `StringExp `toUTF8`(Scope* `sc`);`

    Convert string to char[].

  - `compare`

    #### Declaration

    `const pure nothrow @nogc int `compare`(const StringExp `se2`);`

    Compare two `StringExp` by length, then value

    #### Discussion

    The comparison is not the usual C-style comparison as seen with `strcmp` or `memcmp`, but instead first `compare` based on the length. This allows both faster lookup and sorting when comparing sparse data.
    This ordering scheme is relied on by the string-switching feature. Code in Druntime's `core.internal.switch_` relies on this ordering when doing a binary search among case statements.
    Both `StringExp` should be of the same encoding.

    #### Parameters

    `StringExp `se2`` | String expression to `compare` `this` to

    #### Return Value

    `0` when `this` is equal to `se2`, a value greater than `0` if `this` should be considered greater than ``se2``, and a value less than `0` if `this` is lesser than ``se2``.

  - `toStringz`

    #### Declaration

    `const const(char)[] `toStringz`();`

    Convert string contents to a 0 terminated string, allocated by mem.xmalloc().

  - `peekData`

    #### Declaration

    `const const(ubyte)[] `peekData`();`

    Get a slice of the data.

  - `borrowData`

    #### Declaration

    `ubyte[] `borrowData`();`

    Borrow a slice of the data, so the caller can modify it in-place (!)

  - `setData`

    #### Declaration

    `void `setData`(void* `s`, size_t `len`, ubyte `sz`);`

    Set new string data. `this` becomes the new owner of the data.

- `TupleExp`

  #### Declaration

  `class `TupleExp`: dmd.expression.Expression;`

  A sequence of expressions

  #### Discussion

  1. `alias AliasSeq(T...) = T; alias Tup = AliasSeq!(3, int, "abc");`
- `ArrayLiteralExp`

  #### Declaration

  `class `ArrayLiteralExp`: dmd.expression.Expression;`

  [ e1, e2, e3, ... ]

  #### Discussion

  https://dlang.org/spec/expression.html#array_literals

  - `basis`

    #### Declaration

    `Expression `basis`;`

    If !is `null`, elements[] can be sparse and `basis` is used for the "default" element value. In other words, non-`null` elements[i] overrides this '`basis`' value.

- `AssocArrayLiteralExp`

  #### Declaration

  `class `AssocArrayLiteralExp`: dmd.expression.Expression;`

  [ key0 : value0, key1 : value1, ... ]

  #### Discussion

  https://dlang.org/spec/expression.html#associative_array_literals

- `stageScrub`

  #### Declaration

  `enum int `stageScrub`;`

  scrubReturnValue is running

- `stageSearchPointers`

  #### Declaration

  `enum int `stageSearchPointers`;`

  hasNonConstPointers is running

- `stageOptimize`

  #### Declaration

  `enum int `stageOptimize`;`

  optimize is running

- `stageApply`

  #### Declaration

  `enum int `stageApply`;`

  apply is running

- `stageInlineScan`

  #### Declaration

  `enum int `stageInlineScan`;`

  inlineScan is running

- `stageToCBuffer`

  #### Declaration

  `enum int `stageToCBuffer`;`

  toCBuffer is running

- `StructLiteralExp`

  #### Declaration

  `class `StructLiteralExp`: dmd.expression.Expression;`

  sd( e1, e2, e3, ... )

  - `sd`

    #### Declaration

    `StructDeclaration `sd`;`

    which aggregate this is for

  - `elements`

    #### Declaration

    `Expressions* `elements`;`

    parallels sd.fields[] with `null` entries for fields to skip

  - `stype`

    #### Declaration

    `Type `stype`;`

    final type of result (can be different from sd's type)

  - `sym`

    #### Declaration

    `Symbol* `sym`;`

    back end symbol to initialize with literal

  - `origin`

    #### Declaration

    `StructLiteralExp `origin`;`

    pointer to the `origin` instance of the expression. once a new expression is created, `origin` is set to 'this'. anytime when an expression copy is created, '`origin`' pointer is set to '`origin`' pointer value of the original expression.

  - `inlinecopy`

    #### Declaration

    `StructLiteralExp `inlinecopy`;`

    those fields need to prevent a infinite recursion when one field of struct initialized with 'this' pointer.

  - `stageflags`

    #### Declaration

    `int `stageflags`;`

    anytime when recursive function is calling, '`stageflags`' marks with bit flag of current stage and unmarks before return from this function. 'inlinecopy' uses similar '`stageflags`' and from multiple evaluation 'doInline' (with infinite recursion) of this expression.

  - `useStaticInit`

    #### Declaration

    `bool `useStaticInit`;`

    if this is `true`, use the StructDeclaration's init symbol

  - `isOriginal`

    #### Declaration

    `bool `isOriginal`;`

    used when moving instances to indicate `this is this.origin`

  - `getField`

    #### Declaration

    `Expression `getField`(Type `type`, uint `offset`);`

    Gets expression at `offset` of `type`. Returns NULL if not found.

  - `getFieldIndex`

    #### Declaration

    `int `getFieldIndex`(Type `type`, uint `offset`);`

    Get index of field. Returns -1 if not found.

- `CompoundLiteralExp`

  #### Declaration

  `class `CompoundLiteralExp`: dmd.expression.Expression;`

  C11 6.5.2.5 ( type-name ) { initializer-list }

  - `initializer`

    #### Declaration

    `Initializer `initializer`;`

    `initializer`-list

- `TypeExp`

  #### Declaration

  `class `TypeExp`: dmd.expression.Expression;`

  Mainly just a placeholder

- `ScopeExp`

  #### Declaration

  `class `ScopeExp`: dmd.expression.Expression;`

  Mainly just a placeholder of Package, Module, Nspace, and TemplateInstance (including TemplateMixin)

  #### Discussion

  A template instance that requires IFTI: foo!tiargs(fargs) // foo!tiargs is left until CallExp::semantic() or resolveProperties()

- `TemplateExp`

  #### Declaration

  `class `TemplateExp`: dmd.expression.Expression;`

  Mainly just a placeholder

- `NewExp`

  #### Declaration

  `class `NewExp`: dmd.expression.Expression;`

  newtype(arguments)

  - `argumentList`

    #### Declaration

    `ArgumentList `argumentList`();`

    Puts the `arguments` and `names` into an `ArgumentList` for easily passing them around. The fields are still separate for backwards compatibility

- `NewAnonClassExp`

  #### Declaration

  `class `NewAnonClassExp`: dmd.expression.Expression;`

  class baseclasses { } (arguments)

- `SymbolExp`

  #### Declaration

  `class `SymbolExp`: dmd.expression.Expression;`

- `SymOffExp`

  #### Declaration

  `class `SymOffExp`: dmd.expression.SymbolExp;`

  Offset from symbol

- `VarExp`

  #### Declaration

  `class `VarExp`: dmd.expression.SymbolExp;`

  Variable

- `OverExp`

  #### Declaration

  `class `OverExp`: dmd.expression.Expression;`

  Overload Set

- `FuncExp`

  #### Declaration

  `class `FuncExp`: dmd.expression.Expression;`

  Function/Delegate literal

- `DeclarationExp`

  #### Declaration

  `class `DeclarationExp`: dmd.expression.Expression;`

  Declaration of a symbol

  #### Discussion

  D grammar allows declarations only as statements. However in AST representation it can be part of any expression. This is used, for example, during internal syntax re-writes to inject hidden symbols.

- `TypeidExp`

  #### Declaration

  `class `TypeidExp`: dmd.expression.Expression;`

  typeid(int)

- `TraitsExp`

  #### Declaration

  `class `TraitsExp`: dmd.expression.Expression;`

  _traits(identifier, args...)

- `HaltExp`

  #### Declaration

  `class `HaltExp`: dmd.expression.Expression;`

  Generates a halt instruction

  #### Discussion

  `assert(0)` gets rewritten to this with `CHECKACTION.halt`

- `IsExp`

  #### Declaration

  `class `IsExp`: dmd.expression.Expression;`

  is(targ id tok tspec) is(targ id == tok2)

- `UnaExp`

  #### Declaration

  `abstract class `UnaExp`: dmd.expression.Expression;`

  Base class for unary operators

  #### Discussion

  https://dlang.org/spec/expression.html#unary-expression

  - `incompatibleTypes`

    #### Declaration

    `final Expression `incompatibleTypes`();`

    The type for a unary expression is incompatible. Print error message.

    #### Return Value

    ErrorExp

  - `setNoderefOperand`

    #### Declaration

    `final void `setNoderefOperand`();`

    Mark the operand as will never be dereferenced, which is useful info for @safe checks. Do before semantic() on operands rewrites them.

- `BinExp`

  #### Declaration

  `abstract class `BinExp`: dmd.expression.Expression;`

  Base class for binary operators

  - `incompatibleTypes`

    #### Declaration

    `final Expression `incompatibleTypes`();`

    The types for a binary expression are incompatible. Print error message.

    #### Return Value

    ErrorExp

  - `setNoderefOperands`

    #### Declaration

    `final void `setNoderefOperands`();`

    Mark the operands as will never be dereferenced, which is useful info for @safe checks. Do before semantic() on operands rewrites them.

- `BinAssignExp`

  #### Declaration

  `class `BinAssignExp`: dmd.expression.BinExp;`

  Binary operator assignment, `+=` `-=` `*=` etc.

- `MixinExp`

  #### Declaration

  `class `MixinExp`: dmd.expression.Expression;`

  A string mixin, `mixin("x")`

  #### Discussion

  https://dlang.org/spec/expression.html#mixin_expressions

- `ImportExp`

  #### Declaration

  `class `ImportExp`: dmd.expression.UnaExp;`

  An import expression, `import("file.txt")`

  #### Discussion

  Not to be confused with module imports, `import std.stdio`, which is an `ImportStatement`
  https://dlang.org/spec/expression.html#import_expressions

- `AssertExp`

  #### Declaration

  `class `AssertExp`: dmd.expression.UnaExp;`

  An assert expression, `assert(x == y)`

  #### Discussion

  https://dlang.org/spec/expression.html#assert_expressions

- `ThrowExp`

  #### Declaration

  `class `ThrowExp`: dmd.expression.UnaExp;`

  `throw <e1>` as proposed by DIP 1034.

  #### Discussion

  Replacement for the deprecated `ThrowStatement` that can be nested in other expression.

- `DotIdExp`

  #### Declaration

  `class `DotIdExp`: dmd.expression.UnaExp;`

- `DotTemplateExp`

  #### Declaration

  `class `DotTemplateExp`: dmd.expression.UnaExp;`

  Mainly just a placeholder

- `DotVarExp`

  #### Declaration

  `class `DotVarExp`: dmd.expression.UnaExp;`

- `DotTemplateInstanceExp`

  #### Declaration

  `class `DotTemplateInstanceExp`: dmd.expression.UnaExp;`

  foo.bar!(args)

- `DelegateExp`

  #### Declaration

  `class `DelegateExp`: dmd.expression.UnaExp;`

- `DotTypeExp`

  #### Declaration

  `class `DotTypeExp`: dmd.expression.UnaExp;`

- `ArgumentList`

  #### Declaration

  `struct `ArgumentList`;`

  The arguments of a function call

  #### Discussion

  Contains a list of expressions. If it is a named argument, the `names` list has a non-`null` entry at the same index.

  - `hasNames`

    #### Declaration

    `const pure nothrow @nogc @safe bool `hasNames`();`

    #### Return Value

    whether this argument list contains any named arguments

- `CallExp`

  #### Declaration

  `class `CallExp`: dmd.expression.UnaExp;`

  - `inDebugStatement`

    #### Declaration

    `bool `inDebugStatement`;`

    `true` if this was in a debug statement

  - `ignoreAttributes`

    #### Declaration

    `bool `ignoreAttributes`;`

    don't enforce attributes (e.g. call @gc function in @nogc code)

  - `argumentList`

    #### Declaration

    `ArgumentList `argumentList`();`

    Puts the `arguments` and `names` into an `ArgumentList` for easily passing them around. The fields are still separate for backwards compatibility

  - `this`

    #### Declaration

    `this(const ref Loc `loc`, FuncDeclaration `fd`, Expression `earg1`);`

    Instatiates a new function call expression

    #### Parameters

    `Loc `loc`` | location
    `FuncDeclaration `fd`` | the declaration of the function to call
    `Expression `earg1`` | the function argument

  - `create`

    #### Declaration

    `static CallExp `create`(const ref Loc `loc`, FuncDeclaration `fd`, Expression `earg1`);`

    Creates a new function call expression

    #### Parameters

    `Loc `loc`` | location
    `FuncDeclaration `fd`` | the declaration of the function to call
    `Expression `earg1`` | the function argument

- `AddrExp`

  #### Declaration

  `class `AddrExp`: dmd.expression.UnaExp;`

  The 'address of' operator, `&p`

- `PtrExp`

  #### Declaration

  `class `PtrExp`: dmd.expression.UnaExp;`

  The pointer dereference operator, `*p`

- `NegExp`

  #### Declaration

  `class `NegExp`: dmd.expression.UnaExp;`

  The negation operator, `-x`

- `UAddExp`

  #### Declaration

  `class `UAddExp`: dmd.expression.UnaExp;`

  The unary add operator, `+x`

- `ComExp`

  #### Declaration

  `class `ComExp`: dmd.expression.UnaExp;`

  The bitwise complement operator, `~x`

- `NotExp`

  #### Declaration

  `class `NotExp`: dmd.expression.UnaExp;`

  The logical not operator, `!x`

- `DeleteExp`

  #### Declaration

  `class `DeleteExp`: dmd.expression.UnaExp;`

  The delete operator, `delete x` (deprecated)

  #### Discussion

  https://dlang.org/spec/expression.html#delete_expressions

- `CastExp`

  #### Declaration

  `class `CastExp`: dmd.expression.UnaExp;`

  The type cast operator, `cast(T) x`

  #### Discussion

  It's possible to cast to one type while painting to another type
  https://dlang.org/spec/expression.html#cast_expressions

- `VectorExp`

  #### Declaration

  `class `VectorExp`: dmd.expression.UnaExp;`

- `VectorArrayExp`

  #### Declaration

  `class `VectorArrayExp`: dmd.expression.UnaExp;`

  e1.array property for vectors.

  #### Discussion

  https://dlang.org/spec/simd.html#properties

- `SliceExp`

  #### Declaration

  `class `SliceExp`: dmd.expression.UnaExp;`

  e1 [lwr .. upr]

  #### Discussion

  https://dlang.org/spec/expression.html#slice_expressions

  - `this`

    #### Declaration

    `this(const ref Loc `loc`, Expression `e1`, IntervalExp `ie`);`

- `ArrayLengthExp`

  #### Declaration

  `class `ArrayLengthExp`: dmd.expression.UnaExp;`

  The `.length` property of an array

- `ArrayExp`

  #### Declaration

  `class `ArrayExp`: dmd.expression.UnaExp;`

  e1 [ a0, a1, a2, a3 ,... ]

  #### Discussion

  https://dlang.org/spec/expression.html#index_expressions

- `DotExp`

  #### Declaration

  `class `DotExp`: dmd.expression.BinExp;`

- `CommaExp`

  #### Declaration

  `class `CommaExp`: dmd.expression.BinExp;`

  - `isGenerated`

    #### Declaration

    `const bool `isGenerated`;`

    This is needed because AssignExp rewrites CommaExp, hence it needs to trigger the deprecation.

  - `allowCommaExp`

    #### Declaration

    `bool `allowCommaExp`;`

    Temporary variable to enable / disable deprecation of comma expression depending on the context. Since most constructor calls are rewritting, the only place where `false` will be passed will be from the parser.

  - `allow`

    #### Declaration

    `static void `allow`(Expression `exp`);`

    If the argument is a CommaExp, set a flag to prevent deprecation messages

    #### Discussion

    It's impossible to know from CommaExp.semantic if the result will be used, hence when there is a result (type != void), a deprecation message is always emitted. However, some construct can produce a result but won't use it (ExpStatement and for loop increment). Those should call this function to prevent unwanted deprecations to be emitted.

    #### Parameters

    `Expression `exp`` | An expression that discards its result. If the argument is `null` or not a CommaExp, nothing happens.

- `IntervalExp`

  #### Declaration

  `class `IntervalExp`: dmd.expression.Expression;`

  Mainly just a placeholder

- `DelegatePtrExp`

  #### Declaration

  `class `DelegatePtrExp`: dmd.expression.UnaExp;`

  The `dg.ptr` property, pointing to the delegate's 'context'

  #### Discussion

  c.f.`DelegateFuncptrExp` for the delegate's function pointer `dg.funcptr`

- `DelegateFuncptrExp`

  #### Declaration

  `class `DelegateFuncptrExp`: dmd.expression.UnaExp;`

  The `dg.funcptr` property, pointing to the delegate's function

  #### Discussion

  c.f.`DelegatePtrExp` for the delegate's function pointer `dg.ptr`

- `IndexExp`

  #### Declaration

  `class `IndexExp`: dmd.expression.BinExp;`

  e1 [ e2 ]

- `PostExp`

  #### Declaration

  `class `PostExp`: dmd.expression.BinExp;`

  The postfix increment/decrement operator, `i++` / `i--`

- `PreExp`

  #### Declaration

  `class `PreExp`: dmd.expression.UnaExp;`

  The prefix increment/decrement operator, `++i` / `--i`

- `AssignExp`

  #### Declaration

  `class `AssignExp`: dmd.expression.BinExp;`

  The assignment / initialization operator, `=`

  Note: operator assignment `op=` has a different base class, `BinAssignExp`

  - `this`

    #### Declaration

    `this(const ref Loc `loc`, Expression `e1`, Expression `e2`);`

- `ConstructExp`

  #### Declaration

  `class `ConstructExp`: dmd.expression.AssignExp;`

- `BlitExp`

  #### Declaration

  `class `BlitExp`: dmd.expression.AssignExp;`

  A bit-for-bit copy from `e2` to `e1`

- `AddAssignExp`

  #### Declaration

  `class `AddAssignExp`: dmd.expression.BinAssignExp;`

  `x += y`

- `MinAssignExp`

  #### Declaration

  `class `MinAssignExp`: dmd.expression.BinAssignExp;`

  `x -= y`

- `MulAssignExp`

  #### Declaration

  `class `MulAssignExp`: dmd.expression.BinAssignExp;`

  `x *= y`

- `DivAssignExp`

  #### Declaration

  `class `DivAssignExp`: dmd.expression.BinAssignExp;`

  `x /= y`

- `ModAssignExp`

  #### Declaration

  `class `ModAssignExp`: dmd.expression.BinAssignExp;`

  `x %= y`

- `AndAssignExp`

  #### Declaration

  `class `AndAssignExp`: dmd.expression.BinAssignExp;`

  `x &= y`

- `OrAssignExp`

  #### Declaration

  `class `OrAssignExp`: dmd.expression.BinAssignExp;`

  `x |= y`

- `XorAssignExp`

  #### Declaration

  `class `XorAssignExp`: dmd.expression.BinAssignExp;`

  `x ^= y`

- `PowAssignExp`

  #### Declaration

  `class `PowAssignExp`: dmd.expression.BinAssignExp;`

  `x ^^= y`

- `ShlAssignExp`

  #### Declaration

  `class `ShlAssignExp`: dmd.expression.BinAssignExp;`

  `x <<= y`

- `ShrAssignExp`

  #### Declaration

  `class `ShrAssignExp`: dmd.expression.BinAssignExp;`

  `x >>= y`

- `UshrAssignExp`

  #### Declaration

  `class `UshrAssignExp`: dmd.expression.BinAssignExp;`

  `x >>>= y`

- `CatAssignExp`

  #### Declaration

  `class `CatAssignExp`: dmd.expression.BinAssignExp;`

  The `~=` operator.

  #### Discussion

  It can have one of the following operators:
  EXP.concatenateAssign - appending T[] to T[] EXP.concatenateElemAssign - appending T to T[] EXP.concatenateDcharAssign - appending dchar to T[]
  The parser initially sets it to EXP.concatenateAssign, and semantic() later decides which of the three it will be set to.

- `CatElemAssignExp`

  #### Declaration

  `class `CatElemAssignExp`: dmd.expression.CatAssignExp;`

  The `~=` operator when appending a single element

- `CatDcharAssignExp`

  #### Declaration

  `class `CatDcharAssignExp`: dmd.expression.CatAssignExp;`

  The `~=` operator when appending a single `dchar`

- `AddExp`

  #### Declaration

  `class `AddExp`: dmd.expression.BinExp;`

  The addition operator, `x + y`

  #### Discussion

  https://dlang.org/spec/expression.html#add_expressions

- `MinExp`

  #### Declaration

  `class `MinExp`: dmd.expression.BinExp;`

  The minus operator, `x - y`

  #### Discussion

  https://dlang.org/spec/expression.html#add_expressions

- `CatExp`

  #### Declaration

  `class `CatExp`: dmd.expression.BinExp;`

  The concatenation operator, `x ~ y`

  #### Discussion

  https://dlang.org/spec/expression.html#cat_expressions

- `MulExp`

  #### Declaration

  `class `MulExp`: dmd.expression.BinExp;`

  The multiplication operator, `x * y`

  #### Discussion

  https://dlang.org/spec/expression.html#mul_expressions

- `DivExp`

  #### Declaration

  `class `DivExp`: dmd.expression.BinExp;`

  The division operator, `x / y`

  #### Discussion

  https://dlang.org/spec/expression.html#mul_expressions

- `ModExp`

  #### Declaration

  `class `ModExp`: dmd.expression.BinExp;`

  The modulo operator, `x % y`

  #### Discussion

  https://dlang.org/spec/expression.html#mul_expressions

- `PowExp`

  #### Declaration

  `class `PowExp`: dmd.expression.BinExp;`

  The 'power' operator, `x ^^ y`

  #### Discussion

  https://dlang.org/spec/expression.html#pow_expressions

- `ShlExp`

  #### Declaration

  `class `ShlExp`: dmd.expression.BinExp;`

  The 'shift left' operator, `x << y`

  #### Discussion

  https://dlang.org/spec/expression.html#shift_expressions

- `ShrExp`

  #### Declaration

  `class `ShrExp`: dmd.expression.BinExp;`

  The 'shift right' operator, `x >> y`

  #### Discussion

  https://dlang.org/spec/expression.html#shift_expressions

- `UshrExp`

  #### Declaration

  `class `UshrExp`: dmd.expression.BinExp;`

  The 'unsigned shift right' operator, `x >>> y`

  #### Discussion

  https://dlang.org/spec/expression.html#shift_expressions

- `AndExp`

  #### Declaration

  `class `AndExp`: dmd.expression.BinExp;`

  The bitwise 'and' operator, `x & y`

  #### Discussion

  https://dlang.org/spec/expression.html#and_expressions

- `OrExp`

  #### Declaration

  `class `OrExp`: dmd.expression.BinExp;`

  The bitwise 'or' operator, `x | y`

  #### Discussion

  https://dlang.org/spec/expression.html#or_expressions

- `XorExp`

  #### Declaration

  `class `XorExp`: dmd.expression.BinExp;`

  The bitwise 'xor' operator, `x ^ y`

  #### Discussion

  https://dlang.org/spec/expression.html#xor_expressions

- `LogicalExp`

  #### Declaration

  `class `LogicalExp`: dmd.expression.BinExp;`

  The logical 'and' / 'or' operator, `X && Y` / `X || Y`

  #### Discussion

  https://dlang.org/spec/expression.html#andand_expressions https://dlang.org/spec/expression.html#oror_expressions

- `CmpExp`

  #### Declaration

  `class `CmpExp`: dmd.expression.BinExp;`

  A comparison operator, `<` `<=` `>` `>=`

  #### Discussion

  `op` is one of: EXP.lessThan, EXP.lessOrEqual, EXP.greaterThan, EXP.greaterOrEqual
  https://dlang.org/spec/expression.html#relation_expressions

- `InExp`

  #### Declaration

  `class `InExp`: dmd.expression.BinExp;`

  The `in` operator, `"a" in ["a": 1]`

  Note: `x !in y` is rewritten to `!(x in y)` in the parser
  https://dlang.org/spec/expression.html#in_expressions

- `RemoveExp`

  #### Declaration

  `class `RemoveExp`: dmd.expression.BinExp;`

  Associative array removal, `aa.remove(arg)`

  #### Discussion

  This deletes the key e1 from the associative array e2

- `EqualExp`

  #### Declaration

  `class `EqualExp`: dmd.expression.BinExp;`

  `==` and `!=`

  #### Discussion

  EXP.equal and EXP.notEqual
  https://dlang.org/spec/expression.html#equality_expressions

- `IdentityExp`

  #### Declaration

  `class `IdentityExp`: dmd.expression.BinExp;`

  `is` and `!is`

  #### Discussion

  EXP.identity and EXP.notIdentity
  https://dlang.org/spec/expression.html#identity_expressions

- `CondExp`

  #### Declaration

  `class `CondExp`: dmd.expression.BinExp;`

  The ternary operator, `econd ? e1 : e2`

  #### Discussion

  https://dlang.org/spec/expression.html#conditional_expressions

- `isDefaultInitOp`

  #### Declaration

  `pure nothrow @nogc @safe bool `isDefaultInitOp`(EXP `op`);`

  #### Return Value

  if this token is the ``op`` for a derived `DefaultInitExp` class.

- `DefaultInitExp`

  #### Declaration

  `class `DefaultInitExp`: dmd.expression.Expression;`

  A special keyword when used as a function's default argument

  #### Discussion

  When possible, special keywords are resolved in the parser, but when appearing as a default argument, they result in an expression deriving from this base class that is resolved for each function call.

  1. `const x = __LINE__; // resolved in the parser void foo(string file = __FILE__, int line = __LINE__); // DefaultInitExp`
  https://dlang.org/spec/expression.html#specialkeywords
- `FileInitExp`

  #### Declaration

  `class `FileInitExp`: dmd.expression.DefaultInitExp;`

  The `__FILE__` token as a default argument

- `LineInitExp`

  #### Declaration

  `class `LineInitExp`: dmd.expression.DefaultInitExp;`

  The `__LINE__` token as a default argument

- `ModuleInitExp`

  #### Declaration

  `class `ModuleInitExp`: dmd.expression.DefaultInitExp;`

  The `__MODULE__` token as a default argument

- `FuncInitExp`

  #### Declaration

  `class `FuncInitExp`: dmd.expression.DefaultInitExp;`

  The `__FUNCTION__` token as a default argument

- `PrettyFuncInitExp`

  #### Declaration

  `class `PrettyFuncInitExp`: dmd.expression.DefaultInitExp;`

  The `__PRETTY_FUNCTION__` token as a default argument

- `ObjcClassReferenceExp`

  #### Declaration

  `class `ObjcClassReferenceExp`: dmd.expression.Expression;`

  Objective-C class reference expression.

  #### Discussion

  Used to get the metaclass of an Objective-C class, `NSObject.Class`.

- `GenericExp`

  #### Declaration

  `class `GenericExp`: dmd.expression.Expression;`

  C11 6.5.1.1 Generic Selection For ImportC

  - `cntlExp`

    #### Declaration

    `Expression `cntlExp`;`

    controlling expression of a generic selection (not evaluated)

  - `types`

    #### Declaration

    `Types* `types`;`

    type-names for generic associations (`null` entry for `default`)

  - `exps`

    #### Declaration

    `Expressions* `exps`;`

    1:1 mapping of typeNames to `exps`

- `checkModifiable`

  #### Declaration

  `Modifiable `checkModifiable`(Expression `exp`, Scope* `sc`, ModifyFlags `flag` = ModifyFlags.none);`

  Parameters: `sc`: scope `flag`: 1: do not issue error message for invalid modification 2: the `exp` is a DotVarExp and a subfield of the leftmost variable is modified

  #### Return Value

  Whether the type is modifiable

- `isArrayConstructionOrAssign`

  #### Declaration

  `bool `isArrayConstructionOrAssign`(const Identifier `id`);`

  Verify if the given identifier is any of d_array{ctor,setctor,setassign,assign_l, assign_r}.

  #### Parameters

  `Identifier `id`` | the identifier to verify

  #### Return Value

  `true` if the identifier corresponds to a construction of assignement runtime hook, `false` otherwise.