2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * https://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * https://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/dlang/dmd/blob/master/src/dmd/template.h
13 #include "arraytypes.h"
17 class TemplateInstance
;
18 class TemplateParameter
;
19 class TemplateTypeParameter
;
20 class TemplateThisParameter
;
21 class TemplateValueParameter
;
22 class TemplateAliasParameter
;
23 class TemplateTupleParameter
;
28 class FuncDeclaration
;
31 class Tuple final
: public RootObject
36 // kludge for template.isType()
37 DYNCAST
dyncast() const override
{ return DYNCAST_TUPLE
; }
39 const char *toChars() const override
{ return objects
.toChars(); }
42 struct TemplatePrevious
44 TemplatePrevious
*prev
;
49 struct ArgumentList final
51 Expressions
* arguments
;
58 ArgumentList(Expressions
* arguments
, Identifiers
* names
= nullptr) :
64 class TemplateDeclaration final
: public ScopeDsymbol
67 TemplateParameters
*parameters
; // array of TemplateParameter's
69 TemplateParameters
*origParameters
; // originals for Ddoc
70 Expression
*constraint
;
72 // Hash table to look up TemplateInstance's of this TemplateDeclaration
75 TemplateDeclaration
*overnext
; // next overloaded TemplateDeclaration
76 TemplateDeclaration
*overroot
; // first in overnext list
77 FuncDeclaration
*funcroot
; // first function in unified overload list
79 Dsymbol
*onemember
; // if !=NULL then one member of this template
81 d_bool literal
; // this template declaration is a literal
82 d_bool ismixin
; // template declaration is only to be used as a mixin
83 d_bool isstatic
; // this is static template declaration
84 d_bool isTrivialAliasSeq
; // matches `template AliasSeq(T...) { alias AliasSeq = T; }
85 d_bool isTrivialAlias
; // matches pattern `template Alias(T) { alias Alias = qualifiers(T); }`
86 d_bool deprecated_
; // this template declaration is deprecated
87 Visibility visibility
;
89 TemplatePrevious
*previous
; // threaded list of previous instantiation attempts on stack
91 TemplateDeclaration
*syntaxCopy(Dsymbol
*) override
;
92 bool overloadInsert(Dsymbol
*s
) override
;
93 bool hasStaticCtorOrDtor() override
;
94 const char *kind() const override
;
95 const char *toChars() const override
;
97 Visibility
visible() override
;
99 TemplateDeclaration
*isTemplateDeclaration() override
{ return this; }
101 bool isDeprecated() const override
;
102 bool isOverloadable() const override
;
104 void accept(Visitor
*v
) override
{ v
->visit(this); }
107 /* For type-parameter:
108 * template Foo(ident) // specType is set to NULL
109 * template Foo(ident : specType)
110 * For value-parameter:
111 * template Foo(valType ident) // specValue is set to NULL
112 * template Foo(valType ident : specValue)
113 * For alias-parameter:
114 * template Foo(alias ident)
115 * For this-parameter:
116 * template Foo(this ident)
118 class TemplateParameter
: public ASTNode
124 /* True if this is a part of precedent parameter specialization pattern.
126 * template A(T : X!TL, alias X, TL...) {}
127 * // X and TL are dependent template parameter
129 * A dependent template parameter should return MATCHexact in matchArg()
130 * to respect the match level of the corresponding precedent parameter.
134 virtual TemplateTypeParameter
*isTemplateTypeParameter();
135 virtual TemplateValueParameter
*isTemplateValueParameter();
136 virtual TemplateAliasParameter
*isTemplateAliasParameter();
137 virtual TemplateThisParameter
*isTemplateThisParameter();
138 virtual TemplateTupleParameter
*isTemplateTupleParameter();
140 virtual TemplateParameter
*syntaxCopy() = 0;
141 virtual bool declareParameter(Scope
*sc
) = 0;
142 virtual void print(RootObject
*oarg
, RootObject
*oded
) = 0;
143 virtual RootObject
*specialization() = 0;
144 virtual RootObject
*defaultArg(const Loc
&instLoc
, Scope
*sc
) = 0;
145 virtual bool hasDefaultArg() = 0;
147 DYNCAST
dyncast() const override
{ return DYNCAST_TEMPLATEPARAMETER
; }
149 /* Create dummy argument based on parameter.
151 virtual RootObject
*dummyArg() = 0;
152 void accept(Visitor
*v
) override
{ v
->visit(this); }
156 * ident : specType = defaultType
158 class TemplateTypeParameter
: public TemplateParameter
161 Type
*specType
; // type parameter: if !=NULL, this is the type specialization
164 TemplateTypeParameter
*isTemplateTypeParameter() override final
;
165 TemplateTypeParameter
*syntaxCopy() override
;
166 bool declareParameter(Scope
*sc
) override final
;
167 void print(RootObject
*oarg
, RootObject
*oded
) override final
;
168 RootObject
*specialization() override final
;
169 RootObject
*defaultArg(const Loc
&instLoc
, Scope
*sc
) override final
;
170 bool hasDefaultArg() override final
;
171 RootObject
*dummyArg() override final
;
172 void accept(Visitor
*v
) override
{ v
->visit(this); }
176 * this ident : specType = defaultType
178 class TemplateThisParameter final
: public TemplateTypeParameter
181 TemplateThisParameter
*isTemplateThisParameter() override
;
182 TemplateThisParameter
*syntaxCopy() override
;
183 void accept(Visitor
*v
) override
{ v
->visit(this); }
187 * valType ident : specValue = defaultValue
189 class TemplateValueParameter final
: public TemplateParameter
193 Expression
*specValue
;
194 Expression
*defaultValue
;
196 TemplateValueParameter
*isTemplateValueParameter() override
;
197 TemplateValueParameter
*syntaxCopy() override
;
198 bool declareParameter(Scope
*sc
) override
;
199 void print(RootObject
*oarg
, RootObject
*oded
) override
;
200 RootObject
*specialization() override
;
201 RootObject
*defaultArg(const Loc
&instLoc
, Scope
*sc
) override
;
202 bool hasDefaultArg() override
;
203 RootObject
*dummyArg() override
;
204 void accept(Visitor
*v
) override
{ v
->visit(this); }
208 * specType ident : specAlias = defaultAlias
210 class TemplateAliasParameter final
: public TemplateParameter
214 RootObject
*specAlias
;
215 RootObject
*defaultAlias
;
217 TemplateAliasParameter
*isTemplateAliasParameter() override
;
218 TemplateAliasParameter
*syntaxCopy() override
;
219 bool declareParameter(Scope
*sc
) override
;
220 void print(RootObject
*oarg
, RootObject
*oded
) override
;
221 RootObject
*specialization() override
;
222 RootObject
*defaultArg(const Loc
&instLoc
, Scope
*sc
) override
;
223 bool hasDefaultArg() override
;
224 RootObject
*dummyArg() override
;
225 void accept(Visitor
*v
) override
{ v
->visit(this); }
231 class TemplateTupleParameter final
: public TemplateParameter
234 TemplateTupleParameter
*isTemplateTupleParameter() override
;
235 TemplateTupleParameter
*syntaxCopy() override
;
236 bool declareParameter(Scope
*sc
) override
;
237 void print(RootObject
*oarg
, RootObject
*oded
) override
;
238 RootObject
*specialization() override
;
239 RootObject
*defaultArg(const Loc
&instLoc
, Scope
*sc
) override
;
240 bool hasDefaultArg() override
;
241 RootObject
*dummyArg() override
;
242 void accept(Visitor
*v
) override
{ v
->visit(this); }
250 class TemplateInstance
: public ScopeDsymbol
255 // Array of Types/Expressions of template
256 // instance arguments [int*, char, 10*10]
259 // Array of Types/Expressions corresponding
260 // to TemplateDeclaration.parameters
264 // Modules imported by this template instance
265 Modules importedModules
;
267 Dsymbol
*tempdecl
; // referenced by foo.bar.abc
268 Dsymbol
*enclosing
; // if referencing local symbols, this is the context
269 Dsymbol
*aliasdecl
; // !=NULL if instance is an alias for its sole member
270 TemplateInstance
*inst
; // refer to existing instance
271 ScopeDsymbol
*argsym
; // argument symbol table
272 hash_t hash
; // cached result of toHash()
273 Expressions
*fargs
; // for function template, these are the function arguments
275 TemplateInstances
* deferred
;
277 Module
*memberOf
; // if !null, then this TemplateInstance appears in memberOf.members[]
279 // Used to determine the instance needs code generation.
280 // Note that these are inaccurate until semantic analysis phase completed.
281 TemplateInstance
*tinst
; // enclosing template instance
282 TemplateInstance
*tnext
; // non-first instantiated instances
283 Module
*minst
; // the top module that instantiated this instance
286 unsigned short _nest
; // for recursive pretty printing detection, 3 MSBs reserved for flags
288 unsigned char inuse
; // for recursive expansion detection
290 TemplateInstance
*syntaxCopy(Dsymbol
*) override
;
291 Dsymbol
*toAlias() override final
; // resolve real symbol
292 const char *kind() const override
;
293 bool oneMember(Dsymbol
*&ps
, Identifier
*ident
) override
;
294 const char *toChars() const override
;
295 const char* toPrettyCharsHelper() override final
;
296 Identifier
*getIdent() override final
;
298 bool isDiscardable();
301 TemplateInstance
*isTemplateInstance() override final
{ return this; }
302 void accept(Visitor
*v
) override
{ v
->visit(this); }
305 class TemplateMixin final
: public TemplateInstance
308 TypeQualified
*tqual
;
310 TemplateMixin
*syntaxCopy(Dsymbol
*s
) override
;
311 const char *kind() const override
;
312 bool oneMember(Dsymbol
*&ps
, Identifier
*ident
) override
;
313 bool hasPointers() override
;
314 const char *toChars() const override
;
316 TemplateMixin
*isTemplateMixin() override
{ return this; }
317 void accept(Visitor
*v
) override
{ v
->visit(this); }
320 Expression
*isExpression(RootObject
*o
);
321 Dsymbol
*isDsymbol(RootObject
*o
);
322 Type
*isType(RootObject
*o
);
323 Tuple
*isTuple(RootObject
*o
);
324 Parameter
*isParameter(RootObject
*o
);
325 TemplateParameter
*isTemplateParameter(RootObject
*o
);
326 bool isError(const RootObject
*const o
);
327 void printTemplateStats();