template.h revision 1.1.1.2 1 1.1 mrg
2 1.1 mrg /* Compiler implementation of the D programming language
3 1.1.1.2 mrg * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
4 1.1 mrg * written by Walter Bright
5 1.1.1.2 mrg * https://www.digitalmars.com
6 1.1 mrg * Distributed under the Boost Software License, Version 1.0.
7 1.1.1.2 mrg * https://www.boost.org/LICENSE_1_0.txt
8 1.1 mrg * https://github.com/dlang/dmd/blob/master/src/dmd/template.h
9 1.1 mrg */
10 1.1 mrg
11 1.1 mrg #pragma once
12 1.1 mrg
13 1.1 mrg #include "arraytypes.h"
14 1.1 mrg #include "dsymbol.h"
15 1.1 mrg
16 1.1 mrg class Identifier;
17 1.1 mrg class TemplateInstance;
18 1.1 mrg class TemplateParameter;
19 1.1 mrg class TemplateTypeParameter;
20 1.1 mrg class TemplateThisParameter;
21 1.1 mrg class TemplateValueParameter;
22 1.1 mrg class TemplateAliasParameter;
23 1.1 mrg class TemplateTupleParameter;
24 1.1 mrg class Type;
25 1.1 mrg class TypeQualified;
26 1.1 mrg struct Scope;
27 1.1 mrg class Expression;
28 1.1 mrg class FuncDeclaration;
29 1.1 mrg class Parameter;
30 1.1 mrg
31 1.1 mrg class Tuple : public RootObject
32 1.1 mrg {
33 1.1 mrg public:
34 1.1 mrg Objects objects;
35 1.1 mrg
36 1.1 mrg // kludge for template.isType()
37 1.1.1.2 mrg DYNCAST dyncast() const { return DYNCAST_TUPLE; }
38 1.1 mrg
39 1.1.1.2 mrg const char *toChars() const { return objects.toChars(); }
40 1.1 mrg };
41 1.1 mrg
42 1.1 mrg struct TemplatePrevious
43 1.1 mrg {
44 1.1 mrg TemplatePrevious *prev;
45 1.1 mrg Scope *sc;
46 1.1 mrg Objects *dedargs;
47 1.1 mrg };
48 1.1 mrg
49 1.1 mrg class TemplateDeclaration : public ScopeDsymbol
50 1.1 mrg {
51 1.1 mrg public:
52 1.1 mrg TemplateParameters *parameters; // array of TemplateParameter's
53 1.1 mrg
54 1.1 mrg TemplateParameters *origParameters; // originals for Ddoc
55 1.1 mrg Expression *constraint;
56 1.1 mrg
57 1.1 mrg // Hash table to look up TemplateInstance's of this TemplateDeclaration
58 1.1 mrg void *instances;
59 1.1 mrg
60 1.1 mrg TemplateDeclaration *overnext; // next overloaded TemplateDeclaration
61 1.1 mrg TemplateDeclaration *overroot; // first in overnext list
62 1.1 mrg FuncDeclaration *funcroot; // first function in unified overload list
63 1.1 mrg
64 1.1 mrg Dsymbol *onemember; // if !=NULL then one member of this template
65 1.1 mrg
66 1.1 mrg bool literal; // this template declaration is a literal
67 1.1 mrg bool ismixin; // template declaration is only to be used as a mixin
68 1.1 mrg bool isstatic; // this is static template declaration
69 1.1.1.2 mrg bool isTrivialAliasSeq; // matches `template AliasSeq(T...) { alias AliasSeq = T; }
70 1.1.1.2 mrg bool isTrivialAlias; // matches pattern `template Alias(T) { alias Alias = qualifiers(T); }`
71 1.1.1.2 mrg bool deprecated_; // this template declaration is deprecated
72 1.1.1.2 mrg Visibility visibility;
73 1.1.1.2 mrg int inuse; // for recursive expansion detection
74 1.1 mrg
75 1.1 mrg TemplatePrevious *previous; // threaded list of previous instantiation attempts on stack
76 1.1 mrg
77 1.1.1.2 mrg TemplateDeclaration *syntaxCopy(Dsymbol *);
78 1.1 mrg bool overloadInsert(Dsymbol *s);
79 1.1 mrg bool hasStaticCtorOrDtor();
80 1.1 mrg const char *kind() const;
81 1.1.1.2 mrg const char *toChars() const;
82 1.1 mrg
83 1.1.1.2 mrg Visibility visible();
84 1.1 mrg
85 1.1 mrg MATCH leastAsSpecialized(Scope *sc, TemplateDeclaration *td2, Expressions *fargs);
86 1.1 mrg RootObject *declareParameter(Scope *sc, TemplateParameter *tp, RootObject *o);
87 1.1 mrg
88 1.1 mrg TemplateDeclaration *isTemplateDeclaration() { return this; }
89 1.1 mrg
90 1.1 mrg TemplateTupleParameter *isVariadic();
91 1.1.1.2 mrg bool isDeprecated() const;
92 1.1.1.2 mrg bool isOverloadable() const;
93 1.1 mrg
94 1.1 mrg void accept(Visitor *v) { v->visit(this); }
95 1.1 mrg };
96 1.1 mrg
97 1.1 mrg /* For type-parameter:
98 1.1 mrg * template Foo(ident) // specType is set to NULL
99 1.1 mrg * template Foo(ident : specType)
100 1.1 mrg * For value-parameter:
101 1.1 mrg * template Foo(valType ident) // specValue is set to NULL
102 1.1 mrg * template Foo(valType ident : specValue)
103 1.1 mrg * For alias-parameter:
104 1.1 mrg * template Foo(alias ident)
105 1.1 mrg * For this-parameter:
106 1.1 mrg * template Foo(this ident)
107 1.1 mrg */
108 1.1.1.2 mrg class TemplateParameter : public ASTNode
109 1.1 mrg {
110 1.1 mrg public:
111 1.1 mrg Loc loc;
112 1.1 mrg Identifier *ident;
113 1.1 mrg
114 1.1 mrg /* True if this is a part of precedent parameter specialization pattern.
115 1.1 mrg *
116 1.1 mrg * template A(T : X!TL, alias X, TL...) {}
117 1.1 mrg * // X and TL are dependent template parameter
118 1.1 mrg *
119 1.1 mrg * A dependent template parameter should return MATCHexact in matchArg()
120 1.1 mrg * to respect the match level of the corresponding precedent parameter.
121 1.1 mrg */
122 1.1 mrg bool dependent;
123 1.1 mrg
124 1.1 mrg virtual TemplateTypeParameter *isTemplateTypeParameter();
125 1.1 mrg virtual TemplateValueParameter *isTemplateValueParameter();
126 1.1 mrg virtual TemplateAliasParameter *isTemplateAliasParameter();
127 1.1 mrg virtual TemplateThisParameter *isTemplateThisParameter();
128 1.1 mrg virtual TemplateTupleParameter *isTemplateTupleParameter();
129 1.1 mrg
130 1.1 mrg virtual TemplateParameter *syntaxCopy() = 0;
131 1.1 mrg virtual bool declareParameter(Scope *sc) = 0;
132 1.1 mrg virtual void print(RootObject *oarg, RootObject *oded) = 0;
133 1.1 mrg virtual RootObject *specialization() = 0;
134 1.1.1.2 mrg virtual RootObject *defaultArg(const Loc &instLoc, Scope *sc) = 0;
135 1.1 mrg virtual bool hasDefaultArg() = 0;
136 1.1 mrg
137 1.1 mrg /* Create dummy argument based on parameter.
138 1.1 mrg */
139 1.1.1.2 mrg virtual RootObject *dummyArg() = 0;
140 1.1.1.2 mrg void accept(Visitor *v) { v->visit(this); }
141 1.1 mrg };
142 1.1 mrg
143 1.1 mrg /* Syntax:
144 1.1 mrg * ident : specType = defaultType
145 1.1 mrg */
146 1.1 mrg class TemplateTypeParameter : public TemplateParameter
147 1.1 mrg {
148 1.1 mrg public:
149 1.1 mrg Type *specType; // type parameter: if !=NULL, this is the type specialization
150 1.1 mrg Type *defaultType;
151 1.1 mrg
152 1.1 mrg TemplateTypeParameter *isTemplateTypeParameter();
153 1.1.1.2 mrg TemplateTypeParameter *syntaxCopy();
154 1.1 mrg bool declareParameter(Scope *sc);
155 1.1 mrg void print(RootObject *oarg, RootObject *oded);
156 1.1 mrg RootObject *specialization();
157 1.1.1.2 mrg RootObject *defaultArg(const Loc &instLoc, Scope *sc);
158 1.1 mrg bool hasDefaultArg();
159 1.1.1.2 mrg RootObject *dummyArg();
160 1.1 mrg void accept(Visitor *v) { v->visit(this); }
161 1.1 mrg };
162 1.1 mrg
163 1.1 mrg /* Syntax:
164 1.1 mrg * this ident : specType = defaultType
165 1.1 mrg */
166 1.1 mrg class TemplateThisParameter : public TemplateTypeParameter
167 1.1 mrg {
168 1.1 mrg public:
169 1.1 mrg TemplateThisParameter *isTemplateThisParameter();
170 1.1.1.2 mrg TemplateThisParameter *syntaxCopy();
171 1.1 mrg void accept(Visitor *v) { v->visit(this); }
172 1.1 mrg };
173 1.1 mrg
174 1.1 mrg /* Syntax:
175 1.1 mrg * valType ident : specValue = defaultValue
176 1.1 mrg */
177 1.1 mrg class TemplateValueParameter : public TemplateParameter
178 1.1 mrg {
179 1.1 mrg public:
180 1.1 mrg Type *valType;
181 1.1 mrg Expression *specValue;
182 1.1 mrg Expression *defaultValue;
183 1.1 mrg
184 1.1 mrg TemplateValueParameter *isTemplateValueParameter();
185 1.1.1.2 mrg TemplateValueParameter *syntaxCopy();
186 1.1 mrg bool declareParameter(Scope *sc);
187 1.1 mrg void print(RootObject *oarg, RootObject *oded);
188 1.1 mrg RootObject *specialization();
189 1.1.1.2 mrg RootObject *defaultArg(const Loc &instLoc, Scope *sc);
190 1.1 mrg bool hasDefaultArg();
191 1.1.1.2 mrg RootObject *dummyArg();
192 1.1 mrg void accept(Visitor *v) { v->visit(this); }
193 1.1 mrg };
194 1.1 mrg
195 1.1 mrg /* Syntax:
196 1.1 mrg * specType ident : specAlias = defaultAlias
197 1.1 mrg */
198 1.1 mrg class TemplateAliasParameter : public TemplateParameter
199 1.1 mrg {
200 1.1 mrg public:
201 1.1 mrg Type *specType;
202 1.1 mrg RootObject *specAlias;
203 1.1 mrg RootObject *defaultAlias;
204 1.1 mrg
205 1.1 mrg TemplateAliasParameter *isTemplateAliasParameter();
206 1.1.1.2 mrg TemplateAliasParameter *syntaxCopy();
207 1.1 mrg bool declareParameter(Scope *sc);
208 1.1 mrg void print(RootObject *oarg, RootObject *oded);
209 1.1 mrg RootObject *specialization();
210 1.1.1.2 mrg RootObject *defaultArg(const Loc &instLoc, Scope *sc);
211 1.1 mrg bool hasDefaultArg();
212 1.1.1.2 mrg RootObject *dummyArg();
213 1.1 mrg void accept(Visitor *v) { v->visit(this); }
214 1.1 mrg };
215 1.1 mrg
216 1.1 mrg /* Syntax:
217 1.1 mrg * ident ...
218 1.1 mrg */
219 1.1 mrg class TemplateTupleParameter : public TemplateParameter
220 1.1 mrg {
221 1.1 mrg public:
222 1.1 mrg TemplateTupleParameter *isTemplateTupleParameter();
223 1.1.1.2 mrg TemplateTupleParameter *syntaxCopy();
224 1.1 mrg bool declareParameter(Scope *sc);
225 1.1 mrg void print(RootObject *oarg, RootObject *oded);
226 1.1 mrg RootObject *specialization();
227 1.1.1.2 mrg RootObject *defaultArg(const Loc &instLoc, Scope *sc);
228 1.1 mrg bool hasDefaultArg();
229 1.1.1.2 mrg RootObject *dummyArg();
230 1.1 mrg void accept(Visitor *v) { v->visit(this); }
231 1.1 mrg };
232 1.1 mrg
233 1.1 mrg /* Given:
234 1.1 mrg * foo!(args) =>
235 1.1 mrg * name = foo
236 1.1 mrg * tiargs = args
237 1.1 mrg */
238 1.1 mrg class TemplateInstance : public ScopeDsymbol
239 1.1 mrg {
240 1.1 mrg public:
241 1.1 mrg Identifier *name;
242 1.1 mrg
243 1.1 mrg // Array of Types/Expressions of template
244 1.1 mrg // instance arguments [int*, char, 10*10]
245 1.1 mrg Objects *tiargs;
246 1.1 mrg
247 1.1 mrg // Array of Types/Expressions corresponding
248 1.1 mrg // to TemplateDeclaration.parameters
249 1.1 mrg // [int, char, 100]
250 1.1 mrg Objects tdtypes;
251 1.1 mrg
252 1.1.1.2 mrg // Modules imported by this template instance
253 1.1.1.2 mrg Modules importedModules;
254 1.1.1.2 mrg
255 1.1 mrg Dsymbol *tempdecl; // referenced by foo.bar.abc
256 1.1 mrg Dsymbol *enclosing; // if referencing local symbols, this is the context
257 1.1 mrg Dsymbol *aliasdecl; // !=NULL if instance is an alias for its sole member
258 1.1 mrg TemplateInstance *inst; // refer to existing instance
259 1.1 mrg ScopeDsymbol *argsym; // argument symbol table
260 1.1 mrg hash_t hash; // cached result of toHash()
261 1.1 mrg Expressions *fargs; // for function template, these are the function arguments
262 1.1 mrg
263 1.1 mrg TemplateInstances* deferred;
264 1.1 mrg
265 1.1 mrg Module *memberOf; // if !null, then this TemplateInstance appears in memberOf.members[]
266 1.1 mrg
267 1.1 mrg // Used to determine the instance needs code generation.
268 1.1 mrg // Note that these are inaccurate until semantic analysis phase completed.
269 1.1 mrg TemplateInstance *tinst; // enclosing template instance
270 1.1 mrg TemplateInstance *tnext; // non-first instantiated instances
271 1.1 mrg Module *minst; // the top module that instantiated this instance
272 1.1 mrg
273 1.1.1.2 mrg private:
274 1.1.1.2 mrg unsigned short _nest; // for recursive pretty printing detection, 3 MSBs reserved for flags
275 1.1.1.2 mrg public:
276 1.1.1.2 mrg unsigned char inuse; // for recursive expansion detection
277 1.1.1.2 mrg
278 1.1.1.2 mrg TemplateInstance *syntaxCopy(Dsymbol *);
279 1.1 mrg Dsymbol *toAlias(); // resolve real symbol
280 1.1 mrg const char *kind() const;
281 1.1 mrg bool oneMember(Dsymbol **ps, Identifier *ident);
282 1.1.1.2 mrg const char *toChars() const;
283 1.1 mrg const char* toPrettyCharsHelper();
284 1.1 mrg Identifier *getIdent();
285 1.1 mrg hash_t toHash();
286 1.1 mrg
287 1.1.1.2 mrg bool isDiscardable();
288 1.1 mrg bool needsCodegen();
289 1.1 mrg
290 1.1 mrg TemplateInstance *isTemplateInstance() { return this; }
291 1.1 mrg void accept(Visitor *v) { v->visit(this); }
292 1.1 mrg };
293 1.1 mrg
294 1.1 mrg class TemplateMixin : public TemplateInstance
295 1.1 mrg {
296 1.1 mrg public:
297 1.1 mrg TypeQualified *tqual;
298 1.1 mrg
299 1.1.1.2 mrg TemplateMixin *syntaxCopy(Dsymbol *s);
300 1.1 mrg const char *kind() const;
301 1.1 mrg bool oneMember(Dsymbol **ps, Identifier *ident);
302 1.1 mrg bool hasPointers();
303 1.1.1.2 mrg void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion);
304 1.1.1.2 mrg const char *toChars() const;
305 1.1 mrg
306 1.1 mrg TemplateMixin *isTemplateMixin() { return this; }
307 1.1 mrg void accept(Visitor *v) { v->visit(this); }
308 1.1 mrg };
309 1.1 mrg
310 1.1 mrg Expression *isExpression(RootObject *o);
311 1.1 mrg Dsymbol *isDsymbol(RootObject *o);
312 1.1 mrg Type *isType(RootObject *o);
313 1.1 mrg Tuple *isTuple(RootObject *o);
314 1.1 mrg Parameter *isParameter(RootObject *o);
315 1.1.1.2 mrg TemplateParameter *isTemplateParameter(RootObject *o);
316 1.1.1.2 mrg bool isError(const RootObject *const o);
317 1.1.1.2 mrg void printTemplateStats();
318