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

Compiler implementation of the D programming language.
Template implementation.
Authors:

Source: dtemplate.d

Expression isExpression(RootObject o);
These functions substitute for dynamic_cast. dynamic_cast does not work on earlier versions of gcc.
bool isError(RootObject o);
Is this Object an error?
bool arrayObjectIsError(Objects* args);
Are any of the Objects an error?
Type getType(RootObject o);
Try to get arg as a type.
class TemplateDeclaration: ddmd.dsymbol.ScopeDsymbol;
bool overloadInsert(Dsymbol s);
Overload existing TemplateDeclaration 'this' with the new one 's'. Return true if successful; i.e. no conflict.
bool evaluateConstraint(TemplateInstance ti, Scope* sc, Scope* paramscope, Objects* dedargs, FuncDeclaration fd);
Check to see if constraint is satisfied.
MATCH matchWithInstance(Scope* sc, TemplateInstance ti, Objects* dedtypes, Expressions* fargs, int flag);
Given that ti is an instance of this TemplateDeclaration, deduce the types of the parameters to this, and store those deduced types in dedtypes[].

Input: flag 1: don't do semantic() because of dummy types 2: don't change types in matchArg()

Output: dedtypes deduced arguments Return match level.

MATCH leastAsSpecialized(Scope* sc, TemplateDeclaration td2, Expressions* fargs);
Determine partial specialization order of 'this' vs td2.
Returns:
match this is at least as specialized as td2 0 td2 is more specialized than this
MATCH deduceFunctionTemplateMatch(TemplateInstance ti, Scope* sc, ref FuncDeclaration fd, Type tthis, Expressions* fargs);
Match function arguments against a specific template function.

Input: ti sc instantiation scope fd tthis 'this' argument if !NULL fargs arguments to function

Output: fd Partially instantiated function declaration ti.tdtypes Expression/Type deduced template arguments

Returns:
match level bit 0-3 Match template parameters by inferred template arguments bit 4-7 Match template parameters by initial template arguments
RootObject declareParameter(Scope* sc, TemplateParameter tp, RootObject o);
Declare template parameter tp with value o, and install it in the scope sc.
FuncDeclaration doHeaderInstantiation(TemplateInstance ti, Scope* sc2, FuncDeclaration fd, Type tthis, Expressions* fargs);
Limited function template instantiation for using fd.leastAsSpecialized()
TemplateInstance findExistingInstance(TemplateInstance tithis, Expressions* fargs);
Given a new instance tithis of this TemplateDeclaration, see if there already exists an instance. If so, return that existing instance.
TemplateInstance addInstance(TemplateInstance ti);
Add instance ti to TemplateDeclaration's table of instances. Return a handle we can use to later remove it if it fails instantiation.
void removeInstance(TemplateInstance ti);
Remove TemplateInstance from table of instances.

Input: handle returned by addInstance()

TemplateTupleParameter isVariadic();
Check if the last template parameter is a tuple one, and returns it if so, else returns null.
Returns:
The last template parameter if it's a TemplateTupleParameter
bool isOverloadable();
We can overload templates.
void functionResolve(Match* m, Dsymbol dstart, Loc loc, Scope* sc, Objects* tiargs, Type tthis, Expressions* fargs);
Given function arguments, figure out which template function to expand, and return matching result.

Input: m matching result dstart the root of overloaded function templates loc instantiation location sc instantiation scope tiargs initial list of template arguments tthis if !NULL, the 'this' pointer argument fargs arguments to function

abstract class TemplateParameter;
MATCH matchArg(Loc instLoc, Scope* sc, Objects* tiargs, size_t i, TemplateParameters* parameters, Objects* dedtypes, Declaration* psparam);
Match to a particular TemplateParameter.

Input: instLoc location that the template is instantiated. tiargs[] actual arguments to template instance i i'th argument parameters[] template parameters dedtypes[] deduced arguments to template instance *psparam set to symbol declared and initialized to dedtypes[i]

class TemplateTypeParameter: ddmd.dtemplate.TemplateParameter;

Syntax: ident : specType = defaultType

class TemplateThisParameter: ddmd.dtemplate.TemplateTypeParameter;

Syntax: this ident : specType = defaultType

class TemplateValueParameter: ddmd.dtemplate.TemplateParameter;

Syntax: valType ident : specValue = defaultValue

class TemplateAliasParameter: ddmd.dtemplate.TemplateParameter;

Syntax: specType ident : specAlias = defaultAlias

class TemplateTupleParameter: ddmd.dtemplate.TemplateParameter;

Syntax: ident ...

class TemplateInstance: ddmd.dsymbol.ScopeDsymbol;

Given: foo!(args) => name = foo tiargs = args

final this(Loc loc, TemplateDeclaration td, Objects* tiargs);
This constructor is only called when we figured out which function template to instantiate.
final void printInstantiationTrace();
Given an error instantiating the TemplateInstance, give the nested TemplateInstance instantiations that got us here. Those are a list threaded into the nested scopes.
final Identifier getIdent();
Lazily generate identifier for template instance. This is because 75% of the ident's are never needed.
final int compare(RootObject o);
Compare proposed template instantiation with existing template instantiation. Note that this is not commutative because of the auto ref check.
Parameters:
this proposed template instantiation
RootObject o existing template instantiation
Returns:
0 for match, 1 for no match
final bool needsCodegen();
Returns true if this is not instantiated in non-root module, and is a part of non-speculative instantiatiation.

Note: minst does not stabilize until semantic analysis is completed, so don't call this function during semantic analysis to return precise result.

final bool findTempDecl(Scope* sc, WithScopeSymbol* pwithsym);
Find template declaration corresponding to template instance.
Returns:
false if finding fails.

Note: This function is reentrant against error occurrence. If returns false, any members of this object won't be modified, and repetition call will reproduce same error.

final bool updateTempDecl(Scope* sc, Dsymbol s);
Confirm s is a valid template, then store it.

Input: sc s candidate symbol of template. It may be: TemplateDeclaration FuncDeclaration with findTemplateDeclRoot() != NULL OverloadSet which contains candidates

Returns:
true if updating succeeds.
static bool semanticTiargs(Loc loc, Scope* sc, Objects* tiargs, int flags);
Run semantic of tiargs as arguments of template.

Input: loc sc tiargs array of template arguments flags 1: replace const variables with their initializers 2: don't devolve Parameter to Type

Returns:
false if one or more arguments have errors.
final bool semanticTiargs(Scope* sc);
Run semantic on the elements of tiargs.

Input: sc

Returns:
false if one or more arguments have errors.

Note: This function is reentrant against error occurrence. If returns false, all elements of tiargs won't be modified.

final bool needsTypeInference(Scope* sc, int flag = 0);
Determine if template instance is really a template function, and that template function needs to infer types from the function arguments.
Like findBestMatch, iterate possible template candidates, but just looks only the necessity of type inference.
final bool hasNestedArgs(Objects* args, bool isstatic);
Determines if a TemplateInstance will need a nested generation of the TemplateDeclaration. Sets enclosing property if so, and returns != 0;
final Dsymbols* appendToModuleMember();
Append 'this' to the specific module members[]
final void declareParameters(Scope* sc);
Declare parameters of template instance, initialize them with the template instance arguments.
final Identifier genIdent(Objects* args);
This instance needs an identifier for name mangling purposes. Create one by taking the template declaration name and adding the type signature for it.
void unSpeculative(Scope* sc, RootObject o);
IsExpression can evaluate the specified type speculatively, and even if it instantiates any symbols, they are normally unnecessary for the final executable. However, if those symbols leak to the actual code, compiler should remark them as non-speculative to generate their code and link to the final executable.
bool definitelyValueParameter(Expression e);
Return true if e could be valid only as a template value parameter. Return false if it might be an alias or tuple. (Note that even in this case, it could still turn out to be a value).
class TemplateMixin: ddmd.dtemplate.TemplateInstance;
struct TemplateInstanceBox;
This struct is needed for TemplateInstance to be the key in an associative array. Fixing https://issues.dlang.org/show_bug.cgi?id=15812 and

https: //issues.dlang.org/show_bug.cgi?id=15813 would make it unnecessary.