]>
Commit | Line | Data |
---|---|---|
03385ed3 | 1 | |
2 | /* Compiler implementation of the D programming language | |
456185c9 | 3 | * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved |
03385ed3 | 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/declaration.h | |
9 | */ | |
10 | ||
11 | #pragma once | |
12 | ||
13 | #include "dsymbol.h" | |
14 | #include "mtype.h" | |
15 | #include "objc.h" | |
16 | ||
17 | class Expression; | |
18 | class Statement; | |
19 | class LabelDsymbol; | |
20 | class Initializer; | |
21 | class Module; | |
22 | class ForeachStatement; | |
23 | class FuncDeclaration; | |
24 | class ExpInitializer; | |
25 | class StructDeclaration; | |
26 | struct InterState; | |
27 | struct CompiledCtfeFunction; | |
28 | struct ObjcSelector; | |
29 | struct IntRange; | |
30 | ||
31 | enum LINK; | |
32 | enum TOK; | |
33 | enum MATCH; | |
34 | enum PURE; | |
35 | enum PINLINE; | |
36 | ||
37 | #define STCundefined 0LL | |
38 | #define STCstatic 1LL | |
39 | #define STCextern 2LL | |
40 | #define STCconst 4LL | |
41 | #define STCfinal 8LL | |
42 | #define STCabstract 0x10LL | |
43 | #define STCparameter 0x20LL | |
44 | #define STCfield 0x40LL | |
45 | #define STCoverride 0x80LL | |
46 | #define STCauto 0x100LL | |
47 | #define STCsynchronized 0x200LL | |
48 | #define STCdeprecated 0x400LL | |
49 | #define STCin 0x800LL // in parameter | |
50 | #define STCout 0x1000LL // out parameter | |
51 | #define STClazy 0x2000LL // lazy parameter | |
52 | #define STCforeach 0x4000LL // variable for foreach loop | |
53 | #define STCvariadic 0x10000LL // the 'variadic' parameter in: T foo(T a, U b, V variadic...) | |
54 | #define STCctorinit 0x20000LL // can only be set inside constructor | |
55 | #define STCtemplateparameter 0x40000LL // template parameter | |
56 | #define STCscope 0x80000LL | |
57 | #define STCimmutable 0x100000LL | |
58 | #define STCref 0x200000LL | |
59 | #define STCinit 0x400000LL // has explicit initializer | |
60 | #define STCmanifest 0x800000LL // manifest constant | |
61 | #define STCnodtor 0x1000000LL // don't run destructor | |
62 | #define STCnothrow 0x2000000LL // never throws exceptions | |
63 | #define STCpure 0x4000000LL // pure function | |
64 | #define STCtls 0x8000000LL // thread local | |
65 | #define STCalias 0x10000000LL // alias parameter | |
66 | #define STCshared 0x20000000LL // accessible from multiple threads | |
67 | // accessible from multiple threads | |
68 | // but not typed as "shared" | |
69 | #define STCgshared 0x40000000LL | |
70 | #define STCwild 0x80000000LL // for "wild" type constructor | |
71 | #define STC_TYPECTOR (STCconst | STCimmutable | STCshared | STCwild) | |
72 | #define STC_FUNCATTR (STCref | STCnothrow | STCnogc | STCpure | STCproperty | STCsafe | STCtrusted | STCsystem) | |
73 | ||
74 | #define STCproperty 0x100000000LL | |
75 | #define STCsafe 0x200000000LL | |
76 | #define STCtrusted 0x400000000LL | |
77 | #define STCsystem 0x800000000LL | |
78 | #define STCctfe 0x1000000000LL // can be used in CTFE, even if it is static | |
79 | #define STCdisable 0x2000000000LL // for functions that are not callable | |
80 | #define STCresult 0x4000000000LL // for result variables passed to out contracts | |
81 | #define STCnodefaultctor 0x8000000000LL // must be set inside constructor | |
82 | #define STCtemp 0x10000000000LL // temporary variable | |
83 | #define STCrvalue 0x20000000000LL // force rvalue for variables | |
84 | #define STCnogc 0x40000000000LL // @nogc | |
85 | #define STCvolatile 0x80000000000LL // destined for volatile in the back end | |
86 | #define STCreturn 0x100000000000LL // 'return ref' or 'return scope' for function parameters | |
87 | #define STCautoref 0x200000000000LL // Mark for the already deduced 'auto ref' parameter | |
88 | #define STCinference 0x400000000000LL // do attribute inference | |
89 | #define STCexptemp 0x800000000000LL // temporary variable that has lifetime restricted to an expression | |
90 | #define STCmaybescope 0x1000000000000LL // parameter might be 'scope' | |
91 | #define STCscopeinferred 0x2000000000000LL // 'scope' has been inferred and should not be part of mangling | |
92 | #define STCfuture 0x4000000000000LL // introducing new base class function | |
93 | #define STClocal 0x8000000000000LL // do not forward (see ddmd.dsymbol.ForwardingScopeDsymbol). | |
94 | ||
95 | const StorageClass STCStorageClass = (STCauto | STCscope | STCstatic | STCextern | STCconst | STCfinal | | |
96 | STCabstract | STCsynchronized | STCdeprecated | STCfuture | STCoverride | STClazy | STCalias | | |
97 | STCout | STCin | | |
98 | STCmanifest | STCimmutable | STCshared | STCwild | STCnothrow | STCnogc | STCpure | STCref | STCtls | | |
99 | STCgshared | STCproperty | STCsafe | STCtrusted | STCsystem | STCdisable | STClocal); | |
100 | ||
101 | struct Match | |
102 | { | |
103 | int count; // number of matches found | |
104 | MATCH last; // match level of lastf | |
105 | FuncDeclaration *lastf; // last matching function we found | |
106 | FuncDeclaration *nextf; // current matching function | |
107 | FuncDeclaration *anyf; // pick a func, any func, to use for error recovery | |
108 | }; | |
109 | ||
110 | void functionResolve(Match *m, Dsymbol *fd, Loc loc, Scope *sc, Objects *tiargs, Type *tthis, Expressions *fargs); | |
111 | int overloadApply(Dsymbol *fstart, void *param, int (*fp)(void *, Dsymbol *)); | |
112 | ||
113 | void ObjectNotFound(Identifier *id); | |
114 | ||
115 | /**************************************************************/ | |
116 | ||
117 | class Declaration : public Dsymbol | |
118 | { | |
119 | public: | |
120 | Type *type; | |
121 | Type *originalType; // before semantic analysis | |
122 | StorageClass storage_class; | |
123 | Prot protection; | |
124 | LINK linkage; | |
125 | int inuse; // used to detect cycles | |
126 | const char *mangleOverride; // overridden symbol with pragma(mangle, "...") | |
127 | ||
128 | Declaration(Identifier *id); | |
129 | void semantic(Scope *sc); | |
efc08a8f | 130 | const char *kind() const; |
03385ed3 | 131 | d_uns64 size(Loc loc); |
132 | int checkModify(Loc loc, Scope *sc, Type *t, Expression *e1, int flag); | |
133 | ||
134 | Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly); | |
135 | ||
136 | bool isStatic() { return (storage_class & STCstatic) != 0; } | |
137 | virtual bool isDelete(); | |
138 | virtual bool isDataseg(); | |
139 | virtual bool isThreadlocal(); | |
140 | virtual bool isCodeseg() const; | |
141 | bool isCtorinit() { return (storage_class & STCctorinit) != 0; } | |
142 | bool isFinal() { return (storage_class & STCfinal) != 0; } | |
143 | bool isAbstract() { return (storage_class & STCabstract) != 0; } | |
144 | bool isConst() { return (storage_class & STCconst) != 0; } | |
145 | bool isImmutable() { return (storage_class & STCimmutable) != 0; } | |
146 | bool isWild() { return (storage_class & STCwild) != 0; } | |
147 | bool isAuto() { return (storage_class & STCauto) != 0; } | |
148 | bool isScope() { return (storage_class & STCscope) != 0; } | |
149 | bool isSynchronized() { return (storage_class & STCsynchronized) != 0; } | |
150 | bool isParameter() { return (storage_class & STCparameter) != 0; } | |
151 | bool isDeprecated() { return (storage_class & STCdeprecated) != 0; } | |
152 | bool isOverride() { return (storage_class & STCoverride) != 0; } | |
153 | bool isResult() { return (storage_class & STCresult) != 0; } | |
154 | bool isField() { return (storage_class & STCfield) != 0; } | |
155 | ||
156 | bool isIn() { return (storage_class & STCin) != 0; } | |
157 | bool isOut() { return (storage_class & STCout) != 0; } | |
158 | bool isRef() { return (storage_class & STCref) != 0; } | |
159 | ||
160 | bool isFuture() { return (storage_class & STCfuture) != 0; } | |
161 | ||
162 | Prot prot(); | |
163 | ||
164 | Declaration *isDeclaration() { return this; } | |
165 | void accept(Visitor *v) { v->visit(this); } | |
166 | }; | |
167 | ||
168 | /**************************************************************/ | |
169 | ||
170 | class TupleDeclaration : public Declaration | |
171 | { | |
172 | public: | |
173 | Objects *objects; | |
174 | bool isexp; // true: expression tuple | |
175 | ||
176 | TypeTuple *tupletype; // !=NULL if this is a type tuple | |
177 | ||
178 | TupleDeclaration(Loc loc, Identifier *ident, Objects *objects); | |
179 | Dsymbol *syntaxCopy(Dsymbol *); | |
efc08a8f | 180 | const char *kind() const; |
03385ed3 | 181 | Type *getType(); |
182 | Dsymbol *toAlias2(); | |
183 | bool needThis(); | |
184 | ||
185 | TupleDeclaration *isTupleDeclaration() { return this; } | |
186 | void accept(Visitor *v) { v->visit(this); } | |
187 | }; | |
188 | ||
189 | /**************************************************************/ | |
190 | ||
191 | class AliasDeclaration : public Declaration | |
192 | { | |
193 | public: | |
194 | Dsymbol *aliassym; | |
195 | Dsymbol *overnext; // next in overload list | |
196 | Dsymbol *_import; // !=NULL if unresolved internal alias for selective import | |
197 | ||
198 | AliasDeclaration(Loc loc, Identifier *ident, Type *type); | |
199 | AliasDeclaration(Loc loc, Identifier *ident, Dsymbol *s); | |
200 | static AliasDeclaration *create(Loc loc, Identifier *id, Type *type); | |
201 | Dsymbol *syntaxCopy(Dsymbol *); | |
202 | void semantic(Scope *sc); | |
203 | void aliasSemantic(Scope *sc); | |
204 | bool overloadInsert(Dsymbol *s); | |
efc08a8f | 205 | const char *kind() const; |
03385ed3 | 206 | Type *getType(); |
207 | Dsymbol *toAlias(); | |
208 | Dsymbol *toAlias2(); | |
209 | bool isOverloadable(); | |
210 | ||
211 | AliasDeclaration *isAliasDeclaration() { return this; } | |
212 | void accept(Visitor *v) { v->visit(this); } | |
213 | }; | |
214 | ||
215 | /**************************************************************/ | |
216 | ||
217 | class OverDeclaration : public Declaration | |
218 | { | |
219 | public: | |
220 | Dsymbol *overnext; // next in overload list | |
221 | Dsymbol *aliassym; | |
222 | bool hasOverloads; | |
223 | ||
224 | OverDeclaration(Identifier *ident, Dsymbol *s, bool hasOverloads = true); | |
efc08a8f | 225 | const char *kind() const; |
03385ed3 | 226 | void semantic(Scope *sc); |
227 | bool equals(RootObject *o); | |
228 | bool overloadInsert(Dsymbol *s); | |
229 | ||
230 | Dsymbol *toAlias(); | |
231 | Dsymbol *isUnique(); | |
232 | bool isOverloadable(); | |
233 | ||
234 | OverDeclaration *isOverDeclaration() { return this; } | |
235 | void accept(Visitor *v) { v->visit(this); } | |
236 | }; | |
237 | ||
238 | /**************************************************************/ | |
239 | ||
240 | class VarDeclaration : public Declaration | |
241 | { | |
242 | public: | |
243 | Initializer *_init; | |
244 | unsigned offset; | |
245 | unsigned sequenceNumber; // order the variables are declared | |
246 | FuncDeclarations nestedrefs; // referenced by these lexically nested functions | |
247 | bool isargptr; // if parameter that _argptr points to | |
248 | structalign_t alignment; | |
249 | bool ctorinit; // it has been initialized in a ctor | |
250 | bool onstack; // it is a class that was allocated on the stack | |
251 | bool mynew; // it is a class new'd with custom operator new | |
252 | int canassign; // it can be assigned to | |
253 | bool overlapped; // if it is a field and has overlapping | |
254 | bool overlapUnsafe; // if it is an overlapping field and the overlaps are unsafe | |
255 | bool doNotInferScope; // do not infer 'scope' for this variable | |
256 | unsigned char isdataseg; // private data for isDataseg | |
257 | Dsymbol *aliassym; // if redone as alias to another symbol | |
258 | VarDeclaration *lastVar; // Linked list of variables for goto-skips-init detection | |
259 | unsigned endlinnum; // line number of end of scope that this var lives in | |
260 | ||
261 | // When interpreting, these point to the value (NULL if value not determinable) | |
262 | // The index of this variable on the CTFE stack, -1 if not allocated | |
263 | int ctfeAdrOnStack; | |
264 | Expression *edtor; // if !=NULL, does the destruction of the variable | |
265 | IntRange *range; // if !NULL, the variable is known to be within the range | |
266 | ||
267 | VarDeclaration(Loc loc, Type *t, Identifier *id, Initializer *init); | |
fe275d8d | 268 | static VarDeclaration *create(Loc loc, Type *t, Identifier *id, Initializer *init); |
03385ed3 | 269 | Dsymbol *syntaxCopy(Dsymbol *); |
270 | void semantic(Scope *sc); | |
271 | void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion); | |
272 | void semantic2(Scope *sc); | |
efc08a8f | 273 | const char *kind() const; |
03385ed3 | 274 | AggregateDeclaration *isThis(); |
275 | bool needThis(); | |
276 | bool isExport() const; | |
277 | bool isImportedSymbol() const; | |
278 | bool isDataseg(); | |
279 | bool isThreadlocal(); | |
280 | bool isCTFE(); | |
281 | bool isOverlappedWith(VarDeclaration *v); | |
282 | bool hasPointers(); | |
283 | bool canTakeAddressOf(); | |
284 | bool needsScopeDtor(); | |
285 | bool enclosesLifetimeOf(VarDeclaration *v) const; | |
286 | Expression *callScopeDtor(Scope *sc); | |
287 | Expression *getConstInitializer(bool needFullType = true); | |
288 | Expression *expandInitializer(Loc loc); | |
289 | void checkCtorConstInit(); | |
290 | bool checkNestedReference(Scope *sc, Loc loc); | |
291 | Dsymbol *toAlias(); | |
292 | // Eliminate need for dynamic_cast | |
293 | VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; } | |
294 | void accept(Visitor *v) { v->visit(this); } | |
295 | }; | |
296 | ||
297 | /**************************************************************/ | |
298 | ||
299 | // This is a shell around a back end symbol | |
300 | ||
301 | class SymbolDeclaration : public Declaration | |
302 | { | |
303 | public: | |
304 | StructDeclaration *dsym; | |
305 | ||
306 | SymbolDeclaration(Loc loc, StructDeclaration *dsym); | |
307 | ||
308 | // Eliminate need for dynamic_cast | |
309 | SymbolDeclaration *isSymbolDeclaration() { return (SymbolDeclaration *)this; } | |
310 | void accept(Visitor *v) { v->visit(this); } | |
311 | }; | |
312 | ||
313 | class TypeInfoDeclaration : public VarDeclaration | |
314 | { | |
315 | public: | |
316 | Type *tinfo; | |
317 | ||
318 | TypeInfoDeclaration(Type *tinfo); | |
319 | static TypeInfoDeclaration *create(Type *tinfo); | |
320 | Dsymbol *syntaxCopy(Dsymbol *); | |
321 | void semantic(Scope *sc); | |
322 | const char *toChars(); | |
323 | ||
324 | TypeInfoDeclaration *isTypeInfoDeclaration() { return this; } | |
325 | void accept(Visitor *v) { v->visit(this); } | |
326 | }; | |
327 | ||
328 | class TypeInfoStructDeclaration : public TypeInfoDeclaration | |
329 | { | |
330 | public: | |
331 | TypeInfoStructDeclaration(Type *tinfo); | |
332 | static TypeInfoStructDeclaration *create(Type *tinfo); | |
333 | ||
334 | void accept(Visitor *v) { v->visit(this); } | |
335 | }; | |
336 | ||
337 | class TypeInfoClassDeclaration : public TypeInfoDeclaration | |
338 | { | |
339 | public: | |
340 | TypeInfoClassDeclaration(Type *tinfo); | |
341 | static TypeInfoClassDeclaration *create(Type *tinfo); | |
342 | ||
343 | void accept(Visitor *v) { v->visit(this); } | |
344 | }; | |
345 | ||
346 | class TypeInfoInterfaceDeclaration : public TypeInfoDeclaration | |
347 | { | |
348 | public: | |
349 | TypeInfoInterfaceDeclaration(Type *tinfo); | |
350 | static TypeInfoInterfaceDeclaration *create(Type *tinfo); | |
351 | ||
352 | void accept(Visitor *v) { v->visit(this); } | |
353 | }; | |
354 | ||
355 | class TypeInfoPointerDeclaration : public TypeInfoDeclaration | |
356 | { | |
357 | public: | |
358 | TypeInfoPointerDeclaration(Type *tinfo); | |
359 | static TypeInfoPointerDeclaration *create(Type *tinfo); | |
360 | ||
361 | void accept(Visitor *v) { v->visit(this); } | |
362 | }; | |
363 | ||
364 | class TypeInfoArrayDeclaration : public TypeInfoDeclaration | |
365 | { | |
366 | public: | |
367 | TypeInfoArrayDeclaration(Type *tinfo); | |
368 | static TypeInfoArrayDeclaration *create(Type *tinfo); | |
369 | ||
370 | void accept(Visitor *v) { v->visit(this); } | |
371 | }; | |
372 | ||
373 | class TypeInfoStaticArrayDeclaration : public TypeInfoDeclaration | |
374 | { | |
375 | public: | |
376 | TypeInfoStaticArrayDeclaration(Type *tinfo); | |
377 | static TypeInfoStaticArrayDeclaration *create(Type *tinfo); | |
378 | ||
379 | void accept(Visitor *v) { v->visit(this); } | |
380 | }; | |
381 | ||
382 | class TypeInfoAssociativeArrayDeclaration : public TypeInfoDeclaration | |
383 | { | |
384 | public: | |
385 | TypeInfoAssociativeArrayDeclaration(Type *tinfo); | |
386 | static TypeInfoAssociativeArrayDeclaration *create(Type *tinfo); | |
387 | ||
388 | void accept(Visitor *v) { v->visit(this); } | |
389 | }; | |
390 | ||
391 | class TypeInfoEnumDeclaration : public TypeInfoDeclaration | |
392 | { | |
393 | public: | |
394 | TypeInfoEnumDeclaration(Type *tinfo); | |
395 | static TypeInfoEnumDeclaration *create(Type *tinfo); | |
396 | ||
397 | void accept(Visitor *v) { v->visit(this); } | |
398 | }; | |
399 | ||
400 | class TypeInfoFunctionDeclaration : public TypeInfoDeclaration | |
401 | { | |
402 | public: | |
403 | TypeInfoFunctionDeclaration(Type *tinfo); | |
404 | static TypeInfoFunctionDeclaration *create(Type *tinfo); | |
405 | ||
406 | void accept(Visitor *v) { v->visit(this); } | |
407 | }; | |
408 | ||
409 | class TypeInfoDelegateDeclaration : public TypeInfoDeclaration | |
410 | { | |
411 | public: | |
412 | TypeInfoDelegateDeclaration(Type *tinfo); | |
413 | static TypeInfoDelegateDeclaration *create(Type *tinfo); | |
414 | ||
415 | void accept(Visitor *v) { v->visit(this); } | |
416 | }; | |
417 | ||
418 | class TypeInfoTupleDeclaration : public TypeInfoDeclaration | |
419 | { | |
420 | public: | |
421 | TypeInfoTupleDeclaration(Type *tinfo); | |
422 | static TypeInfoTupleDeclaration *create(Type *tinfo); | |
423 | ||
424 | void accept(Visitor *v) { v->visit(this); } | |
425 | }; | |
426 | ||
427 | class TypeInfoConstDeclaration : public TypeInfoDeclaration | |
428 | { | |
429 | public: | |
430 | TypeInfoConstDeclaration(Type *tinfo); | |
431 | static TypeInfoConstDeclaration *create(Type *tinfo); | |
432 | ||
433 | void accept(Visitor *v) { v->visit(this); } | |
434 | }; | |
435 | ||
436 | class TypeInfoInvariantDeclaration : public TypeInfoDeclaration | |
437 | { | |
438 | public: | |
439 | TypeInfoInvariantDeclaration(Type *tinfo); | |
440 | static TypeInfoInvariantDeclaration *create(Type *tinfo); | |
441 | ||
442 | void accept(Visitor *v) { v->visit(this); } | |
443 | }; | |
444 | ||
445 | class TypeInfoSharedDeclaration : public TypeInfoDeclaration | |
446 | { | |
447 | public: | |
448 | TypeInfoSharedDeclaration(Type *tinfo); | |
449 | static TypeInfoSharedDeclaration *create(Type *tinfo); | |
450 | ||
451 | void accept(Visitor *v) { v->visit(this); } | |
452 | }; | |
453 | ||
454 | class TypeInfoWildDeclaration : public TypeInfoDeclaration | |
455 | { | |
456 | public: | |
457 | TypeInfoWildDeclaration(Type *tinfo); | |
458 | static TypeInfoWildDeclaration *create(Type *tinfo); | |
459 | ||
460 | void accept(Visitor *v) { v->visit(this); } | |
461 | }; | |
462 | ||
463 | class TypeInfoVectorDeclaration : public TypeInfoDeclaration | |
464 | { | |
465 | public: | |
466 | TypeInfoVectorDeclaration(Type *tinfo); | |
467 | static TypeInfoVectorDeclaration *create(Type *tinfo); | |
468 | ||
469 | void accept(Visitor *v) { v->visit(this); } | |
470 | }; | |
471 | ||
472 | /**************************************************************/ | |
473 | ||
474 | class ThisDeclaration : public VarDeclaration | |
475 | { | |
476 | public: | |
477 | ThisDeclaration(Loc loc, Type *t); | |
478 | Dsymbol *syntaxCopy(Dsymbol *); | |
479 | ThisDeclaration *isThisDeclaration() { return this; } | |
480 | void accept(Visitor *v) { v->visit(this); } | |
481 | }; | |
482 | ||
483 | enum ILS | |
484 | { | |
485 | ILSuninitialized, // not computed yet | |
486 | ILSno, // cannot inline | |
487 | ILSyes // can inline | |
488 | }; | |
489 | ||
490 | /**************************************************************/ | |
491 | ||
492 | enum BUILTIN | |
493 | { | |
494 | BUILTINunknown = -1, // not known if this is a builtin | |
495 | BUILTINno, // this is not a builtin | |
496 | BUILTINyes // this is a builtin | |
497 | }; | |
498 | ||
499 | Expression *eval_builtin(Loc loc, FuncDeclaration *fd, Expressions *arguments); | |
500 | BUILTIN isBuiltin(FuncDeclaration *fd); | |
501 | ||
502 | typedef Expression *(*builtin_fp)(Loc loc, FuncDeclaration *fd, Expressions *arguments); | |
503 | void add_builtin(const char *mangle, builtin_fp fp); | |
504 | void builtin_init(); | |
505 | ||
506 | #define FUNCFLAGpurityInprocess 1 // working on determining purity | |
507 | #define FUNCFLAGsafetyInprocess 2 // working on determining safety | |
508 | #define FUNCFLAGnothrowInprocess 4 // working on determining nothrow | |
509 | #define FUNCFLAGnogcInprocess 8 // working on determining @nogc | |
510 | #define FUNCFLAGreturnInprocess 0x10 // working on inferring 'return' for parameters | |
511 | #define FUNCFLAGinlineScanned 0x20 // function has been scanned for inline possibilities | |
512 | #define FUNCFLAGinferScope 0x40 // infer 'scope' for parameters | |
513 | ||
514 | class FuncDeclaration : public Declaration | |
515 | { | |
516 | public: | |
517 | Types *fthrows; // Array of Type's of exceptions (not used) | |
518 | Statement *frequire; | |
519 | Statement *fensure; | |
520 | Statement *fbody; | |
521 | ||
522 | FuncDeclarations foverrides; // functions this function overrides | |
523 | FuncDeclaration *fdrequire; // function that does the in contract | |
524 | FuncDeclaration *fdensure; // function that does the out contract | |
525 | ||
526 | const char *mangleString; // mangled symbol created from mangleExact() | |
527 | ||
528 | Identifier *outId; // identifier for out statement | |
529 | VarDeclaration *vresult; // variable corresponding to outId | |
530 | LabelDsymbol *returnLabel; // where the return goes | |
531 | ||
532 | // used to prevent symbols in different | |
533 | // scopes from having the same name | |
534 | DsymbolTable *localsymtab; | |
535 | VarDeclaration *vthis; // 'this' parameter (member and nested) | |
536 | VarDeclaration *v_arguments; // '_arguments' parameter | |
537 | ObjcSelector* selector; // Objective-C method selector (member function only) | |
538 | VarDeclaration *v_argptr; // '_argptr' variable | |
539 | VarDeclarations *parameters; // Array of VarDeclaration's for parameters | |
540 | DsymbolTable *labtab; // statement label symbol table | |
541 | Dsymbol *overnext; // next in overload list | |
542 | FuncDeclaration *overnext0; // next in overload list (only used during IFTI) | |
543 | Loc endloc; // location of closing curly bracket | |
544 | int vtblIndex; // for member functions, index into vtbl[] | |
545 | bool naked; // true if naked | |
546 | bool generated; // true if function was generated by the compiler rather than | |
547 | // supplied by the user | |
548 | ILS inlineStatusStmt; | |
549 | ILS inlineStatusExp; | |
550 | PINLINE inlining; | |
551 | ||
552 | CompiledCtfeFunction *ctfeCode; // Compiled code for interpreter | |
553 | int inlineNest; // !=0 if nested inline | |
554 | bool isArrayOp; // true if array operation | |
555 | // true if errors in semantic3 this function's frame ptr | |
556 | bool semantic3Errors; | |
557 | ForeachStatement *fes; // if foreach body, this is the foreach | |
558 | BaseClass* interfaceVirtual; // if virtual, but only appears in interface vtbl[] | |
559 | bool introducing; // true if 'introducing' function | |
560 | // if !=NULL, then this is the type | |
561 | // of the 'introducing' function | |
562 | // this one is overriding | |
563 | Type *tintro; | |
564 | bool inferRetType; // true if return type is to be inferred | |
565 | StorageClass storage_class2; // storage class for template onemember's | |
566 | ||
567 | // Things that should really go into Scope | |
568 | ||
569 | // 1 if there's a return exp; statement | |
570 | // 2 if there's a throw statement | |
571 | // 4 if there's an assert(0) | |
572 | // 8 if there's inline asm | |
573 | // 16 if there are multiple return statements | |
574 | int hasReturnExp; | |
575 | ||
576 | // Support for NRVO (named return value optimization) | |
577 | bool nrvo_can; // true means we can do it | |
578 | VarDeclaration *nrvo_var; // variable to replace with shidden | |
579 | Symbol *shidden; // hidden pointer passed to function | |
580 | ||
581 | ReturnStatements *returns; | |
582 | ||
583 | GotoStatements *gotos; // Gotos with forward references | |
584 | ||
585 | // set if this is a known, builtin function we can evaluate at compile time | |
586 | BUILTIN builtin; | |
587 | ||
588 | // set if someone took the address of this function | |
589 | int tookAddressOf; | |
590 | bool requiresClosure; // this function needs a closure | |
591 | ||
592 | // local variables in this function which are referenced by nested functions | |
593 | VarDeclarations closureVars; | |
594 | // Sibling nested functions which called this one | |
595 | FuncDeclarations siblingCallers; | |
596 | ||
597 | FuncDeclarations *inlinedNestedCallees; | |
598 | ||
599 | unsigned flags; // FUNCFLAGxxxxx | |
600 | ||
601 | FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type); | |
602 | static FuncDeclaration *create(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type); | |
603 | Dsymbol *syntaxCopy(Dsymbol *); | |
604 | void semantic(Scope *sc); | |
605 | void semantic2(Scope *sc); | |
606 | void semantic3(Scope *sc); | |
607 | bool functionSemantic(); | |
608 | bool functionSemantic3(); | |
609 | bool checkForwardRef(Loc loc); | |
610 | // called from semantic3 | |
611 | VarDeclaration *declareThis(Scope *sc, AggregateDeclaration *ad); | |
612 | bool equals(RootObject *o); | |
613 | ||
614 | int overrides(FuncDeclaration *fd); | |
615 | int findVtblIndex(Dsymbols *vtbl, int dim, bool fix17349 = true); | |
616 | BaseClass *overrideInterface(); | |
617 | bool overloadInsert(Dsymbol *s); | |
618 | FuncDeclaration *overloadExactMatch(Type *t); | |
619 | FuncDeclaration *overloadModMatch(Loc loc, Type *tthis, bool &hasOverloads); | |
620 | TemplateDeclaration *findTemplateDeclRoot(); | |
621 | bool inUnittest(); | |
622 | MATCH leastAsSpecialized(FuncDeclaration *g); | |
623 | LabelDsymbol *searchLabel(Identifier *ident); | |
624 | int getLevel(Loc loc, Scope *sc, FuncDeclaration *fd); // lexical nesting level difference | |
625 | const char *toPrettyChars(bool QualifyTypes = false); | |
626 | const char *toFullSignature(); // for diagnostics, e.g. 'int foo(int x, int y) pure' | |
627 | bool isMain(); | |
628 | bool isCMain(); | |
629 | bool isWinMain(); | |
630 | bool isDllMain(); | |
631 | bool isExport() const; | |
632 | bool isImportedSymbol() const; | |
633 | bool isCodeseg() const; | |
634 | bool isOverloadable(); | |
635 | PURE isPure(); | |
636 | PURE isPureBypassingInference(); | |
637 | bool setImpure(); | |
638 | bool isSafe(); | |
639 | bool isSafeBypassingInference(); | |
640 | bool isTrusted(); | |
641 | bool setUnsafe(); | |
642 | ||
643 | bool isNogc(); | |
644 | bool isNogcBypassingInference(); | |
645 | bool setGC(); | |
646 | ||
647 | void printGCUsage(Loc loc, const char *warn); | |
648 | bool isolateReturn(); | |
649 | bool parametersIntersect(Type *t); | |
650 | virtual bool isNested(); | |
651 | AggregateDeclaration *isThis(); | |
652 | bool needThis(); | |
653 | bool isVirtualMethod(); | |
654 | virtual bool isVirtual(); | |
655 | virtual bool isFinalFunc(); | |
656 | virtual bool addPreInvariant(); | |
657 | virtual bool addPostInvariant(); | |
efc08a8f | 658 | const char *kind() const; |
03385ed3 | 659 | FuncDeclaration *isUnique(); |
660 | bool checkNestedReference(Scope *sc, Loc loc); | |
661 | bool needsClosure(); | |
662 | bool checkClosure(); | |
663 | bool hasNestedFrameRefs(); | |
664 | void buildResultVar(Scope *sc, Type *tret); | |
665 | Statement *mergeFrequire(Statement *); | |
666 | Statement *mergeFensure(Statement *, Identifier *oid); | |
667 | Parameters *getParameters(int *pvarargs); | |
668 | ||
669 | static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, const char *name, StorageClass stc=0); | |
670 | static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, Identifier *id, StorageClass stc=0); | |
671 | void checkDmain(); | |
672 | ||
673 | FuncDeclaration *isFuncDeclaration() { return this; } | |
674 | ||
675 | virtual FuncDeclaration *toAliasFunc() { return this; } | |
676 | void accept(Visitor *v) { v->visit(this); } | |
677 | }; | |
678 | ||
679 | FuncDeclaration *resolveFuncCall(Loc loc, Scope *sc, Dsymbol *s, | |
680 | Objects *tiargs, | |
681 | Type *tthis, | |
682 | Expressions *arguments, | |
683 | int flags = 0); | |
684 | ||
685 | class FuncAliasDeclaration : public FuncDeclaration | |
686 | { | |
687 | public: | |
688 | FuncDeclaration *funcalias; | |
689 | bool hasOverloads; | |
690 | ||
691 | FuncAliasDeclaration(Identifier *ident, FuncDeclaration *funcalias, bool hasOverloads = true); | |
692 | ||
693 | FuncAliasDeclaration *isFuncAliasDeclaration() { return this; } | |
efc08a8f | 694 | const char *kind() const; |
03385ed3 | 695 | |
696 | FuncDeclaration *toAliasFunc(); | |
697 | void accept(Visitor *v) { v->visit(this); } | |
698 | }; | |
699 | ||
700 | class FuncLiteralDeclaration : public FuncDeclaration | |
701 | { | |
702 | public: | |
703 | TOK tok; // TOKfunction or TOKdelegate | |
704 | Type *treq; // target of return type inference | |
705 | ||
706 | // backend | |
707 | bool deferToObj; | |
708 | ||
709 | FuncLiteralDeclaration(Loc loc, Loc endloc, Type *type, TOK tok, | |
710 | ForeachStatement *fes, Identifier *id = NULL); | |
711 | Dsymbol *syntaxCopy(Dsymbol *); | |
712 | bool isNested(); | |
713 | AggregateDeclaration *isThis(); | |
714 | bool isVirtual(); | |
715 | bool addPreInvariant(); | |
716 | bool addPostInvariant(); | |
717 | ||
718 | void modifyReturns(Scope *sc, Type *tret); | |
719 | ||
720 | FuncLiteralDeclaration *isFuncLiteralDeclaration() { return this; } | |
efc08a8f | 721 | const char *kind() const; |
03385ed3 | 722 | const char *toPrettyChars(bool QualifyTypes = false); |
723 | void accept(Visitor *v) { v->visit(this); } | |
724 | }; | |
725 | ||
726 | class CtorDeclaration : public FuncDeclaration | |
727 | { | |
728 | public: | |
729 | CtorDeclaration(Loc loc, Loc endloc, StorageClass stc, Type *type); | |
730 | Dsymbol *syntaxCopy(Dsymbol *); | |
731 | void semantic(Scope *sc); | |
efc08a8f | 732 | const char *kind() const; |
03385ed3 | 733 | const char *toChars(); |
734 | bool isVirtual(); | |
735 | bool addPreInvariant(); | |
736 | bool addPostInvariant(); | |
737 | ||
738 | CtorDeclaration *isCtorDeclaration() { return this; } | |
739 | void accept(Visitor *v) { v->visit(this); } | |
740 | }; | |
741 | ||
742 | class PostBlitDeclaration : public FuncDeclaration | |
743 | { | |
744 | public: | |
745 | PostBlitDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id); | |
746 | Dsymbol *syntaxCopy(Dsymbol *); | |
747 | void semantic(Scope *sc); | |
748 | bool isVirtual(); | |
749 | bool addPreInvariant(); | |
750 | bool addPostInvariant(); | |
751 | bool overloadInsert(Dsymbol *s); | |
752 | ||
753 | PostBlitDeclaration *isPostBlitDeclaration() { return this; } | |
754 | void accept(Visitor *v) { v->visit(this); } | |
755 | }; | |
756 | ||
757 | class DtorDeclaration : public FuncDeclaration | |
758 | { | |
759 | public: | |
760 | DtorDeclaration(Loc loc, Loc endloc); | |
761 | DtorDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id); | |
762 | Dsymbol *syntaxCopy(Dsymbol *); | |
763 | void semantic(Scope *sc); | |
efc08a8f | 764 | const char *kind() const; |
03385ed3 | 765 | const char *toChars(); |
766 | bool isVirtual(); | |
767 | bool addPreInvariant(); | |
768 | bool addPostInvariant(); | |
769 | bool overloadInsert(Dsymbol *s); | |
770 | ||
771 | DtorDeclaration *isDtorDeclaration() { return this; } | |
772 | void accept(Visitor *v) { v->visit(this); } | |
773 | }; | |
774 | ||
775 | class StaticCtorDeclaration : public FuncDeclaration | |
776 | { | |
777 | public: | |
778 | StaticCtorDeclaration(Loc loc, Loc endloc, StorageClass stc); | |
779 | StaticCtorDeclaration(Loc loc, Loc endloc, const char *name, StorageClass stc); | |
780 | Dsymbol *syntaxCopy(Dsymbol *); | |
781 | void semantic(Scope *sc); | |
782 | AggregateDeclaration *isThis(); | |
783 | bool isVirtual(); | |
784 | bool addPreInvariant(); | |
785 | bool addPostInvariant(); | |
786 | bool hasStaticCtorOrDtor(); | |
787 | ||
788 | StaticCtorDeclaration *isStaticCtorDeclaration() { return this; } | |
789 | void accept(Visitor *v) { v->visit(this); } | |
790 | }; | |
791 | ||
792 | class SharedStaticCtorDeclaration : public StaticCtorDeclaration | |
793 | { | |
794 | public: | |
795 | SharedStaticCtorDeclaration(Loc loc, Loc endloc, StorageClass stc); | |
796 | Dsymbol *syntaxCopy(Dsymbol *); | |
797 | ||
798 | SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return this; } | |
799 | void accept(Visitor *v) { v->visit(this); } | |
800 | }; | |
801 | ||
802 | class StaticDtorDeclaration : public FuncDeclaration | |
803 | { | |
804 | public: | |
805 | VarDeclaration *vgate; // 'gate' variable | |
806 | ||
807 | StaticDtorDeclaration(Loc loc, Loc endloc, StorageClass stc); | |
808 | StaticDtorDeclaration(Loc loc, Loc endloc, const char *name, StorageClass stc); | |
809 | Dsymbol *syntaxCopy(Dsymbol *); | |
810 | void semantic(Scope *sc); | |
811 | AggregateDeclaration *isThis(); | |
812 | bool isVirtual(); | |
813 | bool hasStaticCtorOrDtor(); | |
814 | bool addPreInvariant(); | |
815 | bool addPostInvariant(); | |
816 | ||
817 | StaticDtorDeclaration *isStaticDtorDeclaration() { return this; } | |
818 | void accept(Visitor *v) { v->visit(this); } | |
819 | }; | |
820 | ||
821 | class SharedStaticDtorDeclaration : public StaticDtorDeclaration | |
822 | { | |
823 | public: | |
824 | SharedStaticDtorDeclaration(Loc loc, Loc endloc, StorageClass stc); | |
825 | Dsymbol *syntaxCopy(Dsymbol *); | |
826 | ||
827 | SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return this; } | |
828 | void accept(Visitor *v) { v->visit(this); } | |
829 | }; | |
830 | ||
831 | class InvariantDeclaration : public FuncDeclaration | |
832 | { | |
833 | public: | |
834 | InvariantDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id = NULL); | |
835 | Dsymbol *syntaxCopy(Dsymbol *); | |
836 | void semantic(Scope *sc); | |
837 | bool isVirtual(); | |
838 | bool addPreInvariant(); | |
839 | bool addPostInvariant(); | |
840 | ||
841 | InvariantDeclaration *isInvariantDeclaration() { return this; } | |
842 | void accept(Visitor *v) { v->visit(this); } | |
843 | }; | |
844 | ||
845 | class UnitTestDeclaration : public FuncDeclaration | |
846 | { | |
847 | public: | |
848 | char *codedoc; /** For documented unittest. */ | |
849 | ||
850 | // toObjFile() these nested functions after this one | |
851 | FuncDeclarations deferredNested; | |
852 | ||
853 | UnitTestDeclaration(Loc loc, Loc endloc, StorageClass stc, char *codedoc); | |
854 | Dsymbol *syntaxCopy(Dsymbol *); | |
855 | void semantic(Scope *sc); | |
856 | AggregateDeclaration *isThis(); | |
857 | bool isVirtual(); | |
858 | bool addPreInvariant(); | |
859 | bool addPostInvariant(); | |
860 | ||
861 | UnitTestDeclaration *isUnitTestDeclaration() { return this; } | |
862 | void accept(Visitor *v) { v->visit(this); } | |
863 | }; | |
864 | ||
865 | class NewDeclaration : public FuncDeclaration | |
866 | { | |
867 | public: | |
868 | Parameters *parameters; | |
869 | int varargs; | |
870 | ||
871 | NewDeclaration(Loc loc, Loc endloc, StorageClass stc, Parameters *arguments, int varargs); | |
872 | Dsymbol *syntaxCopy(Dsymbol *); | |
873 | void semantic(Scope *sc); | |
efc08a8f | 874 | const char *kind() const; |
03385ed3 | 875 | bool isVirtual(); |
876 | bool addPreInvariant(); | |
877 | bool addPostInvariant(); | |
878 | ||
879 | NewDeclaration *isNewDeclaration() { return this; } | |
880 | void accept(Visitor *v) { v->visit(this); } | |
881 | }; | |
882 | ||
883 | ||
884 | class DeleteDeclaration : public FuncDeclaration | |
885 | { | |
886 | public: | |
887 | Parameters *parameters; | |
888 | ||
889 | DeleteDeclaration(Loc loc, Loc endloc, StorageClass stc, Parameters *arguments); | |
890 | Dsymbol *syntaxCopy(Dsymbol *); | |
891 | void semantic(Scope *sc); | |
efc08a8f | 892 | const char *kind() const; |
03385ed3 | 893 | bool isDelete(); |
894 | bool isVirtual(); | |
895 | bool addPreInvariant(); | |
896 | bool addPostInvariant(); | |
897 | ||
898 | DeleteDeclaration *isDeleteDeclaration() { return this; } | |
899 | void accept(Visitor *v) { v->visit(this); } | |
900 | }; |