]>
Commit | Line | Data |
---|---|---|
1 | ||
2 | /* Compiler implementation of the D programming language | |
3 | * Copyright (C) 1999-2025 by The D Language Foundation, All Rights Reserved | |
4 | * written by Walter Bright | |
5 | * https://www.digitalmars.com | |
6 | * Distributed under the Boost Software License, Version 1.0. | |
7 | * https://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 | #include "tokens.h" | |
17 | ||
18 | class Expression; | |
19 | class Statement; | |
20 | class LabelDsymbol; | |
21 | class Initializer; | |
22 | class ForeachStatement; | |
23 | struct Ensure | |
24 | { | |
25 | Identifier *id; | |
26 | Statement *ensure; | |
27 | }; | |
28 | class FuncDeclaration; | |
29 | class StructDeclaration; | |
30 | struct IntRange; | |
31 | struct AttributeViolation; | |
32 | ||
33 | namespace dmd | |
34 | { | |
35 | bool functionSemantic(FuncDeclaration* fd); | |
36 | bool functionSemantic3(FuncDeclaration* fd); | |
37 | bool checkClosure(FuncDeclaration* fd); | |
38 | MATCH leastAsSpecialized(FuncDeclaration *f, FuncDeclaration *g, Identifiers *names); | |
39 | PURE isPure(FuncDeclaration *f); | |
40 | FuncDeclaration *genCfunc(Parameters *args, Type *treturn, const char *name, StorageClass stc=0); | |
41 | FuncDeclaration *genCfunc(Parameters *args, Type *treturn, Identifier *id, StorageClass stc=0); | |
42 | } | |
43 | ||
44 | //enum STC : ulong from astenums.d: | |
45 | ||
46 | #define STCundefined 0ULL | |
47 | ||
48 | #define STCstatic 1ULL /// `static` | |
49 | #define STCextern 2ULL /// `extern` | |
50 | #define STCconst 4ULL /// `const` | |
51 | #define STCfinal 8ULL /// `final` | |
52 | ||
53 | #define STCabstract 0x10ULL /// `abstract` | |
54 | #define STCparameter 0x20ULL /// is function parameter | |
55 | #define STCfield 0x40ULL /// is field of struct, union or class | |
56 | #define STCoverride 0x80ULL /// `override` | |
57 | ||
58 | #define STCauto 0x100ULL /// `auto` | |
59 | #define STCsynchronized 0x200ULL /// `synchronized` | |
60 | #define STCdeprecated 0x400ULL /// `deprecated` | |
61 | #define STCin 0x800ULL /// `in` parameter | |
62 | ||
63 | #define STCout 0x1000ULL /// `out` parameter | |
64 | #define STClazy 0x2000ULL /// `lazy` parameter | |
65 | #define STCforeach 0x4000ULL /// variable for foreach loop | |
66 | #define STCvariadic 0x8000ULL /// the `variadic` parameter in: T foo(T a, U b, V variadic...) | |
67 | ||
68 | #define STCconstscoperef 0x10000ULL /// when `in` means const|scope|ref | |
69 | #define STCtemplateparameter 0x20000ULL /// template parameter | |
70 | #define STCref 0x40000ULL /// `ref` | |
71 | #define STCscope 0x80000ULL /// `scope` | |
72 | ||
73 | #define STCscopeinferred 0x200000ULL /// `scope` has been inferred and should not be part of mangling, `scope` must also be set | |
74 | #define STCreturn 0x400000ULL /// 'return ref' or 'return scope' for function parameters | |
75 | #define STCreturnScope 0x800000ULL /// if `ref return scope` then resolve to `ref` and `return scope` | |
76 | ||
77 | #define STCreturninferred 0x1000000ULL /// `return` has been inferred and should not be part of mangling, `return` must also be set | |
78 | #define STCimmutable 0x2000000ULL /// `immutable` | |
79 | // 0x4000000ULL | |
80 | #define STCmanifest 0x8000000ULL /// manifest constant | |
81 | ||
82 | #define STCnodtor 0x10000000ULL /// do not run destructor | |
83 | #define STCnothrow 0x20000000ULL /// `nothrow` meaning never throws exceptions | |
84 | #define STCpure 0x40000000ULL /// `pure` function | |
85 | ||
86 | #define STCalias 0x100000000ULL /// `alias` parameter | |
87 | #define STCshared 0x200000000ULL /// accessible from multiple threads | |
88 | #define STCgshared 0x400000000ULL /// accessible from multiple threads, but not typed as `shared` | |
89 | #define STCwild 0x800000000ULL /// for wild type constructor | |
90 | ||
91 | #define STCproperty 0x1000000000ULL /// `@property` | |
92 | #define STCsafe 0x2000000000ULL /// `@safe` | |
93 | #define STCtrusted 0x4000000000ULL /// `@trusted` | |
94 | #define STCsystem 0x8000000000ULL /// `@system` | |
95 | ||
96 | #define STCctfe 0x10000000000ULL /// can be used in CTFE, even if it is static | |
97 | #define STCdisable 0x20000000000ULL /// for functions that are not callable | |
98 | #define STCresult 0x40000000000ULL /// for result variables passed to out contracts | |
99 | #define STCnodefaultctor 0x80000000000ULL /// must be set inside constructor | |
100 | ||
101 | #define STCtemp 0x100000000000ULL /// temporary variable | |
102 | #define STCrvalue 0x200000000000ULL /// force rvalue for variables | |
103 | #define STCnogc 0x400000000000ULL /// `@nogc` | |
104 | #define STCautoref 0x800000000000ULL /// Mark for the already deduced `auto ref` parameter | |
105 | ||
106 | #define STCinference 0x1000000000000ULL /// do attribute inference | |
107 | #define STCexptemp 0x2000000000000ULL /// temporary variable that has lifetime restricted to an expression | |
108 | #define STCfuture 0x4000000000000ULL /// introducing new base class function | |
109 | #define STClocal 0x8000000000000ULL /// do not forward (see dmd.dsymbol.ForwardingScopeDsymbol). | |
110 | ||
111 | #define STClive 0x10000000000000ULL /// function `@live` attribute | |
112 | #define STCregister 0x20000000000000ULL /// `register` storage class (ImportC) | |
113 | #define STCvolatile 0x40000000000000ULL /// destined for volatile in the back end | |
114 | ||
115 | #define STC_TYPECTOR (STCconst | STCimmutable | STCshared | STCwild) | |
116 | #define STC_FUNCATTR (STCref | STCnothrow | STCnogc | STCpure | STCproperty | STCsafe | STCtrusted | STCsystem) | |
117 | ||
118 | /**************************************************************/ | |
119 | ||
120 | class Declaration : public Dsymbol | |
121 | { | |
122 | public: | |
123 | Type *type; | |
124 | Type *originalType; // before semantic analysis | |
125 | StorageClass storage_class; | |
126 | DString mangleOverride; // overridden symbol with pragma(mangle, "...") | |
127 | Visibility visibility; | |
128 | short inuse; // used to detect cycles | |
129 | uint8_t bitFields; | |
130 | ||
131 | LINK _linkage() const; | |
132 | LINK _linkage(LINK v); | |
133 | bool noUnderscore() const; | |
134 | ||
135 | const char *kind() const override; | |
136 | uinteger_t size(Loc loc) override final; | |
137 | ||
138 | ||
139 | bool isStatic() const { return (storage_class & STCstatic) != 0; } | |
140 | LINK resolvedLinkage() const; // returns the linkage, resolving the target-specific `System` one | |
141 | virtual bool isDelete(); | |
142 | virtual bool isDataseg(); | |
143 | virtual bool isThreadlocal(); | |
144 | virtual bool isCodeseg() const; | |
145 | bool isFinal() const { return (storage_class & STCfinal) != 0; } | |
146 | virtual bool isAbstract() { return (storage_class & STCabstract) != 0; } | |
147 | bool isConst() const { return (storage_class & STCconst) != 0; } | |
148 | bool isImmutable() const { return (storage_class & STCimmutable) != 0; } | |
149 | bool isWild() const { return (storage_class & STCwild) != 0; } | |
150 | bool isAuto() const { return (storage_class & STCauto) != 0; } | |
151 | bool isScope() const { return (storage_class & STCscope) != 0; } | |
152 | bool isReturn() const { return (storage_class & STCreturn) != 0; } | |
153 | bool isSynchronized() const { return (storage_class & STCsynchronized) != 0; } | |
154 | bool isParameter() const { return (storage_class & STCparameter) != 0; } | |
155 | bool isDeprecated() const override final { return (storage_class & STCdeprecated) != 0; } | |
156 | bool isOverride() const { return (storage_class & STCoverride) != 0; } | |
157 | bool isResult() const { return (storage_class & STCresult) != 0; } | |
158 | bool isField() const { return (storage_class & STCfield) != 0; } | |
159 | ||
160 | bool isIn() const { return (storage_class & STCin) != 0; } | |
161 | bool isOut() const { return (storage_class & STCout) != 0; } | |
162 | bool isRef() const { return (storage_class & STCref) != 0; } | |
163 | bool isReference() const { return (storage_class & (STCref | STCout)) != 0; } | |
164 | ||
165 | bool isFuture() const { return (storage_class & STCfuture) != 0; } | |
166 | ||
167 | Visibility visible() override final; | |
168 | ||
169 | void accept(Visitor *v) override { v->visit(this); } | |
170 | }; | |
171 | ||
172 | /**************************************************************/ | |
173 | ||
174 | class TupleDeclaration final : public Declaration | |
175 | { | |
176 | public: | |
177 | Objects *objects; | |
178 | TypeTuple *tupletype; // !=NULL if this is a type tuple | |
179 | d_bool isexp; // true: expression tuple | |
180 | d_bool building; // it's growing in AliasAssign semantic | |
181 | ||
182 | TupleDeclaration *syntaxCopy(Dsymbol *) override; | |
183 | const char *kind() const override; | |
184 | Type *getType() override; | |
185 | Dsymbol *toAlias2() override; | |
186 | bool needThis() override; | |
187 | ||
188 | void accept(Visitor *v) override { v->visit(this); } | |
189 | }; | |
190 | ||
191 | /**************************************************************/ | |
192 | ||
193 | class AliasDeclaration final : public Declaration | |
194 | { | |
195 | public: | |
196 | Dsymbol *aliassym; | |
197 | Dsymbol *overnext; // next in overload list | |
198 | Dsymbol *_import; // !=NULL if unresolved internal alias for selective import | |
199 | ||
200 | static AliasDeclaration *create(Loc loc, Identifier *id, Type *type); | |
201 | AliasDeclaration *syntaxCopy(Dsymbol *) override; | |
202 | bool overloadInsert(Dsymbol *s) override; | |
203 | const char *kind() const override; | |
204 | Type *getType() override; | |
205 | Dsymbol *toAlias() override; | |
206 | Dsymbol *toAlias2() override; | |
207 | bool isOverloadable() const override; | |
208 | ||
209 | void accept(Visitor *v) override { v->visit(this); } | |
210 | }; | |
211 | ||
212 | /**************************************************************/ | |
213 | ||
214 | class OverDeclaration final : public Declaration | |
215 | { | |
216 | public: | |
217 | Dsymbol *overnext; // next in overload list | |
218 | Dsymbol *aliassym; | |
219 | ||
220 | const char *kind() const override; | |
221 | bool equals(const RootObject * const o) const override; | |
222 | bool overloadInsert(Dsymbol *s) override; | |
223 | ||
224 | Dsymbol *toAlias() override; | |
225 | Dsymbol *isUnique(); | |
226 | bool isOverloadable() const override; | |
227 | ||
228 | void accept(Visitor *v) override { v->visit(this); } | |
229 | }; | |
230 | ||
231 | /**************************************************************/ | |
232 | ||
233 | class VarDeclaration : public Declaration | |
234 | { | |
235 | public: | |
236 | Initializer *_init; | |
237 | FuncDeclarations nestedrefs; // referenced by these lexically nested functions | |
238 | TupleDeclaration *aliasTuple; // if `this` is really a tuple of declarations | |
239 | VarDeclaration *lastVar; // Linked list of variables for goto-skips-init detection | |
240 | Expression *edtor; // if !=NULL, does the destruction of the variable | |
241 | IntRange *range; // if !NULL, the variable is known to be within the range | |
242 | ||
243 | unsigned endlinnum; // line number of end of scope that this var lives in | |
244 | unsigned offset; | |
245 | unsigned sequenceNumber; // order the variables are declared | |
246 | structalign_t alignment; | |
247 | ||
248 | // When interpreting, these point to the value (NULL if value not determinable) | |
249 | // The index of this variable on the CTFE stack, ~0u if not allocated | |
250 | unsigned ctfeAdrOnStack; | |
251 | private: | |
252 | uint32_t bitFields; | |
253 | public: | |
254 | int8_t canassign; // // it can be assigned to | |
255 | uint8_t isdataseg; // private data for isDataseg | |
256 | bool isargptr() const; // if parameter that _argptr points to | |
257 | bool isargptr(bool v); | |
258 | bool ctorinit() const; // it has been initialized in a ctor | |
259 | bool ctorinit(bool v); | |
260 | bool iscatchvar() const; // this is the exception object variable in catch() clause | |
261 | bool iscatchvar(bool v); | |
262 | bool isowner() const; // this is an Owner, despite it being `scope` | |
263 | bool isowner(bool v); | |
264 | bool setInCtorOnly() const; // field can only be set in a constructor, as it is const or immutable | |
265 | bool setInCtorOnly(bool v); | |
266 | bool onstack() const; // it is a class that was allocated on the stack | |
267 | bool onstack(bool v); | |
268 | bool overlapped() const; // if it is a field and has overlapping | |
269 | bool overlapped(bool v); | |
270 | bool overlapUnsafe() const; // if it is an overlapping field and the overlaps are unsafe | |
271 | bool overlapUnsafe(bool v); | |
272 | bool maybeScope() const; // allow inferring 'scope' for this variable | |
273 | bool maybeScope(bool v); | |
274 | bool doNotInferReturn() const; // do not infer 'return' for this variable | |
275 | bool doNotInferReturn(bool v); | |
276 | bool isArgDtorVar() const; // temporary created to handle scope destruction of a function argument | |
277 | bool isArgDtorVar(bool v); | |
278 | bool isCmacro() const; // if a C macro turned into a C variable | |
279 | bool isCmacro(bool v); | |
280 | #if MARS | |
281 | bool inClosure() const; // is inserted into a GC allocated closure | |
282 | bool inClosure(bool v); | |
283 | bool inAlignSection() const; // is inserted into aligned section on stack | |
284 | bool inAlignSection(bool v); | |
285 | #endif | |
286 | bool systemInferred() const; | |
287 | bool systemInferred(bool v); | |
288 | static VarDeclaration *create(Loc loc, Type *t, Identifier *id, Initializer *init, StorageClass storage_class = STCundefined); | |
289 | VarDeclaration *syntaxCopy(Dsymbol *) override; | |
290 | const char *kind() const override; | |
291 | AggregateDeclaration *isThis() override final; | |
292 | bool needThis() override final; | |
293 | bool isExport() const override final; | |
294 | bool isImportedSymbol() const override final; | |
295 | bool isCtorinit() const; | |
296 | bool isDataseg() override final; | |
297 | bool isThreadlocal() override final; | |
298 | bool isCTFE(); | |
299 | bool isOverlappedWith(VarDeclaration *v); | |
300 | bool hasPointers() override final; | |
301 | bool canTakeAddressOf(); | |
302 | bool needsScopeDtor(); | |
303 | Dsymbol *toAlias() override final; | |
304 | // Eliminate need for dynamic_cast | |
305 | void accept(Visitor *v) override { v->visit(this); } | |
306 | }; | |
307 | ||
308 | /**************************************************************/ | |
309 | ||
310 | class BitFieldDeclaration : public VarDeclaration | |
311 | { | |
312 | public: | |
313 | Expression *width; | |
314 | ||
315 | unsigned fieldWidth; | |
316 | unsigned bitOffset; | |
317 | ||
318 | BitFieldDeclaration *syntaxCopy(Dsymbol *) override; | |
319 | void accept(Visitor *v) override { v->visit(this); } | |
320 | }; | |
321 | ||
322 | /**************************************************************/ | |
323 | ||
324 | // This is a shell around a back end symbol | |
325 | ||
326 | class SymbolDeclaration final : public Declaration | |
327 | { | |
328 | public: | |
329 | AggregateDeclaration *dsym; | |
330 | ||
331 | // Eliminate need for dynamic_cast | |
332 | void accept(Visitor *v) override { v->visit(this); } | |
333 | }; | |
334 | ||
335 | class TypeInfoDeclaration : public VarDeclaration | |
336 | { | |
337 | public: | |
338 | Type *tinfo; | |
339 | ||
340 | static TypeInfoDeclaration *create(Type *tinfo); | |
341 | TypeInfoDeclaration *syntaxCopy(Dsymbol *) override final; | |
342 | ||
343 | void accept(Visitor *v) override { v->visit(this); } | |
344 | }; | |
345 | ||
346 | class TypeInfoStructDeclaration final : public TypeInfoDeclaration | |
347 | { | |
348 | public: | |
349 | static TypeInfoStructDeclaration *create(Type *tinfo); | |
350 | ||
351 | void accept(Visitor *v) override { v->visit(this); } | |
352 | }; | |
353 | ||
354 | class TypeInfoClassDeclaration final : public TypeInfoDeclaration | |
355 | { | |
356 | public: | |
357 | static TypeInfoClassDeclaration *create(Type *tinfo); | |
358 | ||
359 | void accept(Visitor *v) override { v->visit(this); } | |
360 | }; | |
361 | ||
362 | class TypeInfoInterfaceDeclaration final : public TypeInfoDeclaration | |
363 | { | |
364 | public: | |
365 | static TypeInfoInterfaceDeclaration *create(Type *tinfo); | |
366 | ||
367 | void accept(Visitor *v) override { v->visit(this); } | |
368 | }; | |
369 | ||
370 | class TypeInfoPointerDeclaration final : public TypeInfoDeclaration | |
371 | { | |
372 | public: | |
373 | static TypeInfoPointerDeclaration *create(Type *tinfo); | |
374 | ||
375 | void accept(Visitor *v) override { v->visit(this); } | |
376 | }; | |
377 | ||
378 | class TypeInfoArrayDeclaration final : public TypeInfoDeclaration | |
379 | { | |
380 | public: | |
381 | static TypeInfoArrayDeclaration *create(Type *tinfo); | |
382 | ||
383 | void accept(Visitor *v) override { v->visit(this); } | |
384 | }; | |
385 | ||
386 | class TypeInfoStaticArrayDeclaration final : public TypeInfoDeclaration | |
387 | { | |
388 | public: | |
389 | static TypeInfoStaticArrayDeclaration *create(Type *tinfo); | |
390 | ||
391 | void accept(Visitor *v) override { v->visit(this); } | |
392 | }; | |
393 | ||
394 | class TypeInfoAssociativeArrayDeclaration final : public TypeInfoDeclaration | |
395 | { | |
396 | public: | |
397 | Type* entry; | |
398 | ||
399 | static TypeInfoAssociativeArrayDeclaration *create(Type *tinfo); | |
400 | ||
401 | void accept(Visitor *v) override { v->visit(this); } | |
402 | }; | |
403 | ||
404 | class TypeInfoEnumDeclaration final : public TypeInfoDeclaration | |
405 | { | |
406 | public: | |
407 | static TypeInfoEnumDeclaration *create(Type *tinfo); | |
408 | ||
409 | void accept(Visitor *v) override { v->visit(this); } | |
410 | }; | |
411 | ||
412 | class TypeInfoFunctionDeclaration final : public TypeInfoDeclaration | |
413 | { | |
414 | public: | |
415 | static TypeInfoFunctionDeclaration *create(Type *tinfo); | |
416 | ||
417 | void accept(Visitor *v) override { v->visit(this); } | |
418 | }; | |
419 | ||
420 | class TypeInfoDelegateDeclaration final : public TypeInfoDeclaration | |
421 | { | |
422 | public: | |
423 | static TypeInfoDelegateDeclaration *create(Type *tinfo); | |
424 | ||
425 | void accept(Visitor *v) override { v->visit(this); } | |
426 | }; | |
427 | ||
428 | class TypeInfoTupleDeclaration final : public TypeInfoDeclaration | |
429 | { | |
430 | public: | |
431 | static TypeInfoTupleDeclaration *create(Type *tinfo); | |
432 | ||
433 | void accept(Visitor *v) override { v->visit(this); } | |
434 | }; | |
435 | ||
436 | class TypeInfoConstDeclaration final : public TypeInfoDeclaration | |
437 | { | |
438 | public: | |
439 | static TypeInfoConstDeclaration *create(Type *tinfo); | |
440 | ||
441 | void accept(Visitor *v) override { v->visit(this); } | |
442 | }; | |
443 | ||
444 | class TypeInfoInvariantDeclaration final : public TypeInfoDeclaration | |
445 | { | |
446 | public: | |
447 | static TypeInfoInvariantDeclaration *create(Type *tinfo); | |
448 | ||
449 | void accept(Visitor *v) override { v->visit(this); } | |
450 | }; | |
451 | ||
452 | class TypeInfoSharedDeclaration final : public TypeInfoDeclaration | |
453 | { | |
454 | public: | |
455 | static TypeInfoSharedDeclaration *create(Type *tinfo); | |
456 | ||
457 | void accept(Visitor *v) override { v->visit(this); } | |
458 | }; | |
459 | ||
460 | class TypeInfoWildDeclaration final : public TypeInfoDeclaration | |
461 | { | |
462 | public: | |
463 | static TypeInfoWildDeclaration *create(Type *tinfo); | |
464 | ||
465 | void accept(Visitor *v) override { v->visit(this); } | |
466 | }; | |
467 | ||
468 | class TypeInfoVectorDeclaration final : public TypeInfoDeclaration | |
469 | { | |
470 | public: | |
471 | static TypeInfoVectorDeclaration *create(Type *tinfo); | |
472 | ||
473 | void accept(Visitor *v) override { v->visit(this); } | |
474 | }; | |
475 | ||
476 | /**************************************************************/ | |
477 | ||
478 | class ThisDeclaration final : public VarDeclaration | |
479 | { | |
480 | public: | |
481 | ThisDeclaration *syntaxCopy(Dsymbol *) override; | |
482 | void accept(Visitor *v) override { v->visit(this); } | |
483 | }; | |
484 | ||
485 | enum class ILS : unsigned char | |
486 | { | |
487 | ILSuninitialized, // not computed yet | |
488 | ILSno, // cannot inline | |
489 | ILSyes // can inline | |
490 | }; | |
491 | ||
492 | /**************************************************************/ | |
493 | ||
494 | enum class BUILTIN : unsigned char | |
495 | { | |
496 | unknown = 255, /// not known if this is a builtin | |
497 | unimp = 0, /// this is not a builtin | |
498 | gcc, /// this is a GCC builtin | |
499 | llvm, /// this is an LLVM builtin | |
500 | sin, | |
501 | cos, | |
502 | tan, | |
503 | sqrt, | |
504 | fabs, | |
505 | ldexp, | |
506 | log, | |
507 | log2, | |
508 | log10, | |
509 | exp, | |
510 | expm1, | |
511 | exp2, | |
512 | round, | |
513 | floor, | |
514 | ceil, | |
515 | trunc, | |
516 | copysign, | |
517 | pow, | |
518 | fmin, | |
519 | fmax, | |
520 | fma, | |
521 | isnan, | |
522 | isinfinity, | |
523 | isfinite, | |
524 | bsf, | |
525 | bsr, | |
526 | bswap, | |
527 | popcnt, | |
528 | yl2x, | |
529 | yl2xp1, | |
530 | toPrecFloat, | |
531 | toPrecDouble, | |
532 | toPrecReal | |
533 | }; | |
534 | ||
535 | Expression *eval_builtin(Loc loc, FuncDeclaration *fd, Expressions *arguments); | |
536 | BUILTIN isBuiltin(FuncDeclaration *fd); | |
537 | ||
538 | struct ContractInfo; | |
539 | ||
540 | class FuncDeclaration : public Declaration | |
541 | { | |
542 | public: | |
543 | Statement *fbody; | |
544 | ||
545 | FuncDeclarations foverrides; // functions this function overrides | |
546 | ||
547 | private: | |
548 | ContractInfo *contracts; // contract information | |
549 | ||
550 | public: | |
551 | const char *mangleString; // mangled symbol created from mangleExact() | |
552 | ||
553 | VarDeclaration *vresult; // result variable for out contracts | |
554 | LabelDsymbol *returnLabel; // where the return goes | |
555 | ||
556 | void *isTypeIsolatedCache; // An AA on the D side to cache an expensive check result | |
557 | ||
558 | // used to prevent symbols in different | |
559 | // scopes from having the same name | |
560 | DsymbolTable *localsymtab; | |
561 | VarDeclaration *vthis; // 'this' parameter (member and nested) | |
562 | VarDeclaration *v_arguments; // '_arguments' parameter | |
563 | ||
564 | VarDeclaration *v_argptr; // '_argptr' variable | |
565 | VarDeclarations *parameters; // Array of VarDeclaration's for parameters | |
566 | DsymbolTable *labtab; // statement label symbol table | |
567 | Dsymbol *overnext; // next in overload list | |
568 | FuncDeclaration *overnext0; // next in overload list (only used during IFTI) | |
569 | Loc endloc; // location of closing curly bracket | |
570 | int vtblIndex; // for member functions, index into vtbl[] | |
571 | ||
572 | ILS inlineStatusStmt; | |
573 | ILS inlineStatusExp; | |
574 | PINLINE inlining; | |
575 | ||
576 | int inlineNest; // !=0 if nested inline | |
577 | ||
578 | // true if errors in semantic3 this function's frame ptr | |
579 | ForeachStatement *fes; // if foreach body, this is the foreach | |
580 | BaseClass* interfaceVirtual; // if virtual, but only appears in interface vtbl[] | |
581 | // if !=NULL, then this is the type | |
582 | // of the 'introducing' function | |
583 | // this one is overriding | |
584 | Type *tintro; | |
585 | StorageClass storage_class2; // storage class for template onemember's | |
586 | ||
587 | // Things that should really go into Scope | |
588 | ||
589 | VarDeclaration *nrvo_var; // variable to replace with shidden | |
590 | Symbol *shidden; // hidden pointer passed to function | |
591 | ||
592 | ReturnStatements *returns; | |
593 | ||
594 | GotoStatements *gotos; // Gotos with forward references | |
595 | ||
596 | // set if this is a known, builtin function we can evaluate at compile time | |
597 | BUILTIN builtin; | |
598 | ||
599 | // set if someone took the address of this function | |
600 | int tookAddressOf; | |
601 | d_bool requiresClosure; // this function needs a closure | |
602 | ||
603 | // local variables in this function which are referenced by nested functions | |
604 | VarDeclarations closureVars; | |
605 | ||
606 | /** Outer variables which are referenced by this nested function | |
607 | * (the inverse of closureVars) | |
608 | */ | |
609 | VarDeclarations outerVars; | |
610 | ||
611 | // Sibling nested functions which called this one | |
612 | FuncDeclarations siblingCallers; | |
613 | ||
614 | FuncDeclarations *inlinedNestedCallees; | |
615 | ||
616 | AttributeViolation* safetyViolation; | |
617 | AttributeViolation* nogcViolation; | |
618 | AttributeViolation* pureViolation; | |
619 | AttributeViolation* nothrowViolation; | |
620 | ||
621 | // Formerly FUNCFLAGS | |
622 | uint32_t flags; | |
623 | bool purityInprocess() const; | |
624 | bool purityInprocess(bool v); | |
625 | bool safetyInprocess() const; | |
626 | bool safetyInprocess(bool v); | |
627 | bool nothrowInprocess() const; | |
628 | bool nothrowInprocess(bool v); | |
629 | bool nogcInprocess() const; | |
630 | bool nogcInprocess(bool v); | |
631 | bool saferD() const; | |
632 | bool saferD(bool v); | |
633 | bool scopeInprocess() const; | |
634 | bool scopeInprocess(bool v); | |
635 | bool inlineScanned() const; | |
636 | bool inlineScanned(bool v); | |
637 | bool hasCatches() const; | |
638 | bool hasCatches(bool v); | |
639 | bool skipCodegen() const; | |
640 | bool skipCodegen(bool v); | |
641 | bool printf() const; | |
642 | bool printf(bool v); | |
643 | bool scanf() const; | |
644 | bool scanf(bool v); | |
645 | bool noreturn() const; | |
646 | bool noreturn(bool v); | |
647 | bool isNRVO() const; | |
648 | bool isNRVO(bool v); | |
649 | bool isNaked() const; | |
650 | bool isNaked(bool v); | |
651 | bool isGenerated() const; | |
652 | bool isGenerated(bool v); | |
653 | bool isIntroducing() const; | |
654 | bool isIntroducing(bool v); | |
655 | bool hasSemantic3Errors() const; | |
656 | bool hasSemantic3Errors(bool v); | |
657 | bool hasNoEH() const; | |
658 | bool hasNoEH(bool v); | |
659 | bool inferRetType() const; | |
660 | bool inferRetType(bool v); | |
661 | bool hasDualContext() const; | |
662 | bool hasDualContext(bool v); | |
663 | bool hasAlwaysInlines() const; | |
664 | bool hasAlwaysInlines(bool v); | |
665 | bool isCrtCtor() const; | |
666 | bool isCrtCtor(bool v); | |
667 | bool isCrtDtor() const; | |
668 | bool isCrtDtor(bool v); | |
669 | bool dllImport() const; | |
670 | bool dllImport(bool v); | |
671 | bool dllExport() const; | |
672 | bool dllExport(bool v); | |
673 | bool hasReturnExp() const; | |
674 | bool hasReturnExp(bool v); | |
675 | bool hasInlineAsm() const; | |
676 | bool hasInlineAsm(bool v); | |
677 | bool hasMultipleReturnExp() const; | |
678 | bool hasMultipleReturnExp(bool v); | |
679 | ||
680 | // Data for a function declaration that is needed for the Objective-C | |
681 | // integration. | |
682 | ObjcFuncDeclaration objc; | |
683 | ||
684 | static FuncDeclaration *create(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type, bool noreturn = false); | |
685 | FuncDeclaration *syntaxCopy(Dsymbol *) override; | |
686 | Statements *frequires(); | |
687 | Ensures *fensures(); | |
688 | Statement *frequire(); | |
689 | Statement *fensure(); | |
690 | FuncDeclaration *fdrequire(); | |
691 | FuncDeclaration *fdensure(); | |
692 | Expressions *fdrequireParams(); | |
693 | Expressions *fdensureParams(); | |
694 | Statements *frequires(Statements *frs); | |
695 | Ensures *fensures(Statements *fes); | |
696 | Statement *frequire(Statement *fr); | |
697 | Statement *fensure(Statement *fe); | |
698 | FuncDeclaration *fdrequire(FuncDeclaration *fdr); | |
699 | FuncDeclaration *fdensure(FuncDeclaration *fde); | |
700 | Expressions *fdrequireParams(Expressions *fdrp); | |
701 | Expressions *fdensureParams(Expressions *fdep); | |
702 | bool equals(const RootObject * const o) const override final; | |
703 | ||
704 | bool overloadInsert(Dsymbol *s) override; | |
705 | bool inUnittest(); | |
706 | LabelDsymbol *searchLabel(Identifier *ident, Loc loc); | |
707 | const char *toPrettyChars(bool QualifyTypes = false) override; | |
708 | const char *toFullSignature(); // for diagnostics, e.g. 'int foo(int x, int y) pure' | |
709 | bool isMain() const; | |
710 | bool isCMain() const; | |
711 | bool isWinMain() const; | |
712 | bool isDllMain() const; | |
713 | bool isExport() const override final; | |
714 | bool isImportedSymbol() const override final; | |
715 | bool isCodeseg() const override final; | |
716 | bool isOverloadable() const override final; | |
717 | bool isAbstract() override final; | |
718 | bool isSafe(); | |
719 | bool isTrusted(); | |
720 | ||
721 | virtual bool isNested() const; | |
722 | AggregateDeclaration *isThis() override; | |
723 | bool needThis() override final; | |
724 | bool isVirtualMethod(); | |
725 | virtual bool isVirtual() const; | |
726 | bool isFinalFunc() const; | |
727 | virtual bool addPreInvariant(); | |
728 | virtual bool addPostInvariant(); | |
729 | const char *kind() const override; | |
730 | bool isUnique(); | |
731 | bool needsClosure(); | |
732 | bool hasNestedFrameRefs(); | |
733 | ParameterList getParameterList(); | |
734 | ||
735 | virtual FuncDeclaration *toAliasFunc() { return this; } | |
736 | void accept(Visitor *v) override { v->visit(this); } | |
737 | }; | |
738 | ||
739 | class FuncAliasDeclaration final : public FuncDeclaration | |
740 | { | |
741 | public: | |
742 | FuncDeclaration *funcalias; | |
743 | d_bool hasOverloads; | |
744 | ||
745 | const char *kind() const override; | |
746 | ||
747 | FuncDeclaration *toAliasFunc() override; | |
748 | void accept(Visitor *v) override { v->visit(this); } | |
749 | }; | |
750 | ||
751 | class FuncLiteralDeclaration final : public FuncDeclaration | |
752 | { | |
753 | public: | |
754 | TOK tok; // TOKfunction or TOKdelegate | |
755 | Type *treq; // target of return type inference | |
756 | ||
757 | // backend | |
758 | d_bool deferToObj; | |
759 | ||
760 | FuncLiteralDeclaration *syntaxCopy(Dsymbol *) override; | |
761 | bool isNested() const override; | |
762 | AggregateDeclaration *isThis() override; | |
763 | bool isVirtual() const override; | |
764 | bool addPreInvariant() override; | |
765 | bool addPostInvariant() override; | |
766 | ||
767 | const char *kind() const override; | |
768 | const char *toPrettyChars(bool QualifyTypes = false) override; | |
769 | void accept(Visitor *v) override { v->visit(this); } | |
770 | }; | |
771 | ||
772 | class CtorDeclaration final : public FuncDeclaration | |
773 | { | |
774 | public: | |
775 | d_bool isCpCtor; | |
776 | d_bool isMoveCtor; | |
777 | CtorDeclaration *syntaxCopy(Dsymbol *) override; | |
778 | const char *kind() const override; | |
779 | bool isVirtual() const override; | |
780 | bool addPreInvariant() override; | |
781 | bool addPostInvariant() override; | |
782 | ||
783 | void accept(Visitor *v) override { v->visit(this); } | |
784 | }; | |
785 | ||
786 | class PostBlitDeclaration final : public FuncDeclaration | |
787 | { | |
788 | public: | |
789 | PostBlitDeclaration *syntaxCopy(Dsymbol *) override; | |
790 | bool isVirtual() const override; | |
791 | bool addPreInvariant() override; | |
792 | bool addPostInvariant() override; | |
793 | bool overloadInsert(Dsymbol *s) override; | |
794 | ||
795 | void accept(Visitor *v) override { v->visit(this); } | |
796 | }; | |
797 | ||
798 | class DtorDeclaration final : public FuncDeclaration | |
799 | { | |
800 | public: | |
801 | DtorDeclaration *syntaxCopy(Dsymbol *) override; | |
802 | const char *kind() const override; | |
803 | bool isVirtual() const override; | |
804 | bool addPreInvariant() override; | |
805 | bool addPostInvariant() override; | |
806 | bool overloadInsert(Dsymbol *s) override; | |
807 | ||
808 | void accept(Visitor *v) override { v->visit(this); } | |
809 | }; | |
810 | ||
811 | class StaticCtorDeclaration : public FuncDeclaration | |
812 | { | |
813 | public: | |
814 | StaticCtorDeclaration *syntaxCopy(Dsymbol *) override; | |
815 | AggregateDeclaration *isThis() override final; | |
816 | bool isVirtual() const override final; | |
817 | bool addPreInvariant() override final; | |
818 | bool addPostInvariant() override final; | |
819 | ||
820 | void accept(Visitor *v) override { v->visit(this); } | |
821 | }; | |
822 | ||
823 | class SharedStaticCtorDeclaration final : public StaticCtorDeclaration | |
824 | { | |
825 | public: | |
826 | bool standalone; | |
827 | SharedStaticCtorDeclaration *syntaxCopy(Dsymbol *) override; | |
828 | ||
829 | void accept(Visitor *v) override { v->visit(this); } | |
830 | }; | |
831 | ||
832 | class StaticDtorDeclaration : public FuncDeclaration | |
833 | { | |
834 | public: | |
835 | VarDeclaration *vgate; // 'gate' variable | |
836 | ||
837 | StaticDtorDeclaration *syntaxCopy(Dsymbol *) override; | |
838 | AggregateDeclaration *isThis() override final; | |
839 | bool isVirtual() const override final; | |
840 | bool addPreInvariant() override final; | |
841 | bool addPostInvariant() override final; | |
842 | ||
843 | void accept(Visitor *v) override { v->visit(this); } | |
844 | }; | |
845 | ||
846 | class SharedStaticDtorDeclaration final : public StaticDtorDeclaration | |
847 | { | |
848 | public: | |
849 | SharedStaticDtorDeclaration *syntaxCopy(Dsymbol *) override; | |
850 | ||
851 | void accept(Visitor *v) override { v->visit(this); } | |
852 | }; | |
853 | ||
854 | class InvariantDeclaration final : public FuncDeclaration | |
855 | { | |
856 | public: | |
857 | InvariantDeclaration *syntaxCopy(Dsymbol *) override; | |
858 | bool isVirtual() const override; | |
859 | bool addPreInvariant() override; | |
860 | bool addPostInvariant() override; | |
861 | ||
862 | void accept(Visitor *v) override { v->visit(this); } | |
863 | }; | |
864 | ||
865 | class UnitTestDeclaration final : public FuncDeclaration | |
866 | { | |
867 | public: | |
868 | char *codedoc; /** For documented unittest. */ | |
869 | ||
870 | // toObjFile() these nested functions after this one | |
871 | FuncDeclarations deferredNested; | |
872 | ||
873 | UnitTestDeclaration *syntaxCopy(Dsymbol *) override; | |
874 | AggregateDeclaration *isThis() override; | |
875 | bool isVirtual() const override; | |
876 | bool addPreInvariant() override; | |
877 | bool addPostInvariant() override; | |
878 | ||
879 | void accept(Visitor *v) override { v->visit(this); } | |
880 | }; | |
881 | ||
882 | class NewDeclaration final : public FuncDeclaration | |
883 | { | |
884 | public: | |
885 | NewDeclaration *syntaxCopy(Dsymbol *) override; | |
886 | const char *kind() const override; | |
887 | bool isVirtual() const override; | |
888 | bool addPreInvariant() override; | |
889 | bool addPostInvariant() override; | |
890 | ||
891 | void accept(Visitor *v) override { v->visit(this); } | |
892 | }; |