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

Compiler implementation of the D programming language.
Authors:

Source: func.d

enum ILS: int;
Inline Status
ILSuninitialized
not computed yet
ILSno
cannot inline
ILSyes
can inline
enum int FUNCFLAGpurityInprocess;
working on determining purity
enum int FUNCFLAGsafetyInprocess;
working on determining safety
enum int FUNCFLAGnothrowInprocess;
working on determining nothrow
enum int FUNCFLAGnogcInprocess;
working on determining @nogc
enum int FUNCFLAGreturnInprocess;
working on inferring 'return' for parameters
enum int FUNCFLAGinlineScanned;
function has been scanned for inline possibilities
enum int FUNCFLAGinferScope;
infer 'scope' for parameters
class FuncDeclaration: ddmd.declaration.Declaration;
Types* fthrows;
Array of Type's of exceptions (not used)
Statement frequire;
in contract body
Statement fensure;
out contract body
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
const(char)* mangleString;
mangled symbol created from mangleExact()
Identifier outId;
identifier for out statement
VarDeclaration vresult;
variable corresponding to outId
LabelDsymbol returnLabel;
where the return goes
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[]
bool naked;
true if naked
bool generated;
true if function was generated by the compiler rather than
ILS inlineStatusStmt;
supplied by the user
CompiledCtfeFunction* ctfeCode;
Compiled code for interpreter (not actually)
int inlineNest;
!=0 if nested inline
bool isArrayOp;
true if array operation
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
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;
FUNCFLAGxxxxx
void semantic(Scope* sc);
Do the semantic analysis on the external interface to the function.
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(Loc loc);
Check that this function type is properly resolved. If not, report "forward reference error" and return true.
final int overrides(FuncDeclaration fd);
Determine if 'this' overrides fd. Return !=0 if it does.
final int findVtblIndex(Dsymbols* vtbl, int dim);
Find index of function in vtbl[0..dim] that this function overrides. Prefer an exact match to a covariant one.
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.
Parameters:
cd class that function is in
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(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(Loc loc, Scope* sc, FuncDeclaration fd);
Determine lexical level difference from 'this' to nested function 'fd'. Error if this cannot call fd.
Returns:
0 same level >0 decrease nesting by number -1 increase nesting by 1 (fd is nested within 'this') -2 error
final const(char)* toFullSignature();
for diagnostics, e.g. 'int foo(int x, int y) pure'
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 unsave, 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 isolateReturn();
Returns true if the function return value has no indirection which comes from the parameters.
final bool parametersIntersect(Type t);
Returns true if an object typed t can have indirections which come from the parameters.
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.

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: If isThis() returns true, isNested() should return false.

final FuncDeclaration isUnique();
If there are no overloads of function f, return that function, otherwise return NULL.
final bool checkNestedReference(Scope* sc, 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);
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.
final Statement mergeFensure(Statement sf, Identifier oid);
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 Parameters* getParameters(int* pvarargs);
Return 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(Loc loc, Scope* sc, AggregateDeclaration ad, VarDeclaration vthis, bool direct);
Generate Expression to call the invariant.

Input: ad aggregate with the invariant vthis variable with 'this' direct call invariant directly

Returns:
void expression that calls the invariant
int overloadApply(Dsymbol fstart, scope int delegate(Dsymbol) dg);
Visit each overloaded function/template in turn, and call dg(s) on it. Exit when no more, or dg(s) returns nonzero.
Returns:
==0 continue !=0 done
FuncDeclaration resolveFuncCall(Loc loc, Scope* sc, Dsymbol s, Objects* tiargs, Type tthis, Expressions* fargs, int flags = 0);
Given a symbol that could be either a FuncDeclaration or a function template, resolve it to a function symbol. loc instantiation location sc instantiation scope tiargs initial list of template arguments tthis if !NULL, the 'this' pointer argument fargs arguments to function flags 1: do not issue error message on no match, just return NULL 2: overloadResolve only
Type getIndirection(Type t);
Returns an indirect type one step from t.
bool traverseIndirections(Type ta, Type tb, void* p = null, bool reversePass = false);
Returns true if memory reachable through a reference B to a value of type tb, which has been constructed with a reference A to a value of type ta available, can alias memory reachable from A based on the types involved (either directly or via any number of indirections).
Note that this relation is not symmetric in the two arguments. For example, a const(int) reference can point to a pre-existing int, but not the other way round.
class FuncAliasDeclaration: ddmd.func.FuncDeclaration;
Used as a way to import a set of functions from another scope into this one.
class FuncLiteralDeclaration: ddmd.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: ddmd.func.FuncDeclaration;
class PostBlitDeclaration: ddmd.func.FuncDeclaration;
class DtorDeclaration: ddmd.func.FuncDeclaration;
class StaticCtorDeclaration: ddmd.func.FuncDeclaration;
class SharedStaticCtorDeclaration: ddmd.func.StaticCtorDeclaration;
class StaticDtorDeclaration: ddmd.func.FuncDeclaration;
class SharedStaticDtorDeclaration: ddmd.func.StaticDtorDeclaration;
class InvariantDeclaration: ddmd.func.FuncDeclaration;
static Identifier unitTestId(Loc loc);
Generate unique unittest function Id so we can have multiple instances per module.
class UnitTestDeclaration: ddmd.func.FuncDeclaration;
class NewDeclaration: ddmd.func.FuncDeclaration;
class DeleteDeclaration: ddmd.func.FuncDeclaration;