comparison gcc/d/dmd/template.h @ 145:1830386684a0

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