xref: /netbsd/external/gpl3/gcc/dist/gcc/d/dmd/declaration.h (revision f0fbc68b)
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 
isStatic()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;
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(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 
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 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
isVarDeclaration()291     VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; }
accept(Visitor * v)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*);
isBitFieldDeclaration()306     BitFieldDeclaration *isBitFieldDeclaration() { return this; }
accept(Visitor * v)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
isSymbolDeclaration()320     SymbolDeclaration *isSymbolDeclaration() { return (SymbolDeclaration *)this; }
accept(Visitor * v)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 
isTypeInfoDeclaration()333     TypeInfoDeclaration *isTypeInfoDeclaration() { return this; }
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)462     void accept(Visitor *v) { v->visit(this); }
463 };
464 
465 /**************************************************************/
466 
467 class ThisDeclaration : public VarDeclaration
468 {
469 public:
470     ThisDeclaration *syntaxCopy(Dsymbol *);
isThisDeclaration()471     ThisDeclaration *isThisDeclaration() { return this; }
accept(Visitor * v)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 
isFuncDeclaration()692     FuncDeclaration *isFuncDeclaration() { return this; }
693 
toAliasFunc()694     virtual FuncDeclaration *toAliasFunc() { return this; }
accept(Visitor * v)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 
isFuncAliasDeclaration()704     FuncAliasDeclaration *isFuncAliasDeclaration() { return this; }
705     const char *kind() const;
706 
707     FuncDeclaration *toAliasFunc();
accept(Visitor * v)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 
isFuncLiteralDeclaration()729     FuncLiteralDeclaration *isFuncLiteralDeclaration() { return this; }
730     const char *kind() const;
731     const char *toPrettyChars(bool QualifyTypes = false);
accept(Visitor * v)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 
isCtorDeclaration()746     CtorDeclaration *isCtorDeclaration() { return this; }
accept(Visitor * v)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 
isPostBlitDeclaration()759     PostBlitDeclaration *isPostBlitDeclaration() { return this; }
accept(Visitor * v)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 
isDtorDeclaration()774     DtorDeclaration *isDtorDeclaration() { return this; }
accept(Visitor * v)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 
isStaticCtorDeclaration()788     StaticCtorDeclaration *isStaticCtorDeclaration() { return this; }
accept(Visitor * v)789     void accept(Visitor *v) { v->visit(this); }
790 };
791 
792 class SharedStaticCtorDeclaration : public StaticCtorDeclaration
793 {
794 public:
795     SharedStaticCtorDeclaration *syntaxCopy(Dsymbol *);
796 
isSharedStaticCtorDeclaration()797     SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return this; }
accept(Visitor * v)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 
isStaticDtorDeclaration()813     StaticDtorDeclaration *isStaticDtorDeclaration() { return this; }
accept(Visitor * v)814     void accept(Visitor *v) { v->visit(this); }
815 };
816 
817 class SharedStaticDtorDeclaration : public StaticDtorDeclaration
818 {
819 public:
820     SharedStaticDtorDeclaration *syntaxCopy(Dsymbol *);
821 
isSharedStaticDtorDeclaration()822     SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return this; }
accept(Visitor * v)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 
isInvariantDeclaration()834     InvariantDeclaration *isInvariantDeclaration() { return this; }
accept(Visitor * v)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 
isUnitTestDeclaration()852     UnitTestDeclaration *isUnitTestDeclaration() { return this; }
accept(Visitor * v)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 
isNewDeclaration()865     NewDeclaration *isNewDeclaration() { return this; }
accept(Visitor * v)866     void accept(Visitor *v) { v->visit(this); }
867 };
868