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