2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://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
: public RootObject
36 // kludge for template.isType()
37 DYNCAST
dyncast() const { return DYNCAST_TUPLE
; }
39 const char *toChars() const { return objects
.toChars(); }
42 struct TemplatePrevious
44 TemplatePrevious
*prev
;
49 class TemplateDeclaration
: public ScopeDsymbol
52 TemplateParameters
*parameters
; // array of TemplateParameter's
54 TemplateParameters
*origParameters
; // originals for Ddoc
55 Expression
*constraint
;
57 // Hash table to look up TemplateInstance's of this TemplateDeclaration
60 TemplateDeclaration
*overnext
; // next overloaded TemplateDeclaration
61 TemplateDeclaration
*overroot
; // first in overnext list
62 FuncDeclaration
*funcroot
; // first function in unified overload list
64 Dsymbol
*onemember
; // if !=NULL then one member of this template
66 bool literal
; // this template declaration is a literal
67 bool ismixin
; // template declaration is only to be used as a mixin
68 bool isstatic
; // this is static template declaration
69 bool isTrivialAliasSeq
; // matches `template AliasSeq(T...) { alias AliasSeq = T; }
70 bool isTrivialAlias
; // matches pattern `template Alias(T) { alias Alias = qualifiers(T); }`
71 bool deprecated_
; // this template declaration is deprecated
72 Visibility visibility
;
73 int inuse
; // for recursive expansion detection
75 TemplatePrevious
*previous
; // threaded list of previous instantiation attempts on stack
77 TemplateDeclaration
*syntaxCopy(Dsymbol
*);
78 bool overloadInsert(Dsymbol
*s
);
79 bool hasStaticCtorOrDtor();
80 const char *kind() const;
81 const char *toChars() const;
85 MATCH
leastAsSpecialized(Scope
*sc
, TemplateDeclaration
*td2
, Expressions
*fargs
);
86 RootObject
*declareParameter(Scope
*sc
, TemplateParameter
*tp
, RootObject
*o
);
88 TemplateDeclaration
*isTemplateDeclaration() { return this; }
90 TemplateTupleParameter
*isVariadic();
91 bool isDeprecated() const;
92 bool isOverloadable() const;
94 void accept(Visitor
*v
) { v
->visit(this); }
97 /* For type-parameter:
98 * template Foo(ident) // specType is set to NULL
99 * template Foo(ident : specType)
100 * For value-parameter:
101 * template Foo(valType ident) // specValue is set to NULL
102 * template Foo(valType ident : specValue)
103 * For alias-parameter:
104 * template Foo(alias ident)
105 * For this-parameter:
106 * template Foo(this ident)
108 class TemplateParameter
: public ASTNode
114 /* True if this is a part of precedent parameter specialization pattern.
116 * template A(T : X!TL, alias X, TL...) {}
117 * // X and TL are dependent template parameter
119 * A dependent template parameter should return MATCHexact in matchArg()
120 * to respect the match level of the corresponding precedent parameter.
124 virtual TemplateTypeParameter
*isTemplateTypeParameter();
125 virtual TemplateValueParameter
*isTemplateValueParameter();
126 virtual TemplateAliasParameter
*isTemplateAliasParameter();
127 virtual TemplateThisParameter
*isTemplateThisParameter();
128 virtual TemplateTupleParameter
*isTemplateTupleParameter();
130 virtual TemplateParameter
*syntaxCopy() = 0;
131 virtual bool declareParameter(Scope
*sc
) = 0;
132 virtual void print(RootObject
*oarg
, RootObject
*oded
) = 0;
133 virtual RootObject
*specialization() = 0;
134 virtual RootObject
*defaultArg(const Loc
&instLoc
, Scope
*sc
) = 0;
135 virtual bool hasDefaultArg() = 0;
137 /* Create dummy argument based on parameter.
139 virtual RootObject
*dummyArg() = 0;
140 void accept(Visitor
*v
) { v
->visit(this); }
144 * ident : specType = defaultType
146 class TemplateTypeParameter
: public TemplateParameter
149 Type
*specType
; // type parameter: if !=NULL, this is the type specialization
152 TemplateTypeParameter
*isTemplateTypeParameter();
153 TemplateTypeParameter
*syntaxCopy();
154 bool declareParameter(Scope
*sc
);
155 void print(RootObject
*oarg
, RootObject
*oded
);
156 RootObject
*specialization();
157 RootObject
*defaultArg(const Loc
&instLoc
, Scope
*sc
);
158 bool hasDefaultArg();
159 RootObject
*dummyArg();
160 void accept(Visitor
*v
) { v
->visit(this); }
164 * this ident : specType = defaultType
166 class TemplateThisParameter
: public TemplateTypeParameter
169 TemplateThisParameter
*isTemplateThisParameter();
170 TemplateThisParameter
*syntaxCopy();
171 void accept(Visitor
*v
) { v
->visit(this); }
175 * valType ident : specValue = defaultValue
177 class TemplateValueParameter
: public TemplateParameter
181 Expression
*specValue
;
182 Expression
*defaultValue
;
184 TemplateValueParameter
*isTemplateValueParameter();
185 TemplateValueParameter
*syntaxCopy();
186 bool declareParameter(Scope
*sc
);
187 void print(RootObject
*oarg
, RootObject
*oded
);
188 RootObject
*specialization();
189 RootObject
*defaultArg(const Loc
&instLoc
, Scope
*sc
);
190 bool hasDefaultArg();
191 RootObject
*dummyArg();
192 void accept(Visitor
*v
) { v
->visit(this); }
196 * specType ident : specAlias = defaultAlias
198 class TemplateAliasParameter
: public TemplateParameter
202 RootObject
*specAlias
;
203 RootObject
*defaultAlias
;
205 TemplateAliasParameter
*isTemplateAliasParameter();
206 TemplateAliasParameter
*syntaxCopy();
207 bool declareParameter(Scope
*sc
);
208 void print(RootObject
*oarg
, RootObject
*oded
);
209 RootObject
*specialization();
210 RootObject
*defaultArg(const Loc
&instLoc
, Scope
*sc
);
211 bool hasDefaultArg();
212 RootObject
*dummyArg();
213 void accept(Visitor
*v
) { v
->visit(this); }
219 class TemplateTupleParameter
: public TemplateParameter
222 TemplateTupleParameter
*isTemplateTupleParameter();
223 TemplateTupleParameter
*syntaxCopy();
224 bool declareParameter(Scope
*sc
);
225 void print(RootObject
*oarg
, RootObject
*oded
);
226 RootObject
*specialization();
227 RootObject
*defaultArg(const Loc
&instLoc
, Scope
*sc
);
228 bool hasDefaultArg();
229 RootObject
*dummyArg();
230 void accept(Visitor
*v
) { v
->visit(this); }
238 class TemplateInstance
: public ScopeDsymbol
243 // Array of Types/Expressions of template
244 // instance arguments [int*, char, 10*10]
247 // Array of Types/Expressions corresponding
248 // to TemplateDeclaration.parameters
252 // Modules imported by this template instance
253 Modules importedModules
;
255 Dsymbol
*tempdecl
; // referenced by foo.bar.abc
256 Dsymbol
*enclosing
; // if referencing local symbols, this is the context
257 Dsymbol
*aliasdecl
; // !=NULL if instance is an alias for its sole member
258 TemplateInstance
*inst
; // refer to existing instance
259 ScopeDsymbol
*argsym
; // argument symbol table
260 hash_t hash
; // cached result of toHash()
261 Expressions
*fargs
; // for function template, these are the function arguments
263 TemplateInstances
* deferred
;
265 Module
*memberOf
; // if !null, then this TemplateInstance appears in memberOf.members[]
267 // Used to determine the instance needs code generation.
268 // Note that these are inaccurate until semantic analysis phase completed.
269 TemplateInstance
*tinst
; // enclosing template instance
270 TemplateInstance
*tnext
; // non-first instantiated instances
271 Module
*minst
; // the top module that instantiated this instance
274 unsigned short _nest
; // for recursive pretty printing detection, 3 MSBs reserved for flags
276 unsigned char inuse
; // for recursive expansion detection
278 TemplateInstance
*syntaxCopy(Dsymbol
*);
279 Dsymbol
*toAlias(); // resolve real symbol
280 const char *kind() const;
281 bool oneMember(Dsymbol
**ps
, Identifier
*ident
);
282 const char *toChars() const;
283 const char* toPrettyCharsHelper();
284 Identifier
*getIdent();
289 TemplateInstance
*isTemplateInstance() { return this; }
290 void accept(Visitor
*v
) { v
->visit(this); }
293 class TemplateMixin
: public TemplateInstance
296 TypeQualified
*tqual
;
298 TemplateMixin
*syntaxCopy(Dsymbol
*s
);
299 const char *kind() const;
300 bool oneMember(Dsymbol
**ps
, Identifier
*ident
);
302 void setFieldOffset(AggregateDeclaration
*ad
, FieldState
& fieldState
, bool isunion
);
303 const char *toChars() const;
305 TemplateMixin
*isTemplateMixin() { return this; }
306 void accept(Visitor
*v
) { v
->visit(this); }
309 Expression
*isExpression(RootObject
*o
);
310 Dsymbol
*isDsymbol(RootObject
*o
);
311 Type
*isType(RootObject
*o
);
312 Tuple
*isTuple(RootObject
*o
);
313 Parameter
*isParameter(RootObject
*o
);
314 TemplateParameter
*isTemplateParameter(RootObject
*o
);
315 bool isError(const RootObject
*const o
);