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

Source: expression.d

  • 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

  • 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

  • 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

  • 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

  • Declaration

    bool isDotOpDispatch(Expression e);

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

  • Declaration

    void expandTuples(Expressions* exps);

    Expand tuples.

    Input: exps aray of Expressions

    Output: exps rewritten in place

  • Declaration

    TupleDeclaration isAliasThisTuple(Expression e);

    Expand alias this tuples.

  • 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

  • Declaration

    Expression valueNoDtor(Expression e);

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

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

  • Declaration

    struct UnionExp;

  • 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

  • Declaration

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

    TypeDotIdExp

  • 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

  • Declaration

    abstract class Expression: dmd.ast_node.ASTNode;

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

    • Declaration

      final Expression copy();

      Does not do a deep copy.

    • Declaration

      static Expression combine(Expression e1, Expression e2);

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

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

    • Declaration

      bool isLvalue();

      Return !=0 if expression is an lvalue.

    • Declaration

      Expression toLvalue(Scope* sc, Expression e);

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

    • Declaration

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

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

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

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

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

    • 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")

    • Declaration

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

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

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

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

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

    • Declaration

      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.

    • Declaration

      Modifiable checkModifiable(Scope* sc, int flag = 0);

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

      Return Value

      Whether the type is modifiable

    • Declaration

      Expression toBoolean(Scope* sc);

      If expression can be tested for true or false, returns the modified expression. Otherwise returns ErrorExp.

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

    • Declaration

      final Expression addressOf();

      Take address of expression.

    • Declaration

      final Expression deref();

      If this is a reference, dereference it.

    • Declaration

      bool isBool(bool result);

      Does this expression statically evaluate to a boolean 'result' (true or false)?

  • Declaration

    class IntegerExp: dmd.expression.Expression;

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

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

  • Declaration

    class ErrorExp: dmd.expression.Expression;

    Use this expression for error recovery. It should behave as a 'sink' to prevent further cascaded error messages.

  • Declaration

    class VoidInitExp: dmd.expression.Expression;

    An uninitialized value, generated from void initializers.

    • var

      Declaration

      VarDeclaration var;

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

    • Declaration

      this(VarDeclaration var);

      Useful for error messages

  • Declaration

    class RealExp: dmd.expression.Expression;

  • Declaration

    class ComplexExp: dmd.expression.Expression;

  • Declaration

    class IdentifierExp: dmd.expression.Expression;

  • Declaration

    class DollarExp: dmd.expression.IdentifierExp;

  • Declaration

    class DsymbolExp: dmd.expression.Expression;

    Won't be generated by parser.

  • Declaration

    class ThisExp: dmd.expression.Expression;

  • Declaration

    class SuperExp: dmd.expression.ThisExp;

  • Declaration

    class NullExp: dmd.expression.Expression;

  • Declaration

    class StringExp: dmd.expression.Expression;

    • 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

    • 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

    • 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

    • 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

    • Declaration

      StringExp toUTF8(Scope* sc);

      Convert string to char[].

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

    • Declaration

      const const(char)[] toStringz();

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

    • Declaration

      const const(ubyte)[] peekData();

      Get a slice of the data.

    • Declaration

      ubyte[] borrowData();

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

    • Declaration

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

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

  • Declaration

    class TupleExp: dmd.expression.Expression;

  • Declaration

    class ArrayLiteralExp: dmd.expression.Expression;

    [ e1, e2, e3, ... ]

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

  • Declaration

    class AssocArrayLiteralExp: dmd.expression.Expression;

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

  • Declaration

    enum int stageScrub;

    scrubReturnValue is running

  • Declaration

    enum int stageSearchPointers;

    hasNonConstPointers is running

  • Declaration

    enum int stageOptimize;

    optimize is running

  • Declaration

    enum int stageApply;

    apply is running

  • Declaration

    enum int stageInlineScan;

    inlineScan is running

  • Declaration

    enum int stageToCBuffer;

    toCBuffer is running

  • Declaration

    class StructLiteralExp: dmd.expression.Expression;

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

    • sd

      Declaration

      StructDeclaration sd;

      which aggregate this is for

    • Declaration

      Expressions* elements;

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

    • 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

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

    • Declaration

      StructLiteralExp inlinecopy;

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

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

    • Declaration

      bool useStaticInit;

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

    • Declaration

      bool isOriginal;

      used when moving instances to indicate this is this.origin

    • Declaration

      Expression getField(Type type, uint offset);

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

    • Declaration

      int getFieldIndex(Type type, uint offset);

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

  • Declaration

    class TypeExp: dmd.expression.Expression;

    Mainly just a placeholder

  • 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()

  • Declaration

    class TemplateExp: dmd.expression.Expression;

    Mainly just a placeholder

  • Declaration

    class NewExp: dmd.expression.Expression;

    thisexp.new(newargs) newtype(arguments)

  • Declaration

    class NewAnonClassExp: dmd.expression.Expression;

    thisexp.new(newargs) class baseclasses { } (arguments)

  • Declaration

    class SymbolExp: dmd.expression.Expression;

  • Declaration

    class SymOffExp: dmd.expression.SymbolExp;

    Offset from symbol

  • Declaration

    class VarExp: dmd.expression.SymbolExp;

    Variable

  • Declaration

    class OverExp: dmd.expression.Expression;

    Overload Set

  • Declaration

    class FuncExp: dmd.expression.Expression;

    Function/Delegate literal

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

  • Declaration

    class TypeidExp: dmd.expression.Expression;

    typeid(int)

  • Declaration

    class TraitsExp: dmd.expression.Expression;

    _traits(identifier, args...)

  • Declaration

    class HaltExp: dmd.expression.Expression;

  • Declaration

    class IsExp: dmd.expression.Expression;

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

  • Declaration

    abstract class UnaExp: dmd.expression.Expression;

    • Declaration

      final Expression incompatibleTypes();

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

      Return Value

      ErrorExp

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

  • Declaration

    abstract class BinExp: dmd.expression.Expression;

    • Declaration

      final Expression incompatibleTypes();

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

      Return Value

      ErrorExp

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

  • Declaration

    class BinAssignExp: dmd.expression.BinExp;

  • Declaration

    class MixinExp: dmd.expression.Expression;

  • Declaration

    class ImportExp: dmd.expression.UnaExp;

  • Declaration

    class AssertExp: dmd.expression.UnaExp;

  • Declaration

    class DotIdExp: dmd.expression.UnaExp;

  • Declaration

    class DotTemplateExp: dmd.expression.UnaExp;

    Mainly just a placeholder

  • Declaration

    class DotVarExp: dmd.expression.UnaExp;

  • Declaration

    class DotTemplateInstanceExp: dmd.expression.UnaExp;

    foo.bar!(args)

  • Declaration

    class DelegateExp: dmd.expression.UnaExp;

  • Declaration

    class DotTypeExp: dmd.expression.UnaExp;

  • Declaration

    class CallExp: dmd.expression.UnaExp;

    • Declaration

      bool inDebugStatement;

      true if this was in a debug statement

    • Declaration

      bool ignoreAttributes;

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

    • Declaration

      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

    • Declaration

      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

  • Declaration

    class AddrExp: dmd.expression.UnaExp;

  • Declaration

    class PtrExp: dmd.expression.UnaExp;

  • Declaration

    class NegExp: dmd.expression.UnaExp;

  • Declaration

    class UAddExp: dmd.expression.UnaExp;

  • Declaration

    class ComExp: dmd.expression.UnaExp;

  • Declaration

    class NotExp: dmd.expression.UnaExp;

  • Declaration

    class DeleteExp: dmd.expression.UnaExp;

  • Declaration

    class CastExp: dmd.expression.UnaExp;

    Possible to cast to one type while painting to another type

  • Declaration

    class VectorExp: dmd.expression.UnaExp;

  • Declaration

    class VectorArrayExp: dmd.expression.UnaExp;

    e1.array property for vectors.

  • Declaration

    class SliceExp: dmd.expression.UnaExp;

    e1 [lwr .. upr]

    • Declaration

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

  • Declaration

    class ArrayLengthExp: dmd.expression.UnaExp;

  • Declaration

    class ArrayExp: dmd.expression.UnaExp;

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

  • Declaration

    class DotExp: dmd.expression.BinExp;

  • Declaration

    class CommaExp: dmd.expression.BinExp;

    • Declaration

      const bool isGenerated;

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

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

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

  • Declaration

    class IntervalExp: dmd.expression.Expression;

    Mainly just a placeholder

  • Declaration

    class DelegateFuncptrExp: dmd.expression.UnaExp;

  • Declaration

    class IndexExp: dmd.expression.BinExp;

    e1 [ e2 ]

  • Declaration

    class PostExp: dmd.expression.BinExp;

    For both i++ and i--

  • Declaration

    class PreExp: dmd.expression.UnaExp;

    For both ++i and --i

  • Declaration

    class AssignExp: dmd.expression.BinExp;

    • Declaration

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

  • Declaration

    class ConstructExp: dmd.expression.AssignExp;

  • Declaration

    class BlitExp: dmd.expression.AssignExp;

  • Declaration

    class AddAssignExp: dmd.expression.BinAssignExp;

  • Declaration

    class MinAssignExp: dmd.expression.BinAssignExp;

  • Declaration

    class MulAssignExp: dmd.expression.BinAssignExp;

  • Declaration

    class DivAssignExp: dmd.expression.BinAssignExp;

  • Declaration

    class ModAssignExp: dmd.expression.BinAssignExp;

  • Declaration

    class AndAssignExp: dmd.expression.BinAssignExp;

  • Declaration

    class OrAssignExp: dmd.expression.BinAssignExp;

  • Declaration

    class XorAssignExp: dmd.expression.BinAssignExp;

  • Declaration

    class PowAssignExp: dmd.expression.BinAssignExp;

  • Declaration

    class ShlAssignExp: dmd.expression.BinAssignExp;

  • Declaration

    class ShrAssignExp: dmd.expression.BinAssignExp;

  • Declaration

    class UshrAssignExp: dmd.expression.BinAssignExp;

  • Declaration

    class CatAssignExp: dmd.expression.BinAssignExp;

    The ~= operator. It can have one of the following operators:

    Discussion

    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.

  • Declaration

    class CatElemAssignExp: dmd.expression.CatAssignExp;

  • Declaration

    class CatDcharAssignExp: dmd.expression.CatAssignExp;

  • Declaration

    class AddExp: dmd.expression.BinExp;

  • Declaration

    class MinExp: dmd.expression.BinExp;

  • Declaration

    class CatExp: dmd.expression.BinExp;

  • Declaration

    class MulExp: dmd.expression.BinExp;

  • Declaration

    class DivExp: dmd.expression.BinExp;

  • Declaration

    class ModExp: dmd.expression.BinExp;

  • Declaration

    class PowExp: dmd.expression.BinExp;

  • Declaration

    class ShlExp: dmd.expression.BinExp;

  • Declaration

    class ShrExp: dmd.expression.BinExp;

  • Declaration

    class UshrExp: dmd.expression.BinExp;

  • Declaration

    class AndExp: dmd.expression.BinExp;

  • Declaration

    class OrExp: dmd.expression.BinExp;

  • Declaration

    class XorExp: dmd.expression.BinExp;

  • Declaration

    class LogicalExp: dmd.expression.BinExp;

  • Declaration

    class CmpExp: dmd.expression.BinExp;

    op is one of: TOK.lessThan, TOK.lessOrEqual, TOK.greaterThan, TOK.greaterOrEqual

  • Declaration

    class InExp: dmd.expression.BinExp;

  • Declaration

    class RemoveExp: dmd.expression.BinExp;

    This deletes the key e1 from the associative array e2

  • Declaration

    class EqualExp: dmd.expression.BinExp;

    == and !=

    Discussion

    TOK.equal and TOK.notEqual

    http://dlang.org/spec/expression.html#equality_expressions

  • Declaration

    class IdentityExp: dmd.expression.BinExp;

    is and !is

    Discussion

    TOK.identity and TOK.notIdentity

    http://dlang.org/spec/expression.html#identity_expressions

  • Declaration

    class CondExp: dmd.expression.BinExp;

  • Declaration

    pure nothrow @nogc @safe bool isDefaultInitOp(TOK op);

    Return Value

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

  • Declaration

    class DefaultInitExp: dmd.expression.Expression;

  • Declaration

    class FileInitExp: dmd.expression.DefaultInitExp;

  • Declaration

    class LineInitExp: dmd.expression.DefaultInitExp;

  • Declaration

    class ModuleInitExp: dmd.expression.DefaultInitExp;

  • Declaration

    class FuncInitExp: dmd.expression.DefaultInitExp;

  • Declaration

    class PrettyFuncInitExp: dmd.expression.DefaultInitExp;

  • Declaration

    class ObjcClassReferenceExp: dmd.expression.Expression;

    Objective-C class reference expression.

    Discussion

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