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