Menu

- Learn
- Documentation
  - Language Reference
  - Library Reference
  - Command-line Reference
  - Feature Overview
  - Articles
- Downloads
- Packages
- Community
  - Blog
  - Orgs using D
  - Twitter
  - Calendar
  - Forums
  - IRC
  - Wiki
  - GitHub
  - Issues
  - Get involved
  - Contributors
  - Foundation
  - Security Team
  - Donate
  - Sponsors
- Resources
  - Tour
  - Books
  - Tutorials
  - Tools
  - Editors
  - IDEs
  - run.dlang.io
  - Visual D
  - Acknowledgments
  - D Style
  - Glossary
  - Sitemap

Search
Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

# dmd.expression

Compiler implementation of the D programming language.
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

inout(Expression) `firstComma`(inout Expression `e`);
  Find the first non-comma expression.
  Parameters:

  Expression `e` | Expressions connected by commas

  Returns:
  left-most non-comma expression
inout(Expression) `lastComma`(inout Expression `e`);
  Find the last non-comma expression.
  Parameters:

  Expression `e` | Expressions connected by commas

  Returns:
  right-most non-comma expression
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

  Returns:
  Found function if it satisfies isThis(), otherwise null
bool `isNeedThisScope`(Scope* `sc`, Declaration `d`);
  Determine if a this is needed to access `d`.
  Parameters:

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

  Returns:
  true means a this is needed
bool `isDotOpDispatch`(Expression `e`);
  check e is exp.opDispatch!(tiargs) or not It's used to switch to UFCS the semantic analysis path
void `expandTuples`(Expressions* `exps`);
  Expand tuples.

  Input exps aray of Expressions

  Output exps rewritten in place

TupleDeclaration `isAliasThisTuple`(Expression `e`);
  Expand alias this tuples.
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

  Returns:
  template for that function, otherwise null
Expression `valueNoDtor`(Expression `e`);
  If we want the value of this expression, but do not want to call the destructor on it.
Expression `doCopyOrMove`(Scope* `sc`, Expression `e`);
  Handle the postblit call on lvalue, or the move of rvalue.
struct `UnionExp`;
int `RealEquals`(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.
DotIdExp `typeDotIdExp`(ref const Loc `loc`, Type `type`, Identifier `ident`);
  TypeDotIdExp
VarDeclaration `expToVariable`(Expression `e`);
  Given an Expression, find the variable it really is.
  For example, a[index] is really a, and s.f is really s.
  Parameters:

  Expression `e` | Expression to look at

  Returns:
  variable if there is one, null if not
abstract class `Expression`: dmd.root.rootobject.RootObject;
  http://dlang.org/spec/expression.html#expression
  final Expression `copy`();
    Does *not* do a deep copy.
  static Expression `combine`(Expression `e1`, Expression `e2`);
    Combine e1 and e2 by CommaExp if both are not NULL.
  static Expression `extractLast`(Expression `e`, Expression* `pe0`);
    If 'e' is a tree of commas, returns the leftmost expression by stripping off it from the tree. The remained part of the tree is returned via *pe0. Otherwise 'e' is directly returned and *pe0 is set to NULL.
  bool `isLvalue`();
    Return !=0 if expression is an lvalue.
  Expression `toLvalue`(Scope* `sc`, Expression `e`);
    Give error if we're not an lvalue. If we can, convert expression to be an lvalue.
  Expression `resolveLoc`(ref const Loc `loc`, Scope* `sc`);
    Resolve __FILE__, __LINE__, __MODULE__, __FUNCTION__, __PRETTY_FUNCTION__, _FILE_FULL_PATH__ to loc.
  bool `checkType`();
    Check that the expression has a valid type. If not, generates an error "... has no type".
    Returns:
    true if the expression is not valid.

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

  bool `checkValue`();
    Check that the expression has a valid value. If not, generates an error "... has no value".
    Returns:
    true if the expression is not valid or has void type.
  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.
  final bool `checkPurity`(Scope* `sc`, VarDeclaration `v`);
    Accessing variable v. Check for purity and safety violations. Returns true if error occurs.
  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.
  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.
  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.
  final bool `checkReadModifyWrite`(TOK `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.
  int `checkModifiable`(Scope* `sc`, int `flag` = 0);

    Parameters sc: scope flag: 1: do not issue error message for invalid modification

    Returns:
    0: is not modifiable 1: is modifiable in default == being related to type.isMutable() 2: is modifiable, because this is a part of initializing.
  Expression `toBoolean`(Scope* `sc`);
    If expression can be tested for true or false, returns the modified expression. Otherwise returns ErrorExp.
  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.
  final Expression `addressOf`();
    Take address of expression.
  final Expression `deref`();
    If this is a reference, dereference it.
  bool `isBool`(bool `result`);
    Does this expression statically evaluate to a boolean 'result' (true or false)?
class `IntegerExp`: dmd.expression.Expression;
class `ErrorExp`: dmd.expression.Expression;
  Use this expression for error recovery. It should behave as a 'sink' to prevent further cascaded error messages.
class `RealExp`: dmd.expression.Expression;
class `ComplexExp`: dmd.expression.Expression;
class `IdentifierExp`: dmd.expression.Expression;
class `DollarExp`: dmd.expression.IdentifierExp;
class `DsymbolExp`: dmd.expression.Expression;
  Won't be generated by parser.
class `ThisExp`: dmd.expression.Expression;
  http://dlang.org/spec/expression.html#this
class `SuperExp`: dmd.expression.ThisExp;
  http://dlang.org/spec/expression.html#super
class `NullExp`: dmd.expression.Expression;
  http://dlang.org/spec/expression.html#null
class `StringExp`: dmd.expression.Expression;
  http://dlang.org/spec/expression.html#string_literals
  final 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

    Returns:
    number of code units
  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

  final const pure dchar `getCodeUnit`(size_t `i`);
    Get the code unit at index i
    Parameters:

    size_t `i` | index

    Returns:
    code unit at index i
  final 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

  char* `toPtr`();
    If the string data is UTF-8 and can be accessed directly, return a pointer to it. Do not assume a terminating 0.
    Returns:
    pointer to string data if possible, null if not
  StringExp `toUTF8`(Scope* `sc`);
    Convert string to char[].
  final const const(char)[] `toStringz`();
    Convert string contents to a 0 terminated string, allocated by mem.xmalloc().
class `TupleExp`: dmd.expression.Expression;
class `ArrayLiteralExp`: dmd.expression.Expression;
  [ e1, e2, e3, ... ]
  http://dlang.org/spec/expression.html#array_literals
  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.
  static Expressions* `copyElements`(Expression `e1`, Expression `e2` = null);
    Copy element Expressions in the parameters when they're ArrayLiteralExps.
    Parameters:

    Expression `e1` | If it's ArrayLiteralExp, its elements will be copied. Otherwise, `e1` itself will be pushed into the new Expressions.
    Expression `e2` | If it's not null, it will be pushed/appended to the new Expressions by the same way with `e1`.

    Returns:
    Newly allocated Expressions. Note that it points to the original Expression values in e1 and e2.
class `AssocArrayLiteralExp`: dmd.expression.Expression;
  [ key0 : value0, key1 : value1, ... ]
  http://dlang.org/spec/expression.html#associative_array_literals
enum int `stageScrub`;
  scrubReturnValue is running
enum int `stageSearchPointers`;
  hasNonConstPointers is running
enum int `stageOptimize`;
  optimize is running
enum int `stageApply`;
  apply is running
enum int `stageInlineScan`;
  inlineScan is running
enum int `stageToCBuffer`;
  toCBuffer is running
class `StructLiteralExp`: dmd.expression.Expression;
  sd( e1, e2, e3, ... )
  StructDeclaration `sd`;
    which aggregate this is for
  Expressions* `elements`;
    parallels sd.fields[] with null entries for fields to skip
  Type `stype`;
    final type of result (can be different from sd's type)
  bool `useStaticInit`;
    if this is true, use the StructDeclaration's init symbol
  Symbol* `sym`;
    back end symbol to initialize with literal
  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.
  StructLiteralExp `inlinecopy`;
    those fields need to prevent a infinite recursion when one field of struct initialized with 'this' pointer.
  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.
  Expression `getField`(Type `type`, uint `offset`);
    Gets expression at offset of type. Returns NULL if not found.
  int `getFieldIndex`(Type `type`, uint `offset`);
    Get index of field. Returns -1 if not found.
class `TypeExp`: dmd.expression.Expression;
  Mainly just a placeholder
class `ScopeExp`: dmd.expression.Expression;
  Mainly just a placeholder of Package, Module, Nspace, and TemplateInstance (including TemplateMixin)
  A template instance that requires IFTI: foo!tiargs(fargs) // foo!tiargs is left until CallExp::semantic() or resolveProperties()
class `TemplateExp`: dmd.expression.Expression;
  Mainly just a placeholder
class `NewExp`: dmd.expression.Expression;
  thisexp.new(newargs) newtype(arguments)
class `NewAnonClassExp`: dmd.expression.Expression;
  thisexp.new(newargs) class baseclasses { } (arguments)
class `SymbolExp`: dmd.expression.Expression;
class `SymOffExp`: dmd.expression.SymbolExp;
  Offset from symbol
class `VarExp`: dmd.expression.SymbolExp;
  Variable
  bool `hasCheckedAttrs`;
    Semantic can be called multiple times for a single expression. This field is needed to ensure the deprecation message will be printed only once.
class `OverExp`: dmd.expression.Expression;
  Overload Set
class `FuncExp`: dmd.expression.Expression;
  Function/Delegate literal
class `DeclarationExp`: dmd.expression.Expression;
  Declaration of a symbol
  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.
class `TypeidExp`: dmd.expression.Expression;
  typeid(int)
class `TraitsExp`: dmd.expression.Expression;
  _traits(identifier, args...)
class `HaltExp`: dmd.expression.Expression;
class `IsExp`: dmd.expression.Expression;
  is(targ id tok tspec) is(targ id == tok2)
class `UnaExp`: dmd.expression.Expression;
  final Expression `incompatibleTypes`();
    The type for a unary expression is incompatible. Print error message.
    Returns:
    ErrorExp
  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.
abstract class `BinExp`: dmd.expression.Expression;
  final Expression `incompatibleTypes`();
    The types for a binary expression are incompatible. Print error message.
    Returns:
    ErrorExp
  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.
class `BinAssignExp`: dmd.expression.BinExp;
class `CompileExp`: dmd.expression.UnaExp;
class `ImportExp`: dmd.expression.UnaExp;
class `AssertExp`: dmd.expression.UnaExp;
  https://dlang.org/spec/expression.html#assert_expressions
class `DotIdExp`: dmd.expression.UnaExp;
class `DotTemplateExp`: dmd.expression.UnaExp;
  Mainly just a placeholder
class `DotVarExp`: dmd.expression.UnaExp;
class `DotTemplateInstanceExp`: dmd.expression.UnaExp;
  foo.bar!(args)
class `DelegateExp`: dmd.expression.UnaExp;
class `DotTypeExp`: dmd.expression.UnaExp;
class `CallExp`: dmd.expression.UnaExp;
  this(ref const 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

  static CallExp `create`(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

class `AddrExp`: dmd.expression.UnaExp;
class `PtrExp`: dmd.expression.UnaExp;
class `NegExp`: dmd.expression.UnaExp;
class `UAddExp`: dmd.expression.UnaExp;
class `ComExp`: dmd.expression.UnaExp;
class `NotExp`: dmd.expression.UnaExp;
class `DeleteExp`: dmd.expression.UnaExp;
class `CastExp`: dmd.expression.UnaExp;
  Possible to cast to one type while painting to another type
class `VectorExp`: dmd.expression.UnaExp;
class `SliceExp`: dmd.expression.UnaExp;
  e1 [lwr .. upr]
  http://dlang.org/spec/expression.html#slice_expressions
  this(ref const Loc `loc`, Expression `e1`, IntervalExp `ie`);
class `ArrayLengthExp`: dmd.expression.UnaExp;
  static Expression `rewriteOpAssign`(BinExp `exp`);

    Rewrite array.length op= e2 as: array.length = array.length op e2 or: auto tmp = &array; (*tmp).length = (*tmp).length op e2

class `ArrayExp`: dmd.expression.UnaExp;
  e1 [ a0, a1, a2, a3 ,... ]
  http://dlang.org/spec/expression.html#index_expressions
class `DotExp`: dmd.expression.BinExp;
class `CommaExp`: dmd.expression.BinExp;
  const bool `isGenerated`;
    This is needed because AssignExp rewrites CommaExp, hence it needs to trigger the deprecation.
  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.
  static void `allow`(Expression `exp`);
    If the argument is a CommaExp, set a flag to prevent deprecation messages
    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.

class `IntervalExp`: dmd.expression.Expression;
  Mainly just a placeholder
class `DelegateFuncptrExp`: dmd.expression.UnaExp;
class `IndexExp`: dmd.expression.BinExp;
  e1 [ e2 ]
class `PostExp`: dmd.expression.BinExp;
  For both i++ and i--
class `PreExp`: dmd.expression.UnaExp;
  For both ++i and --i
class `AssignExp`: dmd.expression.BinExp;
  this(ref const Loc `loc`, Expression `e1`, Expression `e2`);
class `ConstructExp`: dmd.expression.AssignExp;
class `BlitExp`: dmd.expression.AssignExp;
class `AddAssignExp`: dmd.expression.BinAssignExp;
class `MinAssignExp`: dmd.expression.BinAssignExp;
class `MulAssignExp`: dmd.expression.BinAssignExp;
class `DivAssignExp`: dmd.expression.BinAssignExp;
class `ModAssignExp`: dmd.expression.BinAssignExp;
class `AndAssignExp`: dmd.expression.BinAssignExp;
class `OrAssignExp`: dmd.expression.BinAssignExp;
class `XorAssignExp`: dmd.expression.BinAssignExp;
class `PowAssignExp`: dmd.expression.BinAssignExp;
class `ShlAssignExp`: dmd.expression.BinAssignExp;
class `ShrAssignExp`: dmd.expression.BinAssignExp;
class `UshrAssignExp`: dmd.expression.BinAssignExp;
class `CatAssignExp`: dmd.expression.BinAssignExp;
  The ~= operator. It can have one of the following operators:
  TOK.concatenateAssign - appending T[] to T[] TOK.concatenateElemAssign - appending T to T[] TOK.concatenateDcharAssign - appending dchar to T[]
  The parser initially sets it to TOK.concatenateAssign, and semantic() later decides which of the three it will be set to.
class `AddExp`: dmd.expression.BinExp;
  http://dlang.org/spec/expression.html#add_expressions
class `MinExp`: dmd.expression.BinExp;
class `CatExp`: dmd.expression.BinExp;
  http://dlang.org/spec/expression.html#cat_expressions
class `MulExp`: dmd.expression.BinExp;
  http://dlang.org/spec/expression.html#mul_expressions
class `DivExp`: dmd.expression.BinExp;
  http://dlang.org/spec/expression.html#mul_expressions
class `ModExp`: dmd.expression.BinExp;
  http://dlang.org/spec/expression.html#mul_expressions
class `PowExp`: dmd.expression.BinExp;
  http://dlang.org/spec/expression.html#pow_expressions
class `ShlExp`: dmd.expression.BinExp;
class `ShrExp`: dmd.expression.BinExp;
class `UshrExp`: dmd.expression.BinExp;
class `AndExp`: dmd.expression.BinExp;
class `OrExp`: dmd.expression.BinExp;
class `XorExp`: dmd.expression.BinExp;
class `LogicalExp`: dmd.expression.BinExp;
  http://dlang.org/spec/expression.html#andand_expressions http://dlang.org/spec/expression.html#oror_expressions
class `CmpExp`: dmd.expression.BinExp;
  op is one of: TOK.lessThan, TOK.lessOrEqual, TOK.greaterThan, TOK.greaterOrEqual, TOK.unord, TOK.lg, TOK.leg, TOK.ule, TOK.ul, TOK.uge, TOK.ug, TOK.ue
  http://dlang.org/spec/expression.html#relation_expressions
class `InExp`: dmd.expression.BinExp;
class `RemoveExp`: dmd.expression.BinExp;
  This deletes the key e1 from the associative array e2
class `EqualExp`: dmd.expression.BinExp;
  == and !=
  TOK.equal and TOK.notEqual
  http://dlang.org/spec/expression.html#equality_expressions
class `IdentityExp`: dmd.expression.BinExp;
  is and !is
  TOK.identity and TOK.notIdentity
  http://dlang.org/spec/expression.html#identity_expressions
class `CondExp`: dmd.expression.BinExp;
  econd ? e1 : e2
  http://dlang.org/spec/expression.html#conditional_expressions
class `DefaultInitExp`: dmd.expression.Expression;
class `FileInitExp`: dmd.expression.DefaultInitExp;
class `LineInitExp`: dmd.expression.DefaultInitExp;
class `ModuleInitExp`: dmd.expression.DefaultInitExp;
class `FuncInitExp`: dmd.expression.DefaultInitExp;
class `PrettyFuncInitExp`: dmd.expression.DefaultInitExp;
class `ObjcClassReferenceExp`: dmd.expression.Expression;
  Objective-C class reference expression.
  Used to get the metaclass of an Objective-C class, NSObject.Class.

Copyright © 1999-2018 by the D Language Foundation | Page generated by Ddoc on Thu Oct 11 13:09:21 2018