# 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

  - `size`

    #### Declaration

    `final const pure nothrow @nogc @safe size_t `size`();`

    #### Return Value

    class instance `size` of this expression (implemented manually because `extern(C++)`)

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

  - `checkOverriddenDtor`

    #### Declaration

    `final void `checkOverriddenDtor`(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

  - `committed`

    #### Declaration

    `bool `committed`;`

    Whether the string literal's type is fixed

    Example:

    1. `wstring x = "abc"; // OK, string literal is flexible wstring y = cast(string) "abc"; // Error: type was committed after cast`
  - `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

  - `inlinecopy`

    #### Declaration

    `StructLiteralExp `inlinecopy`;`

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

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

  - `stageflags`

    #### Declaration

    `ubyte `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)

  - `isUfcsRewrite`

    #### Declaration

    `bool `isUfcsRewrite`;`

    the first argument was pushed in here by a UFCS rewrite

  - `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

- `calledFunctionType`

  #### Declaration

  `TypeFunction `calledFunctionType`(CallExp `ce`);`

  Get the called function type from a call expression

  #### Parameters

  `CallExp `ce`` | function call expression. Must have had semantic analysis done.

  #### Return Value

  called function type, or `null` if error / no semantic analysis done

- `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`);`

- `LoweredAssignExp`

  #### Declaration

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

  When an assignment expression is lowered to a druntime call this class is used to store the lowering. It essentially behaves the same as an AssignExp, but it is used to not waste space for other AssignExp that are not lowered to anything.

- `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

- `isArrayConstruction`

  #### Declaration

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

  Verify if the given identifier is d_array{,set}ctor.

  #### Parameters

  `Identifier `id`` | the identifier to verify

  #### Return Value

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