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