Compiler implementation of the D programming language.

Walter Bright
Boost License 1.0
enum ILS: int;

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;
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;


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.

Dsymbols* vtbl vtable to use
int dim maximal vtable dimension
bool fix17349 enable fix https://issues.dlang.org/show_bug.cgi?id=17349
-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.

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().

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.

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

Loc loc location for error messages
Scope* sc context
FuncDeclaration fd target of call
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.

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

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.

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.

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.
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.
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();
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().

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.

FuncDeclaration fd the function to search
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();
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.

ad aggregate with the invariant vthis variable with 'this'
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.

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.peekSlice == "`shared` ");

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

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

mismatches = MODMatchToBuffer(&buf, 0, MODFlags.const_);
assert(buf.peekSlice == "mutable ");
enum FuncResolveFlag: ubyte;

Flag used by resolveFuncCall.


issue error messages, solve the call.


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


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.

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

© 1999–2019 The D Language Foundation
Licensed under the Boost License 1.0.