dmd.dtemplate
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 or TypeIdentifier is encountered. TypeInstance have a bang (e.g. Foo!(arg)) while TypeIdentifier don't.
- A TemplateInstance is instantiated
- Semantic is run on the TemplateInstance (see dmd.dsymbolsem)
- The TemplateInstance search for its TemplateDeclaration, 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.
Source dtemplate.d
Documentation https://dlang.org/phobos/dmd_dtemplate.html
- pure nothrow @nogc @safe inout(Expression)
isExpression
(inout RootObjecto
); - These functions substitute for dynamic_cast. dynamic_cast does not work on earlier versions of gcc.
- pure nothrow @nogc @safe bool
isError
(const RootObjecto
); - Is this Object an error?
- pure nothrow @nogc @safe bool
arrayObjectIsError
(const Objects*args
); - Are any of the Objects an error?
- pure nothrow @nogc @safe inout(Type)
getType
(inout RootObjecto
); - Try to get arg as a type.
- class
TemplateDeclaration
: dmd.dsymbol.ScopeDsymbol; - [mixin] template Identifier (parameters) [Constraint] https://dlang.org/spec/template.html https://dlang.org/spec/template-mixin.html
- bool
isTrivialAliasSeq
; - matches pattern template AliasSeq(T...) { alias AliasSeq = T; }
- bool
isTrivialAlias
; - matches pattern template Alias(T) { alias Alias = qualifiers(T); }
- bool
deprecated_
; - this template declaration is deprecated
- bool
overloadInsert
(Dsymbols
); - Overload existing TemplateDeclaration 'this' with the new one 's'. Return true if successful; i.e. no conflict.
- const const(char)*
toCharsNoConstraints
(); - Similar to toChars, but does not print the template constraints
- bool
evaluateConstraint
(TemplateInstanceti
, Scope*sc
, Scope*paramscope
, Objects*dedargs
, FuncDeclarationfd
); - Check to see if constraint is satisfied.
- const(char)*
getConstraintEvalError
(ref const(char)*tip
); - Destructively get the error message from the last constraint evaluationParameters:
const(char)* tip
tip to show after printing all overloads - Scope*
scopeForTemplateParameters
(TemplateInstanceti
, Scope*sc
); - Create a scope for the parameters of the TemplateInstance
ti
in the parent scope sc from the ScopeDsymbol paramsym.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 Returns:a scope for the parameters of ti - MATCH
matchWithInstance
(Scope*sc
, TemplateInstanceti
, Objects*dedtypes
, ArgumentListargumentList
, intflag
); - 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
, TemplateDeclarationtd2
, ArgumentListargumentList
); - 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
- MATCHpair
deduceFunctionTemplateMatch
(TemplateInstanceti
, Scope*sc
, ref FuncDeclarationfd
, Typetthis
, ArgumentListargumentList
); - Match function arguments against a specific template function.Parameters:
TemplateInstance ti
template instance. ti
.tdtypes will be set to Expression/Type deduced template argumentsScope* sc
instantiation scope FuncDeclaration fd
Partially instantiated function declaration, which is set to an instantiated function declaration Type tthis
'this' argument if !NULL ArgumentList argumentList
arguments to function Returns:match pair of initial and inferred template arguments - RootObject
declareParameter
(Scope*sc
, TemplateParametertp
, RootObjecto
); - Declare template parameter tp with value o, and install it in the scope sc.
- FuncDeclaration
doHeaderInstantiation
(TemplateInstanceti
, Scope*sc2
, FuncDeclarationfd
, Typetthis
, Expressions*fargs
); - Limited function template instantiation for using fd.leastAsSpecialized()
- 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.
- 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.
- void
removeInstance
(TemplateInstanceti
); - 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
- const bool
isOverloadable
(); - We can overload templates.
- void
functionResolve
(ref MatchAccumulatorm
, Dsymboldstart
, Locloc
, Scope*sc
, Objects*tiargs
, Typetthis
, ArgumentListargumentList
, 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 ArgumentList argumentList
arguments to function const(char)** pMessage
address to store error message, or null - 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, returns false. 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. - abstract class
TemplateParameter
: dmd.ast_node.ASTNode; - class
TemplateTypeParameter
: dmd.dtemplate.TemplateParameter; Syntax ident : specType = defaultType
- class
TemplateThisParameter
: dmd.dtemplate.TemplateTypeParameter; Syntax this ident : specType = defaultType
- class
TemplateValueParameter
: dmd.dtemplate.TemplateParameter; Syntax valType ident : specValue = defaultValue
- class
TemplateAliasParameter
: dmd.dtemplate.TemplateParameter; Syntax specType ident : specAlias = defaultAlias
- class
TemplateTupleParameter
: dmd.dtemplate.TemplateParameter; Syntax ident ...
- class
TemplateInstance
: dmd.dsymbol.ScopeDsymbol; Given foo!(args) => name = foo tiargs = args
- final const pure nothrow @nogc @property @safe bool
semantictiargsdone
(); - has semanticTiargs() been done?
- final const pure nothrow @nogc @property @safe bool
havetempdecl
(); - if used second constructor
- final const pure nothrow @nogc @property @safe bool
gagged
(); - if the instantiation is done with error gagging
- scope this(const ref Loc
loc
, TemplateDeclarationtd
, Objects*tiargs
); - This constructor is only called when we figured out which function template to instantiate.
- final void
printInstantiationTrace
(Classificationcl
= Classification.error, const(uint)max_shown
= global.params.v.errorSupplementCount()); - Given an error instantiating the TemplateInstance, give the nested TemplateInstance instantiations that got us here. Those are a list threaded into the nested scopes.Parameters:
Classification cl
classification of this trace as printing either errors or deprecations const(uint) max_shown
maximum number of trace elements printed (controlled with -v/-verror-limit) - final Identifier
getIdent
(); - Lazily generate identifier for template instance. This is because 75% of the ident's are never needed.
- 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 Returns:true for match - final bool
isDiscardable
(); - Returns: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. - 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
, 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 candidates
Returns:true if updating succeeds. - static bool
semanticTiargs
(const ref Locloc
, Scope*sc
, Objects*tiargs
, intflags
, TupleDeclarationatd
= null); - 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 atd tuple being optimized. If found, it's not expanded here but in AliasAssign semantic.
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
findBestMatch
(Scope*sc
, ArgumentListargumentList
); - Find the TemplateDeclaration that matches this TemplateInstance best.Parameters:
Scope* sc
the scope this TemplateInstance resides in ArgumentList argumentList
function arguments in case of a template function Returns:true if a match was found, false otherwise - 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.Like findBestMatch, iterate possible template candidates, but just looks only the necessity of type inference.
- 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;
- 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
, 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.
- @safe bool
definitelyValueParameter
(Expressione
); - 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
: dmd.dtemplate.TemplateInstance; Syntax mixin MixinTemplateName [TemplateArguments]
Identifier
;- 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.
- 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 instance i i'th argument parameters[] template parameters dedtypes[] deduced arguments to template instance *psparam set to symbol declared and initialized to dedtypes[i]
- struct
TemplateStats
; - Collect and print statistics on template instantiations.
- static void
incInstance
(const TemplateDeclarationtd
, const TemplateInstanceti
); - Add this instance
- static void
incUnique
(const TemplateDeclarationtd
, const TemplateInstanceti
); - Add this unique instance