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.


Defines a function declaration.


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


Source func.d

enum ILS: ubyte;
Inline Status
not computed yet
cannot inline
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
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
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.
final int overrides(FuncDeclaration fd);
Determine if 'this' overrides fd. Return !=0 if it does.
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
static MATCH leastAsSpecialized(FuncDeclaration f, FuncDeclaration g, Identifiers* names);
Determine partial specialization order of functions f vs g. This is very similar to TemplateDeclaration::leastAsSpecialized().
FuncDeclaration f first function
FuncDeclaration g second function
Identifiers* names names of parameters
match 'this' is at least as specialized as g 0 g is more specialized than 'this'
final LabelDsymbol searchLabel(Identifier ident, const ref 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.
Identifier ident identifier of the requested label
Loc loc location used when creating a new LabelDsymbol
the LabelDsymbol for ident
final int getLevel(FuncDeclaration fd, int intypeof);
Determine lexical level difference from this to nested function fd.
FuncDeclaration fd target of call
int intypeof !=0 if inside typeof
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 initInferAttributes();
Initialize for inferring the attributes of this function.
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.
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
true if there's a purity error
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.
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
whether there's a safe error
final bool setUnsafeCall(FuncDeclaration f);
The function is calling @system function f, so mark it as unsafe.
FuncDeclaration f function being called (needed for diagnostic of inferred functions)
whether there's a safe error
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).
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
true if function is marked as @nogc, meaning a user error occurred
final bool setGCCall(FuncDeclaration f);
The function calls non-@nogc function f, mark it as not nogc.
FuncDeclaration f function being called
true if function is marked as @nogc, meaning a user error occurred
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
Loc loc location of action
const(char)* fmt format string for error message
RootObject arg0 (optional) argument to format string
final void setThrowCall(Loc loc, FuncDeclaration f);
The function calls non-nothrow function f, register that in case nothrow is being inferred
Loc loc location of call
FuncDeclaration f function being called
final bool isReturnIsolated();
See if pointers from function parameters, mutable globals, or uplevel functions could leak into return value.
true if the function return value is isolated from any inputs to the function
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.
Type t type to check if it is isolated
true if t is isolated from any inputs to the function
const bool isNested();
Determine if function needs a static frame pointer.
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.
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 const bool isUnique();
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 checkClosure();
Check that the function contains any closure. If it's @nogc, report suitable errors. This is mostly consistent with FuncDeclaration::needsClosure().
true if any errors occur.
final bool hasNestedFrameRefs();
Determine if function's variables are referenced by a function nested within it.
static @safe bool needsFensure(FuncDeclaration fd);
Determine whether an 'out' contract is declared inside the given function or any of its overrides.
FuncDeclaration fd the function to search
true found an 'out' contract
final ParameterList getParameterList();
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 bool checkNRVO();
Check all return statements for a function to verify that returning using NRVO is possible.
false if the result cannot be returned by hidden reference.
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.
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
==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".
OutBuffer* buf output buffer to write to
ubyte lhsMod modifier on the left-hand side
ubyte lhsMod modifier on the right-hand side
A tuple with isMutable and isNotShared set if the lhsMod is missing those modifiers (compared to rhs).
OutBuffer buf;
auto mismatches = MODMatchToBuffer(&buf, MODFlags.shared_, 0);
assert(buf[] == "`shared` ");

mismatches = MODMatchToBuffer(&buf, 0, MODFlags.shared_);
assert(buf[] == "non-shared ");

mismatches = MODMatchToBuffer(&buf, MODFlags.const_, 0);
assert(buf[] == "`const` ");

mismatches = MODMatchToBuffer(&buf, 0, MODFlags.const_);
assert(buf[] == "mutable ");
Type getIndirection(Type t);
Returns an indirect type one step from t.
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 (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 loc;
location of error
const(char)* fmtStr;
printf-style format string
RootObject arg0;

RootObject arg1;

RootObject arg2;
Arguments for up to two %s format specifiers in format string
void errorSupplementalInferredAttr(FuncDeclaration fd, int maxDepth, bool deprecation, STC stc);
Print the reason why fd was inferred @system as a supplemental error
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