1 
2 /* Compiler implementation of the D programming language
3  * Copyright (C) 1999-2021 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 #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     #define STCctorinit           0x10000ULL    /// can only be set inside constructor
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     #define STCinit               0x4000000ULL    /// has explicit initializer
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     #define STCtls                0x80000000ULL    /// thread local
75 
76     #define STCalias              0x100000000ULL    /// `alias` parameter
77     #define STCshared             0x200000000ULL    /// accessible from multiple threads
78     #define STCgshared            0x400000000ULL    /// accessible from multiple threads, but not typed as `shared`
79     #define STCwild               0x800000000ULL    /// for wild type constructor
80 
81     #define STCproperty           0x1000000000ULL    /// `@property`
82     #define STCsafe               0x2000000000ULL    /// `@safe`
83     #define STCtrusted            0x4000000000ULL    /// `@trusted`
84     #define STCsystem             0x8000000000ULL    /// `@system`
85 
86     #define STCctfe               0x10000000000ULL    /// can be used in CTFE, even if it is static
87     #define STCdisable            0x20000000000ULL    /// for functions that are not callable
88     #define STCresult             0x40000000000ULL    /// for result variables passed to out contracts
89     #define STCnodefaultctor      0x80000000000ULL    /// must be set inside constructor
90 
91     #define STCtemp               0x100000000000ULL    /// temporary variable
92     #define STCrvalue             0x200000000000ULL    /// force rvalue for variables
93     #define STCnogc               0x400000000000ULL    /// `@nogc`
94     #define STCautoref            0x800000000000ULL    /// Mark for the already deduced `auto ref` parameter
95 
96     #define STCinference          0x1000000000000ULL    /// do attribute inference
97     #define STCexptemp            0x2000000000000ULL    /// temporary variable that has lifetime restricted to an expression
98     #define STCfuture             0x4000000000000ULL    /// introducing new base class function
99     #define STClocal              0x8000000000000ULL    /// do not forward (see dmd.dsymbol.ForwardingScopeDsymbol).
100 
101     #define STClive               0x10000000000000ULL    /// function `@live` attribute
102     #define STCregister           0x20000000000000ULL    /// `register` storage class (ImportC)
103     #define STCvolatile           0x40000000000000ULL    /// destined for volatile in the back end
104 
105 #define STC_TYPECTOR    (STCconst | STCimmutable | STCshared | STCwild)
106 #define STC_FUNCATTR    (STCref | STCnothrow | STCnogc | STCpure | STCproperty | STCsafe | STCtrusted | STCsystem)
107 
108 void ObjectNotFound(Identifier *id);
109 
110 /**************************************************************/
111 
112 class Declaration : public Dsymbol
113 {
114 public:
115     Type *type;
116     Type *originalType;         // before semantic analysis
117     StorageClass storage_class;
118     Visibility visibility;
119     LINK linkage;
120     short inuse;                // used to detect cycles
121     uint8_t adFlags;
122     DString mangleOverride;     // overridden symbol with pragma(mangle, "...")
123 
124     const char *kind() const;
125     d_uns64 size(const Loc &loc);
126 
127     Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
128 
isStatic()129     bool isStatic() const { return (storage_class & STCstatic) != 0; }
130     virtual bool isDelete();
131     virtual bool isDataseg();
132     virtual bool isThreadlocal();
133     virtual bool isCodeseg() const;
isCtorinit()134     bool isCtorinit() const     { return (storage_class & STCctorinit) != 0; }
isFinal()135     bool isFinal() const        { return (storage_class & STCfinal) != 0; }
isAbstract()136     virtual bool isAbstract()   { return (storage_class & STCabstract) != 0; }
isConst()137     bool isConst() const        { return (storage_class & STCconst) != 0; }
isImmutable()138     bool isImmutable() const    { return (storage_class & STCimmutable) != 0; }
isWild()139     bool isWild() const         { return (storage_class & STCwild) != 0; }
isAuto()140     bool isAuto() const         { return (storage_class & STCauto) != 0; }
isScope()141     bool isScope() const        { return (storage_class & STCscope) != 0; }
isSynchronized()142     bool isSynchronized() const { return (storage_class & STCsynchronized) != 0; }
isParameter()143     bool isParameter() const    { return (storage_class & STCparameter) != 0; }
isDeprecated()144     bool isDeprecated() const   { return (storage_class & STCdeprecated) != 0; }
isOverride()145     bool isOverride() const     { return (storage_class & STCoverride) != 0; }
isResult()146     bool isResult() const       { return (storage_class & STCresult) != 0; }
isField()147     bool isField() const        { return (storage_class & STCfield) != 0; }
148 
isIn()149     bool isIn()  const  { return (storage_class & STCin) != 0; }
isOut()150     bool isOut() const  { return (storage_class & STCout) != 0; }
isRef()151     bool isRef() const  { return (storage_class & STCref) != 0; }
isReference()152     bool isReference() const { return (storage_class & (STCref | STCout)) != 0; }
153 
isFuture()154     bool isFuture() const { return (storage_class & STCfuture) != 0; }
155 
156     Visibility visible();
157 
isDeclaration()158     Declaration *isDeclaration() { return this; }
accept(Visitor * v)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 
isTupleDeclaration()178     TupleDeclaration *isTupleDeclaration() { return this; }
accept(Visitor * v)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(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 
isAliasDeclaration()200     AliasDeclaration *isAliasDeclaration() { return this; }
accept(Visitor * v)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 
isOverDeclaration()220     OverDeclaration *isOverDeclaration() { return this; }
accept(Visitor * v)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 
246     bool isargptr;              // if parameter that _argptr points to
247     bool ctorinit;              // it has been initialized in a ctor
248     bool iscatchvar;            // this is the exception object variable in catch() clause
249     bool isowner;               // this is an Owner, despite it being `scope`
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     char 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     bool doNotInferReturn;      // do not infer 'return' for this variable
257     unsigned char isdataseg;    // private data for isDataseg
258     bool isArgDtorVar;          // temporary created to handle scope destruction of a function argument
259 
260 public:
261     static VarDeclaration *create(const Loc &loc, Type *t, Identifier *id, Initializer *init, StorageClass storage_class = STCundefined);
262     VarDeclaration *syntaxCopy(Dsymbol *);
263     void setFieldOffset(AggregateDeclaration *ad, FieldState& fieldState, bool isunion);
264     const char *kind() const;
265     AggregateDeclaration *isThis();
266     bool needThis();
267     bool isExport() const;
268     bool isImportedSymbol() const;
269     bool isDataseg();
270     bool isThreadlocal();
271     bool isCTFE();
272     bool isOverlappedWith(VarDeclaration *v);
273     bool hasPointers();
274     bool canTakeAddressOf();
275     bool needsScopeDtor();
276     bool enclosesLifetimeOf(VarDeclaration *v) const;
277     void checkCtorConstInit();
278     Dsymbol *toAlias();
279     // Eliminate need for dynamic_cast
isVarDeclaration()280     VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; }
accept(Visitor * v)281     void accept(Visitor *v) { v->visit(this); }
282 };
283 
284 /**************************************************************/
285 
286 class BitFieldDeclaration : public VarDeclaration
287 {
288 public:
289     Expression *width;
290 
291     unsigned fieldWidth;
292     unsigned bitOffset;
293 
294     BitFieldDeclaration *syntaxCopy(Dsymbol*);
isBitFieldDeclaration()295     BitFieldDeclaration *isBitFieldDeclaration() { return this; }
accept(Visitor * v)296     void accept(Visitor *v) { v->visit(this); }
297 };
298 
299 /**************************************************************/
300 
301 // This is a shell around a back end symbol
302 
303 class SymbolDeclaration : public Declaration
304 {
305 public:
306     StructDeclaration *dsym;
307 
308     // Eliminate need for dynamic_cast
isSymbolDeclaration()309     SymbolDeclaration *isSymbolDeclaration() { return (SymbolDeclaration *)this; }
accept(Visitor * v)310     void accept(Visitor *v) { v->visit(this); }
311 };
312 
313 class TypeInfoDeclaration : public VarDeclaration
314 {
315 public:
316     Type *tinfo;
317 
318     static TypeInfoDeclaration *create(Type *tinfo);
319     TypeInfoDeclaration *syntaxCopy(Dsymbol *);
320     const char *toChars() const;
321 
isTypeInfoDeclaration()322     TypeInfoDeclaration *isTypeInfoDeclaration() { return this; }
accept(Visitor * v)323     void accept(Visitor *v) { v->visit(this); }
324 };
325 
326 class TypeInfoStructDeclaration : public TypeInfoDeclaration
327 {
328 public:
329     static TypeInfoStructDeclaration *create(Type *tinfo);
330 
accept(Visitor * v)331     void accept(Visitor *v) { v->visit(this); }
332 };
333 
334 class TypeInfoClassDeclaration : public TypeInfoDeclaration
335 {
336 public:
337     static TypeInfoClassDeclaration *create(Type *tinfo);
338 
accept(Visitor * v)339     void accept(Visitor *v) { v->visit(this); }
340 };
341 
342 class TypeInfoInterfaceDeclaration : public TypeInfoDeclaration
343 {
344 public:
345     static TypeInfoInterfaceDeclaration *create(Type *tinfo);
346 
accept(Visitor * v)347     void accept(Visitor *v) { v->visit(this); }
348 };
349 
350 class TypeInfoPointerDeclaration : public TypeInfoDeclaration
351 {
352 public:
353     static TypeInfoPointerDeclaration *create(Type *tinfo);
354 
accept(Visitor * v)355     void accept(Visitor *v) { v->visit(this); }
356 };
357 
358 class TypeInfoArrayDeclaration : public TypeInfoDeclaration
359 {
360 public:
361     static TypeInfoArrayDeclaration *create(Type *tinfo);
362 
accept(Visitor * v)363     void accept(Visitor *v) { v->visit(this); }
364 };
365 
366 class TypeInfoStaticArrayDeclaration : public TypeInfoDeclaration
367 {
368 public:
369     static TypeInfoStaticArrayDeclaration *create(Type *tinfo);
370 
accept(Visitor * v)371     void accept(Visitor *v) { v->visit(this); }
372 };
373 
374 class TypeInfoAssociativeArrayDeclaration : public TypeInfoDeclaration
375 {
376 public:
377     static TypeInfoAssociativeArrayDeclaration *create(Type *tinfo);
378 
accept(Visitor * v)379     void accept(Visitor *v) { v->visit(this); }
380 };
381 
382 class TypeInfoEnumDeclaration : public TypeInfoDeclaration
383 {
384 public:
385     static TypeInfoEnumDeclaration *create(Type *tinfo);
386 
accept(Visitor * v)387     void accept(Visitor *v) { v->visit(this); }
388 };
389 
390 class TypeInfoFunctionDeclaration : public TypeInfoDeclaration
391 {
392 public:
393     static TypeInfoFunctionDeclaration *create(Type *tinfo);
394 
accept(Visitor * v)395     void accept(Visitor *v) { v->visit(this); }
396 };
397 
398 class TypeInfoDelegateDeclaration : public TypeInfoDeclaration
399 {
400 public:
401     static TypeInfoDelegateDeclaration *create(Type *tinfo);
402 
accept(Visitor * v)403     void accept(Visitor *v) { v->visit(this); }
404 };
405 
406 class TypeInfoTupleDeclaration : public TypeInfoDeclaration
407 {
408 public:
409     static TypeInfoTupleDeclaration *create(Type *tinfo);
410 
accept(Visitor * v)411     void accept(Visitor *v) { v->visit(this); }
412 };
413 
414 class TypeInfoConstDeclaration : public TypeInfoDeclaration
415 {
416 public:
417     static TypeInfoConstDeclaration *create(Type *tinfo);
418 
accept(Visitor * v)419     void accept(Visitor *v) { v->visit(this); }
420 };
421 
422 class TypeInfoInvariantDeclaration : public TypeInfoDeclaration
423 {
424 public:
425     static TypeInfoInvariantDeclaration *create(Type *tinfo);
426 
accept(Visitor * v)427     void accept(Visitor *v) { v->visit(this); }
428 };
429 
430 class TypeInfoSharedDeclaration : public TypeInfoDeclaration
431 {
432 public:
433     static TypeInfoSharedDeclaration *create(Type *tinfo);
434 
accept(Visitor * v)435     void accept(Visitor *v) { v->visit(this); }
436 };
437 
438 class TypeInfoWildDeclaration : public TypeInfoDeclaration
439 {
440 public:
441     static TypeInfoWildDeclaration *create(Type *tinfo);
442 
accept(Visitor * v)443     void accept(Visitor *v) { v->visit(this); }
444 };
445 
446 class TypeInfoVectorDeclaration : public TypeInfoDeclaration
447 {
448 public:
449     static TypeInfoVectorDeclaration *create(Type *tinfo);
450 
accept(Visitor * v)451     void accept(Visitor *v) { v->visit(this); }
452 };
453 
454 /**************************************************************/
455 
456 class ThisDeclaration : public VarDeclaration
457 {
458 public:
459     ThisDeclaration *syntaxCopy(Dsymbol *);
isThisDeclaration()460     ThisDeclaration *isThisDeclaration() { return this; }
accept(Visitor * v)461     void accept(Visitor *v) { v->visit(this); }
462 };
463 
464 enum class ILS : unsigned char
465 {
466     ILSuninitialized,   // not computed yet
467     ILSno,              // cannot inline
468     ILSyes              // can inline
469 };
470 
471 /**************************************************************/
472 
473 enum class BUILTIN : unsigned char
474 {
475     unknown = 255,   /// not known if this is a builtin
476     unimp = 0,       /// this is not a builtin
477     gcc,             /// this is a GCC builtin
478     llvm,            /// this is an LLVM builtin
479     sin,
480     cos,
481     tan,
482     sqrt,
483     fabs,
484     ldexp,
485     log,
486     log2,
487     log10,
488     exp,
489     expm1,
490     exp2,
491     round,
492     floor,
493     ceil,
494     trunc,
495     copysign,
496     pow,
497     fmin,
498     fmax,
499     fma,
500     isnan,
501     isinfinity,
502     isfinite,
503     bsf,
504     bsr,
505     bswap,
506     popcnt,
507     yl2x,
508     yl2xp1,
509     toPrecFloat,
510     toPrecDouble,
511     toPrecReal
512 };
513 
514 Expression *eval_builtin(Loc loc, FuncDeclaration *fd, Expressions *arguments);
515 BUILTIN isBuiltin(FuncDeclaration *fd);
516 
517 class FuncDeclaration : public Declaration
518 {
519 public:
520     Statements *frequires;              // in contracts
521     Ensures *fensures;                  // out contracts
522     Statement *frequire;                // lowered in contract
523     Statement *fensure;                 // lowered out contract
524     Statement *fbody;
525 
526     FuncDeclarations foverrides;        // functions this function overrides
527     FuncDeclaration *fdrequire;         // function that does the in contract
528     FuncDeclaration *fdensure;          // function that does the out contract
529 
530     Expressions *fdrequireParams;       // argument list for __require
531     Expressions *fdensureParams;        // argument list for __ensure
532 
533     const char *mangleString;           // mangled symbol created from mangleExact()
534 
535     VarDeclaration *vresult;            // result variable for out contracts
536     LabelDsymbol *returnLabel;          // where the return goes
537 
538     // used to prevent symbols in different
539     // scopes from having the same name
540     DsymbolTable *localsymtab;
541     VarDeclaration *vthis;              // 'this' parameter (member and nested)
542     bool isThis2;                       // has a dual-context 'this' parameter
543     VarDeclaration *v_arguments;        // '_arguments' parameter
544 
545     VarDeclaration *v_argptr;           // '_argptr' variable
546     VarDeclarations *parameters;        // Array of VarDeclaration's for parameters
547     DsymbolTable *labtab;               // statement label symbol table
548     Dsymbol *overnext;                  // next in overload list
549     FuncDeclaration *overnext0;         // next in overload list (only used during IFTI)
550     Loc endloc;                         // location of closing curly bracket
551     int vtblIndex;                      // for member functions, index into vtbl[]
552     bool naked;                         // true if naked
553     bool generated;                     // true if function was generated by the compiler rather than
554                                         // supplied by the user
555     bool hasAlwaysInlines;              // contains references to functions that must be inlined
556     unsigned char isCrtCtorDtor;        // has attribute pragma(crt_constructor(1)/crt_destructor(2))
557                                         // not set before the glue layer
558     ILS inlineStatusStmt;
559     ILS inlineStatusExp;
560     PINLINE inlining;
561 
562     int inlineNest;                     // !=0 if nested inline
563     bool eh_none;                       /// true if no exception unwinding is needed
564 
565     // true if errors in semantic3 this function's frame ptr
566     bool semantic3Errors;
567     ForeachStatement *fes;              // if foreach body, this is the foreach
568     BaseClass* interfaceVirtual;        // if virtual, but only appears in interface vtbl[]
569     bool introducing;                   // true if 'introducing' function
570     // if !=NULL, then this is the type
571     // of the 'introducing' function
572     // this one is overriding
573     Type *tintro;
574     bool inferRetType;                  // true if return type is to be inferred
575     StorageClass storage_class2;        // storage class for template onemember's
576 
577     // Things that should really go into Scope
578 
579     // 1 if there's a return exp; statement
580     // 2 if there's a throw statement
581     // 4 if there's an assert(0)
582     // 8 if there's inline asm
583     // 16 if there are multiple return statements
584     int hasReturnExp;
585 
586     // Support for NRVO (named return value optimization)
587     bool nrvo_can;                      // true means we can do it
588     VarDeclaration *nrvo_var;           // variable to replace with shidden
589     Symbol *shidden;                    // hidden pointer passed to function
590 
591     ReturnStatements *returns;
592 
593     GotoStatements *gotos;              // Gotos with forward references
594 
595     // set if this is a known, builtin function we can evaluate at compile time
596     BUILTIN builtin;
597 
598     // set if someone took the address of this function
599     int tookAddressOf;
600     bool requiresClosure;               // this function needs a closure
601 
602     // local variables in this function which are referenced by nested functions
603     VarDeclarations closureVars;
604 
605     /** Outer variables which are referenced by this nested function
606      * (the inverse of closureVars)
607      */
608     VarDeclarations outerVars;
609 
610     // Sibling nested functions which called this one
611     FuncDeclarations siblingCallers;
612 
613     FuncDeclarations *inlinedNestedCallees;
614 
615     unsigned flags;                     // FUNCFLAGxxxxx
616 
617     // Data for a function declaration that is needed for the Objective-C
618     // integration.
619     ObjcFuncDeclaration objc;
620 
621     static FuncDeclaration *create(const Loc &loc, const Loc &endloc, Identifier *id, StorageClass storage_class, Type *type, bool noreturn = false);
622     FuncDeclaration *syntaxCopy(Dsymbol *);
623     bool functionSemantic();
624     bool functionSemantic3();
625     bool equals(const RootObject *o) const;
626 
627     int overrides(FuncDeclaration *fd);
628     int findVtblIndex(Dsymbols *vtbl, int dim);
629     BaseClass *overrideInterface();
630     bool overloadInsert(Dsymbol *s);
631     bool inUnittest();
632     MATCH leastAsSpecialized(FuncDeclaration *g);
633     LabelDsymbol *searchLabel(Identifier *ident, const Loc &loc);
634     int getLevel(FuncDeclaration *fd, int intypeof); // lexical nesting level difference
635     int getLevelAndCheck(const Loc &loc, Scope *sc, FuncDeclaration *fd);
636     const char *toPrettyChars(bool QualifyTypes = false);
637     const char *toFullSignature();  // for diagnostics, e.g. 'int foo(int x, int y) pure'
638     bool isMain() const;
639     bool isCMain() const;
640     bool isWinMain() const;
641     bool isDllMain() const;
642     bool isExport() const;
643     bool isImportedSymbol() const;
644     bool isCodeseg() const;
645     bool isOverloadable() const;
646     bool isAbstract();
647     PURE isPure();
648     PURE isPureBypassingInference();
649     bool isSafe();
650     bool isSafeBypassingInference();
651     bool isTrusted();
652 
653     bool isNogc();
654     bool isNogcBypassingInference();
655 
656     virtual bool isNested() const;
657     AggregateDeclaration *isThis();
658     bool needThis();
659     bool isVirtualMethod();
660     virtual bool isVirtual() const;
661     bool isFinalFunc() const;
662     virtual bool addPreInvariant();
663     virtual bool addPostInvariant();
664     const char *kind() const;
665     bool isUnique();
666     bool needsClosure();
667     bool hasNestedFrameRefs();
668     ParameterList getParameterList();
669 
670     static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, const char *name, StorageClass stc=0);
671     static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, Identifier *id, StorageClass stc=0);
672 
673     bool checkNRVO();
674 
isFuncDeclaration()675     FuncDeclaration *isFuncDeclaration() { return this; }
676 
toAliasFunc()677     virtual FuncDeclaration *toAliasFunc() { return this; }
accept(Visitor * v)678     void accept(Visitor *v) { v->visit(this); }
679 };
680 
681 class FuncAliasDeclaration : public FuncDeclaration
682 {
683 public:
684     FuncDeclaration *funcalias;
685     bool hasOverloads;
686 
isFuncAliasDeclaration()687     FuncAliasDeclaration *isFuncAliasDeclaration() { return this; }
688     const char *kind() const;
689 
690     FuncDeclaration *toAliasFunc();
accept(Visitor * v)691     void accept(Visitor *v) { v->visit(this); }
692 };
693 
694 class FuncLiteralDeclaration : public FuncDeclaration
695 {
696 public:
697     TOK tok;                       // TOKfunction or TOKdelegate
698     Type *treq;                         // target of return type inference
699 
700     // backend
701     bool deferToObj;
702 
703     FuncLiteralDeclaration *syntaxCopy(Dsymbol *);
704     bool isNested() const;
705     AggregateDeclaration *isThis();
706     bool isVirtual() const;
707     bool addPreInvariant();
708     bool addPostInvariant();
709 
710     void modifyReturns(Scope *sc, Type *tret);
711 
isFuncLiteralDeclaration()712     FuncLiteralDeclaration *isFuncLiteralDeclaration() { return this; }
713     const char *kind() const;
714     const char *toPrettyChars(bool QualifyTypes = false);
accept(Visitor * v)715     void accept(Visitor *v) { v->visit(this); }
716 };
717 
718 class CtorDeclaration : public FuncDeclaration
719 {
720 public:
721     bool isCpCtor;
722     CtorDeclaration *syntaxCopy(Dsymbol *);
723     const char *kind() const;
724     const char *toChars() const;
725     bool isVirtual() const;
726     bool addPreInvariant();
727     bool addPostInvariant();
728 
isCtorDeclaration()729     CtorDeclaration *isCtorDeclaration() { return this; }
accept(Visitor * v)730     void accept(Visitor *v) { v->visit(this); }
731 };
732 
733 class PostBlitDeclaration : public FuncDeclaration
734 {
735 public:
736     PostBlitDeclaration *syntaxCopy(Dsymbol *);
737     bool isVirtual() const;
738     bool addPreInvariant();
739     bool addPostInvariant();
740     bool overloadInsert(Dsymbol *s);
741 
isPostBlitDeclaration()742     PostBlitDeclaration *isPostBlitDeclaration() { return this; }
accept(Visitor * v)743     void accept(Visitor *v) { v->visit(this); }
744 };
745 
746 class DtorDeclaration : public FuncDeclaration
747 {
748 public:
749     DtorDeclaration *syntaxCopy(Dsymbol *);
750     const char *kind() const;
751     const char *toChars() const;
752     bool isVirtual() const;
753     bool addPreInvariant();
754     bool addPostInvariant();
755     bool overloadInsert(Dsymbol *s);
756 
isDtorDeclaration()757     DtorDeclaration *isDtorDeclaration() { return this; }
accept(Visitor * v)758     void accept(Visitor *v) { v->visit(this); }
759 };
760 
761 class StaticCtorDeclaration : public FuncDeclaration
762 {
763 public:
764     StaticCtorDeclaration *syntaxCopy(Dsymbol *);
765     AggregateDeclaration *isThis();
766     bool isVirtual() const;
767     bool addPreInvariant();
768     bool addPostInvariant();
769     bool hasStaticCtorOrDtor();
770 
isStaticCtorDeclaration()771     StaticCtorDeclaration *isStaticCtorDeclaration() { return this; }
accept(Visitor * v)772     void accept(Visitor *v) { v->visit(this); }
773 };
774 
775 class SharedStaticCtorDeclaration : public StaticCtorDeclaration
776 {
777 public:
778     SharedStaticCtorDeclaration *syntaxCopy(Dsymbol *);
779 
isSharedStaticCtorDeclaration()780     SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return this; }
accept(Visitor * v)781     void accept(Visitor *v) { v->visit(this); }
782 };
783 
784 class StaticDtorDeclaration : public FuncDeclaration
785 {
786 public:
787     VarDeclaration *vgate;      // 'gate' variable
788 
789     StaticDtorDeclaration *syntaxCopy(Dsymbol *);
790     AggregateDeclaration *isThis();
791     bool isVirtual() const;
792     bool hasStaticCtorOrDtor();
793     bool addPreInvariant();
794     bool addPostInvariant();
795 
isStaticDtorDeclaration()796     StaticDtorDeclaration *isStaticDtorDeclaration() { return this; }
accept(Visitor * v)797     void accept(Visitor *v) { v->visit(this); }
798 };
799 
800 class SharedStaticDtorDeclaration : public StaticDtorDeclaration
801 {
802 public:
803     SharedStaticDtorDeclaration *syntaxCopy(Dsymbol *);
804 
isSharedStaticDtorDeclaration()805     SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return this; }
accept(Visitor * v)806     void accept(Visitor *v) { v->visit(this); }
807 };
808 
809 class InvariantDeclaration : public FuncDeclaration
810 {
811 public:
812     InvariantDeclaration *syntaxCopy(Dsymbol *);
813     bool isVirtual() const;
814     bool addPreInvariant();
815     bool addPostInvariant();
816 
isInvariantDeclaration()817     InvariantDeclaration *isInvariantDeclaration() { return this; }
accept(Visitor * v)818     void accept(Visitor *v) { v->visit(this); }
819 };
820 
821 class UnitTestDeclaration : public FuncDeclaration
822 {
823 public:
824     char *codedoc; /** For documented unittest. */
825 
826     // toObjFile() these nested functions after this one
827     FuncDeclarations deferredNested;
828 
829     UnitTestDeclaration *syntaxCopy(Dsymbol *);
830     AggregateDeclaration *isThis();
831     bool isVirtual() const;
832     bool addPreInvariant();
833     bool addPostInvariant();
834 
isUnitTestDeclaration()835     UnitTestDeclaration *isUnitTestDeclaration() { return this; }
accept(Visitor * v)836     void accept(Visitor *v) { v->visit(this); }
837 };
838 
839 class NewDeclaration : public FuncDeclaration
840 {
841 public:
842     Parameters *parameters;
843     VarArg varargs;
844 
845     NewDeclaration *syntaxCopy(Dsymbol *);
846     const char *kind() const;
847     bool isVirtual() const;
848     bool addPreInvariant();
849     bool addPostInvariant();
850 
isNewDeclaration()851     NewDeclaration *isNewDeclaration() { return this; }
accept(Visitor * v)852     void accept(Visitor *v) { v->visit(this); }
853 };
854