1: 
   2: // Compiler implementation of the D programming language
   3: // Copyright (c) 1999-2011 by Digital Mars
   4: // All Rights Reserved
   5: // written by Walter Bright
   6: // http://www.digitalmars.com
   7: // License for redistribution is by either the Artistic License
   8: // in artistic.txt, or the GNU General Public License in gnu.txt.
   9: // See the included readme.txt for details.
  10: 
  11: #include <stdio.h>
  12: static char __file__[] = __FILE__;      /* for tassert.h                */
  13: #include        "tassert.h"
  14: 
  15: #include "cdef.h"
  16: #include "init.h"
  17: #include "declaration.h"
  18: #include "attrib.h"
  19: #include "mtype.h"
  20: #include "template.h"
  21: #include "scope.h"
  22: #include "aggregate.h"
  23: #include "module.h"
  24: #include "id.h"
  25: #include "expression.h"
  26: #include "hdrgen.h"
  27: 
  28: /********************************* Declaration ****************************/
  29: 
  30: Declaration::Declaration(Identifier *id)
  31:     : Dsymbol(id)
  32: {
  33:     type = NULL;
  34:     originalType = NULL;
  35:     storage_class = STCundefined;
  36:     protection = PROTundefined;
  37:     linkage = LINKdefault;
  38:     inuse = 0;
  39:     sem = SemanticStart;
  40: }
  41: 
  42: void Declaration::semantic(Scope *sc)
  43: {
  44: }
  45: 
  46: const char *Declaration::kind()
  47: {
  48:     return "declaration";
  49: }
  50: 
  51: unsigned Declaration::size(Loc loc)
  52: {
  53:     assert(type);
  54:     return type->size();
warning C4244: 'return' : conversion from 'd_uns64' to 'unsigned int', possible loss of data
55: } 56: 57: int Declaration::isDelete() 58: { 59: return FALSE; 60: } 61: 62: int Declaration::isDataseg() 63: { 64: return FALSE; 65: } 66: 67: int Declaration::isThreadlocal() 68: { 69: return FALSE; 70: } 71: 72: int Declaration::isCodeseg() 73: { 74: return FALSE; 75: } 76: 77: enum PROT Declaration::prot() 78: { 79: return protection; 80: } 81: 82: /************************************* 83: * Check to see if declaration can be modified in this context (sc). 84: * Issue error if not. 85: */ 86: 87: #if DMDV2 88: void Declaration::checkModify(Loc loc, Scope *sc, Type *t) 89: { 90: if (sc->incontract && isParameter()) 91: error(loc, "cannot modify parameter '%s' in contract", toChars()); 92: 93: if (sc->incontract && isResult()) 94: error(loc, "cannot modify result '%s' in contract", toChars()); 95: 96: if (isCtorinit() && !t->isMutable()) 97: { // It's only modifiable if inside the right constructor 98: Dsymbol *s = sc->func; 99: while (1) 100: { 101: FuncDeclaration *fd = NULL; 102: if (s) 103: fd = s->isFuncDeclaration(); 104: if (fd && 105: ((fd->isCtorDeclaration() && storage_class & STCfield) || 106: (fd->isStaticCtorDeclaration() && !(storage_class & STCfield))) && 107: fd->toParent2() == toParent() 108: ) 109: { 110: VarDeclaration *v = isVarDeclaration(); 111: assert(v); 112: v->ctorinit = 1; 113: //printf("setting ctorinit\n"); 114: } 115: else 116: { 117: if (s) 118: { s = s->toParent2(); 119: continue; 120: } 121: else 122: { 123: const char *p = isStatic() ? "static " : ""; 124: error(loc, "can only initialize %sconst %s inside %sconstructor", 125: p, toChars(), p); 126: } 127: } 128: break; 129: } 130: } 131: else 132: { 133: VarDeclaration *v = isVarDeclaration(); 134: if (v && v->canassign == 0) 135: { 136: const char *p = NULL; 137: if (isConst()) 138: p = "const"; 139: else if (isImmutable()) 140: p = "immutable"; 141: else if (storage_class & STCmanifest) 142: p = "enum"; 143: else if (!t->isAssignable()) 144: p = "struct with immutable members"; 145: if (p) 146: { error(loc, "cannot modify %s", p); 147: } 148: } 149: } 150: } 151: #endif 152: 153: 154: /********************************* TupleDeclaration ****************************/ 155: 156: TupleDeclaration::TupleDeclaration(Loc loc, Identifier *id, Objects *objects) 157: : Declaration(id) 158: { 159: this->loc = loc; 160: this->type = NULL; 161: this->objects = objects; 162: this->isexp = 0; 163: this->tupletype = NULL; 164: } 165: 166: Dsymbol *TupleDeclaration::syntaxCopy(Dsymbol *s) 167: { 168: assert(0); 169: return NULL; 170: } 171: 172: const char *TupleDeclaration::kind() 173: { 174: return "tuple"; 175: } 176: 177: Type *TupleDeclaration::getType() 178: { 179: /* If this tuple represents a type, return that type 180: */ 181: 182: //printf("TupleDeclaration::getType() %s\n", toChars()); 183: if (isexp) 184: return NULL; 185: if (!tupletype) 186: { 187: /* It's only a type tuple if all the Object's are types 188: */ 189: for (size_t i = 0; i < objects->dim; i++) 190: { Object *o = objects->tdata()[i]; 191: 192: if (o->dyncast() != DYNCAST_TYPE) 193: { 194: //printf("\tnot[%d], %p, %d\n", i, o, o->dyncast()); 195: return NULL; 196: } 197: } 198: 199: /* We know it's a type tuple, so build the TypeTuple 200: */ 201: Types *types = (Types *)objects; 202: Parameters *args = new Parameters();
warning C6211: Leaking memory 'args' due to an exception. Consider using a local catch block to clean up memory: Lines: 183, 185, 189, 190, 192, 189, 190, 192, 189, 201, 202, 203, 204, 205, 206, 207, 216
203: args->setDim(objects->dim); 204: OutBuffer buf; 205: int hasdeco = 1; 206: for (size_t i = 0; i < types->dim; i++) 207: { Type *t = types->tdata()[i]; 208: 209: //printf("type = %s\n", t->toChars()); 210: #if 0 211: buf.printf("_%s_%d", ident->toChars(), i); 212: char *name = (char *)buf.extractData(); 213: Identifier *id = new Identifier(name, TOKidentifier); 214: Parameter *arg = new Parameter(STCin, t, id, NULL); 215: #else 216: Parameter *arg = new Parameter(0, t, NULL, NULL); 217: #endif 218: args->tdata()[i] = arg; 219: if (!t->deco) 220: hasdeco = 0; 221: } 222: 223: tupletype = new TypeTuple(args); 224: if (hasdeco) 225: return tupletype->semantic(0, NULL); 226: } 227: 228: return tupletype; 229: } 230: 231: int TupleDeclaration::needThis() 232: { 233: //printf("TupleDeclaration::needThis(%s)\n", toChars()); 234: for (size_t i = 0; i < objects->dim; i++) 235: { Object *o = objects->tdata()[i]; 236: if (o->dyncast() == DYNCAST_EXPRESSION) 237: { Expression *e = (Expression *)o; 238: if (e->op == TOKdsymbol) 239: { DsymbolExp *ve = (DsymbolExp *)e; 240: Declaration *d = ve->s->isDeclaration(); 241: if (d && d->needThis()) 242: { 243: return 1; 244: } 245: } 246: } 247: } 248: return 0; 249: } 250: 251: 252: /********************************* TypedefDeclaration ****************************/ 253: 254: TypedefDeclaration::TypedefDeclaration(Loc loc, Identifier *id, Type *basetype, Initializer *init) 255: : Declaration(id) 256: { 257: this->type = new TypeTypedef(this); 258: this->basetype = basetype->toBasetype(); 259: this->init = init; 260: this->htype = NULL; 261: this->hbasetype = NULL; 262: this->loc = loc; 263: this->sinit = NULL; 264: } 265: 266: Dsymbol *TypedefDeclaration::syntaxCopy(Dsymbol *s) 267: { 268: Type *basetype = this->basetype->syntaxCopy(); 269: 270: Initializer *init = NULL; 271: if (this->init) 272: init = this->init->syntaxCopy(); 273: 274: assert(!s); 275: TypedefDeclaration *st; 276: st = new TypedefDeclaration(loc, ident, basetype, init); 277: 278: // Syntax copy for header file 279: if (!htype) // Don't overwrite original 280: { if (type) // Make copy for both old and new instances 281: { htype = type->syntaxCopy(); 282: st->htype = type->syntaxCopy(); 283: } 284: } 285: else // Make copy of original for new instance 286: st->htype = htype->syntaxCopy(); 287: if (!hbasetype) 288: { if (basetype) 289: { hbasetype = basetype->syntaxCopy(); 290: st->hbasetype = basetype->syntaxCopy(); 291: } 292: } 293: else 294: st->hbasetype = hbasetype->syntaxCopy(); 295: 296: return st; 297: } 298: 299: void TypedefDeclaration::semantic(Scope *sc) 300: { 301: //printf("TypedefDeclaration::semantic(%s) sem = %d\n", toChars(), sem); 302: if (sem == SemanticStart) 303: { sem = SemanticIn; 304: basetype = basetype->semantic(loc, sc); 305: sem = SemanticDone; 306: #if DMDV2 307: type = type->addStorageClass(storage_class); 308: #endif 309: type = type->semantic(loc, sc); 310: if (sc->parent->isFuncDeclaration() && init) 311: semantic2(sc); 312: storage_class |= sc->stc & STCdeprecated; 313: } 314: else if (sem == SemanticIn) 315: { 316: error("circular definition"); 317: } 318: } 319: 320: void TypedefDeclaration::semantic2(Scope *sc) 321: { 322: //printf("TypedefDeclaration::semantic2(%s) sem = %d\n", toChars(), sem); 323: if (sem == SemanticDone) 324: { sem = Semantic2Done; 325: if (init) 326: { 327: init = init->semantic(sc, basetype, WANTinterpret); 328: 329: ExpInitializer *ie = init->isExpInitializer(); 330: if (ie) 331: { 332: if (ie->exp->type == basetype) 333: ie->exp->type = type; 334: } 335: } 336: } 337: } 338: 339: const char *TypedefDeclaration::kind() 340: { 341: return "typedef"; 342: } 343: 344: Type *TypedefDeclaration::getType() 345: { 346: return type; 347: } 348: 349: void TypedefDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 350: { 351: buf->writestring("typedef "); 352: basetype->toCBuffer(buf, ident, hgs); 353: if (init) 354: { 355: buf->writestring(" = "); 356: init->toCBuffer(buf, hgs); 357: } 358: buf->writeByte(';'); 359: buf->writenl(); 360: } 361: 362: /********************************* AliasDeclaration ****************************/ 363: 364: AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Type *type) 365: : Declaration(id) 366: { 367: //printf("AliasDeclaration(id = '%s', type = %p)\n", id->toChars(), type); 368: //printf("type = '%s'\n", type->toChars()); 369: this->loc = loc; 370: this->type = type; 371: this->aliassym = NULL; 372: this->htype = NULL; 373: this->haliassym = NULL; 374: this->overnext = NULL; 375: this->inSemantic = 0; 376: assert(type); 377: } 378: 379: AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Dsymbol *s) 380: : Declaration(id) 381: { 382: //printf("AliasDeclaration(id = '%s', s = %p)\n", id->toChars(), s); 383: assert(s != this); 384: this->loc = loc; 385: this->type = NULL; 386: this->aliassym = s; 387: this->htype = NULL; 388: this->haliassym = NULL; 389: this->overnext = NULL; 390: this->inSemantic = 0; 391: assert(s); 392: } 393: 394: Dsymbol *AliasDeclaration::syntaxCopy(Dsymbol *s) 395: { 396: //printf("AliasDeclaration::syntaxCopy()\n"); 397: assert(!s); 398: AliasDeclaration *sa; 399: if (type) 400: sa = new AliasDeclaration(loc, ident, type->syntaxCopy()); 401: else 402: sa = new AliasDeclaration(loc, ident, aliassym->syntaxCopy(NULL)); 403: 404: // Syntax copy for header file 405: if (!htype) // Don't overwrite original 406: { if (type) // Make copy for both old and new instances 407: { htype = type->syntaxCopy(); 408: sa->htype = type->syntaxCopy(); 409: } 410: } 411: else // Make copy of original for new instance 412: sa->htype = htype->syntaxCopy(); 413: if (!haliassym) 414: { if (aliassym) 415: { haliassym = aliassym->syntaxCopy(s); 416: sa->haliassym = aliassym->syntaxCopy(s); 417: } 418: } 419: else 420: sa->haliassym = haliassym->syntaxCopy(s); 421: 422: return sa; 423: } 424: 425: void AliasDeclaration::semantic(Scope *sc) 426: { 427: //printf("AliasDeclaration::semantic() %s\n", toChars()); 428: if (aliassym) 429: { 430: if (aliassym->isTemplateInstance()) 431: aliassym->semantic(sc); 432: return; 433: } 434: this->inSemantic = 1; 435: 436: #if DMDV1 // don't really know why this is here 437: if (storage_class & STCconst) 438: error("cannot be const"); 439: #endif 440: 441: storage_class |= sc->stc & STCdeprecated; 442: 443: // Given: 444: // alias foo.bar.abc def; 445: // it is not knowable from the syntax whether this is an alias 446: // for a type or an alias for a symbol. It is up to the semantic() 447: // pass to distinguish. 448: // If it is a type, then type is set and getType() will return that 449: // type. If it is a symbol, then aliassym is set and type is NULL - 450: // toAlias() will return aliasssym. 451: 452: Dsymbol *s; 453: Type *t; 454: Expression *e; 455: 456: /* This section is needed because resolve() will: 457: * const x = 3; 458: * alias x y; 459: * try to alias y to 3. 460: */ 461: s = type->toDsymbol(sc); 462: if (s 463: #if DMDV2 464: && ((s->getType() && type->equals(s->getType())) || s->isEnumMember()) 465: #endif 466: ) 467: goto L2; // it's a symbolic alias 468: 469: #if DMDV2 470: type = type->addStorageClass(storage_class); 471: if (storage_class & (STCref | STCnothrow | STCpure | STCdisable)) 472: { // For 'ref' to be attached to function types, and picked 473: // up by Type::resolve(), it has to go into sc. 474: sc = sc->push(); 475: sc->stc |= storage_class & (STCref | STCnothrow | STCpure | STCshared | STCdisable); 476: type->resolve(loc, sc, &e, &t, &s); 477: sc = sc->pop(); 478: } 479: else 480: #endif 481: type->resolve(loc, sc, &e, &t, &s); 482: if (s) 483: { 484: goto L2; 485: } 486: else if (e) 487: { 488: // Try to convert Expression to Dsymbol 489: s = getDsymbol(e); 490: if (s) 491: goto L2; 492: 493: error("cannot alias an expression %s", e->toChars()); 494: t = e->type; 495: } 496: else if (t) 497: { 498: type = t; 499: //printf("\talias resolved to type %s\n", type->toChars()); 500: } 501: if (overnext) 502: ScopeDsymbol::multiplyDefined(0, this, overnext); 503: this->inSemantic = 0; 504: return; 505: 506: L2: 507: //printf("alias is a symbol %s %s\n", s->kind(), s->toChars()); 508: type = NULL; 509: VarDeclaration *v = s->isVarDeclaration(); 510: if (0 && v && v->linkage == LINKdefault) 511: { 512: error("forward reference of %s", v->toChars()); 513: s = NULL; 514: } 515: else 516: { 517: FuncDeclaration *f = s->toAlias()->isFuncDeclaration(); 518: if (f) 519: { 520: if (overnext) 521: { 522: FuncAliasDeclaration *fa = new FuncAliasDeclaration(f); 523: if (!fa->overloadInsert(overnext)) 524: ScopeDsymbol::multiplyDefined(0, f, overnext); 525: overnext = NULL; 526: s = fa; 527: s->parent = sc->parent; 528: } 529: } 530: if (overnext) 531: ScopeDsymbol::multiplyDefined(0, this, overnext); 532: if (s == this) 533: { 534: assert(global.errors); 535: s = NULL; 536: } 537: } 538: //printf("setting aliassym %s to %s %s\n", toChars(), s->kind(), s->toChars()); 539: aliassym = s; 540: this->inSemantic = 0; 541: } 542: 543: int AliasDeclaration::overloadInsert(Dsymbol *s) 544: { 545: /* Don't know yet what the aliased symbol is, so assume it can 546: * be overloaded and check later for correctness. 547: */ 548: 549: //printf("AliasDeclaration::overloadInsert('%s')\n", s->toChars()); 550: if (aliassym) // see test/test56.d 551: { 552: Dsymbol *a = aliassym->toAlias(); 553: FuncDeclaration *f = a->isFuncDeclaration(); 554: if (f) // BUG: what if it's a template? 555: { 556: FuncAliasDeclaration *fa = new FuncAliasDeclaration(f); 557: aliassym = fa; 558: return fa->overloadInsert(s); 559: } 560: } 561: 562: if (overnext == NULL) 563: { 564: if (s == this) 565: { 566: return TRUE; 567: } 568: overnext = s; 569: return TRUE; 570: } 571: else 572: { 573: return overnext->overloadInsert(s); 574: } 575: } 576: 577: const char *AliasDeclaration::kind() 578: { 579: return "alias"; 580: } 581: 582: Type *AliasDeclaration::getType() 583: { 584: return type; 585: } 586: 587: Dsymbol *AliasDeclaration::toAlias() 588: { 589: //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : ""); 590: assert(this != aliassym); 591: //static int count; if (++count == 10) *(char*)0=0; 592: if (inSemantic) 593: { error("recursive alias declaration"); 594: aliassym = new TypedefDeclaration(loc, ident, Type::terror, NULL); 595: type = Type::terror; 596: } 597: else if (!aliassym && scope) 598: semantic(scope); 599: Dsymbol *s = aliassym ? aliassym->toAlias() : this; 600: return s; 601: } 602: 603: void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 604: { 605: buf->writestring("alias "); 606: #if 0 607: if (hgs->hdrgen) 608: { 609: if (haliassym) 610: { 611: haliassym->toCBuffer(buf, hgs); 612: buf->writeByte(' '); 613: buf->writestring(ident->toChars()); 614: } 615: else 616: htype->toCBuffer(buf, ident, hgs); 617: } 618: else 619: #endif 620: { 621: if (aliassym) 622: { 623: aliassym->toCBuffer(buf, hgs); 624: buf->writeByte(' '); 625: buf->writestring(ident->toChars()); 626: } 627: else 628: type->toCBuffer(buf, ident, hgs); 629: } 630: buf->writeByte(';'); 631: buf->writenl(); 632: } 633: 634: /********************************* VarDeclaration ****************************/ 635: 636: VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer *init) 637: : Declaration(id) 638: { 639: //printf("VarDeclaration('%s')\n", id->toChars()); 640: #ifdef DEBUG 641: if (!type && !init) 642: { printf("VarDeclaration('%s')\n", id->toChars()); 643: //*(char*)0=0; 644: } 645: #endif 646: assert(type || init); 647: this->type = type; 648: this->init = init; 649: this->htype = NULL; 650: this->hinit = NULL; 651: this->loc = loc; 652: offset = 0; 653: noscope = 0; 654: #if DMDV2 655: isargptr = FALSE; 656: #endif 657: #if DMDV1 658: nestedref = 0; 659: #endif 660: ctorinit = 0; 661: aliassym = NULL; 662: onstack = 0; 663: canassign = 0; 664: setValueNull(); 665: #if DMDV2 666: rundtor = NULL; 667: edtor = NULL; 668: #endif 669: } 670: 671: Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) 672: { 673: //printf("VarDeclaration::syntaxCopy(%s)\n", toChars()); 674: 675: VarDeclaration *sv; 676: if (s) 677: { sv = (VarDeclaration *)s; 678: } 679: else 680: { 681: Initializer *init = NULL; 682: if (this->init) 683: { init = this->init->syntaxCopy(); 684: //init->isExpInitializer()->exp->print(); 685: //init->isExpInitializer()->exp->dump(0); 686: } 687: 688: sv = new VarDeclaration(loc, type ? type->syntaxCopy() : NULL, ident, init); 689: sv->storage_class = storage_class; 690: } 691: 692: // Syntax copy for header file 693: if (!htype) // Don't overwrite original 694: { if (type) // Make copy for both old and new instances 695: { htype = type->syntaxCopy(); 696: sv->htype = type->syntaxCopy(); 697: } 698: } 699: else // Make copy of original for new instance 700: sv->htype = htype->syntaxCopy(); 701: if (!hinit) 702: { if (init) 703: { hinit = init->syntaxCopy(); 704: sv->hinit = init->syntaxCopy(); 705: } 706: } 707: else 708: sv->hinit = hinit->syntaxCopy(); 709: 710: return sv; 711: } 712: 713: void VarDeclaration::semantic(Scope *sc) 714: { 715: #if 0 716: printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars()); 717: printf(" type = %s\n", type ? type->toChars() : "null"); 718: printf(" stc = x%x\n", sc->stc); 719: printf(" storage_class = x%x\n", storage_class); 720: printf("linkage = %d\n", sc->linkage); 721: //if (strcmp(toChars(), "mul") == 0) halt(); 722: #endif 723: 724: // if (sem > SemanticStart) 725: // return; 726: // sem = SemanticIn; 727: 728: if (scope) 729: { sc = scope; 730: scope = NULL; 731: } 732: 733: /* Pick up storage classes from context, but skip synchronized 734: */ 735: storage_class |= (sc->stc & ~STCsynchronized); 736: if (storage_class & STCextern && init) 737: error("extern symbols cannot have initializers"); 738: 739: AggregateDeclaration *ad = isThis(); 740: if (ad) 741: storage_class |= ad->storage_class & STC_TYPECTOR; 742: 743: /* If auto type inference, do the inference 744: */ 745: int inferred = 0; 746: if (!type) 747: { inuse++; 748: 749: ArrayInitializer *ai = init->isArrayInitializer(); 750: if (ai) 751: { Expression *e; 752: if (ai->isAssociativeArray()) 753: e = ai->toAssocArrayLiteral(); 754: else 755: e = init->toExpression(); 756: if (!e) 757: { 758: error("cannot infer type from initializer"); 759: e = new ErrorExp(); 760: } 761: init = new ExpInitializer(e->loc, e); 762: type = init->inferType(sc); 763: if (type->ty == Tsarray) 764: type = type->nextOf()->arrayOf(); 765: } 766: else 767: type = init->inferType(sc); 768: 769: //printf("test2: %s, %s, %s\n", toChars(), type->toChars(), type->deco); 770: // type = type->semantic(loc, sc); 771: 772: inuse--; 773: inferred = 1; 774: 775: if (init->isArrayInitializer() && type->toBasetype()->ty == Tsarray) 776: { // Prefer array literals to give a T[] type rather than a T[dim] 777: type = type->toBasetype()->nextOf()->arrayOf(); 778: } 779: 780: /* This is a kludge to support the existing syntax for RAII 781: * declarations. 782: */ 783: storage_class &= ~STCauto; 784: originalType = type; 785: } 786: else 787: { if (!originalType) 788: originalType = type; 789: type = type->semantic(loc, sc); 790: } 791: //printf(" semantic type = %s\n", type ? type->toChars() : "null"); 792: 793: type->checkDeprecated(loc, sc); 794: linkage = sc->linkage; 795: this->parent = sc->parent; 796: //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars()); 797: protection = sc->protection; 798: //printf("sc->stc = %x\n", sc->stc); 799: //printf("storage_class = x%x\n", storage_class); 800: 801: #if DMDV2 802: // Safety checks 803: if (sc->func && !sc->intypeof) 804: { 805: if (storage_class & STCgshared) 806: { 807: if (sc->func->setUnsafe()) 808: error("__gshared not allowed in safe functions; use shared"); 809: } 810: if (init && init->isVoidInitializer() && type->hasPointers()) 811: { 812: if (sc->func->setUnsafe()) 813: error("void initializers for pointers not allowed in safe functions"); 814: } 815: if (type->hasPointers() && type->toDsymbol(sc)) 816: { 817: Dsymbol *s = type->toDsymbol(sc); 818: if (s) 819: { 820: AggregateDeclaration *ad = s->isAggregateDeclaration();
warning C6246: Local declaration of 'ad' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '739' of 'c:\projects\extern\d\dmd\src\declaration.c': Lines: 739
821: if (ad && ad->hasUnions) 822: { 823: if (sc->func->setUnsafe()) 824: error("unions containing pointers are not allowed in @safe functions"); 825: } 826: } 827: } 828: } 829: #endif 830: 831: Dsymbol *parent = toParent(); 832: FuncDeclaration *fd = parent->isFuncDeclaration(); 833: 834: Type *tb = type->toBasetype(); 835: if (tb->ty == Tvoid && !(storage_class & STClazy)) 836: { error("voids have no value"); 837: type = Type::terror; 838: tb = type; 839: } 840: if (tb->ty == Tfunction) 841: { error("cannot be declared to be a function"); 842: type = Type::terror; 843: tb = type; 844: } 845: if (tb->ty == Tstruct) 846: { TypeStruct *ts = (TypeStruct *)tb; 847: 848: if (!ts->sym->members) 849: { 850: error("no definition of struct %s", ts->toChars()); 851: } 852: } 853: if ((storage_class & STCauto) && !inferred) 854: error("storage class 'auto' has no effect if type is not inferred, did you mean 'scope'?"); 855: 856: if (tb->ty == Ttuple) 857: { /* Instead, declare variables for each of the tuple elements 858: * and add those. 859: */ 860: TypeTuple *tt = (TypeTuple *)tb; 861: size_t nelems = Parameter::dim(tt->arguments); 862: Objects *exps = new Objects(); 863: exps->setDim(nelems); 864: Expression *ie = init ? init->toExpression() : NULL; 865: 866: for (size_t i = 0; i < nelems; i++) 867: { Parameter *arg = Parameter::getNth(tt->arguments, i); 868: 869: OutBuffer buf; 870: buf.printf("_%s_field_%"SIZE_T_FORMAT"u", ident->toChars(), i); 871: buf.writeByte(0); 872: const char *name = (const char *)buf.extractData(); 873: Identifier *id = Lexer::idPool(name); 874: 875: Expression *einit = ie; 876: if (ie && ie->op == TOKtuple) 877: { einit = ((TupleExp *)ie)->exps->tdata()[i]; 878: } 879: Initializer *ti = init; 880: if (einit) 881: { ti = new ExpInitializer(einit->loc, einit); 882: } 883: 884: VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti); 885: //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars()); 886: v->semantic(sc); 887: 888: if (sc->scopesym) 889: { //printf("adding %s to %s\n", v->toChars(), sc->scopesym->toChars()); 890: if (sc->scopesym->members) 891: sc->scopesym->members->push(v); 892: } 893: 894: Expression *e = new DsymbolExp(loc, v); 895: exps->tdata()[i] = e; 896: } 897: TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps); 898: v2->isexp = 1; 899: aliassym = v2; 900: return; 901: } 902: 903: Lagain:
warning C4102: 'Lagain' : unreferenced label
904: /* Storage class can modify the type 905: */ 906: type = type->addStorageClass(storage_class); 907: 908: /* Adjust storage class to reflect type 909: */ 910: if (type->isConst()) 911: { storage_class |= STCconst; 912: if (type->isShared()) 913: storage_class |= STCshared; 914: } 915: else if (type->isImmutable()) 916: storage_class |= STCimmutable; 917: else if (type->isShared()) 918: storage_class |= STCshared; 919: else if (type->isWild()) 920: storage_class |= STCwild; 921: 922: if (isSynchronized()) 923: { 924: error("variable %s cannot be synchronized", toChars()); 925: } 926: else if (isOverride()) 927: { 928: error("override cannot be applied to variable"); 929: } 930: else if (isAbstract()) 931: { 932: error("abstract cannot be applied to variable"); 933: } 934: else if (storage_class & STCfinal) 935: { 936: error("final cannot be applied to variable"); 937: } 938: 939: if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter | STCtls | STCgshared | STCctfe)) 940: { 941: } 942: else 943: { 944: AggregateDeclaration *aad = sc->anonAgg; 945: if (!aad) 946: aad = parent->isAggregateDeclaration(); 947: if (aad) 948: { 949: #if DMDV2 950: assert(!(storage_class & (STCextern | STCstatic | STCtls | STCgshared))); 951: 952: if (storage_class & (STCconst | STCimmutable) && init) 953: { 954: if (!tb->isTypeBasic()) 955: storage_class |= STCstatic; 956: } 957: else 958: { 959: aad->addField(sc, this); 960: if (tb->ty == Tstruct && ((TypeStruct *)tb)->sym->noDefaultCtor || 961: tb->ty == Tclass && ((TypeClass *)tb)->sym->noDefaultCtor) 962: aad->noDefaultCtor = TRUE; 963: } 964: #else 965: aad->addField(sc, this); 966: #endif 967: } 968: 969: InterfaceDeclaration *id = parent->isInterfaceDeclaration(); 970: if (id) 971: { 972: error("field not allowed in interface"); 973: } 974: 975: /* Templates cannot add fields to aggregates 976: */ 977: TemplateInstance *ti = parent->isTemplateInstance(); 978: if (ti) 979: { 980: // Take care of nested templates 981: while (1) 982: { 983: TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance(); 984: if (!ti2) 985: break; 986: ti = ti2; 987: } 988: 989: // If it's a member template 990: AggregateDeclaration *ad = ti->tempdecl->isMember();
warning C6246: Local declaration of 'ad' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '739' of 'c:\projects\extern\d\dmd\src\declaration.c': Lines: 739
991: if (ad && storage_class != STCundefined) 992: { 993: error("cannot use template to add field to aggregate '%s'", ad->toChars()); 994: } 995: } 996: } 997: 998: #if DMDV2 999: if ((storage_class & (STCref | STCparameter | STCforeach)) == STCref && 1000: ident != Id::This) 1001: { 1002: error("only parameters or foreach declarations can be ref"); 1003: } 1004: 1005: if ((storage_class & (STCstatic | STCextern | STCtls | STCgshared | STCmanifest) || 1006: isDataseg()) && 1007: type->hasWild()) 1008: { 1009: error("only fields, parameters or stack based variables can be inout"); 1010: } 1011: 1012: if (!(storage_class & (STCfield | STCctfe)) && tb->ty == Tstruct && 1013: ((TypeStruct *)tb)->sym->noDefaultCtor) 1014: { 1015: if (!init) 1016: error("initializer required for type %s", type->toChars()); 1017: } 1018: #endif 1019: 1020: if (type->isscope() && !noscope) 1021: { 1022: if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls | STCgshared) || !fd) 1023: { 1024: error("globals, statics, fields, manifest constants, ref and out parameters cannot be scope"); 1025: } 1026: 1027: if (!(storage_class & STCscope)) 1028: { 1029: if (!(storage_class & STCparameter) && ident != Id::withSym) 1030: error("reference to scope class must be scope"); 1031: } 1032: } 1033: 1034: if (!init && !fd) 1035: { // If not mutable, initializable by constructor only 1036: storage_class |= STCctorinit; 1037: } 1038: 1039: if (init) 1040: storage_class |= STCinit; // remember we had an explicit initializer 1041: else if (storage_class & STCmanifest) 1042: error("manifest constants must have initializers"); 1043: 1044: enum TOK op = TOKconstruct; 1045: if (!init && !sc->inunion && !isStatic() && fd && 1046: (!(storage_class & (STCfield | STCin | STCforeach | STCparameter | STCresult)) 1047: || (storage_class & STCout)) && 1048: type->size() != 0) 1049: { 1050: // Provide a default initializer 1051: //printf("Providing default initializer for '%s'\n", toChars()); 1052: if (type->ty == Tstruct && 1053: ((TypeStruct *)type)->sym->zeroInit == 1) 1054: { /* If a struct is all zeros, as a special case 1055: * set it's initializer to the integer 0. 1056: * In AssignExp::toElem(), we check for this and issue 1057: * a memset() to initialize the struct. 1058: * Must do same check in interpreter. 1059: */ 1060: Expression *e = new IntegerExp(loc, 0, Type::tint32); 1061: Expression *e1; 1062: e1 = new VarExp(loc, this); 1063: e = new ConstructExp(loc, e1, e); 1064: e->type = e1->type; // don't type check this, it would fail 1065: init = new ExpInitializer(loc, e); 1066: goto Ldtor; 1067: } 1068: else if (type->ty == Ttypedef) 1069: { TypeTypedef *td = (TypeTypedef *)type; 1070: if (td->sym->init) 1071: { init = td->sym->init; 1072: ExpInitializer *ie = init->isExpInitializer(); 1073: if (ie) 1074: // Make copy so we can modify it 1075: init = new ExpInitializer(ie->loc, ie->exp); 1076: } 1077: else 1078: init = getExpInitializer(); 1079: } 1080: else 1081: { 1082: init = getExpInitializer(); 1083: } 1084: // Default initializer is always a blit 1085: op = TOKblit; 1086: } 1087: 1088: if (init) 1089: { 1090: sc = sc->push(); 1091: sc->stc &= ~(STC_TYPECTOR | STCpure | STCnothrow | STCref | STCdisable); 1092: 1093: ArrayInitializer *ai = init->isArrayInitializer(); 1094: if (ai && tb->ty == Taarray) 1095: { 1096: Expression *e = ai->toAssocArrayLiteral(); 1097: init = new ExpInitializer(e->loc, e); 1098: } 1099: 1100: StructInitializer *si = init->isStructInitializer(); 1101: ExpInitializer *ei = init->isExpInitializer(); 1102: 1103: // See if initializer is a NewExp that can be allocated on the stack 1104: if (ei && isScope() && ei->exp->op == TOKnew) 1105: { NewExp *ne = (NewExp *)ei->exp; 1106: if (!(ne->newargs && ne->newargs->dim)) 1107: { ne->onstack = 1; 1108: onstack = 1; 1109: if (type->isBaseOf(ne->newtype->semantic(loc, sc), NULL)) 1110: onstack = 2; 1111: } 1112: } 1113: 1114: // If inside function, there is no semantic3() call 1115: if (sc->func) 1116: { 1117: // If local variable, use AssignExp to handle all the various 1118: // possibilities. 1119: if (fd && 1120: !(storage_class & (STCmanifest | STCstatic | STCtls | STCgshared | STCextern)) && 1121: !init->isVoidInitializer()) 1122: { 1123: //printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars()); 1124: if (!ei) 1125: { 1126: Expression *e = init->toExpression(); 1127: if (!e) 1128: { 1129: init = init->semantic(sc, type, 0); // Don't need to interpret 1130: e = init->toExpression(); 1131: if (!e) 1132: { error("is not a static and cannot have static initializer"); 1133: return; 1134: } 1135: } 1136: ei = new ExpInitializer(init->loc, e); 1137: init = ei; 1138: } 1139: 1140: Expression *e1 = new VarExp(loc, this); 1141: 1142: Type *t = type->toBasetype(); 1143: 1144: Linit2: 1145: if (t->ty == Tsarray && !(storage_class & (STCref | STCout))) 1146: { 1147: ei->exp = ei->exp->semantic(sc); 1148: if (!ei->exp->implicitConvTo(type)) 1149: { 1150: int dim = ((TypeSArray *)t)->dim->toInteger();
warning C4244: 'initializing' : conversion from 'dinteger_t' to 'int', possible loss of data
1151: // If multidimensional static array, treat as one large array 1152: while (1) 1153: { 1154: t = t->nextOf()->toBasetype(); 1155: if (t->ty != Tsarray) 1156: break; 1157: dim *= ((TypeSArray *)t)->dim->toInteger();
warning C4244: '*=' : conversion from 'dinteger_t' to 'int', possible loss of data
1158: e1->type = new TypeSArray(t->nextOf(), new IntegerExp(0, dim, Type::tindex)); 1159: } 1160: } 1161: e1 = new SliceExp(loc, e1, NULL, NULL); 1162: } 1163: else if (t->ty == Tstruct) 1164: { 1165: ei->exp = ei->exp->semantic(sc); 1166: ei->exp = resolveProperties(sc, ei->exp); 1167: StructDeclaration *sd = ((TypeStruct *)t)->sym; 1168: #if DMDV2 1169: Expression** pinit = &ei->exp; 1170: while ((*pinit)->op == TOKcomma) 1171: { 1172: pinit = &((CommaExp *)*pinit)->e2; 1173: } 1174: 1175: /* Look to see if initializer is a call to the constructor 1176: */ 1177: if (sd->ctor && // there are constructors 1178: (*pinit)->type->ty == Tstruct && // rvalue is the same struct 1179: ((TypeStruct *)(*pinit)->type)->sym == sd && 1180: (*pinit)->op == TOKcall) 1181: { 1182: /* Look for form of constructor call which is: 1183: * *__ctmp.ctor(arguments...) 1184: */ 1185: if (1) 1186: { CallExp *ce = (CallExp *)(*pinit); 1187: if (ce->e1->op == TOKdotvar) 1188: { DotVarExp *dve = (DotVarExp *)ce->e1; 1189: if (dve->var->isCtorDeclaration()) 1190: { /* It's a constructor call, currently constructing 1191: * a temporary __ctmp. 1192: */ 1193: /* Before calling the constructor, initialize 1194: * variable with a bit copy of the default 1195: * initializer 1196: */ 1197: Expression *e; 1198: if (sd->zeroInit == 1) 1199: { 1200: e = new ConstructExp(loc, new VarExp(loc, this), new IntegerExp(loc, 0, Type::tint32)); 1201: } 1202: else 1203: { e = new AssignExp(loc, new VarExp(loc, this), t->defaultInit(loc)); 1204: e->op = TOKblit; 1205: } 1206: e->type = t; 1207: (*pinit) = new CommaExp(loc, e, (*pinit)); 1208: 1209: /* Replace __ctmp being constructed with e1 1210: */ 1211: dve->e1 = e1; 1212: (*pinit) = (*pinit)->semantic(sc); 1213: goto Ldtor; 1214: } 1215: } 1216: } 1217: } 1218: 1219: /* Look for ((S tmp = S()),tmp) and replace it with just S() 1220: */ 1221: Expression *e2 = ei->exp->isTemp(); 1222: if (e2) 1223: { 1224: ei->exp = e2; 1225: goto Linit2; 1226: } 1227: #endif 1228: if (!ei->exp->implicitConvTo(type)) 1229: { 1230: Type *ti = ei->exp->type->toBasetype(); 1231: // Look for constructor first 1232: if (sd->ctor && 1233: /* Initializing with the same type is done differently 1234: */ 1235: !(ti->ty == Tstruct && t->toDsymbol(sc) == ti->toDsymbol(sc))) 1236: { 1237: // Rewrite as e1.ctor(arguments) 1238: Expression *ector = new DotIdExp(loc, e1, Id::ctor); 1239: ei->exp = new CallExp(loc, ector, ei->exp); 1240: /* Before calling the constructor, initialize 1241: * variable with a bit copy of the default 1242: * initializer 1243: */ 1244: Expression *e = new AssignExp(loc, e1, t->defaultInit(loc)); 1245: e->op = TOKblit; 1246: e->type = t; 1247: ei->exp = new CommaExp(loc, e, ei->exp); 1248: } 1249: else 1250: /* Look for opCall 1251: * See bugzilla 2702 for more discussion 1252: */ 1253: // Don't cast away invariant or mutability in initializer 1254: if (search_function(sd, Id::call) && 1255: /* Initializing with the same type is done differently 1256: */ 1257: !(ti->ty == Tstruct && t->toDsymbol(sc) == ti->toDsymbol(sc))) 1258: { // Rewrite as e1.call(arguments) 1259: Expression * eCall = new DotIdExp(loc, e1, Id::call); 1260: ei->exp = new CallExp(loc, eCall, ei->exp); 1261: } 1262: } 1263: } 1264: ei->exp = new AssignExp(loc, e1, ei->exp); 1265: ei->exp->op = op; 1266: canassign++; 1267: ei->exp = ei->exp->semantic(sc); 1268: canassign--; 1269: ei->exp->optimize(WANTvalue); 1270: } 1271: else 1272: { 1273: init = init->semantic(sc, type, WANTinterpret); 1274: } 1275: } 1276: else if (storage_class & (STCconst | STCimmutable | STCmanifest) || 1277: type->isConst() || type->isImmutable() || 1278: parent->isAggregateDeclaration()) 1279: { 1280: /* Because we may need the results of a const declaration in a 1281: * subsequent type, such as an array dimension, before semantic2() 1282: * gets ordinarily run, try to run semantic2() now. 1283: * Ignore failure. 1284: */ 1285: 1286: if (!global.errors && !inferred) 1287: { 1288: unsigned errors = global.errors; 1289: global.gag++; 1290: //printf("+gag\n"); 1291: Expression *e; 1292: Initializer *i2 = init; 1293: inuse++; 1294: if (ei) 1295: { 1296: e = ei->exp->syntaxCopy(); 1297: e = e->semantic(sc); 1298: e = resolveProperties(sc, e); 1299: #if DMDV2 1300: /* The problem is the following code: 1301: * struct CopyTest { 1302: * double x; 1303: * this(double a) { x = a * 10.0;} 1304: * this(this) { x += 2.0; } 1305: * } 1306: * const CopyTest z = CopyTest(5.3); // ok 1307: * const CopyTest w = z; // not ok, postblit not run 1308: * static assert(w.x == 55.0); 1309: * because the postblit doesn't get run on the initialization of w. 1310: */ 1311: 1312: Type *tb = e->type->toBasetype();
warning C6246: Local declaration of 'tb' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '834' of 'c:\projects\extern\d\dmd\src\declaration.c': Lines: 834
1313: if (tb->ty == Tstruct) 1314: { StructDeclaration *sd = ((TypeStruct *)tb)->sym; 1315: Type *typeb = type->toBasetype(); 1316: /* Look to see if initializer involves a copy constructor 1317: * (which implies a postblit) 1318: */ 1319: if (sd->cpctor && // there is a copy constructor 1320: typeb->equals(tb)) // rvalue is the same struct 1321: { 1322: // The only allowable initializer is a (non-copy) constructor 1323: if (e->op == TOKcall) 1324: { 1325: CallExp *ce = (CallExp *)e; 1326: if (ce->e1->op == TOKdotvar) 1327: { 1328: DotVarExp *dve = (DotVarExp *)ce->e1; 1329: if (dve->var->isCtorDeclaration()) 1330: goto LNoCopyConstruction; 1331: } 1332: } 1333: global.gag--; 1334: error("of type struct %s uses this(this), which is not allowed in static initialization", typeb->toChars()); 1335: global.gag++; 1336: 1337: LNoCopyConstruction: 1338: ; 1339: } 1340: } 1341: #endif 1342: e = e->implicitCastTo(sc, type); 1343: } 1344: else if (si || ai) 1345: { i2 = init->syntaxCopy(); 1346: i2 = i2->semantic(sc, type, WANTinterpret); 1347: } 1348: inuse--; 1349: global.gag--; 1350: //printf("-gag\n"); 1351: if (errors != global.errors) // if errors happened 1352: { 1353: if (global.gag == 0) 1354: global.errors = errors; // act as if nothing happened 1355: #if DMDV2 1356: /* Save scope for later use, to try again 1357: */ 1358: scope = new Scope(*sc); 1359: scope->setNoFree(); 1360: #endif 1361: } 1362: else if (ei) 1363: { 1364: if (isDataseg() || (storage_class & STCmanifest)) 1365: e = e->optimize(WANTvalue | WANTinterpret); 1366: else 1367: e = e->optimize(WANTvalue); 1368: switch (e->op) 1369: { 1370: case TOKint64: 1371: case TOKfloat64: 1372: case TOKstring: 1373: case TOKarrayliteral: 1374: case TOKassocarrayliteral: 1375: case TOKstructliteral: 1376: case TOKnull: 1377: ei->exp = e; // no errors, keep result 1378: break; 1379: 1380: default: 1381: #if DMDV2 1382: /* Save scope for later use, to try again 1383: */ 1384: scope = new Scope(*sc); 1385: scope->setNoFree(); 1386: #endif 1387: break; 1388: } 1389: } 1390: else 1391: init = i2; // no errors, keep result 1392: } 1393: } 1394: sc = sc->pop(); 1395: } 1396: 1397: Ldtor: 1398: /* Build code to execute destruction, if necessary 1399: */ 1400: edtor = callScopeDtor(sc); 1401: if (edtor) 1402: { 1403: edtor = edtor->semantic(sc); 1404: 1405: #if 0 // currently disabled because of std.stdio.stdin, stdout and stderr 1406: if (isDataseg() && !(storage_class & STCextern)) 1407: error("static storage variables cannot have destructors"); 1408: #endif 1409: } 1410: 1411: sem = SemanticDone; 1412: } 1413: 1414: void VarDeclaration::semantic2(Scope *sc) 1415: { 1416: //printf("VarDeclaration::semantic2('%s')\n", toChars()); 1417: if (init && !toParent()->isFuncDeclaration()) 1418: { inuse++; 1419: #if 0 1420: ExpInitializer *ei = init->isExpInitializer(); 1421: if (ei) 1422: { 1423: ei->exp->dump(0); 1424: printf("type = %p\n", ei->exp->type); 1425: } 1426: #endif 1427: init = init->semantic(sc, type, WANTinterpret); 1428: inuse--; 1429: } 1430: sem = Semantic2Done; 1431: } 1432: 1433: const char *VarDeclaration::kind() 1434: { 1435: return "variable"; 1436: } 1437: 1438: Dsymbol *VarDeclaration::toAlias() 1439: { 1440: //printf("VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\n", toChars(), this, aliassym); 1441: assert(this != aliassym); 1442: Dsymbol *s = aliassym ? aliassym->toAlias() : this; 1443: return s; 1444: } 1445: 1446: void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 1447: { 1448: StorageClassDeclaration::stcToCBuffer(buf, storage_class); 1449: 1450: /* If changing, be sure and fix CompoundDeclarationStatement::toCBuffer() 1451: * too. 1452: */ 1453: if (type) 1454: type->toCBuffer(buf, ident, hgs); 1455: else 1456: buf->writestring(ident->toChars()); 1457: if (init) 1458: { buf->writestring(" = "); 1459: #if DMDV2 1460: ExpInitializer *ie = init->isExpInitializer(); 1461: if (ie && (ie->exp->op == TOKconstruct || ie->exp->op == TOKblit)) 1462: ((AssignExp *)ie->exp)->e2->toCBuffer(buf, hgs); 1463: else 1464: #endif 1465: init->toCBuffer(buf, hgs); 1466: } 1467: buf->writeByte(';'); 1468: buf->writenl(); 1469: } 1470: 1471: AggregateDeclaration *VarDeclaration::isThis() 1472: { 1473: AggregateDeclaration *ad = NULL; 1474: 1475: if (!(storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter | 1476: STCtls | STCgshared | STCctfe))) 1477: { 1478: if ((storage_class & (STCconst | STCimmutable | STCwild)) && init) 1479: return NULL; 1480: 1481: for (Dsymbol *s = this; s; s = s->parent) 1482: { 1483: ad = s->isMember(); 1484: if (ad) 1485: break; 1486: if (!s->parent || !s->parent->isTemplateMixin()) break; 1487: } 1488: } 1489: return ad; 1490: } 1491: 1492: int VarDeclaration::needThis() 1493: { 1494: //printf("VarDeclaration::needThis(%s, x%x)\n", toChars(), storage_class); 1495: return storage_class & STCfield; 1496: } 1497: 1498: int VarDeclaration::isImportedSymbol() 1499: { 1500: if (protection == PROTexport && !init && 1501: (storage_class & STCstatic || parent->isModule())) 1502: return TRUE; 1503: return FALSE; 1504: } 1505: 1506: void VarDeclaration::checkCtorConstInit() 1507: { 1508: #if 0 /* doesn't work if more than one static ctor */ 1509: if (ctorinit == 0 && isCtorinit() && !(storage_class & STCfield)) 1510: error("missing initializer in static constructor for const variable"); 1511: #endif 1512: } 1513: 1514: /************************************ 1515: * Check to see if this variable is actually in an enclosing function 1516: * rather than the current one. 1517: */ 1518: 1519: void VarDeclaration::checkNestedReference(Scope *sc, Loc loc) 1520: { 1521: //printf("VarDeclaration::checkNestedReference() %s\n", toChars()); 1522: if (parent && !isDataseg() && parent != sc->parent && 1523: !(storage_class & STCmanifest)) 1524: { 1525: // The function that this variable is in 1526: FuncDeclaration *fdv = toParent()->isFuncDeclaration(); 1527: // The current function 1528: FuncDeclaration *fdthis = sc->parent->isFuncDeclaration(); 1529: 1530: if (fdv && fdthis && fdv != fdthis) 1531: { 1532: if (loc.filename) 1533: fdthis->getLevel(loc, fdv); 1534: 1535: for (int i = 0; i < nestedrefs.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
1536: { FuncDeclaration *f = nestedrefs.tdata()[i]; 1537: if (f == fdthis) 1538: goto L1; 1539: } 1540: nestedrefs.push(fdthis); 1541: L1: ; 1542: 1543: 1544: for (int i = 0; i < fdv->closureVars.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
1545: { Dsymbol *s = fdv->closureVars.tdata()[i]; 1546: if (s == this) 1547: goto L2; 1548: } 1549: 1550: fdv->closureVars.push(this); 1551: L2: ; 1552: 1553: //printf("fdthis is %s\n", fdthis->toChars()); 1554: //printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars()); 1555: // __dollar creates problems because it isn't a real variable Bugzilla 3326 1556: if (ident == Id::dollar) 1557: ::error(loc, "cannnot use $ inside a function literal"); 1558: } 1559: } 1560: } 1561: 1562: /**************************** 1563: * Get ExpInitializer for a variable, if there is one. 1564: */ 1565: 1566: ExpInitializer *VarDeclaration::getExpInitializer() 1567: { 1568: ExpInitializer *ei; 1569: 1570: if (init) 1571: ei = init->isExpInitializer(); 1572: else 1573: { 1574: Expression *e = type->defaultInit(loc); 1575: if (e) 1576: ei = new ExpInitializer(loc, e); 1577: else 1578: ei = NULL; 1579: } 1580: return ei; 1581: } 1582: 1583: /******************************************* 1584: * If variable has a constant expression initializer, get it. 1585: * Otherwise, return NULL. 1586: */ 1587: 1588: Expression *VarDeclaration::getConstInitializer() 1589: { 1590: if ((isConst() || isImmutable() || storage_class & STCmanifest) && 1591: storage_class & STCinit) 1592: { 1593: ExpInitializer *ei = getExpInitializer(); 1594: if (ei) 1595: return ei->exp; 1596: } 1597: 1598: return NULL; 1599: } 1600: 1601: /************************************* 1602: * Return !=0 if we can take the address of this variable. 1603: */ 1604: 1605: int VarDeclaration::canTakeAddressOf() 1606: { 1607: #if 0 1608: /* Global variables and struct/class fields of the form: 1609: * const int x = 3; 1610: * are not stored and hence cannot have their address taken. 1611: */ 1612: if ((isConst() || isImmutable()) && 1613: storage_class & STCinit && 1614: (!(storage_class & (STCstatic | STCextern)) || (storage_class & STCfield)) && 1615: (!parent || toParent()->isModule() || toParent()->isTemplateInstance()) && 1616: type->toBasetype()->isTypeBasic() 1617: ) 1618: { 1619: return 0; 1620: } 1621: #else 1622: if (storage_class & STCmanifest) 1623: return 0; 1624: #endif 1625: return 1; 1626: } 1627: 1628: 1629: /******************************* 1630: * Does symbol go into data segment? 1631: * Includes extern variables. 1632: */ 1633: 1634: int VarDeclaration::isDataseg() 1635: { 1636: #if 0 1637: printf("VarDeclaration::isDataseg(%p, '%s')\n", this, toChars()); 1638: printf("%llx, isModule: %p, isTemplateInstance: %p\n", storage_class & (STCstatic | STCconst), parent->isModule(), parent->isTemplateInstance()); 1639: printf("parent = '%s'\n", parent->toChars()); 1640: #endif 1641: if (storage_class & STCmanifest) 1642: return 0; 1643: Dsymbol *parent = this->toParent(); 1644: if (!parent && !(storage_class & STCstatic)) 1645: { error("forward referenced"); 1646: type = Type::terror; 1647: return 0; 1648: } 1649: return canTakeAddressOf() && 1650: (storage_class & (STCstatic | STCextern | STCtls | STCgshared) || 1651: toParent()->isModule() || 1652: toParent()->isTemplateInstance()); 1653: } 1654: 1655: /************************************ 1656: * Does symbol go into thread local storage? 1657: */ 1658: 1659: int VarDeclaration::isThreadlocal() 1660: { 1661: //printf("VarDeclaration::isThreadlocal(%p, '%s')\n", this, toChars()); 1662: #if 0 //|| TARGET_OSX 1663: /* To be thread-local, must use the __thread storage class. 1664: * BUG: OSX doesn't support thread local yet. 1665: */ 1666: return isDataseg() && 1667: (storage_class & (STCtls | STCconst | STCimmutable | STCshared | STCgshared)) == STCtls; 1668: #else 1669: /* Data defaults to being thread-local. It is not thread-local 1670: * if it is immutable, const or shared. 1671: */ 1672: int i = isDataseg() && 1673: !(storage_class & (STCimmutable | STCconst | STCshared | STCgshared)); 1674: //printf("\treturn %d\n", i); 1675: return i; 1676: #endif 1677: } 1678: 1679: /******************************************** 1680: * Can variable be read and written by CTFE? 1681: */ 1682: 1683: int VarDeclaration::isCTFE() 1684: { 1685: return (storage_class & STCctfe) != 0; // || !isDataseg(); 1686: } 1687: 1688: int VarDeclaration::hasPointers() 1689: { 1690: //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty); 1691: return (!isDataseg() && type->hasPointers()); 1692: } 1693: 1694: /****************************************** 1695: * Return TRUE if variable needs to call the destructor. 1696: */ 1697: 1698: int VarDeclaration::needsAutoDtor() 1699: { 1700: //printf("VarDeclaration::needsAutoDtor() %s\n", toChars()); 1701: 1702: if (noscope || !edtor) 1703: return FALSE; 1704: 1705: return TRUE; 1706: } 1707: 1708: 1709: /****************************************** 1710: * If a variable has a scope destructor call, return call for it. 1711: * Otherwise, return NULL. 1712: */ 1713: 1714: Expression *VarDeclaration::callScopeDtor(Scope *sc) 1715: { Expression *e = NULL; 1716: 1717: //printf("VarDeclaration::callScopeDtor() %s\n", toChars()); 1718: 1719: // Destruction of STCfield's is handled by buildDtor() 1720: if (noscope || storage_class & (STCnodtor | STCref | STCout | STCfield)) 1721: { 1722: return NULL; 1723: } 1724: 1725: // Destructors for structs and arrays of structs 1726: bool array = false; 1727: Type *tv = type->toBasetype(); 1728: while (tv->ty == Tsarray) 1729: { TypeSArray *ta = (TypeSArray *)tv; 1730: array = true; 1731: tv = tv->nextOf()->toBasetype(); 1732: } 1733: if (tv->ty == Tstruct) 1734: { TypeStruct *ts = (TypeStruct *)tv; 1735: StructDeclaration *sd = ts->sym; 1736: if (sd->dtor) 1737: { 1738: if (array) 1739: { 1740: // Typeinfo.destroy(cast(void*)&v); 1741: Expression *ea = new SymOffExp(loc, this, 0, 0); 1742: ea = new CastExp(loc, ea, Type::tvoid->pointerTo()); 1743: Expressions *args = new Expressions(); 1744: args->push(ea); 1745: 1746: Expression *et = type->getTypeInfo(sc); 1747: et = new DotIdExp(loc, et, Id::destroy); 1748: 1749: e = new CallExp(loc, et, args); 1750: } 1751: else 1752: { 1753: e = new VarExp(loc, this); 1754: /* This is a hack so we can call destructors on const/immutable objects. 1755: * Need to add things like "const ~this()" and "immutable ~this()" to 1756: * fix properly. 1757: */ 1758: e->type = e->type->mutableOf(); 1759: e = new DotVarExp(loc, e, sd->dtor, 0); 1760: e = new CallExp(loc, e); 1761: } 1762: return e; 1763: } 1764: } 1765: 1766: // Destructors for classes 1767: if (storage_class & (STCauto | STCscope)) 1768: { 1769: for (ClassDeclaration *cd = type->isClassHandle(); 1770: cd; 1771: cd = cd->baseClass) 1772: { 1773: /* We can do better if there's a way with onstack 1774: * classes to determine if there's no way the monitor 1775: * could be set. 1776: */ 1777: //if (cd->isInterfaceDeclaration()) 1778: //error("interface %s cannot be scope", cd->toChars()); 1779: if (1 || onstack || cd->dtors.dim) // if any destructors
warning C6235: (<non-zero constant> || <expression>) is always a non-zero constant
1780: { 1781: // delete this; 1782: Expression *ec; 1783: 1784: ec = new VarExp(loc, this); 1785: e = new DeleteExp(loc, ec); 1786: e->type = Type::tvoid; 1787: break; 1788: } 1789: } 1790: } 1791: return e; 1792: } 1793: 1794: 1795: /********************************* ClassInfoDeclaration ****************************/ 1796: 1797: ClassInfoDeclaration::ClassInfoDeclaration(ClassDeclaration *cd) 1798: : VarDeclaration(0, ClassDeclaration::classinfo->type, cd->ident, NULL) 1799: { 1800: this->cd = cd; 1801: storage_class = STCstatic | STCgshared; 1802: } 1803: 1804: Dsymbol *ClassInfoDeclaration::syntaxCopy(Dsymbol *s) 1805: { 1806: assert(0); // should never be produced by syntax 1807: return NULL; 1808: } 1809: 1810: void ClassInfoDeclaration::semantic(Scope *sc) 1811: { 1812: } 1813: 1814: /********************************* ModuleInfoDeclaration ****************************/ 1815: 1816: ModuleInfoDeclaration::ModuleInfoDeclaration(Module *mod) 1817: : VarDeclaration(0, Module::moduleinfo->type, mod->ident, NULL) 1818: { 1819: this->mod = mod; 1820: storage_class = STCstatic | STCgshared; 1821: } 1822: 1823: Dsymbol *ModuleInfoDeclaration::syntaxCopy(Dsymbol *s) 1824: { 1825: assert(0); // should never be produced by syntax 1826: return NULL; 1827: } 1828: 1829: void ModuleInfoDeclaration::semantic(Scope *sc) 1830: { 1831: } 1832: 1833: /********************************* TypeInfoDeclaration ****************************/ 1834: 1835: TypeInfoDeclaration::TypeInfoDeclaration(Type *tinfo, int internal) 1836: : VarDeclaration(0, Type::typeinfo->type, tinfo->getTypeInfoIdent(internal), NULL) 1837: { 1838: this->tinfo = tinfo; 1839: storage_class = STCstatic | STCgshared; 1840: protection = PROTpublic; 1841: linkage = LINKc; 1842: } 1843: 1844: Dsymbol *TypeInfoDeclaration::syntaxCopy(Dsymbol *s) 1845: { 1846: assert(0); // should never be produced by syntax 1847: return NULL; 1848: } 1849: 1850: void TypeInfoDeclaration::semantic(Scope *sc) 1851: { 1852: assert(linkage == LINKc); 1853: } 1854: 1855: /***************************** TypeInfoConstDeclaration **********************/ 1856: 1857: #if DMDV2 1858: TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo) 1859: : TypeInfoDeclaration(tinfo, 0) 1860: { 1861: type = Type::typeinfoconst->type; 1862: } 1863: #endif 1864: 1865: /***************************** TypeInfoInvariantDeclaration **********************/ 1866: 1867: #if DMDV2 1868: TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo) 1869: : TypeInfoDeclaration(tinfo, 0) 1870: { 1871: type = Type::typeinfoinvariant->type; 1872: } 1873: #endif 1874: 1875: /***************************** TypeInfoSharedDeclaration **********************/ 1876: 1877: #if DMDV2 1878: TypeInfoSharedDeclaration::TypeInfoSharedDeclaration(Type *tinfo) 1879: : TypeInfoDeclaration(tinfo, 0) 1880: { 1881: type = Type::typeinfoshared->type; 1882: } 1883: #endif 1884: 1885: /***************************** TypeInfoWildDeclaration **********************/ 1886: 1887: #if DMDV2 1888: TypeInfoWildDeclaration::TypeInfoWildDeclaration(Type *tinfo) 1889: : TypeInfoDeclaration(tinfo, 0) 1890: { 1891: type = Type::typeinfowild->type; 1892: } 1893: #endif 1894: 1895: /***************************** TypeInfoStructDeclaration **********************/ 1896: 1897: TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo) 1898: : TypeInfoDeclaration(tinfo, 0) 1899: { 1900: type = Type::typeinfostruct->type; 1901: } 1902: 1903: /***************************** TypeInfoClassDeclaration ***********************/ 1904: 1905: TypeInfoClassDeclaration::TypeInfoClassDeclaration(Type *tinfo) 1906: : TypeInfoDeclaration(tinfo, 0) 1907: { 1908: type = Type::typeinfoclass->type; 1909: } 1910: 1911: /***************************** TypeInfoInterfaceDeclaration *******************/ 1912: 1913: TypeInfoInterfaceDeclaration::TypeInfoInterfaceDeclaration(Type *tinfo) 1914: : TypeInfoDeclaration(tinfo, 0) 1915: { 1916: type = Type::typeinfointerface->type; 1917: } 1918: 1919: /***************************** TypeInfoTypedefDeclaration *********************/ 1920: 1921: TypeInfoTypedefDeclaration::TypeInfoTypedefDeclaration(Type *tinfo) 1922: : TypeInfoDeclaration(tinfo, 0) 1923: { 1924: type = Type::typeinfotypedef->type; 1925: } 1926: 1927: /***************************** TypeInfoPointerDeclaration *********************/ 1928: 1929: TypeInfoPointerDeclaration::TypeInfoPointerDeclaration(Type *tinfo) 1930: : TypeInfoDeclaration(tinfo, 0) 1931: { 1932: type = Type::typeinfopointer->type; 1933: } 1934: 1935: /***************************** TypeInfoArrayDeclaration ***********************/ 1936: 1937: TypeInfoArrayDeclaration::TypeInfoArrayDeclaration(Type *tinfo) 1938: : TypeInfoDeclaration(tinfo, 0) 1939: { 1940: type = Type::typeinfoarray->type; 1941: } 1942: 1943: /***************************** TypeInfoStaticArrayDeclaration *****************/ 1944: 1945: TypeInfoStaticArrayDeclaration::TypeInfoStaticArrayDeclaration(Type *tinfo) 1946: : TypeInfoDeclaration(tinfo, 0) 1947: { 1948: type = Type::typeinfostaticarray->type; 1949: } 1950: 1951: /***************************** TypeInfoAssociativeArrayDeclaration ************/ 1952: 1953: TypeInfoAssociativeArrayDeclaration::TypeInfoAssociativeArrayDeclaration(Type *tinfo) 1954: : TypeInfoDeclaration(tinfo, 0) 1955: { 1956: type = Type::typeinfoassociativearray->type; 1957: } 1958: 1959: /***************************** TypeInfoEnumDeclaration ***********************/ 1960: 1961: TypeInfoEnumDeclaration::TypeInfoEnumDeclaration(Type *tinfo) 1962: : TypeInfoDeclaration(tinfo, 0) 1963: { 1964: type = Type::typeinfoenum->type; 1965: } 1966: 1967: /***************************** TypeInfoFunctionDeclaration ********************/ 1968: 1969: TypeInfoFunctionDeclaration::TypeInfoFunctionDeclaration(Type *tinfo) 1970: : TypeInfoDeclaration(tinfo, 0) 1971: { 1972: type = Type::typeinfofunction->type; 1973: } 1974: 1975: /***************************** TypeInfoDelegateDeclaration ********************/ 1976: 1977: TypeInfoDelegateDeclaration::TypeInfoDelegateDeclaration(Type *tinfo) 1978: : TypeInfoDeclaration(tinfo, 0) 1979: { 1980: type = Type::typeinfodelegate->type; 1981: } 1982: 1983: /***************************** TypeInfoTupleDeclaration **********************/ 1984: 1985: TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo) 1986: : TypeInfoDeclaration(tinfo, 0) 1987: { 1988: type = Type::typeinfotypelist->type; 1989: } 1990: 1991: /********************************* ThisDeclaration ****************************/ 1992: 1993: // For the "this" parameter to member functions 1994: 1995: ThisDeclaration::ThisDeclaration(Loc loc, Type *t) 1996: : VarDeclaration(loc, t, Id::This, NULL) 1997: { 1998: noscope = 1; 1999: } 2000: 2001: Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s) 2002: { 2003: assert(0); // should never be produced by syntax 2004: return NULL; 2005: } 2006: 2007: