Home | History | Annotate | Line # | Download | only in dmd
      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 
     18 class Expression;
     19 class Statement;
     20 class LabelDsymbol;
     21 class Initializer;
     22 class ForeachStatement;
     23 struct Ensure
     24 {
     25     Identifier *id;
     26     Statement *ensure;
     27 };
     28 class FuncDeclaration;
     29 class StructDeclaration;
     30 struct 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 
    107 void ObjectNotFound(Identifier *id);
    108 
    109 /**************************************************************/
    110 
    111 class Declaration : public Dsymbol
    112 {
    113 public:
    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 
    164 class TupleDeclaration : public Declaration
    165 {
    166 public:
    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 
    184 class AliasDeclaration : public Declaration
    185 {
    186 public:
    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 
    206 class OverDeclaration : public Declaration
    207 {
    208 public:
    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 
    226 class VarDeclaration : public Declaration
    227 {
    228 public:
    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;
    245 private:
    246     uint16_t bitFields;
    247 public:
    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 
    297 class BitFieldDeclaration : public VarDeclaration
    298 {
    299 public:
    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 
    314 class SymbolDeclaration : public Declaration
    315 {
    316 public:
    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 
    324 class TypeInfoDeclaration : public VarDeclaration
    325 {
    326 public:
    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 
    337 class TypeInfoStructDeclaration : public TypeInfoDeclaration
    338 {
    339 public:
    340     static TypeInfoStructDeclaration *create(Type *tinfo);
    341 
    342     void accept(Visitor *v) { v->visit(this); }
    343 };
    344 
    345 class TypeInfoClassDeclaration : public TypeInfoDeclaration
    346 {
    347 public:
    348     static TypeInfoClassDeclaration *create(Type *tinfo);
    349 
    350     void accept(Visitor *v) { v->visit(this); }
    351 };
    352 
    353 class TypeInfoInterfaceDeclaration : public TypeInfoDeclaration
    354 {
    355 public:
    356     static TypeInfoInterfaceDeclaration *create(Type *tinfo);
    357 
    358     void accept(Visitor *v) { v->visit(this); }
    359 };
    360 
    361 class TypeInfoPointerDeclaration : public TypeInfoDeclaration
    362 {
    363 public:
    364     static TypeInfoPointerDeclaration *create(Type *tinfo);
    365 
    366     void accept(Visitor *v) { v->visit(this); }
    367 };
    368 
    369 class TypeInfoArrayDeclaration : public TypeInfoDeclaration
    370 {
    371 public:
    372     static TypeInfoArrayDeclaration *create(Type *tinfo);
    373 
    374     void accept(Visitor *v) { v->visit(this); }
    375 };
    376 
    377 class TypeInfoStaticArrayDeclaration : public TypeInfoDeclaration
    378 {
    379 public:
    380     static TypeInfoStaticArrayDeclaration *create(Type *tinfo);
    381 
    382     void accept(Visitor *v) { v->visit(this); }
    383 };
    384 
    385 class TypeInfoAssociativeArrayDeclaration : public TypeInfoDeclaration
    386 {
    387 public:
    388     static TypeInfoAssociativeArrayDeclaration *create(Type *tinfo);
    389 
    390     void accept(Visitor *v) { v->visit(this); }
    391 };
    392 
    393 class TypeInfoEnumDeclaration : public TypeInfoDeclaration
    394 {
    395 public:
    396     static TypeInfoEnumDeclaration *create(Type *tinfo);
    397 
    398     void accept(Visitor *v) { v->visit(this); }
    399 };
    400 
    401 class TypeInfoFunctionDeclaration : public TypeInfoDeclaration
    402 {
    403 public:
    404     static TypeInfoFunctionDeclaration *create(Type *tinfo);
    405 
    406     void accept(Visitor *v) { v->visit(this); }
    407 };
    408 
    409 class TypeInfoDelegateDeclaration : public TypeInfoDeclaration
    410 {
    411 public:
    412     static TypeInfoDelegateDeclaration *create(Type *tinfo);
    413 
    414     void accept(Visitor *v) { v->visit(this); }
    415 };
    416 
    417 class TypeInfoTupleDeclaration : public TypeInfoDeclaration
    418 {
    419 public:
    420     static TypeInfoTupleDeclaration *create(Type *tinfo);
    421 
    422     void accept(Visitor *v) { v->visit(this); }
    423 };
    424 
    425 class TypeInfoConstDeclaration : public TypeInfoDeclaration
    426 {
    427 public:
    428     static TypeInfoConstDeclaration *create(Type *tinfo);
    429 
    430     void accept(Visitor *v) { v->visit(this); }
    431 };
    432 
    433 class TypeInfoInvariantDeclaration : public TypeInfoDeclaration
    434 {
    435 public:
    436     static TypeInfoInvariantDeclaration *create(Type *tinfo);
    437 
    438     void accept(Visitor *v) { v->visit(this); }
    439 };
    440 
    441 class TypeInfoSharedDeclaration : public TypeInfoDeclaration
    442 {
    443 public:
    444     static TypeInfoSharedDeclaration *create(Type *tinfo);
    445 
    446     void accept(Visitor *v) { v->visit(this); }
    447 };
    448 
    449 class TypeInfoWildDeclaration : public TypeInfoDeclaration
    450 {
    451 public:
    452     static TypeInfoWildDeclaration *create(Type *tinfo);
    453 
    454     void accept(Visitor *v) { v->visit(this); }
    455 };
    456 
    457 class TypeInfoVectorDeclaration : public TypeInfoDeclaration
    458 {
    459 public:
    460     static TypeInfoVectorDeclaration *create(Type *tinfo);
    461 
    462     void accept(Visitor *v) { v->visit(this); }
    463 };
    464 
    465 /**************************************************************/
    466 
    467 class ThisDeclaration : public VarDeclaration
    468 {
    469 public:
    470     ThisDeclaration *syntaxCopy(Dsymbol *);
    471     ThisDeclaration *isThisDeclaration() { return this; }
    472     void accept(Visitor *v) { v->visit(this); }
    473 };
    474 
    475 enum class ILS : unsigned char
    476 {
    477     ILSuninitialized,   // not computed yet
    478     ILSno,              // cannot inline
    479     ILSyes              // can inline
    480 };
    481 
    482 /**************************************************************/
    483 
    484 enum 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 
    525 Expression *eval_builtin(const Loc &loc, FuncDeclaration *fd, Expressions *arguments);
    526 BUILTIN isBuiltin(FuncDeclaration *fd);
    527 
    528 class FuncDeclaration : public Declaration
    529 {
    530 public:
    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 
    698 class FuncAliasDeclaration : public FuncDeclaration
    699 {
    700 public:
    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 
    711 class FuncLiteralDeclaration : public FuncDeclaration
    712 {
    713 public:
    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 
    735 class CtorDeclaration : public FuncDeclaration
    736 {
    737 public:
    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 
    750 class PostBlitDeclaration : public FuncDeclaration
    751 {
    752 public:
    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 
    763 class DtorDeclaration : public FuncDeclaration
    764 {
    765 public:
    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 
    778 class StaticCtorDeclaration : public FuncDeclaration
    779 {
    780 public:
    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 
    792 class SharedStaticCtorDeclaration : public StaticCtorDeclaration
    793 {
    794 public:
    795     SharedStaticCtorDeclaration *syntaxCopy(Dsymbol *);
    796 
    797     SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return this; }
    798     void accept(Visitor *v) { v->visit(this); }
    799 };
    800 
    801 class StaticDtorDeclaration : public FuncDeclaration
    802 {
    803 public:
    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 
    817 class SharedStaticDtorDeclaration : public StaticDtorDeclaration
    818 {
    819 public:
    820     SharedStaticDtorDeclaration *syntaxCopy(Dsymbol *);
    821 
    822     SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return this; }
    823     void accept(Visitor *v) { v->visit(this); }
    824 };
    825 
    826 class InvariantDeclaration : public FuncDeclaration
    827 {
    828 public:
    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 
    838 class UnitTestDeclaration : public FuncDeclaration
    839 {
    840 public:
    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 
    856 class NewDeclaration : public FuncDeclaration
    857 {
    858 public:
    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