declaration.h revision 1.1.1.1
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    Dsymbol *syntaxCopy(Dsymbol *);
269    void semantic(Scope *sc);
270    void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
271    void semantic2(Scope *sc);
272    const char *kind() const;
273    AggregateDeclaration *isThis();
274    bool needThis();
275    bool isExport() const;
276    bool isImportedSymbol() const;
277    bool isDataseg();
278    bool isThreadlocal();
279    bool isCTFE();
280    bool isOverlappedWith(VarDeclaration *v);
281    bool hasPointers();
282    bool canTakeAddressOf();
283    bool needsScopeDtor();
284    bool enclosesLifetimeOf(VarDeclaration *v) const;
285    Expression *callScopeDtor(Scope *sc);
286    Expression *getConstInitializer(bool needFullType = true);
287    Expression *expandInitializer(Loc loc);
288    void checkCtorConstInit();
289    bool checkNestedReference(Scope *sc, Loc loc);
290    Dsymbol *toAlias();
291    // Eliminate need for dynamic_cast
292    VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; }
293    void accept(Visitor *v) { v->visit(this); }
294};
295
296/**************************************************************/
297
298// This is a shell around a back end symbol
299
300class SymbolDeclaration : public Declaration
301{
302public:
303    StructDeclaration *dsym;
304
305    SymbolDeclaration(Loc loc, StructDeclaration *dsym);
306
307    // Eliminate need for dynamic_cast
308    SymbolDeclaration *isSymbolDeclaration() { return (SymbolDeclaration *)this; }
309    void accept(Visitor *v) { v->visit(this); }
310};
311
312class TypeInfoDeclaration : public VarDeclaration
313{
314public:
315    Type *tinfo;
316
317    TypeInfoDeclaration(Type *tinfo);
318    static TypeInfoDeclaration *create(Type *tinfo);
319    Dsymbol *syntaxCopy(Dsymbol *);
320    void semantic(Scope *sc);
321    const char *toChars();
322
323    TypeInfoDeclaration *isTypeInfoDeclaration() { return this; }
324    void accept(Visitor *v) { v->visit(this); }
325};
326
327class TypeInfoStructDeclaration : public TypeInfoDeclaration
328{
329public:
330    TypeInfoStructDeclaration(Type *tinfo);
331    static TypeInfoStructDeclaration *create(Type *tinfo);
332
333    void accept(Visitor *v) { v->visit(this); }
334};
335
336class TypeInfoClassDeclaration : public TypeInfoDeclaration
337{
338public:
339    TypeInfoClassDeclaration(Type *tinfo);
340    static TypeInfoClassDeclaration *create(Type *tinfo);
341
342    void accept(Visitor *v) { v->visit(this); }
343};
344
345class TypeInfoInterfaceDeclaration : public TypeInfoDeclaration
346{
347public:
348    TypeInfoInterfaceDeclaration(Type *tinfo);
349    static TypeInfoInterfaceDeclaration *create(Type *tinfo);
350
351    void accept(Visitor *v) { v->visit(this); }
352};
353
354class TypeInfoPointerDeclaration : public TypeInfoDeclaration
355{
356public:
357    TypeInfoPointerDeclaration(Type *tinfo);
358    static TypeInfoPointerDeclaration *create(Type *tinfo);
359
360    void accept(Visitor *v) { v->visit(this); }
361};
362
363class TypeInfoArrayDeclaration : public TypeInfoDeclaration
364{
365public:
366    TypeInfoArrayDeclaration(Type *tinfo);
367    static TypeInfoArrayDeclaration *create(Type *tinfo);
368
369    void accept(Visitor *v) { v->visit(this); }
370};
371
372class TypeInfoStaticArrayDeclaration : public TypeInfoDeclaration
373{
374public:
375    TypeInfoStaticArrayDeclaration(Type *tinfo);
376    static TypeInfoStaticArrayDeclaration *create(Type *tinfo);
377
378    void accept(Visitor *v) { v->visit(this); }
379};
380
381class TypeInfoAssociativeArrayDeclaration : public TypeInfoDeclaration
382{
383public:
384    TypeInfoAssociativeArrayDeclaration(Type *tinfo);
385    static TypeInfoAssociativeArrayDeclaration *create(Type *tinfo);
386
387    void accept(Visitor *v) { v->visit(this); }
388};
389
390class TypeInfoEnumDeclaration : public TypeInfoDeclaration
391{
392public:
393    TypeInfoEnumDeclaration(Type *tinfo);
394    static TypeInfoEnumDeclaration *create(Type *tinfo);
395
396    void accept(Visitor *v) { v->visit(this); }
397};
398
399class TypeInfoFunctionDeclaration : public TypeInfoDeclaration
400{
401public:
402    TypeInfoFunctionDeclaration(Type *tinfo);
403    static TypeInfoFunctionDeclaration *create(Type *tinfo);
404
405    void accept(Visitor *v) { v->visit(this); }
406};
407
408class TypeInfoDelegateDeclaration : public TypeInfoDeclaration
409{
410public:
411    TypeInfoDelegateDeclaration(Type *tinfo);
412    static TypeInfoDelegateDeclaration *create(Type *tinfo);
413
414    void accept(Visitor *v) { v->visit(this); }
415};
416
417class TypeInfoTupleDeclaration : public TypeInfoDeclaration
418{
419public:
420    TypeInfoTupleDeclaration(Type *tinfo);
421    static TypeInfoTupleDeclaration *create(Type *tinfo);
422
423    void accept(Visitor *v) { v->visit(this); }
424};
425
426class TypeInfoConstDeclaration : public TypeInfoDeclaration
427{
428public:
429    TypeInfoConstDeclaration(Type *tinfo);
430    static TypeInfoConstDeclaration *create(Type *tinfo);
431
432    void accept(Visitor *v) { v->visit(this); }
433};
434
435class TypeInfoInvariantDeclaration : public TypeInfoDeclaration
436{
437public:
438    TypeInfoInvariantDeclaration(Type *tinfo);
439    static TypeInfoInvariantDeclaration *create(Type *tinfo);
440
441    void accept(Visitor *v) { v->visit(this); }
442};
443
444class TypeInfoSharedDeclaration : public TypeInfoDeclaration
445{
446public:
447    TypeInfoSharedDeclaration(Type *tinfo);
448    static TypeInfoSharedDeclaration *create(Type *tinfo);
449
450    void accept(Visitor *v) { v->visit(this); }
451};
452
453class TypeInfoWildDeclaration : public TypeInfoDeclaration
454{
455public:
456    TypeInfoWildDeclaration(Type *tinfo);
457    static TypeInfoWildDeclaration *create(Type *tinfo);
458
459    void accept(Visitor *v) { v->visit(this); }
460};
461
462class TypeInfoVectorDeclaration : public TypeInfoDeclaration
463{
464public:
465    TypeInfoVectorDeclaration(Type *tinfo);
466    static TypeInfoVectorDeclaration *create(Type *tinfo);
467
468    void accept(Visitor *v) { v->visit(this); }
469};
470
471/**************************************************************/
472
473class ThisDeclaration : public VarDeclaration
474{
475public:
476    ThisDeclaration(Loc loc, Type *t);
477    Dsymbol *syntaxCopy(Dsymbol *);
478    ThisDeclaration *isThisDeclaration() { return this; }
479    void accept(Visitor *v) { v->visit(this); }
480};
481
482enum ILS
483{
484    ILSuninitialized,   // not computed yet
485    ILSno,              // cannot inline
486    ILSyes              // can inline
487};
488
489/**************************************************************/
490
491enum BUILTIN
492{
493    BUILTINunknown = -1,        // not known if this is a builtin
494    BUILTINno,                  // this is not a builtin
495    BUILTINyes                  // this is a builtin
496};
497
498Expression *eval_builtin(Loc loc, FuncDeclaration *fd, Expressions *arguments);
499BUILTIN isBuiltin(FuncDeclaration *fd);
500
501typedef Expression *(*builtin_fp)(Loc loc, FuncDeclaration *fd, Expressions *arguments);
502void add_builtin(const char *mangle, builtin_fp fp);
503void builtin_init();
504
505#define FUNCFLAGpurityInprocess    1    // working on determining purity
506#define FUNCFLAGsafetyInprocess    2    // working on determining safety
507#define FUNCFLAGnothrowInprocess   4    // working on determining nothrow
508#define FUNCFLAGnogcInprocess      8    // working on determining @nogc
509#define FUNCFLAGreturnInprocess 0x10    // working on inferring 'return' for parameters
510#define FUNCFLAGinlineScanned   0x20    // function has been scanned for inline possibilities
511#define FUNCFLAGinferScope      0x40    // infer 'scope' for parameters
512
513class FuncDeclaration : public Declaration
514{
515public:
516    Types *fthrows;                     // Array of Type's of exceptions (not used)
517    Statement *frequire;
518    Statement *fensure;
519    Statement *fbody;
520
521    FuncDeclarations foverrides;        // functions this function overrides
522    FuncDeclaration *fdrequire;         // function that does the in contract
523    FuncDeclaration *fdensure;          // function that does the out contract
524
525    const char *mangleString;           // mangled symbol created from mangleExact()
526
527    Identifier *outId;                  // identifier for out statement
528    VarDeclaration *vresult;            // variable corresponding to outId
529    LabelDsymbol *returnLabel;          // where the return goes
530
531    // used to prevent symbols in different
532    // scopes from having the same name
533    DsymbolTable *localsymtab;
534    VarDeclaration *vthis;              // 'this' parameter (member and nested)
535    VarDeclaration *v_arguments;        // '_arguments' parameter
536    ObjcSelector* selector;             // Objective-C method selector (member function only)
537    VarDeclaration *v_argptr;           // '_argptr' variable
538    VarDeclarations *parameters;        // Array of VarDeclaration's for parameters
539    DsymbolTable *labtab;               // statement label symbol table
540    Dsymbol *overnext;                  // next in overload list
541    FuncDeclaration *overnext0;         // next in overload list (only used during IFTI)
542    Loc endloc;                         // location of closing curly bracket
543    int vtblIndex;                      // for member functions, index into vtbl[]
544    bool naked;                         // true if naked
545    bool generated;                     // true if function was generated by the compiler rather than
546                                        // supplied by the user
547    ILS inlineStatusStmt;
548    ILS inlineStatusExp;
549    PINLINE inlining;
550
551    CompiledCtfeFunction *ctfeCode;     // Compiled code for interpreter
552    int inlineNest;                     // !=0 if nested inline
553    bool isArrayOp;                     // true if array operation
554    // true if errors in semantic3 this function's frame ptr
555    bool semantic3Errors;
556    ForeachStatement *fes;              // if foreach body, this is the foreach
557    BaseClass* interfaceVirtual;        // if virtual, but only appears in interface vtbl[]
558    bool introducing;                   // true if 'introducing' function
559    // if !=NULL, then this is the type
560    // of the 'introducing' function
561    // this one is overriding
562    Type *tintro;
563    bool inferRetType;                  // true if return type is to be inferred
564    StorageClass storage_class2;        // storage class for template onemember's
565
566    // Things that should really go into Scope
567
568    // 1 if there's a return exp; statement
569    // 2 if there's a throw statement
570    // 4 if there's an assert(0)
571    // 8 if there's inline asm
572    // 16 if there are multiple return statements
573    int hasReturnExp;
574
575    // Support for NRVO (named return value optimization)
576    bool nrvo_can;                      // true means we can do it
577    VarDeclaration *nrvo_var;           // variable to replace with shidden
578    Symbol *shidden;                    // hidden pointer passed to function
579
580    ReturnStatements *returns;
581
582    GotoStatements *gotos;              // Gotos with forward references
583
584    // set if this is a known, builtin function we can evaluate at compile time
585    BUILTIN builtin;
586
587    // set if someone took the address of this function
588    int tookAddressOf;
589    bool requiresClosure;               // this function needs a closure
590
591    // local variables in this function which are referenced by nested functions
592    VarDeclarations closureVars;
593    // Sibling nested functions which called this one
594    FuncDeclarations siblingCallers;
595
596    FuncDeclarations *inlinedNestedCallees;
597
598    unsigned flags;                     // FUNCFLAGxxxxx
599
600    FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type);
601    static FuncDeclaration *create(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type);
602    Dsymbol *syntaxCopy(Dsymbol *);
603    void semantic(Scope *sc);
604    void semantic2(Scope *sc);
605    void semantic3(Scope *sc);
606    bool functionSemantic();
607    bool functionSemantic3();
608    bool checkForwardRef(Loc loc);
609    // called from semantic3
610    VarDeclaration *declareThis(Scope *sc, AggregateDeclaration *ad);
611    bool equals(RootObject *o);
612
613    int overrides(FuncDeclaration *fd);
614    int findVtblIndex(Dsymbols *vtbl, int dim, bool fix17349 = true);
615    BaseClass *overrideInterface();
616    bool overloadInsert(Dsymbol *s);
617    FuncDeclaration *overloadExactMatch(Type *t);
618    FuncDeclaration *overloadModMatch(Loc loc, Type *tthis, bool &hasOverloads);
619    TemplateDeclaration *findTemplateDeclRoot();
620    bool inUnittest();
621    MATCH leastAsSpecialized(FuncDeclaration *g);
622    LabelDsymbol *searchLabel(Identifier *ident);
623    int getLevel(Loc loc, Scope *sc, FuncDeclaration *fd); // lexical nesting level difference
624    const char *toPrettyChars(bool QualifyTypes = false);
625    const char *toFullSignature();  // for diagnostics, e.g. 'int foo(int x, int y) pure'
626    bool isMain();
627    bool isCMain();
628    bool isWinMain();
629    bool isDllMain();
630    bool isExport() const;
631    bool isImportedSymbol() const;
632    bool isCodeseg() const;
633    bool isOverloadable();
634    PURE isPure();
635    PURE isPureBypassingInference();
636    bool setImpure();
637    bool isSafe();
638    bool isSafeBypassingInference();
639    bool isTrusted();
640    bool setUnsafe();
641
642    bool isNogc();
643    bool isNogcBypassingInference();
644    bool setGC();
645
646    void printGCUsage(Loc loc, const char *warn);
647    bool isolateReturn();
648    bool parametersIntersect(Type *t);
649    virtual bool isNested();
650    AggregateDeclaration *isThis();
651    bool needThis();
652    bool isVirtualMethod();
653    virtual bool isVirtual();
654    virtual bool isFinalFunc();
655    virtual bool addPreInvariant();
656    virtual bool addPostInvariant();
657    const char *kind() const;
658    FuncDeclaration *isUnique();
659    bool checkNestedReference(Scope *sc, Loc loc);
660    bool needsClosure();
661    bool checkClosure();
662    bool hasNestedFrameRefs();
663    void buildResultVar(Scope *sc, Type *tret);
664    Statement *mergeFrequire(Statement *);
665    Statement *mergeFensure(Statement *, Identifier *oid);
666    Parameters *getParameters(int *pvarargs);
667
668    static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, const char *name, StorageClass stc=0);
669    static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, Identifier *id, StorageClass stc=0);
670    void checkDmain();
671
672    FuncDeclaration *isFuncDeclaration() { return this; }
673
674    virtual FuncDeclaration *toAliasFunc() { return this; }
675    void accept(Visitor *v) { v->visit(this); }
676};
677
678FuncDeclaration *resolveFuncCall(Loc loc, Scope *sc, Dsymbol *s,
679        Objects *tiargs,
680        Type *tthis,
681        Expressions *arguments,
682        int flags = 0);
683
684class FuncAliasDeclaration : public FuncDeclaration
685{
686public:
687    FuncDeclaration *funcalias;
688    bool hasOverloads;
689
690    FuncAliasDeclaration(Identifier *ident, FuncDeclaration *funcalias, bool hasOverloads = true);
691
692    FuncAliasDeclaration *isFuncAliasDeclaration() { return this; }
693    const char *kind() const;
694
695    FuncDeclaration *toAliasFunc();
696    void accept(Visitor *v) { v->visit(this); }
697};
698
699class FuncLiteralDeclaration : public FuncDeclaration
700{
701public:
702    TOK tok;                       // TOKfunction or TOKdelegate
703    Type *treq;                         // target of return type inference
704
705    // backend
706    bool deferToObj;
707
708    FuncLiteralDeclaration(Loc loc, Loc endloc, Type *type, TOK tok,
709        ForeachStatement *fes, Identifier *id = NULL);
710    Dsymbol *syntaxCopy(Dsymbol *);
711    bool isNested();
712    AggregateDeclaration *isThis();
713    bool isVirtual();
714    bool addPreInvariant();
715    bool addPostInvariant();
716
717    void modifyReturns(Scope *sc, Type *tret);
718
719    FuncLiteralDeclaration *isFuncLiteralDeclaration() { return this; }
720    const char *kind() const;
721    const char *toPrettyChars(bool QualifyTypes = false);
722    void accept(Visitor *v) { v->visit(this); }
723};
724
725class CtorDeclaration : public FuncDeclaration
726{
727public:
728    CtorDeclaration(Loc loc, Loc endloc, StorageClass stc, Type *type);
729    Dsymbol *syntaxCopy(Dsymbol *);
730    void semantic(Scope *sc);
731    const char *kind() const;
732    const char *toChars();
733    bool isVirtual();
734    bool addPreInvariant();
735    bool addPostInvariant();
736
737    CtorDeclaration *isCtorDeclaration() { return this; }
738    void accept(Visitor *v) { v->visit(this); }
739};
740
741class PostBlitDeclaration : public FuncDeclaration
742{
743public:
744    PostBlitDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id);
745    Dsymbol *syntaxCopy(Dsymbol *);
746    void semantic(Scope *sc);
747    bool isVirtual();
748    bool addPreInvariant();
749    bool addPostInvariant();
750    bool overloadInsert(Dsymbol *s);
751
752    PostBlitDeclaration *isPostBlitDeclaration() { return this; }
753    void accept(Visitor *v) { v->visit(this); }
754};
755
756class DtorDeclaration : public FuncDeclaration
757{
758public:
759    DtorDeclaration(Loc loc, Loc endloc);
760    DtorDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id);
761    Dsymbol *syntaxCopy(Dsymbol *);
762    void semantic(Scope *sc);
763    const char *kind() const;
764    const char *toChars();
765    bool isVirtual();
766    bool addPreInvariant();
767    bool addPostInvariant();
768    bool overloadInsert(Dsymbol *s);
769
770    DtorDeclaration *isDtorDeclaration() { return this; }
771    void accept(Visitor *v) { v->visit(this); }
772};
773
774class StaticCtorDeclaration : public FuncDeclaration
775{
776public:
777    StaticCtorDeclaration(Loc loc, Loc endloc, StorageClass stc);
778    StaticCtorDeclaration(Loc loc, Loc endloc, const char *name, StorageClass stc);
779    Dsymbol *syntaxCopy(Dsymbol *);
780    void semantic(Scope *sc);
781    AggregateDeclaration *isThis();
782    bool isVirtual();
783    bool addPreInvariant();
784    bool addPostInvariant();
785    bool hasStaticCtorOrDtor();
786
787    StaticCtorDeclaration *isStaticCtorDeclaration() { return this; }
788    void accept(Visitor *v) { v->visit(this); }
789};
790
791class SharedStaticCtorDeclaration : public StaticCtorDeclaration
792{
793public:
794    SharedStaticCtorDeclaration(Loc loc, Loc endloc, StorageClass stc);
795    Dsymbol *syntaxCopy(Dsymbol *);
796
797    SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return this; }
798    void accept(Visitor *v) { v->visit(this); }
799};
800
801class StaticDtorDeclaration : public FuncDeclaration
802{
803public:
804    VarDeclaration *vgate;      // 'gate' variable
805
806    StaticDtorDeclaration(Loc loc, Loc endloc, StorageClass stc);
807    StaticDtorDeclaration(Loc loc, Loc endloc, const char *name, StorageClass stc);
808    Dsymbol *syntaxCopy(Dsymbol *);
809    void semantic(Scope *sc);
810    AggregateDeclaration *isThis();
811    bool isVirtual();
812    bool hasStaticCtorOrDtor();
813    bool addPreInvariant();
814    bool addPostInvariant();
815
816    StaticDtorDeclaration *isStaticDtorDeclaration() { return this; }
817    void accept(Visitor *v) { v->visit(this); }
818};
819
820class SharedStaticDtorDeclaration : public StaticDtorDeclaration
821{
822public:
823    SharedStaticDtorDeclaration(Loc loc, Loc endloc, StorageClass stc);
824    Dsymbol *syntaxCopy(Dsymbol *);
825
826    SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return this; }
827    void accept(Visitor *v) { v->visit(this); }
828};
829
830class InvariantDeclaration : public FuncDeclaration
831{
832public:
833    InvariantDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id = NULL);
834    Dsymbol *syntaxCopy(Dsymbol *);
835    void semantic(Scope *sc);
836    bool isVirtual();
837    bool addPreInvariant();
838    bool addPostInvariant();
839
840    InvariantDeclaration *isInvariantDeclaration() { return this; }
841    void accept(Visitor *v) { v->visit(this); }
842};
843
844class UnitTestDeclaration : public FuncDeclaration
845{
846public:
847    char *codedoc; /** For documented unittest. */
848
849    // toObjFile() these nested functions after this one
850    FuncDeclarations deferredNested;
851
852    UnitTestDeclaration(Loc loc, Loc endloc, StorageClass stc, char *codedoc);
853    Dsymbol *syntaxCopy(Dsymbol *);
854    void semantic(Scope *sc);
855    AggregateDeclaration *isThis();
856    bool isVirtual();
857    bool addPreInvariant();
858    bool addPostInvariant();
859
860    UnitTestDeclaration *isUnitTestDeclaration() { return this; }
861    void accept(Visitor *v) { v->visit(this); }
862};
863
864class NewDeclaration : public FuncDeclaration
865{
866public:
867    Parameters *parameters;
868    int varargs;
869
870    NewDeclaration(Loc loc, Loc endloc, StorageClass stc, Parameters *arguments, int varargs);
871    Dsymbol *syntaxCopy(Dsymbol *);
872    void semantic(Scope *sc);
873    const char *kind() const;
874    bool isVirtual();
875    bool addPreInvariant();
876    bool addPostInvariant();
877
878    NewDeclaration *isNewDeclaration() { return this; }
879    void accept(Visitor *v) { v->visit(this); }
880};
881
882
883class DeleteDeclaration : public FuncDeclaration
884{
885public:
886    Parameters *parameters;
887
888    DeleteDeclaration(Loc loc, Loc endloc, StorageClass stc, Parameters *arguments);
889    Dsymbol *syntaxCopy(Dsymbol *);
890    void semantic(Scope *sc);
891    const char *kind() const;
892    bool isDelete();
893    bool isVirtual();
894    bool addPreInvariant();
895    bool addPostInvariant();
896
897    DeleteDeclaration *isDeleteDeclaration() { return this; }
898    void accept(Visitor *v) { v->visit(this); }
899};
900