dmd.dtemplate
Defines TemplateDeclaration
, TemplateInstance
and a few utilities
Discussion
This modules holds the two main template types:
TemplateDeclaration
, which is the user-provided declaration of a template,
and TemplateInstance
, which is an instance of a TemplateDeclaration
with specific arguments.
Template Parameter:
Additionally, the classes for template parameters are defined in this module.
The base class, TemplateParameter
, is inherited by:
TemplateTypeParameter
TemplateThisParameter
TemplateValueParameter
TemplateAliasParameter
TemplateTupleParameter
Templates semantic: The start of the template instantiation process looks like this:
- A
TypeInstance
orTypeIdentifier
is encountered.TypeInstance
have a bang (e.g.Foo!(arg)
) whileTypeIdentifier
don't. - A
TemplateInstance
is instantiated - Semantic is run on the
TemplateInstance
(seedmd.dsymbolsem
) - The
TemplateInstance
search for itsTemplateDeclaration
, runs semantic on the template arguments and deduce the best match among the possible overloads. - The
TemplateInstance
search for existing instances with the same arguments, and uses it if found. - Otherwise, the rest of semantic is run on the
TemplateInstance
.
License
Source: dtemplate.d
Documentation: https://dlang.org/phobos/dmd_dtemplate.html
-
Declaration
pure nothrow @nogc inout(Expression)
isExpression
(inout RootObjecto
);These functions substitute for dynamic_cast. dynamic_cast does not work on earlier versions of gcc.
-
Declaration
pure nothrow @nogc bool
isError
(const RootObjecto
);Is this Object an error?
-
Declaration
pure nothrow @nogc bool
arrayObjectIsError
(const Objects*args
);Are any of the Objects an error?
-
Declaration
pure nothrow @nogc inout(Type)
getType
(inout RootObjecto
);Try to get arg as a type.
-
Declaration
class
TemplateDeclaration
: dmd.dsymbol.ScopeDsymbol;[mixin] template Identifier (parameters) [Constraint] https://dlang.org/spec/template.html https://dlang.org/spec/template-mixin.html
-
Declaration
bool
isTrivialAliasSeq
;matches pattern
template AliasSeq(T...) { alias AliasSeq = T; }
-
Declaration
bool
isTrivialAlias
;matches pattern
template Alias(T) { alias Alias = qualifiers(T); }
-
Declaration
bool
deprecated_
;this template declaration is deprecated
-
Declaration
int
inuse
;for recursive expansion detection
-
Declaration
bool
overloadInsert
(Dsymbols
);Overload existing TemplateDeclaration 'this' with the new one '
s
'. Returntrue
if successful; i.e. no conflict. -
Declaration
const const(char)*
toCharsNoConstraints
();Similar to
toChars
, but does not print the template constraints -
Declaration
bool
evaluateConstraint
(TemplateInstanceti
, Scope*sc
, Scope*paramscope
, Objects*dedargs
, FuncDeclarationfd
);Check to see if constraint is satisfied.
-
Declaration
const(char)*
getConstraintEvalError
(ref const(char)*tip
);Destructively get the error message from the last constraint evaluation
Parameters
const(char)*
tip
tip
to show after printing all overloads -
Declaration
Scope*
scopeForTemplateParameters
(TemplateInstanceti
, Scope*sc
);Create a scope for the parameters of the TemplateInstance
in the parent scopeti
sc
from the ScopeDsymbol paramsym.Discussion
If paramsym is
null
a new ScopeDsymbol is used in place of paramsym.Parameters
TemplateInstance
ti
the TemplateInstance whose parameters to generate the scope for.
Scope*
sc
the parent scope of
ti
Return Value
a scope for the parameters of
ti
-
Declaration
MATCH
matchWithInstance
(Scope*sc
, TemplateInstanceti
, Objects*dedtypes
, Expressions*fargs
, intflag
);Given that
ti
is an instance of this TemplateDeclaration, deduce the types of the parameters to this, and store those deduced types indedtypes
[].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. -
Declaration
MATCH
leastAsSpecialized
(Scope*sc
, TemplateDeclarationtd2
, Expressions*fargs
);Determine partial specialization order of 'this' vs
td2
.Return Value
match this is at least as specialized as
td2
0td2
is more specialized than this -
Declaration
MATCH
deduceFunctionTemplateMatch
(TemplateInstanceti
, Scope*sc
, ref FuncDeclarationfd
, Typetthis
, Expressions*fargs
);Match function arguments against a specific template function.
Input:
ti
sc
instantiation scopefd
tthis
'this' argument if !NULLfargs
arguments to functionOutput:
fd
Partially instantiated function declarationti
.tdtypes Expression/Type deduced template argumentsReturn Value
match level bit 0-3 Match template parameters by inferred template arguments bit 4-7 Match template parameters by initial template arguments
-
Declaration
RootObject
declareParameter
(Scope*sc
, TemplateParametertp
, RootObjecto
);Declare template parameter
tp
with valueo
, and install it in the scopesc
. -
Declaration
FuncDeclaration
doHeaderInstantiation
(TemplateInstanceti
, Scope*sc2
, FuncDeclarationfd
, Typetthis
, Expressions*fargs
);Limited function template instantiation for using
fd
.leastAsSpecialized() -
Declaration
TemplateInstance
findExistingInstance
(TemplateInstancetithis
, Expressions*fargs
);Given a new instance
tithis
of this TemplateDeclaration, see if there already exists an instance. If so, return that existing instance. -
Declaration
TemplateInstance
addInstance
(TemplateInstanceti
);Add instance
ti
to TemplateDeclaration's table of instances. Return a handle we can use to later remove it if it fails instantiation. -
Declaration
void
removeInstance
(TemplateInstanceti
);Remove TemplateInstance from table of instances.
Input: handle returned by addInstance()
-
Declaration
TemplateTupleParameter
isVariadic
();Check if the last template parameter is a tuple one, and returns it if so, else returns
null
.Return Value
The last template parameter if it's a
TemplateTupleParameter
-
Declaration
const bool
isOverloadable
();We can overload templates.
-
-
Declaration
void
functionResolve
(ref MatchAccumulatorm
, Dsymboldstart
, Locloc
, Scope*sc
, Objects*tiargs
, Typetthis
, Expressions*fargs
, const(char)**pMessage
= null);Given function arguments, figure out which template function to expand, and return matching result.
Parameters
MatchAccumulator
m
matching result
Dsymbol
dstart
the root of overloaded function templates
Loc
loc
instantiation location
Scope*
sc
instantiation scope
Objects*
tiargs
initial list of template arguments
Type
tthis
if !NULL, the 'this' pointer argument
Expressions*
fargs
arguments to function
const(char)**
pMessage
address to store error message, or
null
-
Declaration
bool
reliesOnTident
(Typet
, TemplateParameters*tparams
, size_tiStart
= 0);Check whether the type
t
representation relies on one or more the template parameters.Parameters
Type
t
Tested type, if
null
, returnsfalse
.TemplateParameters*
tparams
Template parameters.
size_t
iStart
Start index of
tparams
to limit the tested parameters. If it's nonzero,tparams
[0..iStart
] will be excluded from the test target. -
Declaration
abstract class
TemplateParameter
: dmd.ast_node.ASTNode; -
Declaration
class
TemplateTypeParameter
: dmd.dtemplate.TemplateParameter;Syntax: ident : specType = defaultType
-
Declaration
class
TemplateThisParameter
: dmd.dtemplate.TemplateTypeParameter;Syntax: this ident : specType = defaultType
-
Declaration
class
TemplateValueParameter
: dmd.dtemplate.TemplateParameter;Syntax: valType ident : specValue = defaultValue
-
Declaration
class
TemplateAliasParameter
: dmd.dtemplate.TemplateParameter;Syntax: specType ident : specAlias = defaultAlias
-
Declaration
class
TemplateTupleParameter
: dmd.dtemplate.TemplateParameter;Syntax: ident ...
-
Declaration
class
TemplateInstance
: dmd.dsymbol.ScopeDsymbol;Given: foo!(args) => name = foo tiargs = args
-
Declaration
final const pure nothrow @nogc @property @safe bool
semantictiargsdone
();has semanticTiargs() been done?
-
Declaration
final const pure nothrow @nogc @property @safe bool
havetempdecl
();if used second constructor
-
Declaration
final const pure nothrow @nogc @property @safe bool
gagged
();if the instantiation is done with error gagging
-
Declaration
this(ref const Loc
loc
, TemplateDeclarationtd
, Objects*tiargs
);This constructor is only called when we figured out which function template to instantiate.
-
Declaration
final void
printInstantiationTrace
(Classificationcl
= Classification.error);Given an error instantiating the TemplateInstance, give the nested TemplateInstance instantiations that got us here. Those are a list threaded into the nested scopes.
-
Declaration
final Identifier
getIdent
();Lazily generate identifier for template instance. This is because 75% of the ident's are never needed.
-
Declaration
final bool
equalsx
(TemplateInstanceti
);Compare proposed template instantiation with existing template instantiation. Note that this is not commutative because of the auto ref check.
Parameters
TemplateInstance
ti
existing template instantiation
Return Value
true
for match -
Declaration
final bool
isDiscardable
();Return Value
true
if the instances' innards are discardable.
The idea of this function is to see if the template instantiation can be 100% replaced with its eponymous member. All other members can be discarded, even in the compiler to free memory (for example, the template could be expanded in a region allocator, deemed trivial, the end result copied back out independently and the entire region freed), and can be elided entirely from the binary.
The current implementation affects code that generally looks like:
template foo(args...) { some_basic_type_or_string helper() { .... } enum foo = helper(); }
since it was the easiest starting point of implementation but it can and should be expanded more later. -
Declaration
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.
-
Declaration
final bool
findTempDecl
(Scope*sc
, WithScopeSymbol*pwithsym
);Find template declaration corresponding to template instance.
Return Value
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. -
Declaration
final bool
updateTempDecl
(Scope*sc
, Dsymbols
);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 candidatesReturn Value
true
if updating succeeds. -
Declaration
static bool
semanticTiargs
(ref const Locloc
, Scope*sc
, Objects*tiargs
, intflags
);Run semantic of
tiargs
as arguments of template.Input:
loc
sc
tiargs
array of template argumentsflags
1: replace const variables with their initializers 2: don't devolve Parameter to TypeReturn Value
false
if one or more arguments have errors. -
Declaration
final bool
semanticTiargs
(Scope*sc
);Run semantic on the elements of tiargs.
Input:
sc
Return Value
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. -
Declaration
final bool
findBestMatch
(Scope*sc
, Expressions*fargs
);Find the TemplateDeclaration that matches this TemplateInstance best.
Parameters
Scope*
sc
the scope this TemplateInstance resides in
Expressions*
fargs
function arguments in case of a template function,
null
otherwiseReturn Value
true
if a match was found,false
otherwise -
Declaration
final bool
needsTypeInference
(Scope*sc
, intflag
= 0);Determine if template instance is really a template function, and that template function needs to infer types from the function arguments.
Discussion
Like findBestMatch, iterate possible template candidates, but just looks only the necessity of type inference.
-
Declaration
final bool
hasNestedArgs
(Objects*args
, boolisstatic
);Determines if a TemplateInstance will need a nested generation of the TemplateDeclaration. Sets enclosing property if so, and returns != 0;
-
Declaration
final Dsymbols*
appendToModuleMember
();Append 'this' to the specific module members[]
-
Declaration
final void
declareParameters
(Scope*sc
);Declare parameters of template instance, initialize them with the template instance arguments.
-
Declaration
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.
-
-
Declaration
void
unSpeculative
(Scope*sc
, RootObjecto
);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.
-
Declaration
bool
definitelyValueParameter
(Expressione
);Return
true
ife
could be valid only as a template value parameter. Returnfalse
if it might be an alias or tuple. (Note that even in this case, it could still turn out to be a value). -
Declaration
class
TemplateMixin
: dmd.dtemplate.TemplateInstance;Syntax: mixin MixinTemplateName [TemplateArguments]
Identifier
; -
Declaration
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.
-
Declaration
MATCH
matchArg
(TemplateParametertp
, LocinstLoc
, Scope*sc
, Objects*tiargs
, size_ti
, TemplateParameters*parameters
, Objects*dedtypes
, Declaration*psparam
);Match to a particular TemplateParameter.
Input:
instLoc
location that the template is instantiated.tiargs
[] actual arguments to template instancei
i
'th argumentparameters
[] templateparameters
dedtypes
[] deduced arguments to template instance *psparam
set to symbol declared and initialized todedtypes
[i
] -
Declaration
struct
TemplateStats
;Collect and print statistics on template instantiations.
-
Declaration
static void
incInstance
(const TemplateDeclarationtd
, const TemplateInstanceti
);Add this instance
-
Declaration
static void
incUnique
(const TemplateDeclarationtd
, const TemplateInstanceti
);Add this unique instance
-