Mercurial > hg > CbC > CbC_gcc
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); |