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
17class Expression;
18class Statement;
19class LabelDsymbol;
20class Initializer;
21class Module;
22class ForeachStatement;
23class FuncDeclaration;
24class ExpInitializer;
25class StructDeclaration;
26struct InterState;
27struct CompiledCtfeFunction;
28struct ObjcSelector;
29struct IntRange;
30
31enum LINK;
32enum TOK;
33enum MATCH;
34enum PURE;
35enum 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
95const 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
101struct 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
110void functionResolve(Match *m, Dsymbol *fd, Loc loc, Scope *sc, Objects *tiargs, Type *tthis, Expressions *fargs);
111int overloadApply(Dsymbol *fstart, void *param, int (*fp)(void *, Dsymbol *));
112
113void ObjectNotFound(Identifier *id);
114
115/**************************************************************/
116
117class Declaration : public Dsymbol
118{
119public:
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
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;
141    bool isCtorinit()     { return (storage_class & STCctorinit) != 0; }
142    bool isFinal()        { return (storage_class & STCfinal) != 0; }
143    bool isAbstract()     { return (storage_class & STCabstract) != 0; }
144    bool isConst()        { return (storage_class & STCconst) != 0; }
145    bool isImmutable()    { return (storage_class & STCimmutable) != 0; }
146    bool isWild()         { return (storage_class & STCwild) != 0; }
147    bool isAuto()         { return (storage_class & STCauto) != 0; }
148    bool isScope()        { return (storage_class & STCscope) != 0; }
149    bool isSynchronized() { return (storage_class & STCsynchronized) != 0; }
150    bool isParameter()    { return (storage_class & STCparameter) != 0; }
151    bool isDeprecated()   { return (storage_class & STCdeprecated) != 0; }
152    bool isOverride()     { return (storage_class & STCoverride) != 0; }
153    bool isResult()       { return (storage_class & STCresult) != 0; }
154    bool isField()        { return (storage_class & STCfield) != 0; }
155
156    bool isIn()    { return (storage_class & STCin) != 0; }
157    bool isOut()   { return (storage_class & STCout) != 0; }
158    bool isRef()   { return (storage_class & STCref) != 0; }
159
160    bool isFuture() { return (storage_class & STCfuture) != 0; }
161
162    Prot prot();
163
164    Declaration *isDeclaration() { return this; }
165    void accept(Visitor *v) { v->visit(this); }
166};
167
168/**************************************************************/
169
170class TupleDeclaration : public Declaration
171{
172public:
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
185    TupleDeclaration *isTupleDeclaration() { return this; }
186    void accept(Visitor *v) { v->visit(this); }
187};
188
189/**************************************************************/
190
191class AliasDeclaration : public Declaration
192{
193public:
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
211    AliasDeclaration *isAliasDeclaration() { return this; }
212    void accept(Visitor *v) { v->visit(this); }
213};
214
215/**************************************************************/
216
217class OverDeclaration : public Declaration
218{
219public:
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
234    OverDeclaration *isOverDeclaration() { return this; }
235    void accept(Visitor *v) { v->visit(this); }
236};
237
238/**************************************************************/
239
240class VarDeclaration : public Declaration
241{
242public:
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
293    VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; }
294    void accept(Visitor *v) { v->visit(this); }
295};
296
297/**************************************************************/
298
299// This is a shell around a back end symbol
300
301class SymbolDeclaration : public Declaration
302{
303public:
304    StructDeclaration *dsym;
305
306    SymbolDeclaration(Loc loc, StructDeclaration *dsym);
307
308    // Eliminate need for dynamic_cast
309    SymbolDeclaration *isSymbolDeclaration() { return (SymbolDeclaration *)this; }
310    void accept(Visitor *v) { v->visit(this); }
311};
312
313class TypeInfoDeclaration : public VarDeclaration
314{
315public:
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
324    TypeInfoDeclaration *isTypeInfoDeclaration() { return this; }
325    void accept(Visitor *v) { v->visit(this); }
326};
327
328class TypeInfoStructDeclaration : public TypeInfoDeclaration
329{
330public:
331    TypeInfoStructDeclaration(Type *tinfo);
332    static TypeInfoStructDeclaration *create(Type *tinfo);
333
334    void accept(Visitor *v) { v->visit(this); }
335};
336
337class TypeInfoClassDeclaration : public TypeInfoDeclaration
338{
339public:
340    TypeInfoClassDeclaration(Type *tinfo);
341    static TypeInfoClassDeclaration *create(Type *tinfo);
342
343    void accept(Visitor *v) { v->visit(this); }
344};
345
346class TypeInfoInterfaceDeclaration : public TypeInfoDeclaration
347{
348public:
349    TypeInfoInterfaceDeclaration(Type *tinfo);
350    static TypeInfoInterfaceDeclaration *create(Type *tinfo);
351
352    void accept(Visitor *v) { v->visit(this); }
353};
354
355class TypeInfoPointerDeclaration : public TypeInfoDeclaration
356{
357public:
358    TypeInfoPointerDeclaration(Type *tinfo);
359    static TypeInfoPointerDeclaration *create(Type *tinfo);
360
361    void accept(Visitor *v) { v->visit(this); }
362};
363
364class TypeInfoArrayDeclaration : public TypeInfoDeclaration
365{
366public:
367    TypeInfoArrayDeclaration(Type *tinfo);
368    static TypeInfoArrayDeclaration *create(Type *tinfo);
369
370    void accept(Visitor *v) { v->visit(this); }
371};
372
373class TypeInfoStaticArrayDeclaration : public TypeInfoDeclaration
374{
375public:
376    TypeInfoStaticArrayDeclaration(Type *tinfo);
377    static TypeInfoStaticArrayDeclaration *create(Type *tinfo);
378
379    void accept(Visitor *v) { v->visit(this); }
380};
381
382class TypeInfoAssociativeArrayDeclaration : public TypeInfoDeclaration
383{
384public:
385    TypeInfoAssociativeArrayDeclaration(Type *tinfo);
386    static TypeInfoAssociativeArrayDeclaration *create(Type *tinfo);
387
388    void accept(Visitor *v) { v->visit(this); }
389};
390
391class TypeInfoEnumDeclaration : public TypeInfoDeclaration
392{
393public:
394    TypeInfoEnumDeclaration(Type *tinfo);
395    static TypeInfoEnumDeclaration *create(Type *tinfo);
396
397    void accept(Visitor *v) { v->visit(this); }
398};
399
400class TypeInfoFunctionDeclaration : public TypeInfoDeclaration
401{
402public:
403    TypeInfoFunctionDeclaration(Type *tinfo);
404    static TypeInfoFunctionDeclaration *create(Type *tinfo);
405
406    void accept(Visitor *v) { v->visit(this); }
407};
408
409class TypeInfoDelegateDeclaration : public TypeInfoDeclaration
410{
411public:
412    TypeInfoDelegateDeclaration(Type *tinfo);
413    static TypeInfoDelegateDeclaration *create(Type *tinfo);
414
415    void accept(Visitor *v) { v->visit(this); }
416};
417
418class TypeInfoTupleDeclaration : public TypeInfoDeclaration
419{
420public:
421    TypeInfoTupleDeclaration(Type *tinfo);
422    static TypeInfoTupleDeclaration *create(Type *tinfo);
423
424    void accept(Visitor *v) { v->visit(this); }
425};
426
427class TypeInfoConstDeclaration : public TypeInfoDeclaration
428{
429public:
430    TypeInfoConstDeclaration(Type *tinfo);
431    static TypeInfoConstDeclaration *create(Type *tinfo);
432
433    void accept(Visitor *v) { v->visit(this); }
434};
435
436class TypeInfoInvariantDeclaration : public TypeInfoDeclaration
437{
438public:
439    TypeInfoInvariantDeclaration(Type *tinfo);
440    static TypeInfoInvariantDeclaration *create(Type *tinfo);
441
442    void accept(Visitor *v) { v->visit(this); }
443};
444
445class TypeInfoSharedDeclaration : public TypeInfoDeclaration
446{
447public:
448    TypeInfoSharedDeclaration(Type *tinfo);
449    static TypeInfoSharedDeclaration *create(Type *tinfo);
450
451    void accept(Visitor *v) { v->visit(this); }
452};
453
454class TypeInfoWildDeclaration : public TypeInfoDeclaration
455{
456public:
457    TypeInfoWildDeclaration(Type *tinfo);
458    static TypeInfoWildDeclaration *create(Type *tinfo);
459
460    void accept(Visitor *v) { v->visit(this); }
461};
462
463class TypeInfoVectorDeclaration : public TypeInfoDeclaration
464{
465public:
466    TypeInfoVectorDeclaration(Type *tinfo);
467    static TypeInfoVectorDeclaration *create(Type *tinfo);
468
469    void accept(Visitor *v) { v->visit(this); }
470};
471
472/**************************************************************/
473
474class ThisDeclaration : public VarDeclaration
475{
476public:
477    ThisDeclaration(Loc loc, Type *t);
478    Dsymbol *syntaxCopy(Dsymbol *);
479    ThisDeclaration *isThisDeclaration() { return this; }
480    void accept(Visitor *v) { v->visit(this); }
481};
482
483enum ILS
484{
485    ILSuninitialized,   // not computed yet
486    ILSno,              // cannot inline
487    ILSyes              // can inline
488};
489
490/**************************************************************/
491
492enum 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
499Expression *eval_builtin(Loc loc, FuncDeclaration *fd, Expressions *arguments);
500BUILTIN isBuiltin(FuncDeclaration *fd);
501
502typedef Expression *(*builtin_fp)(Loc loc, FuncDeclaration *fd, Expressions *arguments);
503void add_builtin(const char *mangle, builtin_fp fp);
504void 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
514class FuncDeclaration : public Declaration
515{
516public:
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
673    FuncDeclaration *isFuncDeclaration() { return this; }
674
675    virtual FuncDeclaration *toAliasFunc() { return this; }
676    void accept(Visitor *v) { v->visit(this); }
677};
678
679FuncDeclaration *resolveFuncCall(Loc loc, Scope *sc, Dsymbol *s,
680        Objects *tiargs,
681        Type *tthis,
682        Expressions *arguments,
683        int flags = 0);
684
685class FuncAliasDeclaration : public FuncDeclaration
686{
687public:
688    FuncDeclaration *funcalias;
689    bool hasOverloads;
690
691    FuncAliasDeclaration(Identifier *ident, FuncDeclaration *funcalias, bool hasOverloads = true);
692
693    FuncAliasDeclaration *isFuncAliasDeclaration() { return this; }
694    const char *kind() const;
695
696    FuncDeclaration *toAliasFunc();
697    void accept(Visitor *v) { v->visit(this); }
698};
699
700class FuncLiteralDeclaration : public FuncDeclaration
701{
702public:
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
720    FuncLiteralDeclaration *isFuncLiteralDeclaration() { return this; }
721    const char *kind() const;
722    const char *toPrettyChars(bool QualifyTypes = false);
723    void accept(Visitor *v) { v->visit(this); }
724};
725
726class CtorDeclaration : public FuncDeclaration
727{
728public:
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
738    CtorDeclaration *isCtorDeclaration() { return this; }
739    void accept(Visitor *v) { v->visit(this); }
740};
741
742class PostBlitDeclaration : public FuncDeclaration
743{
744public:
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
753    PostBlitDeclaration *isPostBlitDeclaration() { return this; }
754    void accept(Visitor *v) { v->visit(this); }
755};
756
757class DtorDeclaration : public FuncDeclaration
758{
759public:
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
771    DtorDeclaration *isDtorDeclaration() { return this; }
772    void accept(Visitor *v) { v->visit(this); }
773};
774
775class StaticCtorDeclaration : public FuncDeclaration
776{
777public:
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
788    StaticCtorDeclaration *isStaticCtorDeclaration() { return this; }
789    void accept(Visitor *v) { v->visit(this); }
790};
791
792class SharedStaticCtorDeclaration : public StaticCtorDeclaration
793{
794public:
795    SharedStaticCtorDeclaration(Loc loc, Loc endloc, StorageClass stc);
796    Dsymbol *syntaxCopy(Dsymbol *);
797
798    SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return this; }
799    void accept(Visitor *v) { v->visit(this); }
800};
801
802class StaticDtorDeclaration : public FuncDeclaration
803{
804public:
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
817    StaticDtorDeclaration *isStaticDtorDeclaration() { return this; }
818    void accept(Visitor *v) { v->visit(this); }
819};
820
821class SharedStaticDtorDeclaration : public StaticDtorDeclaration
822{
823public:
824    SharedStaticDtorDeclaration(Loc loc, Loc endloc, StorageClass stc);
825    Dsymbol *syntaxCopy(Dsymbol *);
826
827    SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return this; }
828    void accept(Visitor *v) { v->visit(this); }
829};
830
831class InvariantDeclaration : public FuncDeclaration
832{
833public:
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
841    InvariantDeclaration *isInvariantDeclaration() { return this; }
842    void accept(Visitor *v) { v->visit(this); }
843};
844
845class UnitTestDeclaration : public FuncDeclaration
846{
847public:
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
861    UnitTestDeclaration *isUnitTestDeclaration() { return this; }
862    void accept(Visitor *v) { v->visit(this); }
863};
864
865class NewDeclaration : public FuncDeclaration
866{
867public:
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
879    NewDeclaration *isNewDeclaration() { return this; }
880    void accept(Visitor *v) { v->visit(this); }
881};
882
883
884class DeleteDeclaration : public FuncDeclaration
885{
886public:
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
898    DeleteDeclaration *isDeleteDeclaration() { return this; }
899    void accept(Visitor *v) { v->visit(this); }
900};
901