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 "mars.h"
 16: #include "init.h"
 17: #include "expression.h"
 18: #include "statement.h"
 19: #include "identifier.h"
 20: #include "declaration.h"
 21: #include "aggregate.h"
 22: #include "scope.h"
 23: #include "mtype.h"
 24: #include "hdrgen.h"
 25: 
 26: /********************************** Initializer *******************************/
 27: 
 28: Initializer::Initializer(Loc loc)
 29: {
 30:     this->loc = loc;
 31: }
 32: 
 33: Initializer *Initializer::syntaxCopy()
 34: {
 35:     return this;
 36: }
 37: 
 38: Initializer *Initializer::semantic(Scope *sc, Type *t, int needInterpret)
 39: {
 40:     return this;
 41: }
 42: 
 43: Type *Initializer::inferType(Scope *sc)
 44: {
 45:     error(loc, "cannot infer type from initializer");
 46:     return Type::terror;
 47: }
 48: 
 49: Initializers *Initializer::arraySyntaxCopy(Initializers *ai)
 50: {   Initializers *a = NULL;
 51: 
 52:     if (ai)
 53:     {
 54:         a = new Initializers();
 55:         a->setDim(ai->dim);
 56:         for (int i = 0; i < a->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
57: { Initializer *e = ai->tdata()[i]; 58: 59: e = e->syntaxCopy(); 60: a->tdata()[i] = e; 61: } 62: } 63: return a; 64: } 65: 66: char *Initializer::toChars() 67: { OutBuffer *buf; 68: HdrGenState hgs; 69: 70: memset(&hgs, 0, sizeof(hgs)); 71: buf = new OutBuffer(); 72: toCBuffer(buf, &hgs); 73: return buf->toChars(); 74: } 75: 76: /********************************** VoidInitializer ***************************/ 77: 78: VoidInitializer::VoidInitializer(Loc loc) 79: : Initializer(loc) 80: { 81: type = NULL; 82: } 83: 84: 85: Initializer *VoidInitializer::syntaxCopy() 86: { 87: return new VoidInitializer(loc); 88: } 89: 90: 91: Initializer *VoidInitializer::semantic(Scope *sc, Type *t, int needInterpret) 92: { 93: //printf("VoidInitializer::semantic(t = %p)\n", t); 94: type = t; 95: return this; 96: } 97: 98: 99: Expression *VoidInitializer::toExpression() 100: { 101: error(loc, "void initializer has no value"); 102: return new IntegerExp(0); 103: } 104: 105: 106: void VoidInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 107: { 108: buf->writestring("void"); 109: } 110: 111: 112: /********************************** StructInitializer *************************/ 113: 114: StructInitializer::StructInitializer(Loc loc) 115: : Initializer(loc) 116: { 117: ad = NULL; 118: } 119: 120: Initializer *StructInitializer::syntaxCopy() 121: { 122: StructInitializer *ai = new StructInitializer(loc); 123: 124: assert(field.dim == value.dim); 125: ai->field.setDim(field.dim); 126: ai->value.setDim(value.dim); 127: for (int i = 0; i < field.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
128: { 129: ai->field.tdata()[i] = field.tdata()[i]; 130: 131: Initializer *init = value.tdata()[i]; 132: init = init->syntaxCopy(); 133: ai->value.tdata()[i] = init; 134: } 135: return ai; 136: } 137: 138: void StructInitializer::addInit(Identifier *field, Initializer *value) 139: { 140: //printf("StructInitializer::addInit(field = %p, value = %p)\n", field, value); 141: this->field.push(field); 142: this->value.push(value); 143: } 144: 145: Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret) 146: { 147: int errors = 0; 148: 149: //printf("StructInitializer::semantic(t = %s) %s\n", t->toChars(), toChars()); 150: vars.setDim(field.dim); 151: t = t->toBasetype(); 152: if (t->ty == Tstruct) 153: { 154: unsigned fieldi = 0; 155: 156: TypeStruct *ts = (TypeStruct *)t; 157: ad = ts->sym; 158: if (ad->ctor) 159: error(loc, "%s %s has constructors, cannot use { initializers }, use %s( initializers ) instead", 160: ad->kind(), ad->toChars(), ad->toChars()); 161: int nfields = ad->fields.dim; 162: if (((StructDeclaration *)ad)->isnested) nfields--; 163: for (size_t i = 0; i < field.dim; i++) 164: { 165: Identifier *id = field.tdata()[i]; 166: Initializer *val = value.tdata()[i]; 167: Dsymbol *s; 168: VarDeclaration *v; 169: 170: if (id == NULL) 171: { 172: if (fieldi >= nfields)
warning C4018: '>=' : signed/unsigned mismatch
173: { error(loc, "too many initializers for %s", ad->toChars()); 174: errors = 1; 175: field.remove(i); 176: i--; 177: continue; 178: } 179: else 180: { 181: s = ad->fields.tdata()[fieldi]; 182: } 183: } 184: else 185: { 186: //s = ad->symtab->lookup(id); 187: s = ad->search(loc, id, 0); 188: if (!s) 189: { 190: error(loc, "'%s' is not a member of '%s'", id->toChars(), t->toChars()); 191: errors = 1; 192: continue; 193: } 194: 195: // Find out which field index it is 196: for (fieldi = 0; 1; fieldi++) 197: { 198: if (fieldi >= nfields)
warning C4018: '>=' : signed/unsigned mismatch
199: { 200: error(loc, "%s.%s is not a per-instance initializable field", 201: t->toChars(), s->toChars()); 202: errors = 1; 203: break; 204: } 205: if (s == ad->fields.tdata()[fieldi]) 206: break; 207: } 208: } 209: if (s && (v = s->isVarDeclaration()) != NULL) 210: { 211: val = val->semantic(sc, v->type, needInterpret); 212: value.tdata()[i] = val; 213: vars.tdata()[i] = v; 214: } 215: else 216: { error(loc, "%s is not a field of %s", id ? id->toChars() : s->toChars(), ad->toChars());
warning C6011: Dereferencing NULL pointer 's': Lines: 147, 150, 151, 152, 154, 156, 157, 158, 159, 161, 162, 163, 165, 166, 167, 168, 170, 187, 188, 190, 191, 163, 165, 166, 167, 168, 170, 172, 181, 209, 216
217: errors = 1; 218: } 219: fieldi++; 220: } 221: } 222: else if (t->ty == Tdelegate && value.dim == 0) 223: { /* Rewrite as empty delegate literal { } 224: */ 225: Parameters *arguments = new Parameters; 226: Type *tf = new TypeFunction(arguments, NULL, 0, LINKd); 227: FuncLiteralDeclaration *fd = new FuncLiteralDeclaration(loc, 0, tf, TOKdelegate, NULL); 228: fd->fbody = new CompoundStatement(loc, new Statements()); 229: fd->endloc = loc; 230: Expression *e = new FuncExp(loc, fd); 231: ExpInitializer *ie = new ExpInitializer(loc, e); 232: return ie->semantic(sc, t, needInterpret); 233: } 234: else 235: { 236: error(loc, "a struct is not a valid initializer for a %s", t->toChars()); 237: errors = 1; 238: } 239: if (errors) 240: { 241: field.setDim(0); 242: value.setDim(0); 243: vars.setDim(0); 244: } 245: return this; 246: } 247: 248: /*************************************** 249: * This works by transforming a struct initializer into 250: * a struct literal. In the future, the two should be the 251: * same thing. 252: */ 253: Expression *StructInitializer::toExpression() 254: { Expression *e; 255: size_t offset; 256: 257: //printf("StructInitializer::toExpression() %s\n", toChars()); 258: if (!ad) // if fwd referenced 259: { 260: return NULL; 261: } 262: StructDeclaration *sd = ad->isStructDeclaration(); 263: if (!sd) 264: return NULL; 265: Expressions *elements = new Expressions(); 266: int nfields = ad->fields.dim; 267: if (sd->isnested) nfields--; 268: elements->setDim(nfields); 269: for (int i = 0; i < elements->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
270: { 271: elements->tdata()[i] = NULL; 272: } 273: unsigned fieldi = 0; 274: for (int i = 0; i < value.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
275: { 276: Identifier *id = field.tdata()[i]; 277: if (id) 278: { 279: Dsymbol * s = ad->search(loc, id, 0); 280: if (!s) 281: { 282: error(loc, "'%s' is not a member of '%s'", id->toChars(), sd->toChars()); 283: goto Lno; 284: } 285: 286: // Find out which field index it is 287: for (fieldi = 0; 1; fieldi++) 288: { 289: if (fieldi >= nfields)
warning C4018: '>=' : signed/unsigned mismatch
290: { 291: s->error("is not a per-instance initializable field"); 292: goto Lno; 293: } 294: if (s == ad->fields.tdata()[fieldi]) 295: break; 296: } 297: } 298: else if (fieldi >= nfields)
warning C4018: '>=' : signed/unsigned mismatch
299: { error(loc, "too many initializers for '%s'", ad->toChars()); 300: goto Lno; 301: } 302: Initializer *iz = value.tdata()[i]; 303: if (!iz) 304: goto Lno; 305: Expression *ex = iz->toExpression(); 306: if (!ex) 307: goto Lno; 308: if (elements->tdata()[fieldi]) 309: { error(loc, "duplicate initializer for field '%s'", 310: ad->fields.tdata()[fieldi]->toChars()); 311: goto Lno; 312: } 313: elements->tdata()[fieldi] = ex; 314: ++fieldi; 315: } 316: // Now, fill in any missing elements with default initializers. 317: // We also need to validate any anonymous unions 318: offset = 0; 319: for (int i = 0; i < elements->dim; )
warning C4018: '<' : signed/unsigned mismatch
320: { 321: VarDeclaration * vd = ad->fields.tdata()[i]->isVarDeclaration(); 322: 323: //printf("test2 [%d] : %s %d %d\n", i, vd->toChars(), (int)offset, (int)vd->offset); 324: if (vd->offset < offset) 325: { 326: // Only the first field of a union can have an initializer 327: if (elements->tdata()[i]) 328: goto Lno; 329: } 330: else 331: { 332: if (!elements->tdata()[i]) 333: // Default initialize 334: elements->tdata()[i] = vd->type->defaultInit(); 335: } 336: offset = vd->offset + vd->type->size();
warning C4244: '=' : conversion from 'd_uns64' to 'size_t', possible loss of data
337: i++; 338: #if 0 339: int unionSize = ad->numFieldsInUnion(i); 340: if (unionSize == 1) 341: { // Not a union -- default initialize if missing 342: if (!elements->tdata()[i]) 343: elements->tdata()[i] = vd->type->defaultInit(); 344: } 345: else 346: { // anonymous union -- check for errors 347: int found = -1; // index of the first field with an initializer 348: for (int j = i; j < i + unionSize; ++j) 349: { 350: if (!elements->tdata()[j]) 351: continue; 352: if (found >= 0) 353: { 354: VarDeclaration * v1 = ((Dsymbol *)ad->fields.data[found])->isVarDeclaration(); 355: VarDeclaration * v = ((Dsymbol *)ad->fields.data[j])->isVarDeclaration(); 356: error(loc, "%s cannot have initializers for fields %s and %s in same union", 357: ad->toChars(), 358: v1->toChars(), v->toChars()); 359: goto Lno; 360: } 361: found = j; 362: } 363: if (found == -1) 364: { 365: error(loc, "no initializer for union that contains field %s", 366: vd->toChars()); 367: goto Lno; 368: } 369: } 370: i += unionSize; 371: #endif 372: } 373: e = new StructLiteralExp(loc, sd, elements); 374: e->type = sd->type; 375: return e; 376: 377: Lno: 378: delete elements; 379: return NULL; 380: } 381: 382: 383: void StructInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 384: { 385: //printf("StructInitializer::toCBuffer()\n"); 386: buf->writebyte('{'); 387: for (int i = 0; i < field.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
388: { 389: if (i > 0) 390: buf->writebyte(','); 391: Identifier *id = field.tdata()[i]; 392: if (id) 393: { 394: buf->writestring(id->toChars()); 395: buf->writebyte(':'); 396: } 397: Initializer *iz = value.tdata()[i]; 398: if (iz) 399: iz->toCBuffer(buf, hgs); 400: } 401: buf->writebyte('}'); 402: } 403: 404: /********************************** ArrayInitializer ************************************/ 405: 406: ArrayInitializer::ArrayInitializer(Loc loc) 407: : Initializer(loc) 408: { 409: dim = 0; 410: type = NULL; 411: sem = 0; 412: } 413: 414: Initializer *ArrayInitializer::syntaxCopy() 415: { 416: //printf("ArrayInitializer::syntaxCopy()\n"); 417: 418: ArrayInitializer *ai = new ArrayInitializer(loc); 419: 420: assert(index.dim == value.dim); 421: ai->index.setDim(index.dim); 422: ai->value.setDim(value.dim); 423: for (int i = 0; i < ai->value.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
424: { Expression *e = index.tdata()[i]; 425: if (e) 426: e = e->syntaxCopy(); 427: ai->index.tdata()[i] = e; 428: 429: Initializer *init = value.tdata()[i]; 430: init = init->syntaxCopy(); 431: ai->value.tdata()[i] = init; 432: } 433: return ai; 434: } 435: 436: void ArrayInitializer::addInit(Expression *index, Initializer *value) 437: { 438: this->index.push(index); 439: this->value.push(value); 440: dim = 0; 441: type = NULL; 442: } 443: 444: Initializer *ArrayInitializer::semantic(Scope *sc, Type *t, int needInterpret) 445: { unsigned i; 446: unsigned length; 447: const unsigned amax = 0x80000000; 448: 449: //printf("ArrayInitializer::semantic(%s)\n", t->toChars()); 450: if (sem) // if semantic() already run 451: return this; 452: sem = 1; 453: type = t; 454: t = t->toBasetype(); 455: switch (t->ty) 456: { 457: case Tpointer: 458: case Tsarray: 459: case Tarray: 460: break; 461: 462: default: 463: error(loc, "cannot use array to initialize %s", type->toChars()); 464: goto Lerr; 465: } 466: 467: length = 0; 468: for (i = 0; i < index.dim; i++) 469: { 470: Expression *idx = index.tdata()[i]; 471: if (idx) 472: { idx = idx->semantic(sc); 473: idx = idx->optimize(WANTvalue | WANTinterpret); 474: index.tdata()[i] = idx; 475: length = idx->toInteger();
warning C4244: '=' : conversion from 'dinteger_t' to 'unsigned int', possible loss of data
476: } 477: 478: Initializer *val = value.tdata()[i]; 479: val = val->semantic(sc, t->nextOf(), needInterpret); 480: value.tdata()[i] = val; 481: length++; 482: if (length == 0) 483: { error(loc, "array dimension overflow"); 484: goto Lerr; 485: } 486: if (length > dim) 487: dim = length; 488: } 489: if (t->ty == Tsarray) 490: { 491: dinteger_t edim = ((TypeSArray *)t)->dim->toInteger(); 492: if (dim > edim) 493: { 494: error(loc, "array initializer has %u elements, but array length is %jd", dim, edim); 495: goto Lerr; 496: } 497: } 498: 499: if ((unsigned long) dim * t->nextOf()->size() >= amax) 500: { error(loc, "array dimension %u exceeds max of %u", dim, amax / t->nextOf()->size()); 501: goto Lerr; 502: } 503: return this; 504: 505: Lerr: 506: return new ExpInitializer(loc, new ErrorExp()); 507: } 508: 509: /******************************** 510: * If possible, convert array initializer to array literal. 511: * Otherwise return NULL. 512: */ 513: 514: Expression *ArrayInitializer::toExpression() 515: { Expressions *elements; 516: Expression *e;
warning C4101: 'e' : unreferenced local variable
517: 518: //printf("ArrayInitializer::toExpression(), dim = %d\n", dim); 519: //static int i; if (++i == 2) halt(); 520: 521: size_t edim; 522: Type *t = NULL; 523: if (type) 524: { 525: if (type == Type::terror) 526: return new ErrorExp(); 527: 528: t = type->toBasetype(); 529: switch (t->ty) 530: { 531: case Tsarray: 532: edim = ((TypeSArray *)t)->dim->toInteger();
warning C4244: '=' : conversion from 'dinteger_t' to 'size_t', possible loss of data
533: break; 534: 535: case Tpointer: 536: case Tarray: 537: edim = dim; 538: break; 539: 540: default: 541: assert(0); 542: } 543: } 544: else 545: { 546: edim = value.dim; 547: for (size_t i = 0, j = 0; i < value.dim; i++, j++) 548: { 549: if (index.tdata()[i]) 550: j = index.tdata()[i]->toInteger();
warning C4244: '=' : conversion from 'dinteger_t' to 'size_t', possible loss of data
551: if (j >= edim) 552: edim = j + 1; 553: } 554: } 555: 556: elements = new Expressions(); 557: elements->setDim(edim); 558: elements->zero(); 559: for (size_t i = 0, j = 0; i < value.dim; i++, j++) 560: { 561: if (index.tdata()[i]) 562: j = (index.tdata()[i])->toInteger();
warning C4244: '=' : conversion from 'dinteger_t' to 'size_t', possible loss of data
563: assert(j < edim); 564: Initializer *iz = value.tdata()[i]; 565: if (!iz) 566: goto Lno; 567: Expression *ex = iz->toExpression(); 568: if (!ex) 569: { 570: goto Lno; 571: } 572: elements->tdata()[j] = ex; 573: } 574: 575: /* Fill in any missing elements with the default initializer 576: */ 577: { 578: Expression *init = NULL; 579: for (size_t i = 0; i < edim; i++) 580: { 581: if (!elements->tdata()[i]) 582: { 583: if (!type) 584: goto Lno; 585: if (!init) 586: init = ((TypeNext *)t)->next->defaultInit(); 587: elements->tdata()[i] = init; 588: } 589: } 590: 591: Expression *e = new ArrayLiteralExp(loc, elements);
warning C6246: Local declaration of 'e' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '516' of 'c:\projects\extern\d\dmd\src\init.c': Lines: 516
592: e->type = type; 593: return e; 594: } 595: 596: Lno: 597: return NULL; 598: } 599: 600: 601: /******************************** 602: * If possible, convert array initializer to associative array initializer. 603: */ 604: 605: Expression *ArrayInitializer::toAssocArrayLiteral() 606: { 607: Expression *e; 608: 609: //printf("ArrayInitializer::toAssocArrayInitializer()\n"); 610: //static int i; if (++i == 2) halt(); 611: Expressions *keys = new Expressions();
warning C6211: Leaking memory 'keys' due to an exception. Consider using a local catch block to clean up memory: Lines: 607, 611, 612, 613
612: keys->setDim(value.dim); 613: Expressions *values = new Expressions(); 614: values->setDim(value.dim); 615: 616: for (size_t i = 0; i < value.dim; i++) 617: { 618: e = index.tdata()[i]; 619: if (!e) 620: goto Lno; 621: keys->tdata()[i] = e; 622: 623: Initializer *iz = value.tdata()[i]; 624: if (!iz) 625: goto Lno; 626: e = iz->toExpression(); 627: if (!e) 628: goto Lno; 629: values->tdata()[i] = e; 630: } 631: e = new AssocArrayLiteralExp(loc, keys, values); 632: return e; 633: 634: Lno: 635: delete keys; 636: delete values; 637: error(loc, "not an associative array initializer"); 638: return new ErrorExp(); 639: } 640: 641: int ArrayInitializer::isAssociativeArray() 642: { 643: for (size_t i = 0; i < value.dim; i++) 644: { 645: if (index.tdata()[i]) 646: return 1; 647: } 648: return 0; 649: } 650: 651: Type *ArrayInitializer::inferType(Scope *sc) 652: { 653: //printf("ArrayInitializer::inferType() %s\n", toChars()); 654: assert(0); 655: return NULL; 656: #if 0 657: type = Type::terror; 658: for (size_t i = 0; i < value.dim; i++) 659: { 660: if (index.data[i]) 661: goto Laa; 662: } 663: for (size_t i = 0; i < value.dim; i++) 664: { 665: Initializer *iz = (Initializer *)value.data[i]; 666: if (iz) 667: { Type *t = iz->inferType(sc); 668: if (i == 0) 669: { /* BUG: This gets the type from the first element. 670: * Fix to use all the elements to figure out the type. 671: */ 672: t = new TypeSArray(t, new IntegerExp(value.dim)); 673: t = t->semantic(loc, sc); 674: type = t; 675: } 676: } 677: } 678: return type; 679: 680: Laa: 681: /* It's possibly an associative array initializer. 682: * BUG: inferring type from first member. 683: */ 684: Initializer *iz = (Initializer *)value.data[0]; 685: Expression *indexinit = (Expression *)index.data[0]; 686: if (iz && indexinit) 687: { Type *t = iz->inferType(sc); 688: indexinit = indexinit->semantic(sc); 689: Type *indext = indexinit->type; 690: t = new TypeAArray(t, indext); 691: type = t->semantic(loc, sc); 692: } 693: else 694: error(loc, "cannot infer type from this array initializer"); 695: return type; 696: #endif 697: } 698: 699: 700: void ArrayInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 701: { 702: buf->writebyte('['); 703: for (int i = 0; i < index.dim; i++)
warning C4018: '<' : signed/unsigned mismatch
704: { 705: if (i > 0) 706: buf->writebyte(','); 707: Expression *ex = index.tdata()[i]; 708: if (ex) 709: { 710: ex->toCBuffer(buf, hgs); 711: buf->writebyte(':'); 712: } 713: Initializer *iz = value.tdata()[i]; 714: if (iz) 715: iz->toCBuffer(buf, hgs); 716: } 717: buf->writebyte(']'); 718: } 719: 720: 721: /********************************** ExpInitializer ************************************/ 722: 723: ExpInitializer::ExpInitializer(Loc loc, Expression *exp) 724: : Initializer(loc) 725: { 726: this->exp = exp; 727: } 728: 729: Initializer *ExpInitializer::syntaxCopy() 730: { 731: return new ExpInitializer(loc, exp->syntaxCopy()); 732: } 733: 734: bool arrayHasNonConstPointers(Expressions *elems); 735: 736: bool hasNonConstPointers(Expression *e) 737: { 738: if (e->op == TOKnull) 739: return false; 740: if (e->op == TOKstructliteral) 741: { 742: StructLiteralExp *se = (StructLiteralExp *)e; 743: return arrayHasNonConstPointers(se->elements); 744: } 745: if (e->op == TOKarrayliteral) 746: { 747: if (!e->type->nextOf()->hasPointers()) 748: return false; 749: ArrayLiteralExp *ae = (ArrayLiteralExp *)e; 750: return arrayHasNonConstPointers(ae->elements); 751: } 752: if (e->op == TOKassocarrayliteral) 753: { 754: AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)e; 755: if (ae->type->nextOf()->hasPointers() && 756: arrayHasNonConstPointers(ae->values)) 757: return true; 758: if (((TypeAArray *)ae->type)->index->hasPointers()) 759: return arrayHasNonConstPointers(ae->keys); 760: return false; 761: } 762: if (e->type->ty== Tpointer && e->type->nextOf()->ty != Tfunction) 763: { 764: if (e->op == TOKsymoff) // address of a global is OK 765: return false; 766: if (e->op == TOKint64) // cast(void *)int is OK 767: return false; 768: if (e->op == TOKstring) // "abc".ptr is OK 769: return false; 770: return true; 771: } 772: return false; 773: } 774: 775: bool arrayHasNonConstPointers(Expressions *elems) 776: { 777: for (size_t i = 0; i < elems->dim; i++) 778: { 779: if (!elems->tdata()[i]) 780: continue; 781: if (hasNonConstPointers(elems->tdata()[i])) 782: return true; 783: } 784: return false; 785: } 786: 787: 788: 789: Initializer *ExpInitializer::semantic(Scope *sc, Type *t, int needInterpret) 790: { 791: //printf("ExpInitializer::semantic(%s), type = %s\n", exp->toChars(), t->toChars()); 792: exp = exp->semantic(sc); 793: exp = resolveProperties(sc, exp); 794: int wantOptimize = needInterpret ? WANTinterpret|WANTvalue : WANTvalue; 795: 796: int olderrors = global.errors; 797: exp = exp->optimize(wantOptimize); 798: if (!global.gag && olderrors != global.errors) 799: return this; // Failed, suppress duplicate error messages 800: 801: // Make sure all pointers are constants 802: if (needInterpret && hasNonConstPointers(exp)) 803: { 804: exp->error("cannot use non-constant CTFE pointer in an initializer '%s'", exp->toChars()); 805: return this; 806: } 807: 808: Type *tb = t->toBasetype(); 809: 810: /* Look for case of initializing a static array with a too-short 811: * string literal, such as: 812: * char[5] foo = "abc"; 813: * Allow this by doing an explicit cast, which will lengthen the string 814: * literal. 815: */ 816: if (exp->op == TOKstring && tb->ty == Tsarray && exp->type->ty == Tsarray) 817: { StringExp *se = (StringExp *)exp; 818: 819: if (!se->committed && se->type->ty == Tsarray && 820: ((TypeSArray *)se->type)->dim->toInteger() < 821: ((TypeSArray *)t)->dim->toInteger()) 822: { 823: exp = se->castTo(sc, t); 824: goto L1; 825: } 826: } 827: 828: // Look for the case of statically initializing an array 829: // with a single member. 830: if (tb->ty == Tsarray && 831: !tb->nextOf()->equals(exp->type->toBasetype()->nextOf()) && 832: exp->implicitConvTo(tb->nextOf()) 833: ) 834: { 835: t = tb->nextOf(); 836: } 837: 838: exp = exp->implicitCastTo(sc, t); 839: L1: 840: exp = exp->optimize(wantOptimize); 841: //printf("-ExpInitializer::semantic(): "); exp->print(); 842: return this; 843: } 844: 845: Type *ExpInitializer::inferType(Scope *sc) 846: { 847: //printf("ExpInitializer::inferType() %s\n", toChars()); 848: exp = exp->semantic(sc); 849: exp = resolveProperties(sc, exp); 850: 851: // Give error for overloaded function addresses 852: if (exp->op == TOKsymoff) 853: { SymOffExp *se = (SymOffExp *)exp; 854: if (se->hasOverloads && !se->var->isFuncDeclaration()->isUnique()) 855: exp->error("cannot infer type from overloaded function symbol %s", exp->toChars()); 856: } 857: 858: // Give error for overloaded function addresses 859: if (exp->op == TOKdelegate) 860: { DelegateExp *se = (DelegateExp *)exp; 861: if ( 862: se->func->isFuncDeclaration() && 863: !se->func->isFuncDeclaration()->isUnique()) 864: exp->error("cannot infer type from overloaded function symbol %s", exp->toChars()); 865: } 866: 867: Type *t = exp->type; 868: if (!t) 869: t = Initializer::inferType(sc); 870: return t; 871: } 872: 873: Expression *ExpInitializer::toExpression() 874: { 875: return exp; 876: } 877: 878: 879: void ExpInitializer::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 880: { 881: exp->toCBuffer(buf, hgs); 882: } 883: 884: 885: 886: