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