dmd.func

Defines a function declaration.

Includes:

  • function/delegate literals
  • function aliases
  • (static/shared) constructors/destructors/post-blits
  • invariant
  • unittest

Authors

Walter Bright

Source: func.d

  • ILS

    Declaration

    enum ILS: ubyte;

    Inline Status

    • Declaration

      uninitialized

      not computed yet

    • no

      Declaration

      no

      cannot inline

    • yes

      Declaration

      yes

      can inline

  • Declaration

    struct Ensure;

    Tuple of result identifier (possibly null) and statement. This is used to store out contracts: out(id){ ensure }

    • Declaration

      static Ensures* arraySyntaxCopy(Ensures* a);

      Do syntax copy of an array of Ensure's.

  • Declaration

    class FuncDeclaration: dmd.declaration.Declaration;

    • Declaration

      Statement fbody;

      function body

    • Declaration

      FuncDeclarations foverrides;

      functions this function overrides

    • Declaration

      const(char)* mangleString;

      mangled symbol created from mangleExact()

    • Declaration

      VarDeclaration vresult;

      result variable for out contracts

    • Declaration

      LabelDsymbol returnLabel;

      where the return goes

    • Declaration

      bool[size_t] isTypeIsolatedCache;

      cache for the potentially very expensive isTypeIsolated check

    • Declaration

      VarDeclaration vthis;

      'this' parameter (member and nested)

    • Declaration

      VarDeclaration v_arguments;

      'arguments' parameter

    • Declaration

      VarDeclaration v_argptr;

      'argptr' variable

    • Declaration

      VarDeclarations* parameters;

      Array of VarDeclaration's for parameters

    • Declaration

      DsymbolTable labtab;

      statement label symbol table

    • Declaration

      Dsymbol overnext;

      next in overload list

    • Declaration

      FuncDeclaration overnext0;

      next in overload list (only used during IFTI)

    • Declaration

      Loc endloc;

      location of closing curly bracket

    • Declaration

      int vtblIndex;

      for member functions, index into vtbl[]

    • Declaration

      int inlineNest;

      !=0 if nested inline

    • fes

      Declaration

      ForeachStatement fes;

      if foreach body, this is the foreach

    • Declaration

      BaseClass* interfaceVirtual;

      if virtual, but only appears in base interface vtbl[]

    • Declaration

      Type tintro;

      if !=NULL, then this is the type of the 'introducing' function this one is overriding

    • Declaration

      StorageClass storage_class2;

      storage class for template onemember's

    • Declaration

      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

    • Declaration

      VarDeclaration nrvo_var;

      variable to replace with shidden

    • Declaration

      Symbol* shidden;

      hidden pointer passed to function

    • Declaration

      GotoStatements* gotos;

      Gotos with forward references

    • Declaration

      VarDeclarations* alignSectionVars;

      local variables with alignment needs larger than stackAlign

    • Declaration

      Symbol* salignSection;

      pointer to aligned section, if any

    • Declaration

      BUILTIN builtin;

      set if this is a known, builtin function we can evaluate at compile time

    • Declaration

      int tookAddressOf;

      set if someone took the address of this function

    • Declaration

      VarDeclarations closureVars;

      local variables in this function which are referenced by nested functions (They'll get put into the "closure" for this function.)

    • Declaration

      VarDeclarations outerVars;

      Outer variables which are referenced by this nested function (the inverse of closureVars)

    • Declaration

      FuncDeclarations siblingCallers;

      Sibling nested functions which called this one

    • Declaration

      AttributeViolation* safetyViolation;

      In case of failed @safe inference, store the error that made the function @system for better diagnostics

    • Declaration

      ObjcFuncDeclaration objc;

      Data for a function declaration that is needed for the Objective-C integration.

    • Declaration

      final bool functionSemantic();

      Resolve forward reference of function signature - parameter types, return type, and attributes.

      Return Value

      false if any errors exist in the signature.

    • Declaration

      final bool functionSemantic3();

      Resolve forward reference of function body. Returns false if any errors exist in the body.

    • Declaration

      final bool checkForwardRef(const ref Loc loc);

      Check that this function type is properly resolved. If not, report "forward reference error" and return true.

    • Declaration

      final void declareThis(Scope* sc);

      Creates and returns the hidden parameters for this function declaration.

      Discussion

      Hidden parameters include the this parameter of a class, struct or nested function and the selector parameter for Objective-C methods.

    • Declaration

      final int overrides(FuncDeclaration fd);

      Determine if 'this' overrides fd. Return !=0 if it does.

    • Declaration

      final int findVtblIndex(Dsymbols* vtbl, int dim);

      Find index of function in vtbl[0..length] that this function overrides. Prefer an exact match to a covariant one.

      Parameters

      Dsymbols* vtbl

      vtable to use

      int dim

      maximal vtable dimension

      Return Value

      -1 didn't find one -2 can't determine because of forward references

    • Declaration

      final BaseClass* overrideInterface();

      If function a function in a base class, return that base class.

      Return Value

      base class if overriding, null if not

    • Declaration

      bool overloadInsert(Dsymbol s);

      Overload this FuncDeclaration with the new one f. Return true if successful; i.e. no conflict.

    • Declaration

      final FuncDeclaration overloadExactMatch(Type t);

      Find function in overload list that exactly matches t.

    • Declaration

      final FuncDeclaration overloadModMatch(const ref Loc loc, Type tthis, ref bool hasOverloads);

      Find function in overload list that matches to the 'this' modifier. There's four result types.

      Discussion

      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.

    • Declaration

      final TemplateDeclaration findTemplateDeclRoot();

      find function template root in overload list

    • Declaration

      final bool inUnittest();

      Returns true if function was declared directly or indirectly in a unittest block

    • Declaration

      final MATCH leastAsSpecialized(FuncDeclaration g, Identifiers* names);

      Determine partial specialization order of 'this' vs g. This is very similar to TemplateDeclaration::leastAsSpecialized().

      Return Value

      match 'this' is at least as specialized as g 0 g is more specialized than 'this'

    • Declaration

      final LabelDsymbol searchLabel(Identifier ident, const ref Loc loc = Loc.initial);

      Searches for a label with the given identifier. This function will insert a new LabelDsymbol into labtab if it does not contain a mapping for ident.

      Parameters

      Identifier ident

      identifier of the requested label

      Loc loc

      location used when creating a new LabelDsymbol

      Return Value

      the LabelDsymbol for ident

    • Declaration

      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

      Return Value

      0 same level

      0 decrease nesting by number -1 increase nesting by 1 (fd is nested within this) LevelError error, this cannot call fd

    • Declaration

      final int getLevelAndCheck(const ref Loc loc, Scope* sc, FuncDeclaration fd, Declaration decl);

      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

      Declaration decl

      The Declaration that triggered this check. Used to provide a better error message only.

      Return Value

      0 same level

      0 decrease nesting by number -1 increase nesting by 1 (fd is nested within 'this') LevelError error

    • Declaration

      final const(char)* toFullSignature();

      for diagnostics, e.g. 'int foo(int x, int y) pure'

    • Declaration

      final bool isAbstract();

      Override so it can work even if semantic() hasn't yet been run.

    • Declaration

      final bool canInferAttributes(Scope* sc);

      Decide if attributes for this function can be inferred from examining the function body.

      Return Value

      true if can

    • Declaration

      final void initInferAttributes();

      Initialize for inferring the attributes of this function.

    • Declaration

      final bool setImpure(Loc loc = Loc.init, const(char)* fmt = null, RootObject arg0 = null);

      The function is doing something impure, so mark it as impure.

      Parameters

      Loc loc

      location of impure action

      const(char)* fmt

      format string for error message. Must include "%s %s" for the function kind and name.

      RootObject arg0

      (optional) argument to format string

      Return Value

      true if there's a purity error

    • Declaration

      final bool setUnsafe(bool gag = false, Loc loc = Loc.init, const(char)* fmt = null, RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null);

      The function is doing something unsafe, so mark it as unsafe.

      Parameters

      bool gag

      surpress error message (used in escape.d)

      Loc loc

      location of error

      const(char)* fmt

      printf-style format string

      RootObject arg0

      (optional) argument for first %s format specifier

      RootObject arg1

      (optional) argument for second %s format specifier

      RootObject arg2

      (optional) argument for third %s format specifier

      Return Value

      whether there's a safe error

    • Declaration

      final bool setUnsafeCall(FuncDeclaration f);

      The function is calling @system function f, so mark it as unsafe.

      Parameters

      FuncDeclaration f

      function being called (needed for diagnostic of inferred functions)

      Return Value

      whether there's a safe error

    • Declaration

      final bool setGC(Loc loc, const(char)* fmt, RootObject arg0 = null);

      The function is doing something that may allocate with the GC, so mark it as not nogc (not no-how).

      Parameters

      Loc loc

      location of impure action

      const(char)* fmt

      format string for error message. Must include "%s %s" for the function kind and name.

      RootObject arg0

      (optional) argument to format string

      Return Value

      true if function is marked as @nogc, meaning a user error occurred

    • Declaration

      final bool setGCCall(FuncDeclaration f);

      The function calls non-@nogc function f, mark it as not nogc.

      Parameters

      FuncDeclaration f

      function being called

      Return Value

      true if function is marked as @nogc, meaning a user error occurred

    • Declaration

      final void setThrow(Loc loc, const(char)* fmt, RootObject arg0 = null);

      The function is doing something that may throw an exception, register that in case nothrow is being inferred

      Parameters

      Loc loc

      location of action

      const(char)* fmt

      format string for error message

      RootObject arg0

      (optional) argument to format string

    • Declaration

      final void setThrowCall(Loc loc, FuncDeclaration f);

      The function calls non-nothrow function f, register that in case nothrow is being inferred

      Parameters

      Loc loc

      location of call

      FuncDeclaration f

      function being called

    • Declaration

      final bool isReturnIsolated();

      See if pointers from function parameters, mutable globals, or uplevel functions could leak into return value.

      Return Value

      true if the function return value is isolated from any inputs to the function

    • Declaration

      final bool isTypeIsolated(Type t);
      final bool isTypeIsolated(Type t, ref StringTable!Type parentTypes);

      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

      Return Value

      true if t is isolated from any inputs to the function

    • Declaration

      const bool isNested();

      Determine if function needs a static frame pointer.

      Return Value

      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.

    • Declaration

      inout inout(AggregateDeclaration) isThis();

      Determine if function is a non-static member function that has an implicit 'this' expression.

      Return Value

      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.

    • Declaration

      final const bool isUnique();

      Return Value

      true if there are no overloads of this function

    • Declaration

      final bool checkNestedReference(Scope* sc, const ref 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.

    • Declaration

      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.

    • Declaration

      final bool checkClosure();

      Check that the function contains any closure. If it's @nogc, report suitable errors. This is mostly consistent with FuncDeclaration::needsClosure().

      Return Value

      true if any errors occur.

    • Declaration

      final bool hasNestedFrameRefs();

      Determine if function's variables are referenced by a function nested within it.

    • Declaration

      final void buildResultVar(Scope* sc, Type tret);

      Declare result variable lazily.

    • Declaration

      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.

    • Declaration

      final Statement mergeFrequireInclusivePreview(Statement sf, Expressions* params);

      Merge into this function the 'in' contracts of all it overrides.

    • Declaration

      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

      Return Value

      true found an 'out' contract

    • Declaration

      final void buildEnsureRequire();

      Rewrite contracts as statements.

    • Declaration

      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.

    • Declaration

      final ParameterList getParameterList();

      Return Value

      the function's parameter list, and whether it is variadic or not.

    • Declaration

      static FuncDeclaration genCfunc(Parameters* fparams, Type treturn, const(char)* name, StorageClass stc = 0);

      Generate a FuncDeclaration for a runtime library function.

    • Declaration

      final bool checkNRVO();

      Check all return statements for a function to verify that returning using NRVO is possible.

      Return Value

      false if the result cannot be returned by hidden reference.

  • Declaration

    Expression addInvariant(AggregateDeclaration ad, VarDeclaration vthis);

    Generate Expression to call the invariant.

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

    Return Value

    void expression that calls the invariant

  • Declaration

    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

    Return Value

    ==0 continue !=0 done (and the return value from the last dg() call)

  • Declaration

    auto MODMatchToBuffer(OutBuffer* buf, ubyte lhsMod, ubyte rhsMod);

    Checks for mismatching modifiers between lhsMod and rhsMod and prints the mismatching modifiers to buf.

    Discussion

    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

    Return Value

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

    Examples

    1. OutBuffer buf; auto mismatches = MODMatchToBuffer(&buf, MODFlags.shared_, 0); assert(buf[] == "`shared` "); assert(!mismatches.isNotShared); buf.setsize(0); mismatches = MODMatchToBuffer(&buf, 0, MODFlags.shared_); assert(buf[] == "non-shared "); assert(mismatches.isNotShared); buf.setsize(0); mismatches = MODMatchToBuffer(&buf, MODFlags.const_, 0); assert(buf[] == "`const` "); assert(!mismatches.isMutable); buf.setsize(0); mismatches = MODMatchToBuffer(&buf, 0, MODFlags.const_); assert(buf[] == "mutable "); assert(mismatches.isMutable);

  • Declaration

    enum FuncResolveFlag: ubyte;

    Flag used by .

    • Declaration

      standard

      issue error messages, solve the call.

    • Declaration

      quiet

      do not issue error message on no match, just return null.

    • Declaration

      overloadOnly

      only resolve overloads, i.e. do not issue error on ambiguous

    • Declaration

      ufcs

      matches and need explicit this.

      Discussion

      trying to resolve UFCS call

  • Declaration

    FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s, Objects* tiargs, Type tthis, ArgumentList argumentList, 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

    ArgumentList argumentList

    arguments to function

    FuncResolveFlag flags

    see .

    Return Value

    if match is found, then function symbol, else null

  • Declaration

    Type getIndirection(Type t);

    Returns an indirect type one step from t.

  • Declaration

    class FuncAliasDeclaration: dmd.func.FuncDeclaration;

    Used as a way to import a set of functions from another scope into this one.

  • Declaration

    class FuncLiteralDeclaration: dmd.func.FuncDeclaration;

    • Declaration

      void modifyReturns(Scope* sc, Type tret);

      Modify all expression type of return statements to tret.

      Discussion

      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.

  • Declaration

    class CtorDeclaration: dmd.func.FuncDeclaration;

  • Declaration

    class PostBlitDeclaration: dmd.func.FuncDeclaration;

  • Declaration

    class DtorDeclaration: dmd.func.FuncDeclaration;

  • Declaration

    class StaticCtorDeclaration: dmd.func.FuncDeclaration;

  • Declaration

    class SharedStaticCtorDeclaration: dmd.func.StaticCtorDeclaration;

  • Declaration

    class StaticDtorDeclaration: dmd.func.FuncDeclaration;

  • Declaration

    class SharedStaticDtorDeclaration: dmd.func.StaticDtorDeclaration;

  • Declaration

    class InvariantDeclaration: dmd.func.FuncDeclaration;

  • Declaration

    class UnitTestDeclaration: dmd.func.FuncDeclaration;

  • Declaration

    class NewDeclaration: dmd.func.FuncDeclaration;

  • Declaration

    bool isRootTraitsCompilesScope(Scope* sc);

    When a traits(compiles) is used on a function literal call we need to take into account if the body of the function violates any attributes, however, we must not affect the attribute inference on the outer function. The attributes of the function literal still need to be inferred, therefore we need a way to check for the scope that the traits compiles introduces.

    Parameters

    Scope* sc

    scope to be checked for

    Return Value

    true if the provided scope is the root of the traits compiles list of scopes.

  • Declaration

    bool setUnsafe(Scope* sc, bool gag = false, Loc loc = Loc.init, const(char)* fmt = null, RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null);

    A statement / expression in this scope is not @safe, so mark the enclosing function as @system

    Parameters

    Scope* sc

    scope that the unsafe statement / expression is in

    bool gag

    surpress error message (used in escape.d)

    Loc loc

    location of error

    const(char)* fmt

    printf-style format string

    RootObject arg0

    (optional) argument for first %s format specifier

    RootObject arg1

    (optional) argument for second %s format specifier

    RootObject arg2

    (optional) argument for third %s format specifier

    Return Value

    whether there's a safe error

  • Declaration

    bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, const(char)* msg, RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null);

    Like setUnsafe, but for safety errors still behind preview switches

    Discussion

    Given a FeatureState fs, for example dip1000 / dip25 / systemVariables, the behavior changes based on the setting:

    • In case of -revert=fs, it does nothing.
    • In case of -preview=fs, it's the same as setUnsafe
    • By default, print a deprecation in @safe functions, or store an attribute violation in inferred functions.

    Parameters

    Scope* sc

    used to find affected function/variable, and for checking whether we are in a deprecated / speculative scope

    FeatureState fs

    feature state from the preview flag

    bool gag

    surpress error message

    Loc loc

    location of error

    const(char)* msg

    printf-style format string

    RootObject arg0

    (optional) argument for first %s format specifier

    RootObject arg1

    (optional) argument for second %s format specifier

    RootObject arg2

    (optional) argument for third %s format specifier

    Return Value

    whether an actual safe error (not deprecation) occured

  • Declaration

    struct AttributeViolation;

    Stores a reason why a function failed to infer a function attribute like @safe or pure

    Discussion

    Has two modes:

    • a regular safety error, stored in (fmtStr, arg0, arg1)
    • a call to a function without the attribute, which is a special case, because in that case,
    that function might recursively also have a AttributeViolation. This way, in case of a big call stack, the error can go down all the way to the root cause. The FunctionDeclaration is then stored in arg0 and fmtStr must be null.

    • loc

      Declaration

      Loc loc;

      location of error

    • Declaration

      const(char)* fmtStr;

      printf-style format string

    • Declaration

      RootObject arg0;
      RootObject arg1;
      RootObject arg2;

      Arguments for up to two %s format specifiers in format string

  • Declaration

    void errorSupplementalInferredAttr(FuncDeclaration fd, int maxDepth, bool deprecation, STC stc);

    Print the reason why fd was inferred @system as a supplemental error

    Parameters

    FuncDeclaration fd

    function to check

    int maxDepth

    up to how many functions deep to report errors

    bool deprecation

    print deprecations instead of errors

    STC stc

    storage class of attribute to check