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