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