1 2 /* Compiler implementation of the D programming language 3 * Copyright (C) 1999-2019 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/D-Programming-Language/dmd/blob/master/src/struct.c 9 */ 10 11 #include "root/dsystem.h" 12 #include "root/root.h" 13 14 #include "errors.h" 15 #include "aggregate.h" 16 #include "scope.h" 17 #include "mtype.h" 18 #include "init.h" 19 #include "declaration.h" 20 #include "module.h" 21 #include "id.h" 22 #include "statement.h" 23 #include "template.h" 24 #include "tokens.h" 25 26 Type *getTypeInfoType(Loc loc, Type *t, Scope *sc); 27 TypeTuple *toArgTypes(Type *t); 28 void unSpeculative(Scope *sc, RootObject *o); 29 bool MODimplicitConv(MOD modfrom, MOD modto); 30 Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads); 31 32 FuncDeclaration *StructDeclaration::xerreq; // object.xopEquals 33 FuncDeclaration *StructDeclaration::xerrcmp; // object.xopCmp 34 35 /*************************************** 36 * Search toString member function for TypeInfo_Struct. 37 * string toString(); 38 */ 39 FuncDeclaration *search_toString(StructDeclaration *sd) 40 { 41 Dsymbol *s = search_function(sd, Id::tostring); 42 FuncDeclaration *fd = s ? s->isFuncDeclaration() : NULL; 43 if (fd) 44 { 45 static TypeFunction *tftostring; 46 if (!tftostring) 47 { 48 tftostring = new TypeFunction(NULL, Type::tstring, 0, LINKd); 49 tftostring = tftostring->merge()->toTypeFunction(); 50 } 51 52 fd = fd->overloadExactMatch(tftostring); 53 } 54 return fd; 55 } 56 57 /*************************************** 58 * Request additonal semantic analysis for TypeInfo generation. 59 */ 60 void semanticTypeInfo(Scope *sc, Type *t) 61 { 62 class FullTypeInfoVisitor : public Visitor 63 { 64 public: 65 Scope *sc; 66 67 void visit(Type *t) 68 { 69 Type *tb = t->toBasetype(); 70 if (tb != t) 71 tb->accept(this); 72 } 73 void visit(TypeNext *t) 74 { 75 if (t->next) 76 t->next->accept(this); 77 } 78 void visit(TypeBasic *) { } 79 void visit(TypeVector *t) 80 { 81 t->basetype->accept(this); 82 } 83 void visit(TypeAArray *t) 84 { 85 t->index->accept(this); 86 visit((TypeNext *)t); 87 } 88 void visit(TypeFunction *t) 89 { 90 visit((TypeNext *)t); 91 // Currently TypeInfo_Function doesn't store parameter types. 92 } 93 void visit(TypeStruct *t) 94 { 95 //printf("semanticTypeInfo::visit(TypeStruct = %s)\n", t->toChars()); 96 StructDeclaration *sd = t->sym; 97 98 /* Step 1: create TypeInfoDeclaration 99 */ 100 if (!sc) // inline may request TypeInfo. 101 { 102 Scope scx; 103 scx._module = sd->getModule(); 104 getTypeInfoType(sd->loc, t, &scx); 105 sd->requestTypeInfo = true; 106 } 107 else if (!sc->minst) 108 { 109 // don't yet have to generate TypeInfo instance if 110 // the typeid(T) expression exists in speculative scope. 111 } 112 else 113 { 114 getTypeInfoType(sd->loc, t, sc); 115 sd->requestTypeInfo = true; 116 117 // Bugzilla 15149, if the typeid operand type comes from a 118 // result of auto function, it may be yet speculative. 119 unSpeculative(sc, sd); 120 } 121 122 /* Step 2: If the TypeInfo generation requires sd.semantic3, run it later. 123 * This should be done even if typeid(T) exists in speculative scope. 124 * Because it may appear later in non-speculative scope. 125 */ 126 if (!sd->members) 127 return; // opaque struct 128 if (!sd->xeq && !sd->xcmp && !sd->postblit && 129 !sd->dtor && !sd->xhash && !search_toString(sd)) 130 return; // none of TypeInfo-specific members 131 132 // If the struct is in a non-root module, run semantic3 to get 133 // correct symbols for the member function. 134 if (sd->semanticRun >= PASSsemantic3) 135 { 136 // semantic3 is already done 137 } 138 else if (TemplateInstance *ti = sd->isInstantiated()) 139 { 140 if (ti->minst && !ti->minst->isRoot()) 141 Module::addDeferredSemantic3(sd); 142 } 143 else 144 { 145 if (sd->inNonRoot()) 146 { 147 //printf("deferred sem3 for TypeInfo - sd = %s, inNonRoot = %d\n", sd->toChars(), sd->inNonRoot()); 148 Module::addDeferredSemantic3(sd); 149 } 150 } 151 } 152 void visit(TypeClass *) { } 153 void visit(TypeTuple *t) 154 { 155 if (t->arguments) 156 { 157 for (size_t i = 0; i < t->arguments->dim; i++) 158 { 159 Type *tprm = (*t->arguments)[i]->type; 160 if (tprm) 161 tprm->accept(this); 162 } 163 } 164 } 165 }; 166 167 if (sc) 168 { 169 if (!sc->func) 170 return; 171 if (sc->intypeof) 172 return; 173 if (sc->flags & (SCOPEctfe | SCOPEcompile)) 174 return; 175 } 176 177 FullTypeInfoVisitor v; 178 v.sc = sc; 179 t->accept(&v); 180 } 181 182 /********************************* AggregateDeclaration ****************************/ 183 184 AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id) 185 : ScopeDsymbol(id) 186 { 187 this->loc = loc; 188 189 storage_class = 0; 190 protection = Prot(PROTpublic); 191 type = NULL; 192 structsize = 0; // size of struct 193 alignsize = 0; // size of struct for alignment purposes 194 sizeok = SIZEOKnone; // size not determined yet 195 deferred = NULL; 196 isdeprecated = false; 197 inv = NULL; 198 aggNew = NULL; 199 aggDelete = NULL; 200 201 stag = NULL; 202 sinit = NULL; 203 enclosing = NULL; 204 vthis = NULL; 205 206 ctor = NULL; 207 defaultCtor = NULL; 208 aliasthis = NULL; 209 noDefaultCtor = false; 210 dtor = NULL; 211 getRTInfo = NULL; 212 } 213 214 Prot AggregateDeclaration::prot() 215 { 216 return protection; 217 } 218 219 /*************************************** 220 * Create a new scope from sc. 221 * semantic, semantic2 and semantic3 will use this for aggregate members. 222 */ 223 Scope *AggregateDeclaration::newScope(Scope *sc) 224 { 225 Scope *sc2 = sc->push(this); 226 sc2->stc &= STCsafe | STCtrusted | STCsystem; 227 sc2->parent = this; 228 if (isUnionDeclaration()) 229 sc2->inunion = 1; 230 sc2->protection = Prot(PROTpublic); 231 sc2->explicitProtection = 0; 232 sc2->aligndecl = NULL; 233 sc2->userAttribDecl = NULL; 234 return sc2; 235 } 236 237 void AggregateDeclaration::setScope(Scope *sc) 238 { 239 // Might need a scope to resolve forward references. The check for 240 // semanticRun prevents unnecessary setting of _scope during deferred 241 // setScope phases for aggregates which already finished semantic(). 242 // Also see https://issues.dlang.org/show_bug.cgi?id=16607 243 if (semanticRun < PASSsemanticdone) 244 ScopeDsymbol::setScope(sc); 245 } 246 247 void AggregateDeclaration::semantic2(Scope *sc) 248 { 249 //printf("AggregateDeclaration::semantic2(%s) type = %s, errors = %d\n", toChars(), type->toChars(), errors); 250 if (!members) 251 return; 252 253 if (_scope) 254 { 255 error("has forward references"); 256 return; 257 } 258 259 Scope *sc2 = newScope(sc); 260 261 determineSize(loc); 262 263 for (size_t i = 0; i < members->dim; i++) 264 { 265 Dsymbol *s = (*members)[i]; 266 //printf("\t[%d] %s\n", i, s->toChars()); 267 s->semantic2(sc2); 268 } 269 270 sc2->pop(); 271 } 272 273 void AggregateDeclaration::semantic3(Scope *sc) 274 { 275 //printf("AggregateDeclaration::semantic3(%s) type = %s, errors = %d\n", toChars(), type->toChars(), errors); 276 if (!members) 277 return; 278 279 StructDeclaration *sd = isStructDeclaration(); 280 if (!sc) // from runDeferredSemantic3 for TypeInfo generation 281 { 282 assert(sd); 283 sd->semanticTypeInfoMembers(); 284 return; 285 } 286 287 Scope *sc2 = newScope(sc); 288 289 for (size_t i = 0; i < members->dim; i++) 290 { 291 Dsymbol *s = (*members)[i]; 292 s->semantic3(sc2); 293 } 294 295 sc2->pop(); 296 297 // don't do it for unused deprecated types 298 // or error types 299 if (!getRTInfo && Type::rtinfo && 300 (!isDeprecated() || global.params.useDeprecated != DIAGNOSTICerror) && 301 (type && type->ty != Terror)) 302 { 303 // Evaluate: RTinfo!type 304 Objects *tiargs = new Objects(); 305 tiargs->push(type); 306 TemplateInstance *ti = new TemplateInstance(loc, Type::rtinfo, tiargs); 307 308 Scope *sc3 = ti->tempdecl->_scope->startCTFE(); 309 sc3->tinst = sc->tinst; 310 sc3->minst = sc->minst; 311 if (isDeprecated()) 312 sc3->stc |= STCdeprecated; 313 314 ti->semantic(sc3); 315 ti->semantic2(sc3); 316 ti->semantic3(sc3); 317 Expression *e = resolve(Loc(), sc3, ti->toAlias(), false); 318 319 sc3->endCTFE(); 320 321 e = e->ctfeInterpret(); 322 getRTInfo = e; 323 } 324 325 if (sd) 326 sd->semanticTypeInfoMembers(); 327 } 328 329 /*************************************** 330 * Find all instance fields, then push them into `fields`. 331 * 332 * Runs semantic() for all instance field variables, but also 333 * the field types can reamin yet not resolved forward references, 334 * except direct recursive definitions. 335 * After the process sizeok is set to SIZEOKfwd. 336 * 337 * Returns: 338 * false if any errors occur. 339 */ 340 bool AggregateDeclaration::determineFields() 341 { 342 if (sizeok != SIZEOKnone) 343 return true; 344 345 //printf("determineFields() %s, fields.dim = %d\n", toChars(), fields.dim); 346 fields.setDim(0); 347 348 struct SV 349 { 350 AggregateDeclaration *agg; 351 352 static int func(Dsymbol *s, void *param) 353 { 354 VarDeclaration *v = s->isVarDeclaration(); 355 if (!v) 356 return 0; 357 if (v->storage_class & STCmanifest) 358 return 0; 359 360 AggregateDeclaration *ad = ((SV *)param)->agg; 361 362 if (v->_scope) 363 v->semantic(NULL); 364 // Note: Aggregate fields or size could have determined during v->semantic. 365 if (ad->sizeok != SIZEOKnone) 366 return 1; 367 368 if (v->aliassym) 369 return 0; // If this variable was really a tuple, skip it. 370 371 if (v->storage_class & (STCstatic | STCextern | STCtls | STCgshared | STCmanifest | STCctfe | STCtemplateparameter)) 372 return 0; 373 if (!v->isField() || v->semanticRun < PASSsemanticdone) 374 return 1; // unresolvable forward reference 375 376 ad->fields.push(v); 377 378 if (v->storage_class & STCref) 379 return 0; 380 Type *tv = v->type->baseElemOf(); 381 if (tv->ty != Tstruct) 382 return 0; 383 if (ad == ((TypeStruct *)tv)->sym) 384 { 385 const char *psz = (v->type->toBasetype()->ty == Tsarray) ? "static array of " : ""; 386 ad->error("cannot have field %s with %ssame struct type", v->toChars(), psz); 387 ad->type = Type::terror; 388 ad->errors = true; 389 return 1; 390 } 391 return 0; 392 } 393 }; 394 SV sv; 395 sv.agg = this; 396 397 for (size_t i = 0; i < members->dim; i++) 398 { 399 Dsymbol *s = (*members)[i]; 400 if (s->apply(&SV::func, &sv)) 401 { 402 if (sizeok != SIZEOKnone) 403 return true; 404 return false; 405 } 406 } 407 408 if (sizeok != SIZEOKdone) 409 sizeok = SIZEOKfwd; 410 411 return true; 412 } 413 414 /*************************************** 415 * Collect all instance fields, then determine instance size. 416 * Returns: 417 * false if failed to determine the size. 418 */ 419 bool AggregateDeclaration::determineSize(Loc loc) 420 { 421 //printf("AggregateDeclaration::determineSize() %s, sizeok = %d\n", toChars(), sizeok); 422 423 // The previous instance size finalizing had: 424 if (type->ty == Terror) 425 return false; // failed already 426 if (sizeok == SIZEOKdone) 427 return true; // succeeded 428 429 if (!members) 430 { 431 error(loc, "unknown size"); 432 return false; 433 } 434 435 if (_scope) 436 semantic(NULL); 437 438 // Determine the instance size of base class first. 439 if (ClassDeclaration *cd = isClassDeclaration()) 440 { 441 cd = cd->baseClass; 442 if (cd && !cd->determineSize(loc)) 443 goto Lfail; 444 } 445 446 // Determine instance fields when sizeok == SIZEOKnone 447 if (!determineFields()) 448 goto Lfail; 449 if (sizeok != SIZEOKdone) 450 finalizeSize(); 451 452 // this aggregate type has: 453 if (type->ty == Terror) 454 return false; // marked as invalid during the finalizing. 455 if (sizeok == SIZEOKdone) 456 return true; // succeeded to calculate instance size. 457 458 Lfail: 459 // There's unresolvable forward reference. 460 if (type != Type::terror) 461 error(loc, "no size because of forward reference"); 462 // Don't cache errors from speculative semantic, might be resolvable later. 463 // https://issues.dlang.org/show_bug.cgi?id=16574 464 if (!global.gag) 465 { 466 type = Type::terror; 467 errors = true; 468 } 469 return false; 470 } 471 472 void StructDeclaration::semanticTypeInfoMembers() 473 { 474 if (xeq && 475 xeq->_scope && 476 xeq->semanticRun < PASSsemantic3done) 477 { 478 unsigned errors = global.startGagging(); 479 xeq->semantic3(xeq->_scope); 480 if (global.endGagging(errors)) 481 xeq = xerreq; 482 } 483 484 if (xcmp && 485 xcmp->_scope && 486 xcmp->semanticRun < PASSsemantic3done) 487 { 488 unsigned errors = global.startGagging(); 489 xcmp->semantic3(xcmp->_scope); 490 if (global.endGagging(errors)) 491 xcmp = xerrcmp; 492 } 493 494 FuncDeclaration *ftostr = search_toString(this); 495 if (ftostr && 496 ftostr->_scope && 497 ftostr->semanticRun < PASSsemantic3done) 498 { 499 ftostr->semantic3(ftostr->_scope); 500 } 501 502 if (xhash && 503 xhash->_scope && 504 xhash->semanticRun < PASSsemantic3done) 505 { 506 xhash->semantic3(xhash->_scope); 507 } 508 509 if (postblit && 510 postblit->_scope && 511 postblit->semanticRun < PASSsemantic3done) 512 { 513 postblit->semantic3(postblit->_scope); 514 } 515 516 if (dtor && 517 dtor->_scope && 518 dtor->semanticRun < PASSsemantic3done) 519 { 520 dtor->semantic3(dtor->_scope); 521 } 522 } 523 524 d_uns64 AggregateDeclaration::size(Loc loc) 525 { 526 //printf("+AggregateDeclaration::size() %s, scope = %p, sizeok = %d\n", toChars(), _scope, sizeok); 527 bool ok = determineSize(loc); 528 //printf("-AggregateDeclaration::size() %s, scope = %p, sizeok = %d\n", toChars(), _scope, sizeok); 529 return ok ? structsize : SIZE_INVALID; 530 } 531 532 Type *AggregateDeclaration::getType() 533 { 534 return type; 535 } 536 537 bool AggregateDeclaration::isDeprecated() 538 { 539 return isdeprecated; 540 } 541 542 bool AggregateDeclaration::isExport() const 543 { 544 return protection.kind == PROTexport; 545 } 546 547 /*************************************** 548 * Calculate field[i].overlapped and overlapUnsafe, and check that all of explicit 549 * field initializers have unique memory space on instance. 550 * Returns: 551 * true if any errors happen. 552 */ 553 554 bool AggregateDeclaration::checkOverlappedFields() 555 { 556 //printf("AggregateDeclaration::checkOverlappedFields() %s\n", toChars()); 557 assert(sizeok == SIZEOKdone); 558 size_t nfields = fields.dim; 559 if (isNested()) 560 { 561 ClassDeclaration *cd = isClassDeclaration(); 562 if (!cd || !cd->baseClass || !cd->baseClass->isNested()) 563 nfields--; 564 } 565 bool errors = false; 566 567 // Fill in missing any elements with default initializers 568 for (size_t i = 0; i < nfields; i++) 569 { 570 VarDeclaration *vd = fields[i]; 571 if (vd->errors) 572 { 573 errors = true; 574 continue; 575 } 576 577 VarDeclaration *vx = vd; 578 if (vd->_init && vd->_init->isVoidInitializer()) 579 vx = NULL; 580 581 // Find overlapped fields with the hole [vd->offset .. vd->offset->size()]. 582 for (size_t j = 0; j < nfields; j++) 583 { 584 if (i == j) 585 continue; 586 VarDeclaration *v2 = fields[j]; 587 if (v2->errors) 588 { 589 errors = true; 590 continue; 591 } 592 if (!vd->isOverlappedWith(v2)) 593 continue; 594 595 // vd and v2 are overlapping. 596 vd->overlapped = true; 597 v2->overlapped = true; 598 599 if (!MODimplicitConv(vd->type->mod, v2->type->mod)) 600 v2->overlapUnsafe = true; 601 if (!MODimplicitConv(v2->type->mod, vd->type->mod)) 602 vd->overlapUnsafe = true; 603 604 if (!vx) 605 continue; 606 if (v2->_init && v2->_init->isVoidInitializer()) 607 continue; 608 609 if (vx->_init && v2->_init) 610 { 611 ::error(loc, "overlapping default initialization for field %s and %s", v2->toChars(), vd->toChars()); 612 errors = true; 613 } 614 } 615 } 616 return errors; 617 } 618 619 /*************************************** 620 * Fill out remainder of elements[] with default initializers for fields[]. 621 * Input: 622 * loc: location 623 * elements: explicit arguments which given to construct object. 624 * ctorinit: true if the elements will be used for default initialization. 625 * Returns: 626 * false if any errors occur. 627 * Otherwise, returns true and the missing arguments will be pushed in elements[]. 628 */ 629 bool AggregateDeclaration::fill(Loc loc, Expressions *elements, bool ctorinit) 630 { 631 //printf("AggregateDeclaration::fill() %s\n", toChars()); 632 assert(sizeok == SIZEOKdone); 633 assert(elements); 634 size_t nfields = fields.dim - isNested(); 635 bool errors = false; 636 637 size_t dim = elements->dim; 638 elements->setDim(nfields); 639 for (size_t i = dim; i < nfields; i++) 640 (*elements)[i] = NULL; 641 642 // Fill in missing any elements with default initializers 643 for (size_t i = 0; i < nfields; i++) 644 { 645 if ((*elements)[i]) 646 continue; 647 648 VarDeclaration *vd = fields[i]; 649 VarDeclaration *vx = vd; 650 if (vd->_init && vd->_init->isVoidInitializer()) 651 vx = NULL; 652 653 // Find overlapped fields with the hole [vd->offset .. vd->offset->size()]. 654 size_t fieldi = i; 655 for (size_t j = 0; j < nfields; j++) 656 { 657 if (i == j) 658 continue; 659 VarDeclaration *v2 = fields[j]; 660 if (!vd->isOverlappedWith(v2)) 661 continue; 662 663 if ((*elements)[j]) 664 { 665 vx = NULL; 666 break; 667 } 668 if (v2->_init && v2->_init->isVoidInitializer()) 669 continue; 670 671 if (1) 672 { 673 /* Prefer first found non-void-initialized field 674 * union U { int a; int b = 2; } 675 * U u; // Error: overlapping initialization for field a and b 676 */ 677 if (!vx) 678 { 679 vx = v2; 680 fieldi = j; 681 } 682 else if (v2->_init) 683 { 684 ::error(loc, "overlapping initialization for field %s and %s", 685 v2->toChars(), vd->toChars()); 686 errors = true; 687 } 688 } 689 else 690 { 691 // Will fix Bugzilla 1432 by enabling this path always 692 693 /* Prefer explicitly initialized field 694 * union U { int a; int b = 2; } 695 * U u; // OK (u.b == 2) 696 */ 697 if (!vx || (!vx->_init && v2->_init)) 698 { 699 vx = v2; 700 fieldi = j; 701 } 702 else if (vx != vd && !vx->isOverlappedWith(v2)) 703 { 704 // Both vx and v2 fills vd, but vx and v2 does not overlap 705 } 706 else if (vx->_init && v2->_init) 707 { 708 ::error(loc, "overlapping default initialization for field %s and %s", 709 v2->toChars(), vd->toChars()); 710 errors = true; 711 } 712 else 713 assert(vx->_init || (!vx->_init && !v2->_init)); 714 } 715 } 716 if (vx) 717 { 718 Expression *e; 719 if (vx->type->size() == 0) 720 { 721 e = NULL; 722 } 723 else if (vx->_init) 724 { 725 assert(!vx->_init->isVoidInitializer()); 726 if (vx->inuse) // https://issues.dlang.org/show_bug.cgi?id=18057 727 { 728 vx->error(loc, "recursive initialization of field"); 729 errors = true; 730 e = NULL; 731 } 732 else 733 e = vx->getConstInitializer(false); 734 } 735 else 736 { 737 if ((vx->storage_class & STCnodefaultctor) && !ctorinit) 738 { 739 ::error(loc, "field %s.%s must be initialized because it has no default constructor", 740 type->toChars(), vx->toChars()); 741 errors = true; 742 } 743 744 /* Bugzilla 12509: Get the element of static array type. 745 */ 746 Type *telem = vx->type; 747 if (telem->ty == Tsarray) 748 { 749 /* We cannot use Type::baseElemOf() here. 750 * If the bottom of the Tsarray is an enum type, baseElemOf() 751 * will return the base of the enum, and its default initializer 752 * would be different from the enum's. 753 */ 754 while (telem->toBasetype()->ty == Tsarray) 755 telem = ((TypeSArray *)telem->toBasetype())->next; 756 757 if (telem->ty == Tvoid) 758 telem = Type::tuns8->addMod(telem->mod); 759 } 760 if (telem->needsNested() && ctorinit) 761 e = telem->defaultInit(loc); 762 else 763 e = telem->defaultInitLiteral(loc); 764 } 765 (*elements)[fieldi] = e; 766 } 767 } 768 769 for (size_t i = 0; i < elements->dim; i++) 770 { 771 Expression *e = (*elements)[i]; 772 if (e && e->op == TOKerror) 773 return false; 774 } 775 776 return !errors; 777 } 778 779 /**************************** 780 * Do byte or word alignment as necessary. 781 * Align sizes of 0, as we may not know array sizes yet. 782 * 783 * alignment: struct alignment that is in effect 784 * size: alignment requirement of field 785 */ 786 787 void AggregateDeclaration::alignmember( 788 structalign_t alignment, 789 unsigned size, 790 unsigned *poffset) 791 { 792 //printf("alignment = %d, size = %d, offset = %d\n",alignment,size,offset); 793 switch (alignment) 794 { 795 case (structalign_t) 1: 796 // No alignment 797 break; 798 799 case (structalign_t) STRUCTALIGN_DEFAULT: 800 // Alignment in Target::fieldalignsize must match what the 801 // corresponding C compiler's default alignment behavior is. 802 assert(size > 0 && !(size & (size - 1))); 803 *poffset = (*poffset + size - 1) & ~(size - 1); 804 break; 805 806 default: 807 // Align on alignment boundary, which must be a positive power of 2 808 assert(alignment > 0 && !(alignment & (alignment - 1))); 809 *poffset = (*poffset + alignment - 1) & ~(alignment - 1); 810 break; 811 } 812 } 813 814 /**************************************** 815 * Place a member (mem) into an aggregate (agg), which can be a struct, union or class 816 * Returns: 817 * offset to place field at 818 * 819 * nextoffset: next location in aggregate 820 * memsize: size of member 821 * memalignsize: natural alignment of member 822 * alignment: alignment in effect for this member 823 * paggsize: size of aggregate (updated) 824 * paggalignsize: alignment of aggregate (updated) 825 * isunion: the aggregate is a union 826 */ 827 unsigned AggregateDeclaration::placeField( 828 unsigned *nextoffset, 829 unsigned memsize, 830 unsigned memalignsize, 831 structalign_t alignment, 832 unsigned *paggsize, 833 unsigned *paggalignsize, 834 bool isunion 835 ) 836 { 837 unsigned ofs = *nextoffset; 838 839 const unsigned actualAlignment = 840 alignment == STRUCTALIGN_DEFAULT ? memalignsize : alignment; 841 842 alignmember(alignment, memalignsize, &ofs); 843 unsigned memoffset = ofs; 844 ofs += memsize; 845 if (ofs > *paggsize) 846 *paggsize = ofs; 847 if (!isunion) 848 *nextoffset = ofs; 849 850 if (*paggalignsize < actualAlignment) 851 *paggalignsize = actualAlignment; 852 853 return memoffset; 854 } 855 856 857 /**************************************** 858 * Returns true if there's an extra member which is the 'this' 859 * pointer to the enclosing context (enclosing aggregate or function) 860 */ 861 862 bool AggregateDeclaration::isNested() 863 { 864 return enclosing != NULL; 865 } 866 867 /* Append vthis field (this->tupleof[$-1]) to make this aggregate type nested. 868 */ 869 void AggregateDeclaration::makeNested() 870 { 871 if (enclosing) // if already nested 872 return; 873 if (sizeok == SIZEOKdone) 874 return; 875 if (isUnionDeclaration() || isInterfaceDeclaration()) 876 return; 877 if (storage_class & STCstatic) 878 return; 879 880 // If nested struct, add in hidden 'this' pointer to outer scope 881 Dsymbol *s = toParent2(); 882 if (!s) 883 return; 884 Type *t = NULL; 885 if (FuncDeclaration *fd = s->isFuncDeclaration()) 886 { 887 enclosing = fd; 888 889 /* Bugzilla 14422: If a nested class parent is a function, its 890 * context pointer (== `outer`) should be void* always. 891 */ 892 t = Type::tvoidptr; 893 } 894 else if (AggregateDeclaration *ad = s->isAggregateDeclaration()) 895 { 896 if (isClassDeclaration() && ad->isClassDeclaration()) 897 { 898 enclosing = ad; 899 } 900 else if (isStructDeclaration()) 901 { 902 if (TemplateInstance *ti = ad->parent->isTemplateInstance()) 903 { 904 enclosing = ti->enclosing; 905 } 906 } 907 908 t = ad->handleType(); 909 } 910 if (enclosing) 911 { 912 //printf("makeNested %s, enclosing = %s\n", toChars(), enclosing->toChars()); 913 assert(t); 914 if (t->ty == Tstruct) 915 t = Type::tvoidptr; // t should not be a ref type 916 assert(!vthis); 917 vthis = new ThisDeclaration(loc, t); 918 //vthis->storage_class |= STCref; 919 920 // Emulate vthis->addMember() 921 members->push(vthis); 922 923 // Emulate vthis->semantic() 924 vthis->storage_class |= STCfield; 925 vthis->parent = this; 926 vthis->protection = Prot(PROTpublic); 927 vthis->alignment = t->alignment(); 928 vthis->semanticRun = PASSsemanticdone; 929 930 if (sizeok == SIZEOKfwd) 931 fields.push(vthis); 932 } 933 } 934 935 /******************************************* 936 * Look for constructor declaration. 937 */ 938 Dsymbol *AggregateDeclaration::searchCtor() 939 { 940 Dsymbol *s = search(Loc(), Id::ctor); 941 if (s) 942 { 943 if (!(s->isCtorDeclaration() || 944 s->isTemplateDeclaration() || 945 s->isOverloadSet())) 946 { 947 s->error("is not a constructor; identifiers starting with __ are reserved for the implementation"); 948 errors = true; 949 s = NULL; 950 } 951 } 952 if (s && s->toParent() != this) 953 s = NULL; // search() looks through ancestor classes 954 if (s) 955 { 956 // Finish all constructors semantics to determine this->noDefaultCtor. 957 struct SearchCtor 958 { 959 static int fp(Dsymbol *s, void *) 960 { 961 CtorDeclaration *f = s->isCtorDeclaration(); 962 if (f && f->semanticRun == PASSinit) 963 f->semantic(NULL); 964 return 0; 965 } 966 }; 967 968 for (size_t i = 0; i < members->dim; i++) 969 { 970 Dsymbol *sm = (*members)[i]; 971 sm->apply(&SearchCtor::fp, NULL); 972 } 973 } 974 return s; 975 } 976 977 /********************************* StructDeclaration ****************************/ 978 979 StructDeclaration::StructDeclaration(Loc loc, Identifier *id, bool inObject) 980 : AggregateDeclaration(loc, id) 981 { 982 zeroInit = 0; // assume false until we do semantic processing 983 hasIdentityAssign = false; 984 hasIdentityEquals = false; 985 postblit = NULL; 986 987 xeq = NULL; 988 xcmp = NULL; 989 xhash = NULL; 990 alignment = 0; 991 ispod = ISPODfwd; 992 arg1type = NULL; 993 arg2type = NULL; 994 requestTypeInfo = false; 995 996 // For forward references 997 type = new TypeStruct(this); 998 999 if (inObject) 1000 { 1001 if (id == Id::ModuleInfo && !Module::moduleinfo) 1002 Module::moduleinfo = this; 1003 } 1004 } 1005 1006 StructDeclaration *StructDeclaration::create(Loc loc, Identifier *id, bool inObject) 1007 { 1008 return new StructDeclaration(loc, id, inObject); 1009 } 1010 1011 Dsymbol *StructDeclaration::syntaxCopy(Dsymbol *s) 1012 { 1013 StructDeclaration *sd = 1014 s ? (StructDeclaration *)s 1015 : new StructDeclaration(loc, ident, false); 1016 return ScopeDsymbol::syntaxCopy(sd); 1017 } 1018 1019 void StructDeclaration::semantic(Scope *sc) 1020 { 1021 //printf("StructDeclaration::semantic(this=%p, %s '%s', sizeok = %d)\n", this, parent->toChars(), toChars(), sizeok); 1022 1023 //static int count; if (++count == 20) halt(); 1024 1025 if (semanticRun >= PASSsemanticdone) 1026 return; 1027 unsigned errors = global.errors; 1028 1029 //printf("+StructDeclaration::semantic(this=%p, %s '%s', sizeok = %d)\n", this, parent->toChars(), toChars(), sizeok); 1030 Scope *scx = NULL; 1031 if (_scope) 1032 { 1033 sc = _scope; 1034 scx = _scope; // save so we don't make redundant copies 1035 _scope = NULL; 1036 } 1037 1038 if (!parent) 1039 { 1040 assert(sc->parent && sc->func); 1041 parent = sc->parent; 1042 } 1043 assert(parent && !isAnonymous()); 1044 1045 if (this->errors) 1046 type = Type::terror; 1047 if (semanticRun == PASSinit) 1048 type = type->addSTC(sc->stc | storage_class); 1049 type = type->semantic(loc, sc); 1050 1051 if (type->ty == Tstruct && ((TypeStruct *)type)->sym != this) 1052 { 1053 TemplateInstance *ti = ((TypeStruct *)type)->sym->isInstantiated(); 1054 if (ti && isError(ti)) 1055 ((TypeStruct *)type)->sym = this; 1056 } 1057 1058 // Ungag errors when not speculative 1059 Ungag ungag = ungagSpeculative(); 1060 1061 if (semanticRun == PASSinit) 1062 { 1063 protection = sc->protection; 1064 1065 alignment = sc->alignment(); 1066 1067 storage_class |= sc->stc; 1068 if (storage_class & STCdeprecated) 1069 isdeprecated = true; 1070 if (storage_class & STCabstract) 1071 error("structs, unions cannot be abstract"); 1072 userAttribDecl = sc->userAttribDecl; 1073 } 1074 else if (symtab && !scx) 1075 { 1076 return; 1077 } 1078 semanticRun = PASSsemantic; 1079 1080 if (!members) // if opaque declaration 1081 { 1082 semanticRun = PASSsemanticdone; 1083 return; 1084 } 1085 if (!symtab) 1086 { 1087 symtab = new DsymbolTable(); 1088 1089 for (size_t i = 0; i < members->dim; i++) 1090 { 1091 Dsymbol *s = (*members)[i]; 1092 //printf("adding member '%s' to '%s'\n", s->toChars(), this->toChars()); 1093 s->addMember(sc, this); 1094 } 1095 } 1096 1097 Scope *sc2 = newScope(sc); 1098 1099 /* Set scope so if there are forward references, we still might be able to 1100 * resolve individual members like enums. 1101 */ 1102 for (size_t i = 0; i < members->dim; i++) 1103 { 1104 Dsymbol *s = (*members)[i]; 1105 //printf("struct: setScope %s %s\n", s->kind(), s->toChars()); 1106 s->setScope(sc2); 1107 } 1108 1109 for (size_t i = 0; i < members->dim; i++) 1110 { 1111 Dsymbol *s = (*members)[i]; 1112 s->importAll(sc2); 1113 } 1114 1115 for (size_t i = 0; i < members->dim; i++) 1116 { 1117 Dsymbol *s = (*members)[i]; 1118 s->semantic(sc2); 1119 } 1120 1121 if (!determineFields()) 1122 { 1123 assert(type->ty == Terror); 1124 sc2->pop(); 1125 semanticRun = PASSsemanticdone; 1126 return; 1127 } 1128 1129 /* Following special member functions creation needs semantic analysis 1130 * completion of sub-structs in each field types. For example, buildDtor 1131 * needs to check existence of elaborate dtor in type of each fields. 1132 * See the case in compilable/test14838.d 1133 */ 1134 for (size_t i = 0; i < fields.dim; i++) 1135 { 1136 VarDeclaration *v = fields[i]; 1137 Type *tb = v->type->baseElemOf(); 1138 if (tb->ty != Tstruct) 1139 continue; 1140 StructDeclaration *sd = ((TypeStruct *)tb)->sym; 1141 if (sd->semanticRun >= PASSsemanticdone) 1142 continue; 1143 1144 sc2->pop(); 1145 1146 _scope = scx ? scx : sc->copy(); 1147 _scope->setNoFree(); 1148 _scope->_module->addDeferredSemantic(this); 1149 1150 //printf("\tdeferring %s\n", toChars()); 1151 return; 1152 } 1153 1154 /* Look for special member functions. 1155 */ 1156 aggNew = (NewDeclaration *)search(Loc(), Id::classNew); 1157 aggDelete = (DeleteDeclaration *)search(Loc(), Id::classDelete); 1158 1159 // Look for the constructor 1160 ctor = searchCtor(); 1161 1162 dtor = buildDtor(this, sc2); 1163 postblit = buildPostBlit(this, sc2); 1164 1165 buildOpAssign(this, sc2); 1166 buildOpEquals(this, sc2); 1167 1168 if (global.params.useTypeInfo && Type::dtypeinfo) // these functions are used for TypeInfo 1169 { 1170 xeq = buildXopEquals(this, sc2); 1171 xcmp = buildXopCmp(this, sc2); 1172 xhash = buildXtoHash(this, sc2); 1173 } 1174 1175 inv = buildInv(this, sc2); 1176 1177 Module::dprogress++; 1178 semanticRun = PASSsemanticdone; 1179 //printf("-StructDeclaration::semantic(this=%p, '%s')\n", this, toChars()); 1180 1181 sc2->pop(); 1182 1183 if (ctor) 1184 { 1185 Dsymbol *scall = search(Loc(), Id::call); 1186 if (scall) 1187 { 1188 unsigned xerrors = global.startGagging(); 1189 sc = sc->push(); 1190 sc->tinst = NULL; 1191 sc->minst = NULL; 1192 FuncDeclaration *fcall = resolveFuncCall(loc, sc, scall, NULL, NULL, NULL, 1); 1193 sc = sc->pop(); 1194 global.endGagging(xerrors); 1195 1196 if (fcall && fcall->isStatic()) 1197 { 1198 error(fcall->loc, "static opCall is hidden by constructors and can never be called"); 1199 errorSupplemental(fcall->loc, "Please use a factory method instead, or replace all constructors with static opCall."); 1200 } 1201 } 1202 } 1203 1204 if (global.errors != errors) 1205 { 1206 // The type is no good. 1207 type = Type::terror; 1208 this->errors = true; 1209 if (deferred) 1210 deferred->errors = true; 1211 } 1212 1213 if (deferred && !global.gag) 1214 { 1215 deferred->semantic2(sc); 1216 deferred->semantic3(sc); 1217 } 1218 1219 assert(type->ty != Tstruct || ((TypeStruct *)type)->sym == this); 1220 } 1221 1222 Dsymbol *StructDeclaration::search(const Loc &loc, Identifier *ident, int flags) 1223 { 1224 //printf("%s.StructDeclaration::search('%s', flags = x%x)\n", toChars(), ident->toChars(), flags); 1225 1226 if (_scope && !symtab) 1227 semantic(_scope); 1228 1229 if (!members || !symtab) // opaque or semantic() is not yet called 1230 { 1231 error("is forward referenced when looking for '%s'", ident->toChars()); 1232 return NULL; 1233 } 1234 1235 return ScopeDsymbol::search(loc, ident, flags); 1236 } 1237 1238 void StructDeclaration::finalizeSize() 1239 { 1240 //printf("StructDeclaration::finalizeSize() %s, sizeok = %d\n", toChars(), sizeok); 1241 assert(sizeok != SIZEOKdone); 1242 1243 //printf("+StructDeclaration::finalizeSize() %s, fields.dim = %d, sizeok = %d\n", toChars(), fields.dim, sizeok); 1244 1245 fields.setDim(0); // workaround 1246 1247 // Set the offsets of the fields and determine the size of the struct 1248 unsigned offset = 0; 1249 bool isunion = isUnionDeclaration() != NULL; 1250 for (size_t i = 0; i < members->dim; i++) 1251 { 1252 Dsymbol *s = (*members)[i]; 1253 s->setFieldOffset(this, &offset, isunion); 1254 } 1255 if (type->ty == Terror) 1256 return; 1257 1258 // 0 sized struct's are set to 1 byte 1259 if (structsize == 0) 1260 { 1261 structsize = 1; 1262 alignsize = 1; 1263 } 1264 1265 // Round struct size up to next alignsize boundary. 1266 // This will ensure that arrays of structs will get their internals 1267 // aligned properly. 1268 if (alignment == STRUCTALIGN_DEFAULT) 1269 structsize = (structsize + alignsize - 1) & ~(alignsize - 1); 1270 else 1271 structsize = (structsize + alignment - 1) & ~(alignment - 1); 1272 1273 sizeok = SIZEOKdone; 1274 1275 //printf("-StructDeclaration::finalizeSize() %s, fields.dim = %d, structsize = %d\n", toChars(), fields.dim, structsize); 1276 1277 if (errors) 1278 return; 1279 1280 // Calculate fields[i]->overlapped 1281 if (checkOverlappedFields()) 1282 { 1283 errors = true; 1284 return; 1285 } 1286 1287 // Determine if struct is all zeros or not 1288 zeroInit = 1; 1289 for (size_t i = 0; i < fields.dim; i++) 1290 { 1291 VarDeclaration *vd = fields[i]; 1292 if (vd->_init) 1293 { 1294 // Should examine init to see if it is really all 0's 1295 zeroInit = 0; 1296 break; 1297 } 1298 else if (!vd->type->isZeroInit(loc)) 1299 { 1300 zeroInit = 0; 1301 break; 1302 } 1303 } 1304 1305 TypeTuple *tt = toArgTypes(type); 1306 size_t dim = tt->arguments->dim; 1307 if (dim >= 1) 1308 { 1309 assert(dim <= 2); 1310 arg1type = (*tt->arguments)[0]->type; 1311 if (dim == 2) 1312 arg2type = (*tt->arguments)[1]->type; 1313 } 1314 } 1315 1316 /*************************************** 1317 * Fit elements[] to the corresponding type of field[]. 1318 * Input: 1319 * loc 1320 * sc 1321 * elements The explicit arguments that given to construct object. 1322 * stype The constructed object type. 1323 * Returns false if any errors occur. 1324 * Otherwise, returns true and elements[] are rewritten for the output. 1325 */ 1326 bool StructDeclaration::fit(Loc loc, Scope *sc, Expressions *elements, Type *stype) 1327 { 1328 if (!elements) 1329 return true; 1330 1331 size_t nfields = fields.dim - isNested(); 1332 size_t offset = 0; 1333 for (size_t i = 0; i < elements->dim; i++) 1334 { 1335 Expression *e = (*elements)[i]; 1336 if (!e) 1337 continue; 1338 1339 e = resolveProperties(sc, e); 1340 if (i >= nfields) 1341 { 1342 if (i == fields.dim - 1 && isNested() && e->op == TOKnull) 1343 { 1344 // CTFE sometimes creates null as hidden pointer; we'll allow this. 1345 continue; 1346 } 1347 ::error(loc, "more initializers than fields (%d) of %s", (int)nfields, toChars()); 1348 return false; 1349 } 1350 VarDeclaration *v = fields[i]; 1351 if (v->offset < offset) 1352 { 1353 ::error(loc, "overlapping initialization for %s", v->toChars()); 1354 return false; 1355 } 1356 offset = (unsigned)(v->offset + v->type->size()); 1357 1358 Type *t = v->type; 1359 if (stype) 1360 t = t->addMod(stype->mod); 1361 Type *origType = t; 1362 Type *tb = t->toBasetype(); 1363 1364 /* Look for case of initializing a static array with a too-short 1365 * string literal, such as: 1366 * char[5] foo = "abc"; 1367 * Allow this by doing an explicit cast, which will lengthen the string 1368 * literal. 1369 */ 1370 if (e->op == TOKstring && tb->ty == Tsarray) 1371 { 1372 StringExp *se = (StringExp *)e; 1373 Type *typeb = se->type->toBasetype(); 1374 TY tynto = tb->nextOf()->ty; 1375 if (!se->committed && 1376 (typeb->ty == Tarray || typeb->ty == Tsarray) && 1377 (tynto == Tchar || tynto == Twchar || tynto == Tdchar) && 1378 se->numberOfCodeUnits(tynto) < ((TypeSArray *)tb)->dim->toInteger()) 1379 { 1380 e = se->castTo(sc, t); 1381 goto L1; 1382 } 1383 } 1384 1385 while (!e->implicitConvTo(t) && tb->ty == Tsarray) 1386 { 1387 /* Static array initialization, as in: 1388 * T[3][5] = e; 1389 */ 1390 t = tb->nextOf(); 1391 tb = t->toBasetype(); 1392 } 1393 if (!e->implicitConvTo(t)) 1394 t = origType; // restore type for better diagnostic 1395 1396 e = e->implicitCastTo(sc, t); 1397 L1: 1398 if (e->op == TOKerror) 1399 return false; 1400 1401 (*elements)[i] = doCopyOrMove(sc, e); 1402 } 1403 return true; 1404 } 1405 1406 /*************************************** 1407 * Return true if struct is POD (Plain Old Data). 1408 * This is defined as: 1409 * not nested 1410 * no postblits, destructors, or assignment operators 1411 * no 'ref' fields or fields that are themselves non-POD 1412 * The idea being these are compatible with C structs. 1413 */ 1414 bool StructDeclaration::isPOD() 1415 { 1416 // If we've already determined whether this struct is POD. 1417 if (ispod != ISPODfwd) 1418 return (ispod == ISPODyes); 1419 1420 ispod = ISPODyes; 1421 1422 if (enclosing || postblit || dtor) 1423 ispod = ISPODno; 1424 1425 // Recursively check all fields are POD. 1426 for (size_t i = 0; i < fields.dim; i++) 1427 { 1428 VarDeclaration *v = fields[i]; 1429 if (v->storage_class & STCref) 1430 { 1431 ispod = ISPODno; 1432 break; 1433 } 1434 1435 Type *tv = v->type->baseElemOf(); 1436 if (tv->ty == Tstruct) 1437 { 1438 TypeStruct *ts = (TypeStruct *)tv; 1439 StructDeclaration *sd = ts->sym; 1440 if (!sd->isPOD()) 1441 { 1442 ispod = ISPODno; 1443 break; 1444 } 1445 } 1446 } 1447 1448 return (ispod == ISPODyes); 1449 } 1450 1451 const char *StructDeclaration::kind() const 1452 { 1453 return "struct"; 1454 } 1455 1456 /********************************* UnionDeclaration ****************************/ 1457 1458 UnionDeclaration::UnionDeclaration(Loc loc, Identifier *id) 1459 : StructDeclaration(loc, id, false) 1460 { 1461 } 1462 1463 Dsymbol *UnionDeclaration::syntaxCopy(Dsymbol *s) 1464 { 1465 assert(!s); 1466 UnionDeclaration *ud = new UnionDeclaration(loc, ident); 1467 return StructDeclaration::syntaxCopy(ud); 1468 } 1469 1470 const char *UnionDeclaration::kind() const 1471 { 1472 return "union"; 1473 } 1474