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

Defines a function declaration.

Includes

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

Authors:

Source func.d

enum ILS: ubyte;
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;
Statement fbody;
function body
FuncDeclarations foverrides;
functions this function overrides
const(char)* mangleString;
mangled symbol created from mangleExact()
VarDeclaration vresult;
result variable for out contracts
LabelDsymbol returnLabel;
where the return goes
bool[size_t] isTypeIsolatedCache;
cache for the potentially very expensive isTypeIsolated check
VarDeclaration vthis;
'this' parameter (member and nested)
VarDeclaration v_arguments;
'arguments' 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[]
int inlineNest;
!=0 if nested inline
ForeachStatement fes;
if foreach body, this is the foreach
BaseClass* interfaceVirtual;
if virtual, but only appears in base interface vtbl[]
Type tintro;
if !=NULL, then this is the type of the 'introducing' function this one is overriding
STC storage_class2;
storage class for template onemember's
VarDeclaration nrvo_var;
variable to replace with shidden
Symbol* shidden;
hidden pointer passed to function
GotoStatements* gotos;
Gotos with forward references
VarDeclarations* alignSectionVars;
local variables with alignment needs larger than stackAlign
Symbol* salignSection;
pointer to aligned section, if any
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 (They'll get put into the "closure" for this function.)
VarDeclarations outerVars;
Outer variables which are referenced by this nested function (the inverse of closureVars)
FuncDeclarations siblingCallers;
Sibling nested functions which called this one
AttributeViolation* safetyViolation;
In case of failed @safe inference, store the error that made the function @system for better diagnostics
ObjcFuncDeclaration objc;
Data for a function declaration that is needed for the Objective-C integration.
bool overloadInsert(Dsymbol s);
Overload this FuncDeclaration with the new one f. Return true if successful; i.e. no conflict.
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 LabelDsymbol searchLabel(Identifier ident, Loc loc);
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
Returns:
the LabelDsymbol for ident
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 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 void setThrow(Loc loc, const(char)* format, RootObject[] args...);
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)* format format string for error message
RootObject[] args arguments to format string
final void setThrowCall(Loc loc, FuncDeclaration fd);
The function calls non-nothrow function f, register that in case nothrow is being inferred
Parameters:
Loc loc location of call
FuncDeclaration fd function being called
bool isNested() const;
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(AggregateDeclaration) isThis() inout;
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() const;
Returns:
true if there are no overloads of this function
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 hasNestedFrameRefs();
Determine if function's variables are referenced by a function nested within it.
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, STC stc = STC.none);
Generate a FuncDeclaration for a runtime library function.
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[] == "`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);
bool checkEscapingSiblings(FuncDeclaration f, FuncDeclaration outerFunc, void* p = null);
Given a nested function f inside a function outerFunc, check if any sibling callers of f have escaped. If so, mark all the enclosing functions as needing closures. This is recursive: we need to check the callers of our siblings. Note that nested functions can only call lexically earlier nested functions, so loops are impossible.
Parameters:
FuncDeclaration f inner function (nested within outerFunc)
FuncDeclaration outerFunc outer function
void* p for internal recursion use
Returns:
true if any closures were needed
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;
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;
bool standalone;
Exclude this constructor from cyclic dependency check
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;
struct AttributeViolation;
Stores a reason why a function failed to infer a function attribute like @safe or pure
Has two modes:
  • a regular safety error, stored in action
  • 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.
Loc loc;
location of error
FuncDeclaration fd;
function is the focus of the violation
string action;
Action that made the attribute fail to get inferred