template.h revision 1.1 1 1.1 mrg
2 1.1 mrg /* Compiler implementation of the D programming language
3 1.1 mrg * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
4 1.1 mrg * written by Walter Bright
5 1.1 mrg * http://www.digitalmars.com
6 1.1 mrg * Distributed under the Boost Software License, Version 1.0.
7 1.1 mrg * http://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 "root/root.h"
14 1.1 mrg #include "arraytypes.h"
15 1.1 mrg #include "dsymbol.h"
16 1.1 mrg
17 1.1 mrg
18 1.1 mrg struct OutBuffer;
19 1.1 mrg class Identifier;
20 1.1 mrg class TemplateInstance;
21 1.1 mrg class TemplateParameter;
22 1.1 mrg class TemplateTypeParameter;
23 1.1 mrg class TemplateThisParameter;
24 1.1 mrg class TemplateValueParameter;
25 1.1 mrg class TemplateAliasParameter;
26 1.1 mrg class TemplateTupleParameter;
27 1.1 mrg class Type;
28 1.1 mrg class TypeQualified;
29 1.1 mrg class TypeTypeof;
30 1.1 mrg struct Scope;
31 1.1 mrg class Expression;
32 1.1 mrg class AliasDeclaration;
33 1.1 mrg class FuncDeclaration;
34 1.1 mrg class Parameter;
35 1.1 mrg enum MATCH;
36 1.1 mrg enum PASS;
37 1.1 mrg
38 1.1 mrg class Tuple : public RootObject
39 1.1 mrg {
40 1.1 mrg public:
41 1.1 mrg Objects objects;
42 1.1 mrg
43 1.1 mrg // kludge for template.isType()
44 1.1 mrg int dyncast() const { return DYNCAST_TUPLE; }
45 1.1 mrg
46 1.1 mrg const char *toChars() { return objects.toChars(); }
47 1.1 mrg };
48 1.1 mrg
49 1.1 mrg struct TemplatePrevious
50 1.1 mrg {
51 1.1 mrg TemplatePrevious *prev;
52 1.1 mrg Scope *sc;
53 1.1 mrg Objects *dedargs;
54 1.1 mrg };
55 1.1 mrg
56 1.1 mrg class TemplateDeclaration : public ScopeDsymbol
57 1.1 mrg {
58 1.1 mrg public:
59 1.1 mrg TemplateParameters *parameters; // array of TemplateParameter's
60 1.1 mrg
61 1.1 mrg TemplateParameters *origParameters; // originals for Ddoc
62 1.1 mrg Expression *constraint;
63 1.1 mrg
64 1.1 mrg // Hash table to look up TemplateInstance's of this TemplateDeclaration
65 1.1 mrg void *instances;
66 1.1 mrg
67 1.1 mrg TemplateDeclaration *overnext; // next overloaded TemplateDeclaration
68 1.1 mrg TemplateDeclaration *overroot; // first in overnext list
69 1.1 mrg FuncDeclaration *funcroot; // first function in unified overload list
70 1.1 mrg
71 1.1 mrg Dsymbol *onemember; // if !=NULL then one member of this template
72 1.1 mrg
73 1.1 mrg bool literal; // this template declaration is a literal
74 1.1 mrg bool ismixin; // template declaration is only to be used as a mixin
75 1.1 mrg bool isstatic; // this is static template declaration
76 1.1 mrg Prot protection;
77 1.1 mrg
78 1.1 mrg TemplatePrevious *previous; // threaded list of previous instantiation attempts on stack
79 1.1 mrg
80 1.1 mrg TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters,
81 1.1 mrg Expression *constraint, Dsymbols *decldefs, bool ismixin = false, bool literal = false);
82 1.1 mrg Dsymbol *syntaxCopy(Dsymbol *);
83 1.1 mrg void semantic(Scope *sc);
84 1.1 mrg bool overloadInsert(Dsymbol *s);
85 1.1 mrg bool hasStaticCtorOrDtor();
86 1.1 mrg const char *kind() const;
87 1.1 mrg const char *toChars();
88 1.1 mrg
89 1.1 mrg Prot prot();
90 1.1 mrg
91 1.1 mrg bool evaluateConstraint(TemplateInstance *ti, Scope *sc, Scope *paramscope, Objects *dedtypes, FuncDeclaration *fd);
92 1.1 mrg
93 1.1 mrg MATCH matchWithInstance(Scope *sc, TemplateInstance *ti, Objects *atypes, Expressions *fargs, int flag);
94 1.1 mrg MATCH leastAsSpecialized(Scope *sc, TemplateDeclaration *td2, Expressions *fargs);
95 1.1 mrg
96 1.1 mrg MATCH deduceFunctionTemplateMatch(TemplateInstance *ti, Scope *sc, FuncDeclaration *&fd, Type *tthis, Expressions *fargs);
97 1.1 mrg RootObject *declareParameter(Scope *sc, TemplateParameter *tp, RootObject *o);
98 1.1 mrg FuncDeclaration *doHeaderInstantiation(TemplateInstance *ti, Scope *sc, FuncDeclaration *fd, Type *tthis, Expressions *fargs);
99 1.1 mrg TemplateInstance *findExistingInstance(TemplateInstance *tithis, Expressions *fargs);
100 1.1 mrg TemplateInstance *addInstance(TemplateInstance *ti);
101 1.1 mrg void removeInstance(TemplateInstance *handle);
102 1.1 mrg
103 1.1 mrg TemplateDeclaration *isTemplateDeclaration() { return this; }
104 1.1 mrg
105 1.1 mrg TemplateTupleParameter *isVariadic();
106 1.1 mrg bool isOverloadable();
107 1.1 mrg
108 1.1 mrg void accept(Visitor *v) { v->visit(this); }
109 1.1 mrg };
110 1.1 mrg
111 1.1 mrg /* For type-parameter:
112 1.1 mrg * template Foo(ident) // specType is set to NULL
113 1.1 mrg * template Foo(ident : specType)
114 1.1 mrg * For value-parameter:
115 1.1 mrg * template Foo(valType ident) // specValue is set to NULL
116 1.1 mrg * template Foo(valType ident : specValue)
117 1.1 mrg * For alias-parameter:
118 1.1 mrg * template Foo(alias ident)
119 1.1 mrg * For this-parameter:
120 1.1 mrg * template Foo(this ident)
121 1.1 mrg */
122 1.1 mrg class TemplateParameter
123 1.1 mrg {
124 1.1 mrg public:
125 1.1 mrg Loc loc;
126 1.1 mrg Identifier *ident;
127 1.1 mrg
128 1.1 mrg /* True if this is a part of precedent parameter specialization pattern.
129 1.1 mrg *
130 1.1 mrg * template A(T : X!TL, alias X, TL...) {}
131 1.1 mrg * // X and TL are dependent template parameter
132 1.1 mrg *
133 1.1 mrg * A dependent template parameter should return MATCHexact in matchArg()
134 1.1 mrg * to respect the match level of the corresponding precedent parameter.
135 1.1 mrg */
136 1.1 mrg bool dependent;
137 1.1 mrg
138 1.1 mrg TemplateParameter(Loc loc, Identifier *ident);
139 1.1 mrg
140 1.1 mrg virtual TemplateTypeParameter *isTemplateTypeParameter();
141 1.1 mrg virtual TemplateValueParameter *isTemplateValueParameter();
142 1.1 mrg virtual TemplateAliasParameter *isTemplateAliasParameter();
143 1.1 mrg virtual TemplateThisParameter *isTemplateThisParameter();
144 1.1 mrg virtual TemplateTupleParameter *isTemplateTupleParameter();
145 1.1 mrg
146 1.1 mrg virtual TemplateParameter *syntaxCopy() = 0;
147 1.1 mrg virtual bool declareParameter(Scope *sc) = 0;
148 1.1 mrg virtual bool semantic(Scope *sc, TemplateParameters *parameters) = 0;
149 1.1 mrg virtual void print(RootObject *oarg, RootObject *oded) = 0;
150 1.1 mrg virtual RootObject *specialization() = 0;
151 1.1 mrg virtual RootObject *defaultArg(Loc instLoc, Scope *sc) = 0;
152 1.1 mrg virtual bool hasDefaultArg() = 0;
153 1.1 mrg
154 1.1 mrg /* Match actual argument against parameter.
155 1.1 mrg */
156 1.1 mrg virtual MATCH matchArg(Loc instLoc, Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
157 1.1 mrg virtual MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam) = 0;
158 1.1 mrg
159 1.1 mrg /* Create dummy argument based on parameter.
160 1.1 mrg */
161 1.1 mrg virtual void *dummyArg() = 0;
162 1.1 mrg virtual void accept(Visitor *v) { v->visit(this); }
163 1.1 mrg };
164 1.1 mrg
165 1.1 mrg /* Syntax:
166 1.1 mrg * ident : specType = defaultType
167 1.1 mrg */
168 1.1 mrg class TemplateTypeParameter : public TemplateParameter
169 1.1 mrg {
170 1.1 mrg using TemplateParameter::matchArg;
171 1.1 mrg public:
172 1.1 mrg Type *specType; // type parameter: if !=NULL, this is the type specialization
173 1.1 mrg Type *defaultType;
174 1.1 mrg
175 1.1 mrg static Type *tdummy;
176 1.1 mrg
177 1.1 mrg TemplateTypeParameter(Loc loc, Identifier *ident, Type *specType, Type *defaultType);
178 1.1 mrg
179 1.1 mrg TemplateTypeParameter *isTemplateTypeParameter();
180 1.1 mrg TemplateParameter *syntaxCopy();
181 1.1 mrg bool declareParameter(Scope *sc);
182 1.1 mrg bool semantic(Scope *sc, TemplateParameters *parameters);
183 1.1 mrg void print(RootObject *oarg, RootObject *oded);
184 1.1 mrg RootObject *specialization();
185 1.1 mrg RootObject *defaultArg(Loc instLoc, Scope *sc);
186 1.1 mrg bool hasDefaultArg();
187 1.1 mrg MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
188 1.1 mrg void *dummyArg();
189 1.1 mrg void accept(Visitor *v) { v->visit(this); }
190 1.1 mrg };
191 1.1 mrg
192 1.1 mrg /* Syntax:
193 1.1 mrg * this ident : specType = defaultType
194 1.1 mrg */
195 1.1 mrg class TemplateThisParameter : public TemplateTypeParameter
196 1.1 mrg {
197 1.1 mrg public:
198 1.1 mrg TemplateThisParameter(Loc loc, Identifier *ident, Type *specType, Type *defaultType);
199 1.1 mrg
200 1.1 mrg TemplateThisParameter *isTemplateThisParameter();
201 1.1 mrg TemplateParameter *syntaxCopy();
202 1.1 mrg void accept(Visitor *v) { v->visit(this); }
203 1.1 mrg };
204 1.1 mrg
205 1.1 mrg /* Syntax:
206 1.1 mrg * valType ident : specValue = defaultValue
207 1.1 mrg */
208 1.1 mrg class TemplateValueParameter : public TemplateParameter
209 1.1 mrg {
210 1.1 mrg using TemplateParameter::matchArg;
211 1.1 mrg public:
212 1.1 mrg Type *valType;
213 1.1 mrg Expression *specValue;
214 1.1 mrg Expression *defaultValue;
215 1.1 mrg
216 1.1 mrg static AA *edummies;
217 1.1 mrg
218 1.1 mrg TemplateValueParameter(Loc loc, Identifier *ident, Type *valType, Expression *specValue, Expression *defaultValue);
219 1.1 mrg
220 1.1 mrg TemplateValueParameter *isTemplateValueParameter();
221 1.1 mrg TemplateParameter *syntaxCopy();
222 1.1 mrg bool declareParameter(Scope *sc);
223 1.1 mrg bool semantic(Scope *sc, TemplateParameters *parameters);
224 1.1 mrg void print(RootObject *oarg, RootObject *oded);
225 1.1 mrg RootObject *specialization();
226 1.1 mrg RootObject *defaultArg(Loc instLoc, Scope *sc);
227 1.1 mrg bool hasDefaultArg();
228 1.1 mrg MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
229 1.1 mrg void *dummyArg();
230 1.1 mrg void accept(Visitor *v) { v->visit(this); }
231 1.1 mrg };
232 1.1 mrg
233 1.1 mrg /* Syntax:
234 1.1 mrg * specType ident : specAlias = defaultAlias
235 1.1 mrg */
236 1.1 mrg class TemplateAliasParameter : public TemplateParameter
237 1.1 mrg {
238 1.1 mrg using TemplateParameter::matchArg;
239 1.1 mrg public:
240 1.1 mrg Type *specType;
241 1.1 mrg RootObject *specAlias;
242 1.1 mrg RootObject *defaultAlias;
243 1.1 mrg
244 1.1 mrg static Dsymbol *sdummy;
245 1.1 mrg
246 1.1 mrg TemplateAliasParameter(Loc loc, Identifier *ident, Type *specType, RootObject *specAlias, RootObject *defaultAlias);
247 1.1 mrg
248 1.1 mrg TemplateAliasParameter *isTemplateAliasParameter();
249 1.1 mrg TemplateParameter *syntaxCopy();
250 1.1 mrg bool declareParameter(Scope *sc);
251 1.1 mrg bool semantic(Scope *sc, TemplateParameters *parameters);
252 1.1 mrg void print(RootObject *oarg, RootObject *oded);
253 1.1 mrg RootObject *specialization();
254 1.1 mrg RootObject *defaultArg(Loc instLoc, Scope *sc);
255 1.1 mrg bool hasDefaultArg();
256 1.1 mrg MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
257 1.1 mrg void *dummyArg();
258 1.1 mrg void accept(Visitor *v) { v->visit(this); }
259 1.1 mrg };
260 1.1 mrg
261 1.1 mrg /* Syntax:
262 1.1 mrg * ident ...
263 1.1 mrg */
264 1.1 mrg class TemplateTupleParameter : public TemplateParameter
265 1.1 mrg {
266 1.1 mrg public:
267 1.1 mrg TemplateTupleParameter(Loc loc, Identifier *ident);
268 1.1 mrg
269 1.1 mrg TemplateTupleParameter *isTemplateTupleParameter();
270 1.1 mrg TemplateParameter *syntaxCopy();
271 1.1 mrg bool declareParameter(Scope *sc);
272 1.1 mrg bool semantic(Scope *sc, TemplateParameters *parameters);
273 1.1 mrg void print(RootObject *oarg, RootObject *oded);
274 1.1 mrg RootObject *specialization();
275 1.1 mrg RootObject *defaultArg(Loc instLoc, Scope *sc);
276 1.1 mrg bool hasDefaultArg();
277 1.1 mrg MATCH matchArg(Loc loc, Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
278 1.1 mrg MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
279 1.1 mrg void *dummyArg();
280 1.1 mrg void accept(Visitor *v) { v->visit(this); }
281 1.1 mrg };
282 1.1 mrg
283 1.1 mrg /* Given:
284 1.1 mrg * foo!(args) =>
285 1.1 mrg * name = foo
286 1.1 mrg * tiargs = args
287 1.1 mrg */
288 1.1 mrg class TemplateInstance : public ScopeDsymbol
289 1.1 mrg {
290 1.1 mrg public:
291 1.1 mrg Identifier *name;
292 1.1 mrg
293 1.1 mrg // Array of Types/Expressions of template
294 1.1 mrg // instance arguments [int*, char, 10*10]
295 1.1 mrg Objects *tiargs;
296 1.1 mrg
297 1.1 mrg // Array of Types/Expressions corresponding
298 1.1 mrg // to TemplateDeclaration.parameters
299 1.1 mrg // [int, char, 100]
300 1.1 mrg Objects tdtypes;
301 1.1 mrg
302 1.1 mrg Dsymbol *tempdecl; // referenced by foo.bar.abc
303 1.1 mrg Dsymbol *enclosing; // if referencing local symbols, this is the context
304 1.1 mrg Dsymbol *aliasdecl; // !=NULL if instance is an alias for its sole member
305 1.1 mrg TemplateInstance *inst; // refer to existing instance
306 1.1 mrg ScopeDsymbol *argsym; // argument symbol table
307 1.1 mrg int inuse; // for recursive expansion detection
308 1.1 mrg int nest; // for recursive pretty printing detection
309 1.1 mrg bool semantictiargsdone; // has semanticTiargs() been done?
310 1.1 mrg bool havetempdecl; // if used second constructor
311 1.1 mrg bool gagged; // if the instantiation is done with error gagging
312 1.1 mrg hash_t hash; // cached result of toHash()
313 1.1 mrg Expressions *fargs; // for function template, these are the function arguments
314 1.1 mrg
315 1.1 mrg TemplateInstances* deferred;
316 1.1 mrg
317 1.1 mrg Module *memberOf; // if !null, then this TemplateInstance appears in memberOf.members[]
318 1.1 mrg
319 1.1 mrg // Used to determine the instance needs code generation.
320 1.1 mrg // Note that these are inaccurate until semantic analysis phase completed.
321 1.1 mrg TemplateInstance *tinst; // enclosing template instance
322 1.1 mrg TemplateInstance *tnext; // non-first instantiated instances
323 1.1 mrg Module *minst; // the top module that instantiated this instance
324 1.1 mrg
325 1.1 mrg TemplateInstance(Loc loc, Identifier *temp_id);
326 1.1 mrg TemplateInstance(Loc loc, TemplateDeclaration *tempdecl, Objects *tiargs);
327 1.1 mrg static Objects *arraySyntaxCopy(Objects *objs);
328 1.1 mrg Dsymbol *syntaxCopy(Dsymbol *);
329 1.1 mrg void semantic(Scope *sc, Expressions *fargs);
330 1.1 mrg void semantic(Scope *sc);
331 1.1 mrg void semantic2(Scope *sc);
332 1.1 mrg void semantic3(Scope *sc);
333 1.1 mrg Dsymbol *toAlias(); // resolve real symbol
334 1.1 mrg const char *kind() const;
335 1.1 mrg bool oneMember(Dsymbol **ps, Identifier *ident);
336 1.1 mrg const char *toChars();
337 1.1 mrg const char* toPrettyCharsHelper();
338 1.1 mrg void printInstantiationTrace();
339 1.1 mrg Identifier *getIdent();
340 1.1 mrg int compare(RootObject *o);
341 1.1 mrg hash_t toHash();
342 1.1 mrg
343 1.1 mrg bool needsCodegen();
344 1.1 mrg
345 1.1 mrg // Internal
346 1.1 mrg bool findTempDecl(Scope *sc, WithScopeSymbol **pwithsym);
347 1.1 mrg bool updateTempDecl(Scope *sc, Dsymbol *s);
348 1.1 mrg static bool semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int flags);
349 1.1 mrg bool semanticTiargs(Scope *sc);
350 1.1 mrg bool findBestMatch(Scope *sc, Expressions *fargs);
351 1.1 mrg bool needsTypeInference(Scope *sc, int flag = 0);
352 1.1 mrg bool hasNestedArgs(Objects *tiargs, bool isstatic);
353 1.1 mrg Dsymbols *appendToModuleMember();
354 1.1 mrg void declareParameters(Scope *sc);
355 1.1 mrg Identifier *genIdent(Objects *args);
356 1.1 mrg void expandMembers(Scope *sc);
357 1.1 mrg void tryExpandMembers(Scope *sc);
358 1.1 mrg void trySemantic3(Scope *sc2);
359 1.1 mrg
360 1.1 mrg TemplateInstance *isTemplateInstance() { return this; }
361 1.1 mrg void accept(Visitor *v) { v->visit(this); }
362 1.1 mrg };
363 1.1 mrg
364 1.1 mrg class TemplateMixin : public TemplateInstance
365 1.1 mrg {
366 1.1 mrg public:
367 1.1 mrg TypeQualified *tqual;
368 1.1 mrg
369 1.1 mrg TemplateMixin(Loc loc, Identifier *ident, TypeQualified *tqual, Objects *tiargs);
370 1.1 mrg Dsymbol *syntaxCopy(Dsymbol *s);
371 1.1 mrg void semantic(Scope *sc);
372 1.1 mrg void semantic2(Scope *sc);
373 1.1 mrg void semantic3(Scope *sc);
374 1.1 mrg const char *kind() const;
375 1.1 mrg bool oneMember(Dsymbol **ps, Identifier *ident);
376 1.1 mrg int apply(Dsymbol_apply_ft_t fp, void *param);
377 1.1 mrg bool hasPointers();
378 1.1 mrg void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
379 1.1 mrg const char *toChars();
380 1.1 mrg
381 1.1 mrg bool findTempDecl(Scope *sc);
382 1.1 mrg
383 1.1 mrg TemplateMixin *isTemplateMixin() { return this; }
384 1.1 mrg void accept(Visitor *v) { v->visit(this); }
385 1.1 mrg };
386 1.1 mrg
387 1.1 mrg Expression *isExpression(RootObject *o);
388 1.1 mrg Dsymbol *isDsymbol(RootObject *o);
389 1.1 mrg Type *isType(RootObject *o);
390 1.1 mrg Tuple *isTuple(RootObject *o);
391 1.1 mrg Parameter *isParameter(RootObject *o);
392 1.1 mrg bool arrayObjectIsError(Objects *args);
393 1.1 mrg bool isError(RootObject *o);
394 1.1 mrg Type *getType(RootObject *o);
395 1.1 mrg Dsymbol *getDsymbol(RootObject *o);
396 1.1 mrg
397 1.1 mrg RootObject *objectSyntaxCopy(RootObject *o);
398