ddmd.expression - D Programming Language

Menu

- Learn
- Documentation
  - Language Reference
  - Library Reference
  - Command-line Reference
  - Feature Overview
  - Articles
- Packages
- Community
  - Blog
  - Orgs using D
  - Twitter
  - Forums
  - IRC
  - Wiki
  - GitHub
  - Issues
  - Foundation
  - Donate
- Resources
  - Books
  - Tutorials
  - Tools
  - Editors
  - IDEs
  - 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.

# ddmd.expression

Compiler implementation of the D programming language.
Authors:
Walter Bright
License:
Boost License 1.0

Source: expression.d

Expression `getRightThis`(Loc `loc`, Scope* `sc`, AggregateDeclaration `ad`, Expression `e1`, Declaration `var`, int `flag` = 0);
  Given `var`, we need to get the right 'this' pointer if `var` is in an outer class, but our existing 'this' pointer is in an inner class.

  Input: `e1` existing 'this' `ad` struct or class we need the correct 'this' for `var` the specific member of `ad` we're accessing

FuncDeclaration `hasThis`(Scope* `sc`);
  Determine if 'this' is available. If it is, return the FuncDeclaration that has it.
Expression `resolvePropertiesX`(Scope* `sc`, Expression `e1`, Expression `e2` = null);
  Pull out any properties.
bool `checkPropertyCall`(Expression `e`, Expression `emsg`);
  Check the tail CallExp is really property function call.
Expression `resolvePropertiesOnly`(Scope* `sc`, Expression `e1`);
  If `e1` is a property function (template), resolve it.
Expression `searchUFCS`(Scope* `sc`, UnaExp `ue`, Identifier `ident`);
  Find symbol in accordance with the UFCS name look up rule
bool `isDotOpDispatch`(Expression `e`);
  check `e` is exp.opDispatch!(tiargs) or not It's used to switch to UFCS the semantic analysis path
Expression `resolveUFCS`(Scope* `sc`, CallExp `ce`);
  Pull out callable entity with UFCS.
Expression `resolveUFCSProperties`(Scope* `sc`, Expression `e1`, Expression `e2` = null);
  Pull out property with UFCS.
bool `arrayExpressionSemantic`(Expressions* `exps`, Scope* `sc`, bool `preserveErrors` = false);
  Perform semantic() on an array of Expressions.
void `expandTuples`(Expressions* `exps`);
  Expand tuples.

  Input: `exps` aray of Expressions

  Output: `exps` rewritten in place

TupleDeclaration `isAliasThisTuple`(Expression `e`);
  Expand alias this tuples.
bool `arrayExpressionToCommonType`(Scope* `sc`, Expressions* `exps`, Type* `pt`);
  The common type is determined by applying ?: to each pair.

  Output: `exps`[] properties resolved, implicitly cast to common type, rewritten in place *`pt` if `pt` is not NULL, set to the common type

  Returns:
  `true` a semantic error was detected
TemplateDeclaration `getFuncTemplateDecl`(Dsymbol `s`);
  Get TemplateDeclaration enclosing FuncDeclaration.
bool `preFunctionParameters`(Loc `loc`, Scope* `sc`, Expressions* `exps`);
  Preprocess arguments to function.

  Output: `exps`[] tuples expanded, properties resolved, rewritten in place

  Returns:
  `true` a semantic error occurred
Expression `valueNoDtor`(Expression `e`);
  If we want the value of this expression, but do not want to call the destructor on it.
bool `checkDefCtor`(Loc `loc`, Type `t`);
  Issue an error if default construction is disabled for type `t`. Default construction is required for arrays and 'out' parameters.
  Returns:
  `true` an error was issued
Expression `callCpCtor`(Scope* `sc`, Expression `e`);
  If `e` is an instance of a struct, and that struct has a copy constructor, rewrite `e` as: (tmp = `e`),tmp

  Input: `sc` just used to specify the scope of created temporary variable

Expression `doCopyOrMove`(Scope* `sc`, Expression `e`);
  Handle the postblit call on lvalue, or the move of rvalue.
bool `functionParameters`(Loc `loc`, Scope* `sc`, TypeFunction `tf`, Type `tthis`, Expressions* `arguments`, FuncDeclaration `fd`, Type* `prettype`, Expression* `peprefix`);
  Now that we know the exact type of the function we're calling, the `arguments`[] need to be adjusted: 1. implicitly convert argument to the corresponding parameter type 2. add default `arguments` for any missing `arguments` 3. do default promotions on `arguments` corresponding to ... 4. add hidden arguments[] argument 5. call copy constructor for struct value `arguments`

  Input: `tf` type of the function `fd` the function being called, NULL if called indirectly

  Output: *`prettype` return type of function *`peprefix` expression to execute before `arguments`[] are evaluated, NULL if none

  Returns:
  `true` errors happened
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`(Loc `loc`, Type `type`, Identifier `ident`);
  TypeDotIdExp
int `modifyFieldVar`(Loc `loc`, Scope* `sc`, VarDeclaration `var`, Expression `e1`);
  Mark variable v as modified if it is inside a constructor that `var` is a field in.
Expression `extractOpDollarSideEffect`(Scope* `sc`, UnaExp `ue`);
Expression `resolveOpDollar`(Scope* `sc`, ArrayExp `ae`, Expression* `pe0`);
  Runs semantic on `ae`.arguments. Declares temporary variables if '$' was used.
Expression `resolveOpDollar`(Scope* `sc`, ArrayExp `ae`, IntervalExp `ie`, Expression* `pe0`);
  Runs semantic on se.lwr and se.upr. Declares a temporary variable if '$' was used.
StringExp `semanticString`(Scope* `sc`, Expression `exp`, const char* `s`);
  Resolve `exp` as a compile-time known string.
  Parameters:

  Scope* `sc` | scope
  Expression `exp` | Expression which expected as a string
  char* `s` | What the string is expected for, will be used in error diagnostic.

  Returns:
  String literal, or null if error happens.
abstract class `Expression`: ddmd.root.rootobject.RootObject;
  final Expression `copy`();
    Does *not* do a deep `copy`.
  Expression `semantic`(Scope* `sc`);
    Semantically analyze Expression. Determine types, fold constants, etc.
  final Expression `trySemantic`(Scope* `sc`);
    Try to run semantic routines. If they fail, return NULL.
  void `printAST`(int `indent` = 0);
    Print AST data structure in a nice format.
    Parameters:

    int `indent` | indentation level

  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`(Loc `loc`, Scope* `sc`);
    Resolve __FILE__, __LINE__, __MODULE__, __FUNCTION__, __PRETTY_FUNCTION__ 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`: ddmd.expression.Expression;
class `ErrorExp`: ddmd.expression.Expression;
  Use this expression for error recovery. It should behave as a 'sink' to prevent further cascaded error messages.
class `RealExp`: ddmd.expression.Expression;
class `ComplexExp`: ddmd.expression.Expression;
class `IdentifierExp`: ddmd.expression.Expression;
class `DollarExp`: ddmd.expression.IdentifierExp;
class `DsymbolExp`: ddmd.expression.Expression;
  Won't be generated by parser. A placeholder expression to call `DsymbolExp`.resolve on specific symbol.
  static Expression `resolve`(Loc `loc`, Scope* `sc`, Dsymbol `s`, bool `hasOverloads`);
    Resolve a symbol `s` and wraps it in an expression object.
    Parameters:

    bool `hasOverloads` | works if the aliased symbol is a function.

    true: it'`s` overloaded and will be resolved later.

    false: it'`s` exact function symbol.

class `ThisExp`: ddmd.expression.Expression;
class `SuperExp`: ddmd.expression.ThisExp;
class `NullExp`: ddmd.expression.Expression;
class `StringExp`: ddmd.expression.Expression;
  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`: ddmd.expression.Expression;
class `ArrayLiteralExp`: ddmd.expression.Expression;
  [ e1, e2, e3, ... ]
  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 `Expresions. Note that it points the original Expression values in `e1` and `e2`.
class `AssocArrayLiteralExp`: ddmd.expression.Expression;
  [ key0 : value0, key1 : value1, ... ]
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`: ddmd.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`: ddmd.expression.Expression;
  Mainly just a placeholder
class `ScopeExp`: ddmd.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`: ddmd.expression.Expression;
  Mainly just a placeholder
class `NewExp`: ddmd.expression.Expression;
  thisexp.new(newargs) newtype(arguments)
class `NewAnonClassExp`: ddmd.expression.Expression;
  thisexp.new(newargs) class baseclasses { } (arguments)
class `SymbolExp`: ddmd.expression.Expression;
class `SymOffExp`: ddmd.expression.SymbolExp;
  Offset from symbol
class `VarExp`: ddmd.expression.SymbolExp;
  Variable
class `OverExp`: ddmd.expression.Expression;
  Overload Set
class `FuncExp`: ddmd.expression.Expression;
  Function/Delegate literal
class `DeclarationExp`: ddmd.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`: ddmd.expression.Expression;
  typeid(int)
class `TraitsExp`: ddmd.expression.Expression;
  _traits(identifier, args...)
class `HaltExp`: ddmd.expression.Expression;
class `IsExp`: ddmd.expression.Expression;
  is(targ id tok tspec) is(targ id == tok2)
abstract class `UnaExp`: ddmd.expression.Expression;
  final Expression `unaSemantic`(Scope* `sc`);
    Helper function for easy error propagation. If error occurs, returns ErrorExp. Otherwise returns NULL.
  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`: ddmd.expression.Expression;
  final Expression `binSemantic`(Scope* `sc`);
    Helper function for easy error propagation. If error occurs, returns ErrorExp. Otherwise returns NULL.
  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`: ddmd.expression.BinExp;
class `CompileExp`: ddmd.expression.UnaExp;
class `ImportExp`: ddmd.expression.UnaExp;
class `AssertExp`: ddmd.expression.UnaExp;
class `DotIdExp`: ddmd.expression.UnaExp;
class `DotTemplateExp`: ddmd.expression.UnaExp;
  Mainly just a placeholder
class `DotVarExp`: ddmd.expression.UnaExp;
class `DotTemplateInstanceExp`: ddmd.expression.UnaExp;
  foo.bar!(args)
class `DelegateExp`: ddmd.expression.UnaExp;
class `DotTypeExp`: ddmd.expression.UnaExp;
class `CallExp`: ddmd.expression.UnaExp;
class `AddrExp`: ddmd.expression.UnaExp;
class `PtrExp`: ddmd.expression.UnaExp;
class `NegExp`: ddmd.expression.UnaExp;
class `UAddExp`: ddmd.expression.UnaExp;
class `ComExp`: ddmd.expression.UnaExp;
class `NotExp`: ddmd.expression.UnaExp;
class `DeleteExp`: ddmd.expression.UnaExp;
class `CastExp`: ddmd.expression.UnaExp;
  Possible to cast to one type while painting to another type
class `VectorExp`: ddmd.expression.UnaExp;
class `SliceExp`: ddmd.expression.UnaExp;
  this(Loc `loc`, Expression `e1`, IntervalExp `ie`);
class `ArrayLengthExp`: ddmd.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`: ddmd.expression.UnaExp;
  e1 [ a0, a1, a2, a3 ,... ]
class `DotExp`: ddmd.expression.BinExp;
class `CommaExp`: ddmd.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`: ddmd.expression.Expression;
  Mainly just a placeholder
class `DelegateFuncptrExp`: ddmd.expression.UnaExp;
class `IndexExp`: ddmd.expression.BinExp;
  e1 [ e2 ]
class `PostExp`: ddmd.expression.BinExp;
  For both i++ and i--
class `PreExp`: ddmd.expression.UnaExp;
  For both ++i and --i
class `AssignExp`: ddmd.expression.BinExp;
  final this(Loc `loc`, Expression `e1`, Expression `e2`);
class `ConstructExp`: ddmd.expression.AssignExp;
class `BlitExp`: ddmd.expression.AssignExp;
class `AddAssignExp`: ddmd.expression.BinAssignExp;
class `MinAssignExp`: ddmd.expression.BinAssignExp;
class `MulAssignExp`: ddmd.expression.BinAssignExp;
class `DivAssignExp`: ddmd.expression.BinAssignExp;
class `ModAssignExp`: ddmd.expression.BinAssignExp;
class `AndAssignExp`: ddmd.expression.BinAssignExp;
class `OrAssignExp`: ddmd.expression.BinAssignExp;
class `XorAssignExp`: ddmd.expression.BinAssignExp;
class `PowAssignExp`: ddmd.expression.BinAssignExp;
class `ShlAssignExp`: ddmd.expression.BinAssignExp;
class `ShrAssignExp`: ddmd.expression.BinAssignExp;
class `UshrAssignExp`: ddmd.expression.BinAssignExp;
class `CatAssignExp`: ddmd.expression.BinAssignExp;
class `AddExp`: ddmd.expression.BinExp;
class `MinExp`: ddmd.expression.BinExp;
class `CatExp`: ddmd.expression.BinExp;
class `MulExp`: ddmd.expression.BinExp;
class `DivExp`: ddmd.expression.BinExp;
class `ModExp`: ddmd.expression.BinExp;
class `PowExp`: ddmd.expression.BinExp;
class `ShlExp`: ddmd.expression.BinExp;
class `ShrExp`: ddmd.expression.BinExp;
class `UshrExp`: ddmd.expression.BinExp;
class `AndExp`: ddmd.expression.BinExp;
class `OrExp`: ddmd.expression.BinExp;
class `XorExp`: ddmd.expression.BinExp;
class `OrOrExp`: ddmd.expression.BinExp;
class `AndAndExp`: ddmd.expression.BinExp;
class `CmpExp`: ddmd.expression.BinExp;
class `InExp`: ddmd.expression.BinExp;
class `RemoveExp`: ddmd.expression.BinExp;
  This deletes the key e1 from the associative array e2
class `EqualExp`: ddmd.expression.BinExp;
  == and !=
class `IdentityExp`: ddmd.expression.BinExp;
  is and !is
class `CondExp`: ddmd.expression.BinExp;
class `DefaultInitExp`: ddmd.expression.Expression;
class `FileInitExp`: ddmd.expression.DefaultInitExp;
class `LineInitExp`: ddmd.expression.DefaultInitExp;
class `ModuleInitExp`: ddmd.expression.DefaultInitExp;
class `FuncInitExp`: ddmd.expression.DefaultInitExp;
class `PrettyFuncInitExp`: ddmd.expression.DefaultInitExp;

Copyright © 1999-2017 by the D Language Foundation | Page generated by Ddoc on Tue May 23 07:38:49 2017