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 17 class Expression; 18 class Statement; 19 class LabelDsymbol; 20 class Initializer; 21 class Module; 22 class ForeachStatement; 23 struct Ensure 24 { 25 Identifier *id; 26 Statement *ensure; 27 28 Ensure(); 29 Ensure(Identifier *id, Statement *ensure); 30 Ensure syntaxCopy(); 31 static Ensures *arraySyntaxCopy(Ensures *a); 32 }; 33 class AliasDeclaration; 34 class FuncDeclaration; 35 class ExpInitializer; 36 class StructDeclaration; 37 struct InterState; 38 struct CompiledCtfeFunction; 39 struct ObjcSelector; 40 struct IntRange; 41 42 enum LINK; 43 enum TOK; 44 enum MATCH; 45 enum PURE; 46 enum PINLINE; 47 48 #define STCundefined 0LL 49 #define STCstatic 1LL 50 #define STCextern 2LL 51 #define STCconst 4LL 52 #define STCfinal 8LL 53 #define STCabstract 0x10LL 54 #define STCparameter 0x20LL 55 #define STCfield 0x40LL 56 #define STCoverride 0x80LL 57 #define STCauto 0x100LL 58 #define STCsynchronized 0x200LL 59 #define STCdeprecated 0x400LL 60 #define STCin 0x800LL // in parameter 61 #define STCout 0x1000LL // out parameter 62 #define STClazy 0x2000LL // lazy parameter 63 #define STCforeach 0x4000LL // variable for foreach loop 64 #define STCvariadic 0x10000LL // the 'variadic' parameter in: T foo(T a, U b, V variadic...) 65 #define STCctorinit 0x20000LL // can only be set inside constructor 66 #define STCtemplateparameter 0x40000LL // template parameter 67 #define STCscope 0x80000LL 68 #define STCimmutable 0x100000LL 69 #define STCref 0x200000LL 70 #define STCinit 0x400000LL // has explicit initializer 71 #define STCmanifest 0x800000LL // manifest constant 72 #define STCnodtor 0x1000000LL // don't run destructor 73 #define STCnothrow 0x2000000LL // never throws exceptions 74 #define STCpure 0x4000000LL // pure function 75 #define STCtls 0x8000000LL // thread local 76 #define STCalias 0x10000000LL // alias parameter 77 #define STCshared 0x20000000LL // accessible from multiple threads 78 // accessible from multiple threads 79 // but not typed as "shared" 80 #define STCgshared 0x40000000LL 81 #define STCwild 0x80000000LL // for "wild" type constructor 82 #define STC_TYPECTOR (STCconst | STCimmutable | STCshared | STCwild) 83 #define STC_FUNCATTR (STCref | STCnothrow | STCnogc | STCpure | STCproperty | STCsafe | STCtrusted | STCsystem) 84 85 #define STCproperty 0x100000000LL 86 #define STCsafe 0x200000000LL 87 #define STCtrusted 0x400000000LL 88 #define STCsystem 0x800000000LL 89 #define STCctfe 0x1000000000LL // can be used in CTFE, even if it is static 90 #define STCdisable 0x2000000000LL // for functions that are not callable 91 #define STCresult 0x4000000000LL // for result variables passed to out contracts 92 #define STCnodefaultctor 0x8000000000LL // must be set inside constructor 93 #define STCtemp 0x10000000000LL // temporary variable 94 #define STCrvalue 0x20000000000LL // force rvalue for variables 95 #define STCnogc 0x40000000000LL // @nogc 96 #define STCvolatile 0x80000000000LL // destined for volatile in the back end 97 #define STCreturn 0x100000000000LL // 'return ref' or 'return scope' for function parameters 98 #define STCautoref 0x200000000000LL // Mark for the already deduced 'auto ref' parameter 99 #define STCinference 0x400000000000LL // do attribute inference 100 #define STCexptemp 0x800000000000LL // temporary variable that has lifetime restricted to an expression 101 #define STCmaybescope 0x1000000000000LL // parameter might be 'scope' 102 #define STCscopeinferred 0x2000000000000LL // 'scope' has been inferred and should not be part of mangling 103 #define STCfuture 0x4000000000000LL // introducing new base class function 104 #define STClocal 0x8000000000000LL // do not forward (see ddmd.dsymbol.ForwardingScopeDsymbol). 105 106 const StorageClass STCStorageClass = (STCauto | STCscope | STCstatic | STCextern | STCconst | STCfinal | 107 STCabstract | STCsynchronized | STCdeprecated | STCfuture | STCoverride | STClazy | STCalias | 108 STCout | STCin | 109 STCmanifest | STCimmutable | STCshared | STCwild | STCnothrow | STCnogc | STCpure | STCref | STCtls | 110 STCgshared | STCproperty | STCsafe | STCtrusted | STCsystem | STCdisable | STClocal); 111 112 struct Match 113 { 114 int count; // number of matches found 115 MATCH last; // match level of lastf 116 FuncDeclaration *lastf; // last matching function we found 117 FuncDeclaration *nextf; // current matching function 118 FuncDeclaration *anyf; // pick a func, any func, to use for error recovery 119 }; 120 121 void functionResolve(Match *m, Dsymbol *fd, Loc loc, Scope *sc, Objects *tiargs, Type *tthis, Expressions *fargs, const char **pMessage = NULL); 122 int overloadApply(Dsymbol *fstart, void *param, int (*fp)(void *, Dsymbol *)); 123 void aliasSemantic(AliasDeclaration *ds, Scope *sc); 124 125 void ObjectNotFound(Identifier *id); 126 127 /**************************************************************/ 128 129 class Declaration : public Dsymbol 130 { 131 public: 132 Type *type; 133 Type *originalType; // before semantic analysis 134 StorageClass storage_class; 135 Prot protection; 136 LINK linkage; 137 int inuse; // used to detect cycles 138 DString mangleOverride; // overridden symbol with pragma(mangle, "...") 139 140 Declaration(Identifier *id); 141 const char *kind() const; 142 d_uns64 size(Loc loc); 143 bool checkDisabled(Loc loc, Scope *sc, bool isAliasedDeclaration = false); 144 int checkModify(Loc loc, Scope *sc, Type *t, Expression *e1, int flag); 145 146 Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly); 147 isStatic()148 bool isStatic() { return (storage_class & STCstatic) != 0; } 149 virtual bool isDelete(); 150 virtual bool isDataseg(); 151 virtual bool isThreadlocal(); 152 virtual bool isCodeseg() const; isCtorinit()153 bool isCtorinit() { return (storage_class & STCctorinit) != 0; } isFinal()154 bool isFinal() { return (storage_class & STCfinal) != 0; } isAbstract()155 bool isAbstract() { return (storage_class & STCabstract) != 0; } isConst()156 bool isConst() { return (storage_class & STCconst) != 0; } isImmutable()157 bool isImmutable() { return (storage_class & STCimmutable) != 0; } isWild()158 bool isWild() { return (storage_class & STCwild) != 0; } isAuto()159 bool isAuto() { return (storage_class & STCauto) != 0; } isScope()160 bool isScope() { return (storage_class & STCscope) != 0; } isSynchronized()161 bool isSynchronized() { return (storage_class & STCsynchronized) != 0; } isParameter()162 bool isParameter() { return (storage_class & STCparameter) != 0; } isDeprecated()163 bool isDeprecated() { return (storage_class & STCdeprecated) != 0; } isDisabled()164 bool isDisabled() { return (storage_class & STCdisable) != 0; } isOverride()165 bool isOverride() { return (storage_class & STCoverride) != 0; } isResult()166 bool isResult() { return (storage_class & STCresult) != 0; } isField()167 bool isField() { return (storage_class & STCfield) != 0; } 168 isIn()169 bool isIn() { return (storage_class & STCin) != 0; } isOut()170 bool isOut() { return (storage_class & STCout) != 0; } isRef()171 bool isRef() { return (storage_class & STCref) != 0; } 172 isFuture()173 bool isFuture() { return (storage_class & STCfuture) != 0; } 174 175 Prot prot(); 176 isDeclaration()177 Declaration *isDeclaration() { return this; } accept(Visitor * v)178 void accept(Visitor *v) { v->visit(this); } 179 }; 180 181 /**************************************************************/ 182 183 class TupleDeclaration : public Declaration 184 { 185 public: 186 Objects *objects; 187 bool isexp; // true: expression tuple 188 189 TypeTuple *tupletype; // !=NULL if this is a type tuple 190 191 TupleDeclaration(Loc loc, Identifier *ident, Objects *objects); 192 Dsymbol *syntaxCopy(Dsymbol *); 193 const char *kind() const; 194 Type *getType(); 195 Dsymbol *toAlias2(); 196 bool needThis(); 197 isTupleDeclaration()198 TupleDeclaration *isTupleDeclaration() { return this; } accept(Visitor * v)199 void accept(Visitor *v) { v->visit(this); } 200 }; 201 202 /**************************************************************/ 203 204 class AliasDeclaration : public Declaration 205 { 206 public: 207 Dsymbol *aliassym; 208 Dsymbol *overnext; // next in overload list 209 Dsymbol *_import; // !=NULL if unresolved internal alias for selective import 210 211 AliasDeclaration(Loc loc, Identifier *ident, Type *type); 212 AliasDeclaration(Loc loc, Identifier *ident, Dsymbol *s); 213 static AliasDeclaration *create(Loc loc, Identifier *id, Type *type); 214 Dsymbol *syntaxCopy(Dsymbol *); 215 bool overloadInsert(Dsymbol *s); 216 const char *kind() const; 217 Type *getType(); 218 Dsymbol *toAlias(); 219 Dsymbol *toAlias2(); 220 bool isOverloadable(); 221 isAliasDeclaration()222 AliasDeclaration *isAliasDeclaration() { return this; } accept(Visitor * v)223 void accept(Visitor *v) { v->visit(this); } 224 }; 225 226 /**************************************************************/ 227 228 class OverDeclaration : public Declaration 229 { 230 public: 231 Dsymbol *overnext; // next in overload list 232 Dsymbol *aliassym; 233 bool hasOverloads; 234 235 OverDeclaration(Identifier *ident, Dsymbol *s, bool hasOverloads = true); 236 const char *kind() const; 237 bool equals(RootObject *o); 238 bool overloadInsert(Dsymbol *s); 239 240 Dsymbol *toAlias(); 241 Dsymbol *isUnique(); 242 bool isOverloadable(); 243 isOverDeclaration()244 OverDeclaration *isOverDeclaration() { return this; } accept(Visitor * v)245 void accept(Visitor *v) { v->visit(this); } 246 }; 247 248 /**************************************************************/ 249 250 class VarDeclaration : public Declaration 251 { 252 public: 253 Initializer *_init; 254 unsigned offset; 255 unsigned sequenceNumber; // order the variables are declared 256 FuncDeclarations nestedrefs; // referenced by these lexically nested functions 257 bool isargptr; // if parameter that _argptr points to 258 structalign_t alignment; 259 bool ctorinit; // it has been initialized in a ctor 260 bool onstack; // it is a class that was allocated on the stack 261 bool mynew; // it is a class new'd with custom operator new 262 int canassign; // it can be assigned to 263 bool overlapped; // if it is a field and has overlapping 264 bool overlapUnsafe; // if it is an overlapping field and the overlaps are unsafe 265 bool doNotInferScope; // do not infer 'scope' for this variable 266 unsigned char isdataseg; // private data for isDataseg 267 Dsymbol *aliassym; // if redone as alias to another symbol 268 VarDeclaration *lastVar; // Linked list of variables for goto-skips-init detection 269 unsigned endlinnum; // line number of end of scope that this var lives in 270 271 // When interpreting, these point to the value (NULL if value not determinable) 272 // The index of this variable on the CTFE stack, -1 if not allocated 273 int ctfeAdrOnStack; 274 Expression *edtor; // if !=NULL, does the destruction of the variable 275 IntRange *range; // if !NULL, the variable is known to be within the range 276 277 VarDeclaration(Loc loc, Type *t, Identifier *id, Initializer *init); 278 static VarDeclaration *create(Loc loc, Type *t, Identifier *id, Initializer *init); 279 Dsymbol *syntaxCopy(Dsymbol *); 280 void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion); 281 const char *kind() const; 282 AggregateDeclaration *isThis(); 283 bool needThis(); 284 bool isExport() const; 285 bool isImportedSymbol() const; 286 bool isDataseg(); 287 bool isThreadlocal(); 288 bool isCTFE(); 289 bool isOverlappedWith(VarDeclaration *v); 290 bool hasPointers(); 291 bool canTakeAddressOf(); 292 bool needsScopeDtor(); 293 bool enclosesLifetimeOf(VarDeclaration *v) const; 294 Expression *callScopeDtor(Scope *sc); 295 Expression *getConstInitializer(bool needFullType = true); 296 Expression *expandInitializer(Loc loc); 297 void checkCtorConstInit(); 298 bool checkNestedReference(Scope *sc, Loc loc); 299 Dsymbol *toAlias(); 300 // Eliminate need for dynamic_cast isVarDeclaration()301 VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; } accept(Visitor * v)302 void accept(Visitor *v) { v->visit(this); } 303 }; 304 305 /**************************************************************/ 306 307 // This is a shell around a back end symbol 308 309 class SymbolDeclaration : public Declaration 310 { 311 public: 312 StructDeclaration *dsym; 313 314 SymbolDeclaration(Loc loc, StructDeclaration *dsym); 315 316 // Eliminate need for dynamic_cast isSymbolDeclaration()317 SymbolDeclaration *isSymbolDeclaration() { return (SymbolDeclaration *)this; } accept(Visitor * v)318 void accept(Visitor *v) { v->visit(this); } 319 }; 320 321 class TypeInfoDeclaration : public VarDeclaration 322 { 323 public: 324 Type *tinfo; 325 326 TypeInfoDeclaration(Type *tinfo); 327 static TypeInfoDeclaration *create(Type *tinfo); 328 Dsymbol *syntaxCopy(Dsymbol *); 329 const char *toChars(); 330 isTypeInfoDeclaration()331 TypeInfoDeclaration *isTypeInfoDeclaration() { return this; } accept(Visitor * v)332 void accept(Visitor *v) { v->visit(this); } 333 }; 334 335 class TypeInfoStructDeclaration : public TypeInfoDeclaration 336 { 337 public: 338 TypeInfoStructDeclaration(Type *tinfo); 339 static TypeInfoStructDeclaration *create(Type *tinfo); 340 accept(Visitor * v)341 void accept(Visitor *v) { v->visit(this); } 342 }; 343 344 class TypeInfoClassDeclaration : public TypeInfoDeclaration 345 { 346 public: 347 TypeInfoClassDeclaration(Type *tinfo); 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 TypeInfoInterfaceDeclaration(Type *tinfo); 357 static TypeInfoInterfaceDeclaration *create(Type *tinfo); 358 accept(Visitor * v)359 void accept(Visitor *v) { v->visit(this); } 360 }; 361 362 class TypeInfoPointerDeclaration : public TypeInfoDeclaration 363 { 364 public: 365 TypeInfoPointerDeclaration(Type *tinfo); 366 static TypeInfoPointerDeclaration *create(Type *tinfo); 367 accept(Visitor * v)368 void accept(Visitor *v) { v->visit(this); } 369 }; 370 371 class TypeInfoArrayDeclaration : public TypeInfoDeclaration 372 { 373 public: 374 TypeInfoArrayDeclaration(Type *tinfo); 375 static TypeInfoArrayDeclaration *create(Type *tinfo); 376 accept(Visitor * v)377 void accept(Visitor *v) { v->visit(this); } 378 }; 379 380 class TypeInfoStaticArrayDeclaration : public TypeInfoDeclaration 381 { 382 public: 383 TypeInfoStaticArrayDeclaration(Type *tinfo); 384 static TypeInfoStaticArrayDeclaration *create(Type *tinfo); 385 accept(Visitor * v)386 void accept(Visitor *v) { v->visit(this); } 387 }; 388 389 class TypeInfoAssociativeArrayDeclaration : public TypeInfoDeclaration 390 { 391 public: 392 TypeInfoAssociativeArrayDeclaration(Type *tinfo); 393 static TypeInfoAssociativeArrayDeclaration *create(Type *tinfo); 394 accept(Visitor * v)395 void accept(Visitor *v) { v->visit(this); } 396 }; 397 398 class TypeInfoEnumDeclaration : public TypeInfoDeclaration 399 { 400 public: 401 TypeInfoEnumDeclaration(Type *tinfo); 402 static TypeInfoEnumDeclaration *create(Type *tinfo); 403 accept(Visitor * v)404 void accept(Visitor *v) { v->visit(this); } 405 }; 406 407 class TypeInfoFunctionDeclaration : public TypeInfoDeclaration 408 { 409 public: 410 TypeInfoFunctionDeclaration(Type *tinfo); 411 static TypeInfoFunctionDeclaration *create(Type *tinfo); 412 accept(Visitor * v)413 void accept(Visitor *v) { v->visit(this); } 414 }; 415 416 class TypeInfoDelegateDeclaration : public TypeInfoDeclaration 417 { 418 public: 419 TypeInfoDelegateDeclaration(Type *tinfo); 420 static TypeInfoDelegateDeclaration *create(Type *tinfo); 421 accept(Visitor * v)422 void accept(Visitor *v) { v->visit(this); } 423 }; 424 425 class TypeInfoTupleDeclaration : public TypeInfoDeclaration 426 { 427 public: 428 TypeInfoTupleDeclaration(Type *tinfo); 429 static TypeInfoTupleDeclaration *create(Type *tinfo); 430 accept(Visitor * v)431 void accept(Visitor *v) { v->visit(this); } 432 }; 433 434 class TypeInfoConstDeclaration : public TypeInfoDeclaration 435 { 436 public: 437 TypeInfoConstDeclaration(Type *tinfo); 438 static TypeInfoConstDeclaration *create(Type *tinfo); 439 accept(Visitor * v)440 void accept(Visitor *v) { v->visit(this); } 441 }; 442 443 class TypeInfoInvariantDeclaration : public TypeInfoDeclaration 444 { 445 public: 446 TypeInfoInvariantDeclaration(Type *tinfo); 447 static TypeInfoInvariantDeclaration *create(Type *tinfo); 448 accept(Visitor * v)449 void accept(Visitor *v) { v->visit(this); } 450 }; 451 452 class TypeInfoSharedDeclaration : public TypeInfoDeclaration 453 { 454 public: 455 TypeInfoSharedDeclaration(Type *tinfo); 456 static TypeInfoSharedDeclaration *create(Type *tinfo); 457 accept(Visitor * v)458 void accept(Visitor *v) { v->visit(this); } 459 }; 460 461 class TypeInfoWildDeclaration : public TypeInfoDeclaration 462 { 463 public: 464 TypeInfoWildDeclaration(Type *tinfo); 465 static TypeInfoWildDeclaration *create(Type *tinfo); 466 accept(Visitor * v)467 void accept(Visitor *v) { v->visit(this); } 468 }; 469 470 class TypeInfoVectorDeclaration : public TypeInfoDeclaration 471 { 472 public: 473 TypeInfoVectorDeclaration(Type *tinfo); 474 static TypeInfoVectorDeclaration *create(Type *tinfo); 475 accept(Visitor * v)476 void accept(Visitor *v) { v->visit(this); } 477 }; 478 479 /**************************************************************/ 480 481 class ThisDeclaration : public VarDeclaration 482 { 483 public: 484 ThisDeclaration(Loc loc, Type *t); 485 Dsymbol *syntaxCopy(Dsymbol *); isThisDeclaration()486 ThisDeclaration *isThisDeclaration() { return this; } accept(Visitor * v)487 void accept(Visitor *v) { v->visit(this); } 488 }; 489 490 enum ILS 491 { 492 ILSuninitialized, // not computed yet 493 ILSno, // cannot inline 494 ILSyes // can inline 495 }; 496 497 /**************************************************************/ 498 499 enum BUILTIN 500 { 501 BUILTINunknown = 255, /// not known if this is a builtin 502 BUILTINunimp = 0, /// this is not a builtin 503 BUILTINgcc, /// this is a GCC builtin 504 BUILTINllvm, /// this is an LLVM builtin 505 BUILTINsin, 506 BUILTINcos, 507 BUILTINtan, 508 BUILTINsqrt, 509 BUILTINfabs, 510 BUILTINldexp, 511 BUILTINlog, 512 BUILTINlog2, 513 BUILTINlog10, 514 BUILTINexp, 515 BUILTINexpm1, 516 BUILTINexp2, 517 BUILTINround, 518 BUILTINfloor, 519 BUILTINceil, 520 BUILTINtrunc, 521 BUILTINcopysign, 522 BUILTINpow, 523 BUILTINfmin, 524 BUILTINfmax, 525 BUILTINfma, 526 BUILTINisnan, 527 BUILTINisinfinity, 528 BUILTINisfinite, 529 BUILTINbsf, 530 BUILTINbsr, 531 BUILTINbswap, 532 BUILTINpopcnt, 533 BUILTINyl2x, 534 BUILTINyl2xp1, 535 BUILTINtoPrecFloat, 536 BUILTINtoPrecDouble, 537 BUILTINtoPrecReal 538 }; 539 540 Expression *eval_builtin(Loc loc, FuncDeclaration *fd, Expressions *arguments); 541 BUILTIN isBuiltin(FuncDeclaration *fd); 542 543 typedef Expression *(*builtin_fp)(Loc loc, FuncDeclaration *fd, Expressions *arguments); 544 void add_builtin(const char *mangle, builtin_fp fp); 545 void builtin_init(); 546 547 #define FUNCFLAGpurityInprocess 1 // working on determining purity 548 #define FUNCFLAGsafetyInprocess 2 // working on determining safety 549 #define FUNCFLAGnothrowInprocess 4 // working on determining nothrow 550 #define FUNCFLAGnogcInprocess 8 // working on determining @nogc 551 #define FUNCFLAGreturnInprocess 0x10 // working on inferring 'return' for parameters 552 #define FUNCFLAGinlineScanned 0x20 // function has been scanned for inline possibilities 553 #define FUNCFLAGinferScope 0x40 // infer 'scope' for parameters 554 #define FUNCFLAGprintf 0x200 // is a printf-like function 555 #define FUNCFLAGscanf 0x400 // is a scanf-like function 556 557 class FuncDeclaration : public Declaration 558 { 559 public: 560 Types *fthrows; // Array of Type's of exceptions (not used) 561 Statements *frequires; // in contracts 562 Ensures *fensures; // out contracts 563 Statement *frequire; // lowered in contract 564 Statement *fensure; // lowered out contract 565 Statement *fbody; 566 567 FuncDeclarations foverrides; // functions this function overrides 568 FuncDeclaration *fdrequire; // function that does the in contract 569 FuncDeclaration *fdensure; // function that does the out contract 570 571 const char *mangleString; // mangled symbol created from mangleExact() 572 573 VarDeclaration *vresult; // result variable for out contracts 574 LabelDsymbol *returnLabel; // where the return goes 575 576 // used to prevent symbols in different 577 // scopes from having the same name 578 DsymbolTable *localsymtab; 579 VarDeclaration *vthis; // 'this' parameter (member and nested) 580 VarDeclaration *v_arguments; // '_arguments' parameter 581 ObjcSelector* selector; // Objective-C method selector (member function only) 582 VarDeclaration *v_argptr; // '_argptr' variable 583 VarDeclarations *parameters; // Array of VarDeclaration's for parameters 584 DsymbolTable *labtab; // statement label symbol table 585 Dsymbol *overnext; // next in overload list 586 FuncDeclaration *overnext0; // next in overload list (only used during IFTI) 587 Loc endloc; // location of closing curly bracket 588 int vtblIndex; // for member functions, index into vtbl[] 589 bool naked; // true if naked 590 bool generated; // true if function was generated by the compiler rather than 591 // supplied by the user 592 ILS inlineStatusStmt; 593 ILS inlineStatusExp; 594 PINLINE inlining; 595 596 CompiledCtfeFunction *ctfeCode; // Compiled code for interpreter 597 int inlineNest; // !=0 if nested inline 598 bool isArrayOp; // true if array operation 599 // true if errors in semantic3 this function's frame ptr 600 bool semantic3Errors; 601 ForeachStatement *fes; // if foreach body, this is the foreach 602 BaseClass* interfaceVirtual; // if virtual, but only appears in interface vtbl[] 603 bool introducing; // true if 'introducing' function 604 // if !=NULL, then this is the type 605 // of the 'introducing' function 606 // this one is overriding 607 Type *tintro; 608 bool inferRetType; // true if return type is to be inferred 609 StorageClass storage_class2; // storage class for template onemember's 610 611 // Things that should really go into Scope 612 613 // 1 if there's a return exp; statement 614 // 2 if there's a throw statement 615 // 4 if there's an assert(0) 616 // 8 if there's inline asm 617 // 16 if there are multiple return statements 618 int hasReturnExp; 619 620 // Support for NRVO (named return value optimization) 621 bool nrvo_can; // true means we can do it 622 VarDeclaration *nrvo_var; // variable to replace with shidden 623 Symbol *shidden; // hidden pointer passed to function 624 625 ReturnStatements *returns; 626 627 GotoStatements *gotos; // Gotos with forward references 628 629 // set if this is a known, builtin function we can evaluate at compile time 630 BUILTIN builtin; 631 632 // set if someone took the address of this function 633 int tookAddressOf; 634 bool requiresClosure; // this function needs a closure 635 636 // local variables in this function which are referenced by nested functions 637 VarDeclarations closureVars; 638 // Sibling nested functions which called this one 639 FuncDeclarations siblingCallers; 640 641 FuncDeclarations *inlinedNestedCallees; 642 643 unsigned flags; // FUNCFLAGxxxxx 644 645 FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type); 646 static FuncDeclaration *create(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type); 647 Dsymbol *syntaxCopy(Dsymbol *); 648 bool functionSemantic(); 649 bool functionSemantic3(); 650 bool checkForwardRef(Loc loc); 651 // called from semantic3 652 VarDeclaration *declareThis(Scope *sc, AggregateDeclaration *ad); 653 bool equals(RootObject *o); 654 655 int overrides(FuncDeclaration *fd); 656 int findVtblIndex(Dsymbols *vtbl, int dim, bool fix17349 = true); 657 BaseClass *overrideInterface(); 658 bool overloadInsert(Dsymbol *s); 659 FuncDeclaration *overloadExactMatch(Type *t); 660 FuncDeclaration *overloadModMatch(Loc loc, Type *tthis, bool &hasOverloads); 661 TemplateDeclaration *findTemplateDeclRoot(); 662 bool inUnittest(); 663 MATCH leastAsSpecialized(FuncDeclaration *g); 664 LabelDsymbol *searchLabel(Identifier *ident); 665 int getLevel(Loc loc, Scope *sc, FuncDeclaration *fd); // lexical nesting level difference 666 const char *toPrettyChars(bool QualifyTypes = false); 667 const char *toFullSignature(); // for diagnostics, e.g. 'int foo(int x, int y) pure' 668 bool isMain(); 669 bool isCMain(); 670 bool isWinMain(); 671 bool isDllMain(); 672 bool isExport() const; 673 bool isImportedSymbol() const; 674 bool isCodeseg() const; 675 bool isOverloadable(); 676 PURE isPure(); 677 PURE isPureBypassingInference(); 678 bool setImpure(); 679 bool isSafe(); 680 bool isSafeBypassingInference(); 681 bool isTrusted(); 682 bool setUnsafe(); 683 684 bool isNogc(); 685 bool isNogcBypassingInference(); 686 bool setGC(); 687 688 void printGCUsage(Loc loc, const char *warn); 689 bool isolateReturn(); 690 bool parametersIntersect(Type *t); 691 virtual bool isNested(); 692 AggregateDeclaration *isThis(); 693 bool needThis(); 694 bool isVirtualMethod(); 695 virtual bool isVirtual(); 696 virtual bool isFinalFunc(); 697 virtual bool addPreInvariant(); 698 virtual bool addPostInvariant(); 699 const char *kind() const; 700 FuncDeclaration *isUnique(); 701 bool checkNestedReference(Scope *sc, Loc loc); 702 bool needsClosure(); 703 bool checkClosure(); 704 bool hasNestedFrameRefs(); 705 void buildResultVar(Scope *sc, Type *tret); 706 Statement *mergeFrequire(Statement *); 707 static bool needsFensure(FuncDeclaration *fd); 708 void buildEnsureRequire(); 709 Statement *mergeFensure(Statement *, Identifier *oid); 710 ParameterList getParameterList(); 711 712 static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, const char *name, StorageClass stc=0); 713 static FuncDeclaration *genCfunc(Parameters *args, Type *treturn, Identifier *id, StorageClass stc=0); 714 void checkDmain(); 715 bool checkNRVO(); 716 isFuncDeclaration()717 FuncDeclaration *isFuncDeclaration() { return this; } 718 toAliasFunc()719 virtual FuncDeclaration *toAliasFunc() { return this; } accept(Visitor * v)720 void accept(Visitor *v) { v->visit(this); } 721 }; 722 723 FuncDeclaration *resolveFuncCall(Loc loc, Scope *sc, Dsymbol *s, 724 Objects *tiargs, 725 Type *tthis, 726 Expressions *arguments, 727 int flags = 0); 728 729 class FuncAliasDeclaration : public FuncDeclaration 730 { 731 public: 732 FuncDeclaration *funcalias; 733 bool hasOverloads; 734 735 FuncAliasDeclaration(Identifier *ident, FuncDeclaration *funcalias, bool hasOverloads = true); 736 isFuncAliasDeclaration()737 FuncAliasDeclaration *isFuncAliasDeclaration() { return this; } 738 const char *kind() const; 739 740 FuncDeclaration *toAliasFunc(); accept(Visitor * v)741 void accept(Visitor *v) { v->visit(this); } 742 }; 743 744 class FuncLiteralDeclaration : public FuncDeclaration 745 { 746 public: 747 TOK tok; // TOKfunction or TOKdelegate 748 Type *treq; // target of return type inference 749 750 // backend 751 bool deferToObj; 752 753 FuncLiteralDeclaration(Loc loc, Loc endloc, Type *type, TOK tok, 754 ForeachStatement *fes, Identifier *id = NULL); 755 Dsymbol *syntaxCopy(Dsymbol *); 756 bool isNested(); 757 AggregateDeclaration *isThis(); 758 bool isVirtual(); 759 bool addPreInvariant(); 760 bool addPostInvariant(); 761 762 void modifyReturns(Scope *sc, Type *tret); 763 isFuncLiteralDeclaration()764 FuncLiteralDeclaration *isFuncLiteralDeclaration() { return this; } 765 const char *kind() const; 766 const char *toPrettyChars(bool QualifyTypes = false); accept(Visitor * v)767 void accept(Visitor *v) { v->visit(this); } 768 }; 769 770 class CtorDeclaration : public FuncDeclaration 771 { 772 public: 773 CtorDeclaration(Loc loc, Loc endloc, StorageClass stc, Type *type); 774 Dsymbol *syntaxCopy(Dsymbol *); 775 const char *kind() const; 776 const char *toChars(); 777 bool isVirtual(); 778 bool addPreInvariant(); 779 bool addPostInvariant(); 780 isCtorDeclaration()781 CtorDeclaration *isCtorDeclaration() { return this; } accept(Visitor * v)782 void accept(Visitor *v) { v->visit(this); } 783 }; 784 785 class PostBlitDeclaration : public FuncDeclaration 786 { 787 public: 788 PostBlitDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id); 789 Dsymbol *syntaxCopy(Dsymbol *); 790 bool isVirtual(); 791 bool addPreInvariant(); 792 bool addPostInvariant(); 793 bool overloadInsert(Dsymbol *s); 794 isPostBlitDeclaration()795 PostBlitDeclaration *isPostBlitDeclaration() { return this; } accept(Visitor * v)796 void accept(Visitor *v) { v->visit(this); } 797 }; 798 799 class DtorDeclaration : public FuncDeclaration 800 { 801 public: 802 DtorDeclaration(Loc loc, Loc endloc); 803 DtorDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id); 804 Dsymbol *syntaxCopy(Dsymbol *); 805 const char *kind() const; 806 const char *toChars(); 807 bool isVirtual(); 808 bool addPreInvariant(); 809 bool addPostInvariant(); 810 bool overloadInsert(Dsymbol *s); 811 isDtorDeclaration()812 DtorDeclaration *isDtorDeclaration() { return this; } accept(Visitor * v)813 void accept(Visitor *v) { v->visit(this); } 814 }; 815 816 class StaticCtorDeclaration : public FuncDeclaration 817 { 818 public: 819 StaticCtorDeclaration(Loc loc, Loc endloc, StorageClass stc); 820 StaticCtorDeclaration(Loc loc, Loc endloc, const char *name, StorageClass stc); 821 Dsymbol *syntaxCopy(Dsymbol *); 822 AggregateDeclaration *isThis(); 823 bool isVirtual(); 824 bool addPreInvariant(); 825 bool addPostInvariant(); 826 bool hasStaticCtorOrDtor(); 827 isStaticCtorDeclaration()828 StaticCtorDeclaration *isStaticCtorDeclaration() { return this; } accept(Visitor * v)829 void accept(Visitor *v) { v->visit(this); } 830 }; 831 832 class SharedStaticCtorDeclaration : public StaticCtorDeclaration 833 { 834 public: 835 SharedStaticCtorDeclaration(Loc loc, Loc endloc, StorageClass stc); 836 Dsymbol *syntaxCopy(Dsymbol *); 837 isSharedStaticCtorDeclaration()838 SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return this; } accept(Visitor * v)839 void accept(Visitor *v) { v->visit(this); } 840 }; 841 842 class StaticDtorDeclaration : public FuncDeclaration 843 { 844 public: 845 VarDeclaration *vgate; // 'gate' variable 846 847 StaticDtorDeclaration(Loc loc, Loc endloc, StorageClass stc); 848 StaticDtorDeclaration(Loc loc, Loc endloc, const char *name, StorageClass stc); 849 Dsymbol *syntaxCopy(Dsymbol *); 850 AggregateDeclaration *isThis(); 851 bool isVirtual(); 852 bool hasStaticCtorOrDtor(); 853 bool addPreInvariant(); 854 bool addPostInvariant(); 855 isStaticDtorDeclaration()856 StaticDtorDeclaration *isStaticDtorDeclaration() { return this; } accept(Visitor * v)857 void accept(Visitor *v) { v->visit(this); } 858 }; 859 860 class SharedStaticDtorDeclaration : public StaticDtorDeclaration 861 { 862 public: 863 SharedStaticDtorDeclaration(Loc loc, Loc endloc, StorageClass stc); 864 Dsymbol *syntaxCopy(Dsymbol *); 865 isSharedStaticDtorDeclaration()866 SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return this; } accept(Visitor * v)867 void accept(Visitor *v) { v->visit(this); } 868 }; 869 870 class InvariantDeclaration : public FuncDeclaration 871 { 872 public: 873 InvariantDeclaration(Loc loc, Loc endloc, StorageClass stc, Identifier *id = NULL); 874 Dsymbol *syntaxCopy(Dsymbol *); 875 bool isVirtual(); 876 bool addPreInvariant(); 877 bool addPostInvariant(); 878 isInvariantDeclaration()879 InvariantDeclaration *isInvariantDeclaration() { return this; } accept(Visitor * v)880 void accept(Visitor *v) { v->visit(this); } 881 }; 882 883 class UnitTestDeclaration : public FuncDeclaration 884 { 885 public: 886 char *codedoc; /** For documented unittest. */ 887 888 // toObjFile() these nested functions after this one 889 FuncDeclarations deferredNested; 890 891 UnitTestDeclaration(Loc loc, Loc endloc, StorageClass stc, char *codedoc); 892 Dsymbol *syntaxCopy(Dsymbol *); 893 AggregateDeclaration *isThis(); 894 bool isVirtual(); 895 bool addPreInvariant(); 896 bool addPostInvariant(); 897 isUnitTestDeclaration()898 UnitTestDeclaration *isUnitTestDeclaration() { return this; } accept(Visitor * v)899 void accept(Visitor *v) { v->visit(this); } 900 }; 901 902 class NewDeclaration : public FuncDeclaration 903 { 904 public: 905 Parameters *parameters; 906 VarArg varargs; 907 908 NewDeclaration(Loc loc, Loc endloc, StorageClass stc, Parameters *arguments, VarArg varargs); 909 Dsymbol *syntaxCopy(Dsymbol *); 910 const char *kind() const; 911 bool isVirtual(); 912 bool addPreInvariant(); 913 bool addPostInvariant(); 914 isNewDeclaration()915 NewDeclaration *isNewDeclaration() { return this; } accept(Visitor * v)916 void accept(Visitor *v) { v->visit(this); } 917 }; 918 919 920 class DeleteDeclaration : public FuncDeclaration 921 { 922 public: 923 Parameters *parameters; 924 925 DeleteDeclaration(Loc loc, Loc endloc, StorageClass stc, Parameters *arguments); 926 Dsymbol *syntaxCopy(Dsymbol *); 927 const char *kind() const; 928 bool isDelete(); 929 bool isVirtual(); 930 bool addPreInvariant(); 931 bool addPostInvariant(); 932 isDeleteDeclaration()933 DeleteDeclaration *isDeleteDeclaration() { return this; } accept(Visitor * v)934 void accept(Visitor *v) { v->visit(this); } 935 }; 936