dmd.func - D Programming Language

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

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

Source func.d

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

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

enum `ILS`: int;
  Inline Status
  `uninitialized`
    not computed yet
  `no`
    cannot inline
  `yes`
    can inline
struct `Ensure`;
  Tuple of result identifier (possibly null) and statement. This is used to store out contracts: out(id){ ensure }
  static Ensures* `arraySyntaxCopy`(Ensures* `a`);
    Do syntax copy of an array of Ensure's.
class `FuncDeclaration`: dmd.declaration.Declaration;
  struct `HiddenParameters`;
    All hidden parameters bundled.
    VarDeclaration `vthis`;
      The this parameter for methods or nested functions.
      For methods, it would be the class object or struct value the method is called on. For nested functions it would be the enclosing function's stack frame.
    bool `isThis2`;
      Is 'this' a pointer to a static array holding two contexts.
    VarDeclaration `selectorParameter`;
      The selector parameter for Objective-C methods.
  Statements* `frequires`;
    in contracts
  Ensures* `fensures`;
    out contracts
  Statement `frequire`;
    lowered in contract
  Statement `fensure`;
    lowered out contract
  Statement `fbody`;
    function body
  FuncDeclarations `foverrides`;
    functions this function overrides
  FuncDeclaration `fdrequire`;
    function that does the in contract
  FuncDeclaration `fdensure`;
    function that does the out contract
  Expressions* `fdrequireParams`;
    argument list for __require
  Expressions* `fdensureParams`;
    argument list for __ensure
  const(char)* `mangleString`;
    mangled symbol created from mangleExact()
  VarDeclaration `vresult`;
    result variable for out contracts
  LabelDsymbol `returnLabel`;
    where the return goes
  VarDeclaration `vthis`;
    'this' parameter (member and nested)
  bool `isThis2`;
    has a dual-context 'this' parameter
  VarDeclaration `v_arguments`;
    'arguments' parameter
  ObjcSelector* `selector`;
    Objective-C method selector (member function only)
  VarDeclaration `selectorParameter`;
    Objective-C implicit selector parameter
  VarDeclaration `v_argptr`;
    'argptr' variable
  VarDeclarations* `parameters`;
    Array of VarDeclaration's for parameters
  DsymbolTable `labtab`;
    statement label symbol table
  Dsymbol `overnext`;
    next in overload list
  FuncDeclaration `overnext0`;
    next in overload list (only used during IFTI)
  Loc `endloc`;
    location of closing curly bracket
  int `vtblIndex`;
    for member functions, index into vtbl[]
  bool `naked`;
    true if naked
  bool `generated`;
    true if function was generated by the compiler rather than
  ubyte `isCrtCtorDtor`;
    supplied by the user
    has attribute pragma(crt_constructor(1)/crt_destructor(2))
  ILS `inlineStatusStmt`;
    not set before the glue layer
  CompiledCtfeFunctionPimpl `ctfeCode`;
    Local data (i.e. CompileCtfeFunction*) for module dinterpret
  int `inlineNest`;
    !=0 if nested inline
  bool `isArrayOp`;
    true if array operation
  bool `eh_none`;
    true if no exception unwinding is needed
  bool `semantic3Errors`;
    true if errors in semantic3 this function's frame ptr
  ForeachStatement `fes`;
    if foreach body, this is the foreach
  BaseClass* `interfaceVirtual`;
    if virtual, but only appears in base interface vtbl[]
  bool `introducing`;
    true if 'introducing' function
  Type `tintro`;
    if !=NULL, then this is the type of the 'introducing' function this one is overriding
  bool `inferRetType`;
    true if return type is to be inferred
  StorageClass `storage_class2`;
    storage class for template onemember's
  int `hasReturnExp`;
    1 if there's a return exp; statement 2 if there's a throw statement 4 if there's an assert(0) 8 if there's inline asm 16 if there are multiple return statements
  bool `nrvo_can`;
    true means we can do NRVO
  VarDeclaration `nrvo_var`;
    variable to replace with shidden
  Symbol* `shidden`;
    hidden pointer passed to function
  GotoStatements* `gotos`;
    Gotos with forward references
  BUILTIN `builtin`;
    set if this is a known, builtin function we can evaluate at compile time
  int `tookAddressOf`;
    set if someone took the address of this function
  VarDeclarations `closureVars`;
    local variables in this function which are referenced by nested functions
  FuncDeclarations `siblingCallers`;
    Sibling nested functions which called this one
  uint `flags`;
    FUNCFLAG.xxxxx
  final bool `functionSemantic`();
    Resolve forward reference of function signature - parameter types, return type, and attributes. Returns false if any errors exist in the signature.
  final bool `functionSemantic3`();
    Resolve forward reference of function body. Returns false if any errors exist in the body.
  final bool `checkForwardRef`(ref const Loc `loc`);
    Check that this function type is properly resolved. If not, report "forward reference error" and return true.
  final HiddenParameters `declareThis`(Scope* `sc`, AggregateDeclaration `ad`);
    Creates and returns the hidden parameters for this function declaration.
    Hidden parameters include the this parameter of a class, struct or nested function and the selector parameter for Objective-C methods.
  final int `overrides`(FuncDeclaration `fd`);
    Determine if 'this' overrides fd. Return !=0 if it does.
  final int `findVtblIndex`(Dsymbols* `vtbl`, int `dim`, bool `fix17349` = true);
    Find index of function in vtbl[0..dim] that this function overrides. Prefer an exact match to a covariant one.
    Parameters:

    Dsymbols* `vtbl` | vtable to use
    int `dim` | maximal vtable dimension
    bool `fix17349` | enable fix https://issues.dlang.org/show_bug.cgi?id=17349

    Returns:
    -1 didn't find one -2 can't determine because of forward references
  final BaseClass* `overrideInterface`();
    If function a function in a base class, return that base class.
    Returns:
    base class if overriding, null if not
  bool `overloadInsert`(Dsymbol `s`);
    Overload this FuncDeclaration with the new one f. Return true if successful; i.e. no conflict.
  final FuncDeclaration `overloadExactMatch`(Type `t`);
    Find function in overload list that exactly matches t.
  final FuncDeclaration `overloadModMatch`(ref const Loc `loc`, Type `tthis`, ref bool `hasOverloads`);
    Find function in overload list that matches to the 'this' modifier. There's four result types.
    1. If the 'tthis' matches only one candidate, it's an "exact match". Returns the function and 'hasOverloads' is set to false. eg. If 'tthis" is mutable and there's only one mutable method. 2. If there's two or more match candidates, but a candidate function will be a "better match". Returns the better match function but 'hasOverloads' is set to true. eg. If 'tthis' is mutable, and there's both mutable and const methods, the mutable method will be a better match. 3. If there's two or more match candidates, but there's no better match, Returns null and 'hasOverloads' is set to true to represent "ambiguous match". eg. If 'tthis' is mutable, and there's two or more mutable methods. 4. If there's no candidates, it's "no match" and returns null with error report. e.g. If 'tthis' is const but there's no const methods.
  final TemplateDeclaration `findTemplateDeclRoot`();
    find function template root in overload list
  final bool `inUnittest`();
    Returns true if function was declared directly or indirectly in a unittest block
  final MATCH `leastAsSpecialized`(FuncDeclaration `g`);
    Determine partial specialization order of 'this' vs g. This is very similar to TemplateDeclaration::leastAsSpecialized().
    Returns:
    match 'this' is at least as specialized as g 0 g is more specialized than 'this'
  final LabelDsymbol `searchLabel`(Identifier `ident`);
    Labels are in a separate scope, one per function.
  final int `getLevel`(FuncDeclaration `fd`, int `intypeof`);
    Determine lexical level difference from this to nested function `fd`.
    Parameters:

    FuncDeclaration `fd` | target of call
    int `intypeof` | !=0 if inside typeof

    Returns:
    0 same level >0 decrease nesting by number -1 increase nesting by 1 (`fd` is nested within this) LevelError error, this cannot call `fd`
  final int `getLevelAndCheck`(ref const Loc `loc`, Scope* `sc`, FuncDeclaration `fd`);
    Determine lexical level difference from this to nested function `fd`. Issue error if this cannot call `fd`.
    Parameters:

    Loc `loc` | location for error messages
    Scope* `sc` | context
    FuncDeclaration `fd` | target of call

    Returns:
    0 same level >0 decrease nesting by number -1 increase nesting by 1 (`fd` is nested within 'this') LevelError error
  final const(char)* `toFullSignature`();
    for diagnostics, e.g. 'int foo(int x, int y) pure'
  final bool `isAbstract`();
    Override so it can work even if semantic() hasn't yet been run.
  final bool `canInferAttributes`(Scope* `sc`);
    Decide if attributes for this function can be inferred from examining the function body.
    Returns:
    true if can
  final void `initInferAttributes`();
    Initialize for inferring the attributes of this function.
  final bool `setImpure`();
    The function is doing something impure, so mark it as impure. If there's a purity error, return true.
  final bool `setUnsafe`();
    The function is doing something unsafe, so mark it as unsafe. If there's a safe error, return true.
  final bool `setGC`();
    The function is doing something that may allocate with the GC, so mark it as not nogc (not no-how).
    Returns:
    true if function is marked as @nogc, meaning a user error occurred
  final bool `isReturnIsolated`();
    See if pointers from function parameters, mutable globals, or uplevel functions could leak into return value.
    Returns:
    true if the function return value is isolated from any inputs to the function
  final bool `isTypeIsolated`(Type `t`);
    See if pointers from function parameters, mutable globals, or uplevel functions could leak into type `t`.
    Parameters:

    Type `t` | type to check if it is isolated

    Returns:
    true if `t` is isolated from any inputs to the function
  const bool `isNested`();
    Determine if function needs a static frame pointer.
    Returns:
    true if function is really nested within other function.

    Contracts If isNested() returns true, isThis() should return false, unless the function needs a dual-context pointer.

  inout inout(AggregateDeclaration) `isThis`();
    Determine if function is a non-static member function that has an implicit 'this' expression.
    Returns:
    The aggregate it is a member of, or null.

    Contracts Both isThis() and isNested() should return true if function needs a dual-context pointer, otherwise if isThis() returns true, isNested() should return false.

  final bool `isUnique`();
    Returns:
    true if there are no overloads of this function
  final bool `checkNestedReference`(Scope* `sc`, ref const Loc `loc`);
    In the current function, we are calling 'this' function. 1. Check to see if the current function can call 'this' function, issue error if not. 2. If the current function is not the parent of 'this' function, then add the current function to the list of siblings of 'this' function. 3. If the current function is a literal, and it's accessing an uplevel scope, then mark it as a delegate. Returns true if error occurs.
  final bool `needsClosure`();
    Look at all the variables in this function that are referenced by nested functions, and determine if a closure needs to be created for them.
  final bool `checkClosure`();
    Check that the function contains any closure. If it's @nogc, report suitable errors. This is mostly consistent with FuncDeclaration::needsClosure().
    Returns:
    true if any errors occur.
  final bool `hasNestedFrameRefs`();
    Determine if function's variables are referenced by a function nested within it.
  final void `buildResultVar`(Scope* `sc`, Type `tret`);
    Declare result variable lazily.
  final Statement `mergeFrequire`(Statement `sf`, Expressions* `params`);
    Merge into this function the 'in' contracts of all it overrides. 'in's are OR'd together, i.e. only one of them needs to pass.
  static bool `needsFensure`(FuncDeclaration `fd`);
    Determine whether an 'out' contract is declared inside the given function or any of its overrides.
    Parameters:

    FuncDeclaration `fd` | the function to search

    Returns:
    true found an 'out' contract
  final void `buildEnsureRequire`();
    Rewrite contracts as statements.
  final Statement `mergeFensure`(Statement `sf`, Identifier `oid`, Expressions* `params`);
    Merge into this function the 'out' contracts of all it overrides. 'out's are AND'd together, i.e. all of them need to pass.
  final ParameterList `getParameterList`();
    Returns:
    the function's parameter list, and whether it is variadic or not.
  static FuncDeclaration `genCfunc`(Parameters* `fparams`, Type `treturn`, const(char)* `name`, StorageClass `stc` = 0);
    Generate a FuncDeclaration for a runtime library function.
  final void `checkDmain`();
    Check parameters and return type of D main() function. Issue error messages.
Expression `addInvariant`(ref const Loc `loc`, Scope* `sc`, AggregateDeclaration `ad`, VarDeclaration `vthis`);
  Generate Expression to call the invariant.

  Input ad aggregate with the invariant vthis variable with 'this'

  Returns:
  void expression that calls the invariant
int `overloadApply`(Dsymbol `fstart`, scope int delegate(Dsymbol) `dg`, Scope* `sc` = null);
  Visit each overloaded function/template in turn, and call dg(s) on it. Exit when no more, or dg(s) returns nonzero.
  Parameters:

  Dsymbol `fstart` | symbol to start from
  int delegate(Dsymbol) `dg` | the delegate to be called on the overload
  Scope* `sc` | context used to check if symbol is accessible (and therefore visible), can be null

  Returns:
  ==0 continue !=0 done (and the return value from the last dg() call)
auto `MODMatchToBuffer`(OutBuffer* `buf`, ubyte `lhsMod`, ubyte `rhsMod`);
  Checks for mismatching modifiers between `lhsMod` and `rhsMod` and prints the mismatching modifiers to `buf`.
  The modifiers of the `lhsMod` mismatching the ones with the `rhsMod` are printed, i.e. lhs(shared) vs. rhs() prints "shared", wheras lhs() vs rhs(shared) prints "non-shared".
  Parameters:

  OutBuffer* `buf` | output buffer to write to
  ubyte `lhsMod` | modifier on the left-hand side
  ubyte `lhsMod` | modifier on the right-hand side

  Returns:
  A tuple with isMutable and isNotShared set if the `lhsMod` is missing those modifiers (compared to rhs).
  Examples:

      OutBuffer buf;
      auto mismatches = MODMatchToBuffer(&buf, MODFlags.shared_, 0);
      assert(buf.peekSlice == "`shared` ");
      assert(!mismatches.isNotShared);

      buf.reset;
      mismatches = MODMatchToBuffer(&buf, 0, MODFlags.shared_);
      assert(buf.peekSlice == "non-shared ");
      assert(mismatches.isNotShared);

      buf.reset;
      mismatches = MODMatchToBuffer(&buf, MODFlags.const_, 0);
      assert(buf.peekSlice == "`const` ");
      assert(!mismatches.isMutable);

      buf.reset;
      mismatches = MODMatchToBuffer(&buf, 0, MODFlags.const_);
      assert(buf.peekSlice == "mutable ");
      assert(mismatches.isMutable);

enum `FuncResolveFlag`: ubyte;
  Flag used by resolveFuncCall.
  `standard`
    issue error messages, solve the call.
  `quiet`
    do not issue error message on no match, just return null.
  `overloadOnly`
    only resolve overloads.
FuncDeclaration `resolveFuncCall`(ref const Loc `loc`, Scope* `sc`, Dsymbol `s`, Objects* `tiargs`, Type `tthis`, Expressions* `fargs`, FuncResolveFlag `flags`);
  Given a symbol that could be either a FuncDeclaration or a function template, resolve it to a function symbol.
  Parameters:

  Loc `loc` | instantiation location
  Scope* `sc` | instantiation scope
  Dsymbol `s` | instantiation symbol
  Objects* `tiargs` | initial list of template arguments
  Type `tthis` | if !NULL, the this argument type
  Expressions* `fargs` | arguments to function
  FuncResolveFlag `flags` | see FuncResolveFlag.

  Returns:
  if match is found, then function symbol, else null
Type `getIndirection`(Type `t`);
  Returns an indirect type one step from t.
bool `followInstantiationContext`(D...)(Dsymbol `s`, D `p`);
  Returns true if any of the symbols `p` resides in the enclosing instantiation scope of `s`.
class `FuncAliasDeclaration`: dmd.func.FuncDeclaration;
  Used as a way to import a set of functions from another scope into this one.
class `FuncLiteralDeclaration`: dmd.func.FuncDeclaration;
  void `modifyReturns`(Scope* `sc`, Type `tret`);
    Modify all expression type of return statements to tret.
    On function literals, return type may be modified based on the context type after its semantic3 is done, in FuncExp::implicitCastTo.
    A function() dg = (){ return new B(); } // OK if is(B : A) == true
    If B to A conversion is convariant that requires offseet adjusting, all return statements should be adjusted to return expressions typed A.
class `CtorDeclaration`: dmd.func.FuncDeclaration;
class `PostBlitDeclaration`: dmd.func.FuncDeclaration;
class `DtorDeclaration`: dmd.func.FuncDeclaration;
class `StaticCtorDeclaration`: dmd.func.FuncDeclaration;
class `SharedStaticCtorDeclaration`: dmd.func.StaticCtorDeclaration;
class `StaticDtorDeclaration`: dmd.func.FuncDeclaration;
class `SharedStaticDtorDeclaration`: dmd.func.StaticDtorDeclaration;
class `InvariantDeclaration`: dmd.func.FuncDeclaration;
class `UnitTestDeclaration`: dmd.func.FuncDeclaration;
class `NewDeclaration`: dmd.func.FuncDeclaration;
class `DeleteDeclaration`: dmd.func.FuncDeclaration;

Copyright © 1999-2019 by the D Language Foundation | Page generated by Ddoc on Wed Jul 31 09:22:48 2019