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/declaration.c 9 */ 10 11 #include "root/dsystem.h" 12 #include "root/checkedint.h" 13 14 #include "errors.h" 15 #include "init.h" 16 #include "declaration.h" 17 #include "attrib.h" 18 #include "mtype.h" 19 #include "template.h" 20 #include "scope.h" 21 #include "aggregate.h" 22 #include "module.h" 23 #include "import.h" 24 #include "id.h" 25 #include "expression.h" 26 #include "statement.h" 27 #include "ctfe.h" 28 #include "target.h" 29 #include "hdrgen.h" 30 31 bool checkNestedRef(Dsymbol *s, Dsymbol *p); 32 VarDeclaration *copyToTemp(StorageClass stc, const char *name, Expression *e); 33 Expression *semantic(Expression *e, Scope *sc); 34 Initializer *inferType(Initializer *init, Scope *sc); 35 Initializer *semantic(Initializer *init, Scope *sc, Type *t, NeedInterpret needInterpret); 36 37 /************************************ 38 * Check to see the aggregate type is nested and its context pointer is 39 * accessible from the current scope. 40 * Returns true if error occurs. 41 */ 42 bool checkFrameAccess(Loc loc, Scope *sc, AggregateDeclaration *ad, size_t iStart = 0) 43 { 44 Dsymbol *sparent = ad->toParent2(); 45 Dsymbol *s = sc->func; 46 if (ad->isNested() && s) 47 { 48 //printf("ad = %p %s [%s], parent:%p\n", ad, ad->toChars(), ad->loc.toChars(), ad->parent); 49 //printf("sparent = %p %s [%s], parent: %s\n", sparent, sparent->toChars(), sparent->loc.toChars(), sparent->parent->toChars()); 50 if (checkNestedRef(s, sparent)) 51 { 52 error(loc, "cannot access frame pointer of %s", ad->toPrettyChars()); 53 return true; 54 } 55 } 56 57 bool result = false; 58 for (size_t i = iStart; i < ad->fields.dim; i++) 59 { 60 VarDeclaration *vd = ad->fields[i]; 61 Type *tb = vd->type->baseElemOf(); 62 if (tb->ty == Tstruct) 63 { 64 result |= checkFrameAccess(loc, sc, ((TypeStruct *)tb)->sym); 65 } 66 } 67 return result; 68 } 69 70 /********************************* Declaration ****************************/ 71 72 Declaration::Declaration(Identifier *id) 73 : Dsymbol(id) 74 { 75 type = NULL; 76 originalType = NULL; 77 storage_class = STCundefined; 78 protection = Prot(PROTundefined); 79 linkage = LINKdefault; 80 inuse = 0; 81 mangleOverride = NULL; 82 } 83 84 void Declaration::semantic(Scope *) 85 { 86 } 87 88 const char *Declaration::kind() const 89 { 90 return "declaration"; 91 } 92 93 d_uns64 Declaration::size(Loc) 94 { 95 assert(type); 96 return type->size(); 97 } 98 99 bool Declaration::isDelete() 100 { 101 return false; 102 } 103 104 bool Declaration::isDataseg() 105 { 106 return false; 107 } 108 109 bool Declaration::isThreadlocal() 110 { 111 return false; 112 } 113 114 bool Declaration::isCodeseg() const 115 { 116 return false; 117 } 118 119 Prot Declaration::prot() 120 { 121 return protection; 122 } 123 124 /************************************* 125 * Check to see if declaration can be modified in this context (sc). 126 * Issue error if not. 127 */ 128 129 int Declaration::checkModify(Loc loc, Scope *sc, Type *, Expression *e1, int flag) 130 { 131 VarDeclaration *v = isVarDeclaration(); 132 if (v && v->canassign) 133 return 2; 134 135 if (isParameter() || isResult()) 136 { 137 for (Scope *scx = sc; scx; scx = scx->enclosing) 138 { 139 if (scx->func == parent && (scx->flags & SCOPEcontract)) 140 { 141 const char *s = isParameter() && parent->ident != Id::ensure ? "parameter" : "result"; 142 if (!flag) error(loc, "cannot modify %s '%s' in contract", s, toChars()); 143 return 2; // do not report type related errors 144 } 145 } 146 } 147 148 if (v && (isCtorinit() || isField())) 149 { 150 // It's only modifiable if inside the right constructor 151 if ((storage_class & (STCforeach | STCref)) == (STCforeach | STCref)) 152 return 2; 153 return modifyFieldVar(loc, sc, v, e1) ? 2 : 1; 154 } 155 return 1; 156 } 157 158 Dsymbol *Declaration::search(const Loc &loc, Identifier *ident, int flags) 159 { 160 Dsymbol *s = Dsymbol::search(loc, ident, flags); 161 if (!s && type) 162 { 163 s = type->toDsymbol(_scope); 164 if (s) 165 s = s->search(loc, ident, flags); 166 } 167 return s; 168 } 169 170 171 /********************************* TupleDeclaration ****************************/ 172 173 TupleDeclaration::TupleDeclaration(Loc loc, Identifier *id, Objects *objects) 174 : Declaration(id) 175 { 176 this->loc = loc; 177 this->type = NULL; 178 this->objects = objects; 179 this->isexp = false; 180 this->tupletype = NULL; 181 } 182 183 Dsymbol *TupleDeclaration::syntaxCopy(Dsymbol *) 184 { 185 assert(0); 186 return NULL; 187 } 188 189 const char *TupleDeclaration::kind() const 190 { 191 return "tuple"; 192 } 193 194 Type *TupleDeclaration::getType() 195 { 196 /* If this tuple represents a type, return that type 197 */ 198 199 //printf("TupleDeclaration::getType() %s\n", toChars()); 200 if (isexp) 201 return NULL; 202 if (!tupletype) 203 { 204 /* It's only a type tuple if all the Object's are types 205 */ 206 for (size_t i = 0; i < objects->dim; i++) 207 { 208 RootObject *o = (*objects)[i]; 209 if (o->dyncast() != DYNCAST_TYPE) 210 { 211 //printf("\tnot[%d], %p, %d\n", i, o, o->dyncast()); 212 return NULL; 213 } 214 } 215 216 /* We know it's a type tuple, so build the TypeTuple 217 */ 218 Types *types = (Types *)objects; 219 Parameters *args = new Parameters(); 220 args->setDim(objects->dim); 221 OutBuffer buf; 222 int hasdeco = 1; 223 for (size_t i = 0; i < types->dim; i++) 224 { 225 Type *t = (*types)[i]; 226 //printf("type = %s\n", t->toChars()); 227 Parameter *arg = new Parameter(0, t, NULL, NULL); 228 (*args)[i] = arg; 229 if (!t->deco) 230 hasdeco = 0; 231 } 232 233 tupletype = new TypeTuple(args); 234 if (hasdeco) 235 return tupletype->semantic(Loc(), NULL); 236 } 237 238 return tupletype; 239 } 240 241 Dsymbol *TupleDeclaration::toAlias2() 242 { 243 //printf("TupleDeclaration::toAlias2() '%s' objects = %s\n", toChars(), objects->toChars()); 244 245 for (size_t i = 0; i < objects->dim; i++) 246 { 247 RootObject *o = (*objects)[i]; 248 if (Dsymbol *s = isDsymbol(o)) 249 { 250 s = s->toAlias2(); 251 (*objects)[i] = s; 252 } 253 } 254 return this; 255 } 256 257 bool TupleDeclaration::needThis() 258 { 259 //printf("TupleDeclaration::needThis(%s)\n", toChars()); 260 for (size_t i = 0; i < objects->dim; i++) 261 { 262 RootObject *o = (*objects)[i]; 263 if (o->dyncast() == DYNCAST_EXPRESSION) 264 { 265 Expression *e = (Expression *)o; 266 if (e->op == TOKdsymbol) 267 { 268 DsymbolExp *ve = (DsymbolExp *)e; 269 Declaration *d = ve->s->isDeclaration(); 270 if (d && d->needThis()) 271 { 272 return true; 273 } 274 } 275 } 276 } 277 return false; 278 } 279 280 /********************************* AliasDeclaration ****************************/ 281 282 AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Type *type) 283 : Declaration(id) 284 { 285 //printf("AliasDeclaration(id = '%s', type = %p)\n", id->toChars(), type); 286 //printf("type = '%s'\n", type->toChars()); 287 this->loc = loc; 288 this->type = type; 289 this->aliassym = NULL; 290 this->_import = NULL; 291 this->overnext = NULL; 292 assert(type); 293 } 294 295 AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Dsymbol *s) 296 : Declaration(id) 297 { 298 //printf("AliasDeclaration(id = '%s', s = %p)\n", id->toChars(), s); 299 assert(s != this); 300 this->loc = loc; 301 this->type = NULL; 302 this->aliassym = s; 303 this->_import = NULL; 304 this->overnext = NULL; 305 assert(s); 306 } 307 308 AliasDeclaration *AliasDeclaration::create(Loc loc, Identifier *id, Type *type) 309 { 310 return new AliasDeclaration(loc, id, type); 311 } 312 313 Dsymbol *AliasDeclaration::syntaxCopy(Dsymbol *s) 314 { 315 //printf("AliasDeclaration::syntaxCopy()\n"); 316 assert(!s); 317 AliasDeclaration *sa = 318 type ? new AliasDeclaration(loc, ident, type->syntaxCopy()) 319 : new AliasDeclaration(loc, ident, aliassym->syntaxCopy(NULL)); 320 sa->storage_class = storage_class; 321 return sa; 322 } 323 324 void AliasDeclaration::semantic(Scope *sc) 325 { 326 if (semanticRun >= PASSsemanticdone) 327 return; 328 assert(semanticRun <= PASSsemantic); 329 330 storage_class |= sc->stc & STCdeprecated; 331 protection = sc->protection; 332 userAttribDecl = sc->userAttribDecl; 333 334 if (!sc->func && inNonRoot()) 335 return; 336 337 aliasSemantic(sc); 338 } 339 340 void AliasDeclaration::aliasSemantic(Scope *sc) 341 { 342 //printf("AliasDeclaration::semantic() %s\n", toChars()); 343 if (aliassym) 344 { 345 FuncDeclaration *fd = aliassym->isFuncLiteralDeclaration(); 346 TemplateDeclaration *td = aliassym->isTemplateDeclaration(); 347 if (fd || (td && td->literal)) 348 { 349 if (fd && fd->semanticRun >= PASSsemanticdone) 350 return; 351 352 Expression *e = new FuncExp(loc, aliassym); 353 e = ::semantic(e, sc); 354 if (e->op == TOKfunction) 355 { 356 FuncExp *fe = (FuncExp *)e; 357 aliassym = fe->td ? (Dsymbol *)fe->td : fe->fd; 358 } 359 else 360 { 361 aliassym = NULL; 362 type = Type::terror; 363 } 364 return; 365 } 366 367 if (aliassym->isTemplateInstance()) 368 aliassym->semantic(sc); 369 return; 370 } 371 inuse = 1; 372 373 // Given: 374 // alias foo.bar.abc def; 375 // it is not knowable from the syntax whether this is an alias 376 // for a type or an alias for a symbol. It is up to the semantic() 377 // pass to distinguish. 378 // If it is a type, then type is set and getType() will return that 379 // type. If it is a symbol, then aliassym is set and type is NULL - 380 // toAlias() will return aliasssym. 381 382 unsigned int errors = global.errors; 383 Type *oldtype = type; 384 385 // Ungag errors when not instantiated DeclDefs scope alias 386 Ungag ungag(global.gag); 387 //printf("%s parent = %s, gag = %d, instantiated = %d\n", toChars(), parent, global.gag, isInstantiated()); 388 if (parent && global.gag && !isInstantiated() && !toParent2()->isFuncDeclaration()) 389 { 390 //printf("%s type = %s\n", toPrettyChars(), type->toChars()); 391 global.gag = 0; 392 } 393 394 /* This section is needed because Type::resolve() will: 395 * const x = 3; 396 * alias y = x; 397 * try to convert identifier x to 3. 398 */ 399 Dsymbol *s = type->toDsymbol(sc); 400 if (errors != global.errors) 401 { 402 s = NULL; 403 type = Type::terror; 404 } 405 if (s && s == this) 406 { 407 error("cannot resolve"); 408 s = NULL; 409 type = Type::terror; 410 } 411 if (!s || !s->isEnumMember()) 412 { 413 Type *t; 414 Expression *e; 415 Scope *sc2 = sc; 416 if (storage_class & (STCref | STCnothrow | STCnogc | STCpure | STCdisable)) 417 { 418 // For 'ref' to be attached to function types, and picked 419 // up by Type::resolve(), it has to go into sc. 420 sc2 = sc->push(); 421 sc2->stc |= storage_class & (STCref | STCnothrow | STCnogc | STCpure | STCshared | STCdisable); 422 } 423 type = type->addSTC(storage_class); 424 type->resolve(loc, sc2, &e, &t, &s); 425 if (sc2 != sc) 426 sc2->pop(); 427 428 if (e) // Try to convert Expression to Dsymbol 429 { 430 s = getDsymbol(e); 431 if (!s) 432 { 433 if (e->op != TOKerror) 434 error("cannot alias an expression %s", e->toChars()); 435 t = Type::terror; 436 } 437 } 438 type = t; 439 } 440 if (s == this) 441 { 442 assert(global.errors); 443 type = Type::terror; 444 s = NULL; 445 } 446 if (!s) // it's a type alias 447 { 448 //printf("alias %s resolved to type %s\n", toChars(), type->toChars()); 449 type = type->semantic(loc, sc); 450 aliassym = NULL; 451 } 452 else // it's a symbolic alias 453 { 454 //printf("alias %s resolved to %s %s\n", toChars(), s->kind(), s->toChars()); 455 type = NULL; 456 aliassym = s; 457 } 458 if (global.gag && errors != global.errors) 459 { 460 type = oldtype; 461 aliassym = NULL; 462 } 463 inuse = 0; 464 semanticRun = PASSsemanticdone; 465 466 if (Dsymbol *sx = overnext) 467 { 468 overnext = NULL; 469 470 if (!overloadInsert(sx)) 471 ScopeDsymbol::multiplyDefined(Loc(), sx, this); 472 } 473 } 474 475 bool AliasDeclaration::overloadInsert(Dsymbol *s) 476 { 477 //printf("[%s] AliasDeclaration::overloadInsert('%s') s = %s %s @ [%s]\n", 478 // loc.toChars(), toChars(), s->kind(), s->toChars(), s->loc.toChars()); 479 480 /** Aliases aren't overloadable themselves, but if their Aliasee is 481 * overloadable they are converted to an overloadable Alias (either 482 * FuncAliasDeclaration or OverDeclaration). 483 * 484 * This is done by moving the Aliasee into such an overloadable alias 485 * which is then used to replace the existing Aliasee. The original 486 * Alias (_this_) remains a useless shell. 487 * 488 * This is a horrible mess. It was probably done to avoid replacing 489 * existing AST nodes and references, but it needs a major 490 * simplification b/c it's too complex to maintain. 491 * 492 * A simpler approach might be to merge any colliding symbols into a 493 * simple Overload class (an array) and then later have that resolve 494 * all collisions. 495 */ 496 if (semanticRun >= PASSsemanticdone) 497 { 498 /* Semantic analysis is already finished, and the aliased entity 499 * is not overloadable. 500 */ 501 if (type) 502 return false; 503 504 /* When s is added in member scope by static if, mixin("code") or others, 505 * aliassym is determined already. See the case in: test/compilable/test61.d 506 */ 507 Dsymbol *sa = aliassym->toAlias(); 508 if (FuncDeclaration *fd = sa->isFuncDeclaration()) 509 { 510 FuncAliasDeclaration *fa = new FuncAliasDeclaration(ident, fd); 511 fa->protection = protection; 512 fa->parent = parent; 513 aliassym = fa; 514 return aliassym->overloadInsert(s); 515 } 516 if (TemplateDeclaration *td = sa->isTemplateDeclaration()) 517 { 518 OverDeclaration *od = new OverDeclaration(ident, td); 519 od->protection = protection; 520 od->parent = parent; 521 aliassym = od; 522 return aliassym->overloadInsert(s); 523 } 524 if (OverDeclaration *od = sa->isOverDeclaration()) 525 { 526 if (sa->ident != ident || sa->parent != parent) 527 { 528 od = new OverDeclaration(ident, od); 529 od->protection = protection; 530 od->parent = parent; 531 aliassym = od; 532 } 533 return od->overloadInsert(s); 534 } 535 if (OverloadSet *os = sa->isOverloadSet()) 536 { 537 if (sa->ident != ident || sa->parent != parent) 538 { 539 os = new OverloadSet(ident, os); 540 // TODO: protection is lost here b/c OverloadSets have no protection attribute 541 // Might no be a practical issue, b/c the code below fails to resolve the overload anyhow. 542 // ---- 543 // module os1; 544 // import a, b; 545 // private alias merged = foo; // private alias to overload set of a.foo and b.foo 546 // ---- 547 // module os2; 548 // import a, b; 549 // public alias merged = bar; // public alias to overload set of a.bar and b.bar 550 // ---- 551 // module bug; 552 // import os1, os2; 553 // void test() { merged(123); } // should only look at os2.merged 554 // 555 // os.protection = protection; 556 os->parent = parent; 557 aliassym = os; 558 } 559 os->push(s); 560 return true; 561 } 562 return false; 563 } 564 565 /* Don't know yet what the aliased symbol is, so assume it can 566 * be overloaded and check later for correctness. 567 */ 568 if (overnext) 569 return overnext->overloadInsert(s); 570 if (s == this) 571 return true; 572 overnext = s; 573 return true; 574 } 575 576 const char *AliasDeclaration::kind() const 577 { 578 return "alias"; 579 } 580 581 Type *AliasDeclaration::getType() 582 { 583 if (type) 584 return type; 585 return toAlias()->getType(); 586 } 587 588 Dsymbol *AliasDeclaration::toAlias() 589 { 590 //printf("[%s] AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s', inuse = %d)\n", 591 // loc.toChars(), toChars(), this, aliassym, aliassym ? aliassym->kind() : "", inuse); 592 assert(this != aliassym); 593 //static int count; if (++count == 10) *(char*)0=0; 594 if (inuse == 1 && type && _scope) 595 { 596 inuse = 2; 597 unsigned olderrors = global.errors; 598 Dsymbol *s = type->toDsymbol(_scope); 599 //printf("[%s] type = %s, s = %p, this = %p\n", loc.toChars(), type->toChars(), s, this); 600 if (global.errors != olderrors) 601 goto Lerr; 602 if (s) 603 { 604 s = s->toAlias(); 605 if (global.errors != olderrors) 606 goto Lerr; 607 aliassym = s; 608 inuse = 0; 609 } 610 else 611 { 612 Type *t = type->semantic(loc, _scope); 613 if (t->ty == Terror) 614 goto Lerr; 615 if (global.errors != olderrors) 616 goto Lerr; 617 //printf("t = %s\n", t->toChars()); 618 inuse = 0; 619 } 620 } 621 if (inuse) 622 { 623 error("recursive alias declaration"); 624 625 Lerr: 626 // Avoid breaking "recursive alias" state during errors gagged 627 if (global.gag) 628 return this; 629 630 aliassym = new AliasDeclaration(loc, ident, Type::terror); 631 type = Type::terror; 632 return aliassym; 633 } 634 635 if (semanticRun >= PASSsemanticdone) 636 { 637 // semantic is already done. 638 639 // Do not see aliassym !is null, because of lambda aliases. 640 641 // Do not see type.deco !is null, even so "alias T = const int;` needs 642 // semantic analysis to take the storage class `const` as type qualifier. 643 } 644 else 645 { 646 if (_import && _import->_scope) 647 { 648 /* If this is an internal alias for selective/renamed import, 649 * load the module first. 650 */ 651 _import->semantic(NULL); 652 } 653 if (_scope) 654 { 655 aliasSemantic(_scope); 656 } 657 } 658 659 inuse = 1; 660 Dsymbol *s = aliassym ? aliassym->toAlias() : this; 661 inuse = 0; 662 return s; 663 } 664 665 Dsymbol *AliasDeclaration::toAlias2() 666 { 667 if (inuse) 668 { 669 error("recursive alias declaration"); 670 return this; 671 } 672 inuse = 1; 673 Dsymbol *s = aliassym ? aliassym->toAlias2() : this; 674 inuse = 0; 675 return s; 676 } 677 678 bool AliasDeclaration::isOverloadable() 679 { 680 // assume overloadable until alias is resolved 681 return semanticRun < PASSsemanticdone || 682 (aliassym && aliassym->isOverloadable()); 683 } 684 685 /****************************** OverDeclaration **************************/ 686 687 OverDeclaration::OverDeclaration(Identifier *ident, Dsymbol *s, bool hasOverloads) 688 : Declaration(ident) 689 { 690 this->overnext = NULL; 691 this->aliassym = s; 692 693 this->hasOverloads = hasOverloads; 694 if (hasOverloads) 695 { 696 if (OverDeclaration *od = aliassym->isOverDeclaration()) 697 this->hasOverloads = od->hasOverloads; 698 } 699 else 700 { 701 // for internal use 702 assert(!aliassym->isOverDeclaration()); 703 } 704 } 705 706 const char *OverDeclaration::kind() const 707 { 708 return "overload alias"; // todo 709 } 710 711 void OverDeclaration::semantic(Scope *) 712 { 713 } 714 715 bool OverDeclaration::equals(RootObject *o) 716 { 717 if (this == o) 718 return true; 719 720 Dsymbol *s = isDsymbol(o); 721 if (!s) 722 return false; 723 724 OverDeclaration *od1 = this; 725 if (OverDeclaration *od2 = s->isOverDeclaration()) 726 { 727 return od1->aliassym->equals(od2->aliassym) && 728 od1->hasOverloads == od2->hasOverloads; 729 } 730 if (aliassym == s) 731 { 732 if (hasOverloads) 733 return true; 734 if (FuncDeclaration *fd = s->isFuncDeclaration()) 735 { 736 return fd->isUnique() != NULL; 737 } 738 if (TemplateDeclaration *td = s->isTemplateDeclaration()) 739 { 740 return td->overnext == NULL; 741 } 742 } 743 return false; 744 } 745 746 bool OverDeclaration::overloadInsert(Dsymbol *s) 747 { 748 //printf("OverDeclaration::overloadInsert('%s') aliassym = %p, overnext = %p\n", s->toChars(), aliassym, overnext); 749 if (overnext) 750 return overnext->overloadInsert(s); 751 if (s == this) 752 return true; 753 overnext = s; 754 return true; 755 } 756 757 Dsymbol *OverDeclaration::toAlias() 758 { 759 return this; 760 } 761 762 bool OverDeclaration::isOverloadable() 763 { 764 return true; 765 } 766 767 Dsymbol *OverDeclaration::isUnique() 768 { 769 if (!hasOverloads) 770 { 771 if (aliassym->isFuncDeclaration() || 772 aliassym->isTemplateDeclaration()) 773 { 774 return aliassym; 775 } 776 } 777 778 struct ParamUniqueSym 779 { 780 static int fp(void *param, Dsymbol *s) 781 { 782 Dsymbol **ps = (Dsymbol **)param; 783 if (*ps) 784 { 785 *ps = NULL; 786 return 1; // ambiguous, done 787 } 788 else 789 { 790 *ps = s; 791 return 0; 792 } 793 } 794 }; 795 Dsymbol *result = NULL; 796 overloadApply(aliassym, &result, &ParamUniqueSym::fp); 797 return result; 798 } 799 800 /********************************* VarDeclaration ****************************/ 801 802 VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer *init) 803 : Declaration(id) 804 { 805 //printf("VarDeclaration('%s')\n", id->toChars()); 806 assert(id); 807 assert(type || init); 808 this->type = type; 809 this->_init = init; 810 this->loc = loc; 811 offset = 0; 812 isargptr = false; 813 alignment = 0; 814 ctorinit = 0; 815 aliassym = NULL; 816 onstack = false; 817 mynew = false; 818 canassign = 0; 819 overlapped = false; 820 overlapUnsafe = false; 821 doNotInferScope = false; 822 isdataseg = 0; 823 lastVar = NULL; 824 endlinnum = 0; 825 ctfeAdrOnStack = -1; 826 edtor = NULL; 827 range = NULL; 828 829 static unsigned nextSequenceNumber = 0; 830 this->sequenceNumber = ++nextSequenceNumber; 831 } 832 833 Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s) 834 { 835 //printf("VarDeclaration::syntaxCopy(%s)\n", toChars()); 836 assert(!s); 837 VarDeclaration *v = new VarDeclaration(loc, 838 type ? type->syntaxCopy() : NULL, 839 ident, 840 _init ? _init->syntaxCopy() : NULL); 841 v->storage_class = storage_class; 842 return v; 843 } 844 845 846 void VarDeclaration::semantic(Scope *sc) 847 { 848 // if (semanticRun > PASSinit) 849 // return; 850 // semanticRun = PASSsemantic; 851 852 if (semanticRun >= PASSsemanticdone) 853 return; 854 855 Scope *scx = NULL; 856 if (_scope) 857 { 858 sc = _scope; 859 scx = sc; 860 _scope = NULL; 861 } 862 863 /* Pick up storage classes from context, but except synchronized, 864 * override, abstract, and final. 865 */ 866 storage_class |= (sc->stc & ~(STCsynchronized | STCoverride | STCabstract | STCfinal)); 867 if (storage_class & STCextern && _init) 868 error("extern symbols cannot have initializers"); 869 870 userAttribDecl = sc->userAttribDecl; 871 872 AggregateDeclaration *ad = isThis(); 873 if (ad) 874 storage_class |= ad->storage_class & STC_TYPECTOR; 875 876 /* If auto type inference, do the inference 877 */ 878 int inferred = 0; 879 if (!type) 880 { 881 inuse++; 882 883 // Infering the type requires running semantic, 884 // so mark the scope as ctfe if required 885 bool needctfe = (storage_class & (STCmanifest | STCstatic)) != 0; 886 if (needctfe) sc = sc->startCTFE(); 887 888 //printf("inferring type for %s with init %s\n", toChars(), _init->toChars()); 889 _init = inferType(_init, sc); 890 type = initializerToExpression(_init)->type; 891 892 if (needctfe) sc = sc->endCTFE(); 893 894 inuse--; 895 inferred = 1; 896 897 /* This is a kludge to support the existing syntax for RAII 898 * declarations. 899 */ 900 storage_class &= ~STCauto; 901 originalType = type->syntaxCopy(); 902 } 903 else 904 { 905 if (!originalType) 906 originalType = type->syntaxCopy(); 907 908 /* Prefix function attributes of variable declaration can affect 909 * its type: 910 * pure nothrow void function() fp; 911 * static assert(is(typeof(fp) == void function() pure nothrow)); 912 */ 913 Scope *sc2 = sc->push(); 914 sc2->stc |= (storage_class & STC_FUNCATTR); 915 inuse++; 916 type = type->semantic(loc, sc2); 917 inuse--; 918 sc2->pop(); 919 } 920 //printf(" semantic type = %s\n", type ? type->toChars() : "null"); 921 if (type->ty == Terror) 922 errors = true; 923 924 type->checkDeprecated(loc, sc); 925 linkage = sc->linkage; 926 this->parent = sc->parent; 927 //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars()); 928 protection = sc->protection; 929 930 /* If scope's alignment is the default, use the type's alignment, 931 * otherwise the scope overrrides. 932 */ 933 alignment = sc->alignment(); 934 if (alignment == STRUCTALIGN_DEFAULT) 935 alignment = type->alignment(); // use type's alignment 936 937 //printf("sc->stc = %x\n", sc->stc); 938 //printf("storage_class = x%x\n", storage_class); 939 940 if (global.params.vcomplex) 941 type->checkComplexTransition(loc); 942 943 // Calculate type size + safety checks 944 if (sc->func && !sc->intypeof) 945 { 946 if ((storage_class & STCgshared) && !isMember()) 947 { 948 if (sc->func->setUnsafe()) 949 error("__gshared not allowed in safe functions; use shared"); 950 } 951 } 952 953 Dsymbol *parent = toParent(); 954 955 Type *tb = type->toBasetype(); 956 Type *tbn = tb->baseElemOf(); 957 if (tb->ty == Tvoid && !(storage_class & STClazy)) 958 { 959 if (inferred) 960 { 961 error("type %s is inferred from initializer %s, and variables cannot be of type void", 962 type->toChars(), _init->toChars()); 963 } 964 else 965 error("variables cannot be of type void"); 966 type = Type::terror; 967 tb = type; 968 } 969 if (tb->ty == Tfunction) 970 { 971 error("cannot be declared to be a function"); 972 type = Type::terror; 973 tb = type; 974 } 975 if (tb->ty == Tstruct) 976 { 977 TypeStruct *ts = (TypeStruct *)tb; 978 if (!ts->sym->members) 979 { 980 error("no definition of struct %s", ts->toChars()); 981 } 982 } 983 if ((storage_class & STCauto) && !inferred) 984 error("storage class 'auto' has no effect if type is not inferred, did you mean 'scope'?"); 985 986 if (tb->ty == Ttuple) 987 { 988 /* Instead, declare variables for each of the tuple elements 989 * and add those. 990 */ 991 TypeTuple *tt = (TypeTuple *)tb; 992 size_t nelems = Parameter::dim(tt->arguments); 993 Expression *ie = (_init && !_init->isVoidInitializer()) ? initializerToExpression(_init) : NULL; 994 if (ie) 995 ie = ::semantic(ie, sc); 996 997 if (nelems > 0 && ie) 998 { 999 Expressions *iexps = new Expressions(); 1000 iexps->push(ie); 1001 1002 Expressions *exps = new Expressions(); 1003 1004 for (size_t pos = 0; pos < iexps->dim; pos++) 1005 { 1006 Lexpand1: 1007 Expression *e = (*iexps)[pos]; 1008 Parameter *arg = Parameter::getNth(tt->arguments, pos); 1009 arg->type = arg->type->semantic(loc, sc); 1010 //printf("[%d] iexps->dim = %d, ", pos, iexps->dim); 1011 //printf("e = (%s %s, %s), ", Token::tochars[e->op], e->toChars(), e->type->toChars()); 1012 //printf("arg = (%s, %s)\n", arg->toChars(), arg->type->toChars()); 1013 1014 if (e != ie) 1015 { 1016 if (iexps->dim > nelems) 1017 goto Lnomatch; 1018 if (e->type->implicitConvTo(arg->type)) 1019 continue; 1020 } 1021 1022 if (e->op == TOKtuple) 1023 { 1024 TupleExp *te = (TupleExp *)e; 1025 if (iexps->dim - 1 + te->exps->dim > nelems) 1026 goto Lnomatch; 1027 1028 iexps->remove(pos); 1029 iexps->insert(pos, te->exps); 1030 (*iexps)[pos] = Expression::combine(te->e0, (*iexps)[pos]); 1031 goto Lexpand1; 1032 } 1033 else if (isAliasThisTuple(e)) 1034 { 1035 VarDeclaration *v = copyToTemp(0, "__tup", e); 1036 VarExp *ve = new VarExp(loc, v); 1037 ve->type = e->type; 1038 1039 exps->setDim(1); 1040 (*exps)[0] = ve; 1041 expandAliasThisTuples(exps, 0); 1042 1043 for (size_t u = 0; u < exps->dim ; u++) 1044 { 1045 Lexpand2: 1046 Expression *ee = (*exps)[u]; 1047 arg = Parameter::getNth(tt->arguments, pos + u); 1048 arg->type = arg->type->semantic(loc, sc); 1049 //printf("[%d+%d] exps->dim = %d, ", pos, u, exps->dim); 1050 //printf("ee = (%s %s, %s), ", Token::tochars[ee->op], ee->toChars(), ee->type->toChars()); 1051 //printf("arg = (%s, %s)\n", arg->toChars(), arg->type->toChars()); 1052 1053 size_t iexps_dim = iexps->dim - 1 + exps->dim; 1054 if (iexps_dim > nelems) 1055 goto Lnomatch; 1056 if (ee->type->implicitConvTo(arg->type)) 1057 continue; 1058 1059 if (expandAliasThisTuples(exps, u) != -1) 1060 goto Lexpand2; 1061 } 1062 1063 if ((*exps)[0] != ve) 1064 { 1065 Expression *e0 = (*exps)[0]; 1066 (*exps)[0] = new CommaExp(loc, new DeclarationExp(loc, v), e0); 1067 (*exps)[0]->type = e0->type; 1068 1069 iexps->remove(pos); 1070 iexps->insert(pos, exps); 1071 goto Lexpand1; 1072 } 1073 } 1074 } 1075 if (iexps->dim < nelems) 1076 goto Lnomatch; 1077 1078 ie = new TupleExp(_init->loc, iexps); 1079 } 1080 Lnomatch: 1081 1082 if (ie && ie->op == TOKtuple) 1083 { 1084 TupleExp *te = (TupleExp *)ie; 1085 size_t tedim = te->exps->dim; 1086 if (tedim != nelems) 1087 { 1088 ::error(loc, "tuple of %d elements cannot be assigned to tuple of %d elements", (int)tedim, (int)nelems); 1089 for (size_t u = tedim; u < nelems; u++) // fill dummy expression 1090 te->exps->push(new ErrorExp()); 1091 } 1092 } 1093 1094 Objects *exps = new Objects(); 1095 exps->setDim(nelems); 1096 for (size_t i = 0; i < nelems; i++) 1097 { 1098 Parameter *arg = Parameter::getNth(tt->arguments, i); 1099 1100 OutBuffer buf; 1101 buf.printf("__%s_field_%llu", ident->toChars(), (ulonglong)i); 1102 const char *name = buf.extractString(); 1103 Identifier *id = Identifier::idPool(name); 1104 1105 Initializer *ti; 1106 if (ie) 1107 { 1108 Expression *einit = ie; 1109 if (ie->op == TOKtuple) 1110 { 1111 TupleExp *te = (TupleExp *)ie; 1112 einit = (*te->exps)[i]; 1113 if (i == 0) 1114 einit = Expression::combine(te->e0, einit); 1115 } 1116 ti = new ExpInitializer(einit->loc, einit); 1117 } 1118 else 1119 ti = _init ? _init->syntaxCopy() : NULL; 1120 1121 VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti); 1122 v->storage_class |= STCtemp | storage_class; 1123 if (arg->storageClass & STCparameter) 1124 v->storage_class |= arg->storageClass; 1125 //printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars()); 1126 v->semantic(sc); 1127 1128 if (sc->scopesym) 1129 { 1130 //printf("adding %s to %s\n", v->toChars(), sc->scopesym->toChars()); 1131 if (sc->scopesym->members) 1132 sc->scopesym->members->push(v); 1133 } 1134 1135 Expression *e = new DsymbolExp(loc, v); 1136 (*exps)[i] = e; 1137 } 1138 TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps); 1139 v2->parent = this->parent; 1140 v2->isexp = true; 1141 aliassym = v2; 1142 semanticRun = PASSsemanticdone; 1143 return; 1144 } 1145 1146 /* Storage class can modify the type 1147 */ 1148 type = type->addStorageClass(storage_class); 1149 1150 /* Adjust storage class to reflect type 1151 */ 1152 if (type->isConst()) 1153 { 1154 storage_class |= STCconst; 1155 if (type->isShared()) 1156 storage_class |= STCshared; 1157 } 1158 else if (type->isImmutable()) 1159 storage_class |= STCimmutable; 1160 else if (type->isShared()) 1161 storage_class |= STCshared; 1162 else if (type->isWild()) 1163 storage_class |= STCwild; 1164 1165 if (StorageClass stc = storage_class & (STCsynchronized | STCoverride | STCabstract | STCfinal)) 1166 { 1167 if (stc == STCfinal) 1168 error("cannot be final, perhaps you meant const?"); 1169 else 1170 { 1171 OutBuffer buf; 1172 stcToBuffer(&buf, stc); 1173 error("cannot be %s", buf.peekString()); 1174 } 1175 storage_class &= ~stc; // strip off 1176 } 1177 1178 if (storage_class & STCscope) 1179 { 1180 StorageClass stc = storage_class & (STCstatic | STCextern | STCmanifest | STCtls | STCgshared); 1181 if (stc) 1182 { 1183 OutBuffer buf; 1184 stcToBuffer(&buf, stc); 1185 error("cannot be 'scope' and '%s'", buf.peekString()); 1186 } 1187 else if (isMember()) 1188 { 1189 error("field cannot be 'scope'"); 1190 } 1191 else if (!type->hasPointers()) 1192 { 1193 storage_class &= ~STCscope; // silently ignore; may occur in generic code 1194 } 1195 } 1196 1197 if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter | STCtls | STCgshared | STCctfe)) 1198 { 1199 } 1200 else 1201 { 1202 AggregateDeclaration *aad = parent->isAggregateDeclaration(); 1203 if (aad) 1204 { 1205 if (global.params.vfield && 1206 storage_class & (STCconst | STCimmutable) && _init && !_init->isVoidInitializer()) 1207 { 1208 const char *s = (storage_class & STCimmutable) ? "immutable" : "const"; 1209 message(loc, "`%s.%s` is `%s` field", ad->toPrettyChars(), toChars(), s); 1210 } 1211 storage_class |= STCfield; 1212 if (tbn->ty == Tstruct && ((TypeStruct *)tbn)->sym->noDefaultCtor) 1213 { 1214 if (!isThisDeclaration() && !_init) 1215 aad->noDefaultCtor = true; 1216 } 1217 } 1218 1219 InterfaceDeclaration *id = parent->isInterfaceDeclaration(); 1220 if (id) 1221 { 1222 error("field not allowed in interface"); 1223 } 1224 else if (aad && aad->sizeok == SIZEOKdone) 1225 { 1226 error("cannot be further field because it will change the determined %s size", aad->toChars()); 1227 } 1228 1229 /* Templates cannot add fields to aggregates 1230 */ 1231 TemplateInstance *ti = parent->isTemplateInstance(); 1232 if (ti) 1233 { 1234 // Take care of nested templates 1235 while (1) 1236 { 1237 TemplateInstance *ti2 = ti->tempdecl->parent->isTemplateInstance(); 1238 if (!ti2) 1239 break; 1240 ti = ti2; 1241 } 1242 1243 // If it's a member template 1244 AggregateDeclaration *ad2 = ti->tempdecl->isMember(); 1245 if (ad2 && storage_class != STCundefined) 1246 { 1247 error("cannot use template to add field to aggregate '%s'", ad2->toChars()); 1248 } 1249 } 1250 } 1251 1252 if ((storage_class & (STCref | STCparameter | STCforeach | STCtemp | STCresult)) == STCref && ident != Id::This) 1253 { 1254 error("only parameters or foreach declarations can be ref"); 1255 } 1256 1257 if (type->hasWild()) 1258 { 1259 if (storage_class & (STCstatic | STCextern | STCtls | STCgshared | STCmanifest | STCfield) || 1260 isDataseg() 1261 ) 1262 { 1263 error("only parameters or stack based variables can be inout"); 1264 } 1265 FuncDeclaration *func = sc->func; 1266 if (func) 1267 { 1268 if (func->fes) 1269 func = func->fes->func; 1270 bool isWild = false; 1271 for (FuncDeclaration *fd = func; fd; fd = fd->toParent2()->isFuncDeclaration()) 1272 { 1273 if (((TypeFunction *)fd->type)->iswild) 1274 { 1275 isWild = true; 1276 break; 1277 } 1278 } 1279 if (!isWild) 1280 { 1281 error("inout variables can only be declared inside inout functions"); 1282 } 1283 } 1284 } 1285 1286 if (!(storage_class & (STCctfe | STCref | STCresult)) && tbn->ty == Tstruct && 1287 ((TypeStruct *)tbn)->sym->noDefaultCtor) 1288 { 1289 if (!_init) 1290 { 1291 if (isField()) 1292 { 1293 /* For fields, we'll check the constructor later to make sure it is initialized 1294 */ 1295 storage_class |= STCnodefaultctor; 1296 } 1297 else if (storage_class & STCparameter) 1298 ; 1299 else 1300 error("default construction is disabled for type %s", type->toChars()); 1301 } 1302 } 1303 1304 FuncDeclaration *fd = parent->isFuncDeclaration(); 1305 if (type->isscope() && !(storage_class & STCnodtor)) 1306 { 1307 if (storage_class & (STCfield | STCout | STCref | STCstatic | STCmanifest | STCtls | STCgshared) || !fd) 1308 { 1309 error("globals, statics, fields, manifest constants, ref and out parameters cannot be scope"); 1310 } 1311 1312 if (!(storage_class & STCscope)) 1313 { 1314 if (!(storage_class & STCparameter) && ident != Id::withSym) 1315 error("reference to scope class must be scope"); 1316 } 1317 } 1318 1319 // Calculate type size + safety checks 1320 if (sc->func && !sc->intypeof) 1321 { 1322 if (_init && _init->isVoidInitializer() && type->hasPointers()) // get type size 1323 { 1324 if (sc->func->setUnsafe()) 1325 error("void initializers for pointers not allowed in safe functions"); 1326 } 1327 else if (!_init && 1328 !(storage_class & (STCstatic | STCextern | STCtls | STCgshared | STCmanifest | STCfield | STCparameter)) && 1329 type->hasVoidInitPointers()) 1330 { 1331 if (sc->func->setUnsafe()) 1332 error("void initializers for pointers not allowed in safe functions"); 1333 } 1334 } 1335 1336 if (!_init && !fd) 1337 { 1338 // If not mutable, initializable by constructor only 1339 storage_class |= STCctorinit; 1340 } 1341 1342 if (_init) 1343 storage_class |= STCinit; // remember we had an explicit initializer 1344 else if (storage_class & STCmanifest) 1345 error("manifest constants must have initializers"); 1346 1347 bool isBlit = false; 1348 d_uns64 sz = 0; 1349 if (!_init && !sc->inunion && !(storage_class & (STCstatic | STCgshared | STCextern)) && fd && 1350 (!(storage_class & (STCfield | STCin | STCforeach | STCparameter | STCresult)) 1351 || (storage_class & STCout)) && 1352 (sz = type->size()) != 0) 1353 { 1354 // Provide a default initializer 1355 //printf("Providing default initializer for '%s'\n", toChars()); 1356 if (sz == SIZE_INVALID && type->ty != Terror) 1357 error("size of type %s is invalid", type->toChars()); 1358 1359 Type *tv = type; 1360 while (tv->ty == Tsarray) // Don't skip Tenum 1361 tv = tv->nextOf(); 1362 if (tv->needsNested()) 1363 { 1364 /* Nested struct requires valid enclosing frame pointer. 1365 * In StructLiteralExp::toElem(), it's calculated. 1366 */ 1367 assert(tv->toBasetype()->ty == Tstruct); 1368 checkFrameAccess(loc, sc, ((TypeStruct *)tbn)->sym); 1369 1370 Expression *e = tv->defaultInitLiteral(loc); 1371 e = new BlitExp(loc, new VarExp(loc, this), e); 1372 e = ::semantic(e, sc); 1373 _init = new ExpInitializer(loc, e); 1374 goto Ldtor; 1375 } 1376 if (tv->ty == Tstruct && ((TypeStruct *)tv)->sym->zeroInit == 1) 1377 { 1378 /* If a struct is all zeros, as a special case 1379 * set it's initializer to the integer 0. 1380 * In AssignExp::toElem(), we check for this and issue 1381 * a memset() to initialize the struct. 1382 * Must do same check in interpreter. 1383 */ 1384 Expression *e = new IntegerExp(loc, 0, Type::tint32); 1385 e = new BlitExp(loc, new VarExp(loc, this), e); 1386 e->type = type; // don't type check this, it would fail 1387 _init = new ExpInitializer(loc, e); 1388 goto Ldtor; 1389 } 1390 if (type->baseElemOf()->ty == Tvoid) 1391 { 1392 error("%s does not have a default initializer", type->toChars()); 1393 } 1394 else if (Expression *e = type->defaultInit(loc)) 1395 { 1396 _init = new ExpInitializer(loc, e); 1397 } 1398 // Default initializer is always a blit 1399 isBlit = true; 1400 } 1401 1402 if (_init) 1403 { 1404 sc = sc->push(); 1405 sc->stc &= ~(STC_TYPECTOR | STCpure | STCnothrow | STCnogc | STCref | STCdisable); 1406 1407 ExpInitializer *ei = _init->isExpInitializer(); 1408 if (ei) // Bugzilla 13424: Preset the required type to fail in FuncLiteralDeclaration::semantic3 1409 ei->exp = inferType(ei->exp, type); 1410 1411 // If inside function, there is no semantic3() call 1412 if (sc->func || sc->intypeof == 1) 1413 { 1414 // If local variable, use AssignExp to handle all the various 1415 // possibilities. 1416 if (fd && 1417 !(storage_class & (STCmanifest | STCstatic | STCtls | STCgshared | STCextern)) && 1418 !_init->isVoidInitializer()) 1419 { 1420 //printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars()); 1421 if (!ei) 1422 { 1423 ArrayInitializer *ai = _init->isArrayInitializer(); 1424 Expression *e; 1425 if (ai && tb->ty == Taarray) 1426 e = ai->toAssocArrayLiteral(); 1427 else 1428 e = initializerToExpression(_init); 1429 if (!e) 1430 { 1431 // Run semantic, but don't need to interpret 1432 _init = ::semantic(_init, sc, type, INITnointerpret); 1433 e = initializerToExpression(_init); 1434 if (!e) 1435 { 1436 error("is not a static and cannot have static initializer"); 1437 return; 1438 } 1439 } 1440 ei = new ExpInitializer(_init->loc, e); 1441 _init = ei; 1442 } 1443 1444 Expression *exp = ei->exp; 1445 Expression *e1 = new VarExp(loc, this); 1446 if (isBlit) 1447 exp = new BlitExp(loc, e1, exp); 1448 else 1449 exp = new ConstructExp(loc, e1, exp); 1450 canassign++; 1451 exp = ::semantic(exp, sc); 1452 canassign--; 1453 exp = exp->optimize(WANTvalue); 1454 1455 if (exp->op == TOKerror) 1456 { 1457 _init = new ErrorInitializer(); 1458 ei = NULL; 1459 } 1460 else 1461 ei->exp = exp; 1462 1463 if (ei && isScope()) 1464 { 1465 Expression *ex = ei->exp; 1466 while (ex->op == TOKcomma) 1467 ex = ((CommaExp *)ex)->e2; 1468 if (ex->op == TOKblit || ex->op == TOKconstruct) 1469 ex = ((AssignExp *)ex)->e2; 1470 if (ex->op == TOKnew) 1471 { 1472 // See if initializer is a NewExp that can be allocated on the stack 1473 NewExp *ne = (NewExp *)ex; 1474 if (type->toBasetype()->ty == Tclass) 1475 { 1476 if (ne->newargs && ne->newargs->dim > 1) 1477 { 1478 mynew = true; 1479 } 1480 else 1481 { 1482 ne->onstack = true; 1483 onstack = true; 1484 } 1485 } 1486 } 1487 else if (ex->op == TOKfunction) 1488 { 1489 // or a delegate that doesn't escape a reference to the function 1490 FuncDeclaration *f = ((FuncExp *)ex)->fd; 1491 f->tookAddressOf--; 1492 } 1493 } 1494 } 1495 else 1496 { 1497 // Bugzilla 14166: Don't run CTFE for the temporary variables inside typeof 1498 _init = ::semantic(_init, sc, type, sc->intypeof == 1 ? INITnointerpret : INITinterpret); 1499 } 1500 } 1501 else if (parent->isAggregateDeclaration()) 1502 { 1503 _scope = scx ? scx : sc->copy(); 1504 _scope->setNoFree(); 1505 } 1506 else if (storage_class & (STCconst | STCimmutable | STCmanifest) || 1507 type->isConst() || type->isImmutable()) 1508 { 1509 /* Because we may need the results of a const declaration in a 1510 * subsequent type, such as an array dimension, before semantic2() 1511 * gets ordinarily run, try to run semantic2() now. 1512 * Ignore failure. 1513 */ 1514 1515 if (!inferred) 1516 { 1517 unsigned errors = global.errors; 1518 inuse++; 1519 if (ei) 1520 { 1521 Expression *exp = ei->exp->syntaxCopy(); 1522 1523 bool needctfe = isDataseg() || (storage_class & STCmanifest); 1524 if (needctfe) sc = sc->startCTFE(); 1525 exp = ::semantic(exp, sc); 1526 exp = resolveProperties(sc, exp); 1527 if (needctfe) sc = sc->endCTFE(); 1528 1529 Type *tb2 = type->toBasetype(); 1530 Type *ti = exp->type->toBasetype(); 1531 1532 /* The problem is the following code: 1533 * struct CopyTest { 1534 * double x; 1535 * this(double a) { x = a * 10.0;} 1536 * this(this) { x += 2.0; } 1537 * } 1538 * const CopyTest z = CopyTest(5.3); // ok 1539 * const CopyTest w = z; // not ok, postblit not run 1540 * static assert(w.x == 55.0); 1541 * because the postblit doesn't get run on the initialization of w. 1542 */ 1543 if (ti->ty == Tstruct) 1544 { 1545 StructDeclaration *sd = ((TypeStruct *)ti)->sym; 1546 /* Look to see if initializer involves a copy constructor 1547 * (which implies a postblit) 1548 */ 1549 // there is a copy constructor 1550 // and exp is the same struct 1551 if (sd->postblit && 1552 tb2->toDsymbol(NULL) == sd) 1553 { 1554 // The only allowable initializer is a (non-copy) constructor 1555 if (exp->isLvalue()) 1556 error("of type struct %s uses this(this), which is not allowed in static initialization", tb2->toChars()); 1557 } 1558 } 1559 ei->exp = exp; 1560 } 1561 _init = ::semantic(_init, sc, type, INITinterpret); 1562 inuse--; 1563 if (global.errors > errors) 1564 { 1565 _init = new ErrorInitializer(); 1566 type = Type::terror; 1567 } 1568 } 1569 else 1570 { 1571 _scope = scx ? scx : sc->copy(); 1572 _scope->setNoFree(); 1573 } 1574 } 1575 sc = sc->pop(); 1576 } 1577 1578 Ldtor: 1579 /* Build code to execute destruction, if necessary 1580 */ 1581 edtor = callScopeDtor(sc); 1582 if (edtor) 1583 { 1584 if (sc->func && storage_class & (STCstatic | STCgshared)) 1585 edtor = ::semantic(edtor, sc->_module->_scope); 1586 else 1587 edtor = ::semantic(edtor, sc); 1588 1589 #if 0 // currently disabled because of std.stdio.stdin, stdout and stderr 1590 if (isDataseg() && !(storage_class & STCextern)) 1591 error("static storage variables cannot have destructors"); 1592 #endif 1593 } 1594 1595 semanticRun = PASSsemanticdone; 1596 1597 if (type->toBasetype()->ty == Terror) 1598 errors = true; 1599 1600 if (sc->scopesym && !sc->scopesym->isAggregateDeclaration()) 1601 { 1602 for (ScopeDsymbol *sym = sc->scopesym; sym && endlinnum == 0; 1603 sym = sym->parent ? sym->parent->isScopeDsymbol() : NULL) 1604 endlinnum = sym->endlinnum; 1605 } 1606 } 1607 1608 void VarDeclaration::semantic2(Scope *sc) 1609 { 1610 if (semanticRun < PASSsemanticdone && inuse) 1611 return; 1612 1613 //printf("VarDeclaration::semantic2('%s')\n", toChars()); 1614 1615 if (_init && !toParent()->isFuncDeclaration()) 1616 { 1617 inuse++; 1618 // Bugzilla 14166: Don't run CTFE for the temporary variables inside typeof 1619 _init = ::semantic(_init, sc, type, sc->intypeof == 1 ? INITnointerpret : INITinterpret); 1620 inuse--; 1621 } 1622 if (_init && storage_class & STCmanifest) 1623 { 1624 /* Cannot initializer enums with CTFE classreferences and addresses of struct literals. 1625 * Scan initializer looking for them. Issue error if found. 1626 */ 1627 if (ExpInitializer *ei = _init->isExpInitializer()) 1628 { 1629 struct EnumInitializer 1630 { 1631 static bool arrayHasInvalidEnumInitializer(Expressions *elems) 1632 { 1633 for (size_t i = 0; i < elems->dim; i++) 1634 { 1635 Expression *e = (*elems)[i]; 1636 if (e && hasInvalidEnumInitializer(e)) 1637 return true; 1638 } 1639 return false; 1640 } 1641 1642 static bool hasInvalidEnumInitializer(Expression *e) 1643 { 1644 if (e->op == TOKclassreference) 1645 return true; 1646 if (e->op == TOKaddress && ((AddrExp *)e)->e1->op == TOKstructliteral) 1647 return true; 1648 if (e->op == TOKarrayliteral) 1649 return arrayHasInvalidEnumInitializer(((ArrayLiteralExp *)e)->elements); 1650 if (e->op == TOKstructliteral) 1651 return arrayHasInvalidEnumInitializer(((StructLiteralExp *)e)->elements); 1652 if (e->op == TOKassocarrayliteral) 1653 { 1654 AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)e; 1655 return arrayHasInvalidEnumInitializer(ae->values) || 1656 arrayHasInvalidEnumInitializer(ae->keys); 1657 } 1658 return false; 1659 } 1660 }; 1661 if (EnumInitializer::hasInvalidEnumInitializer(ei->exp)) 1662 error(": Unable to initialize enum with class or pointer to struct. Use static const variable instead."); 1663 } 1664 } 1665 else if (_init && isThreadlocal()) 1666 { 1667 if ((type->ty == Tclass) && type->isMutable() && !type->isShared()) 1668 { 1669 ExpInitializer *ei = _init->isExpInitializer(); 1670 if (ei && ei->exp->op == TOKclassreference) 1671 error("is mutable. Only const or immutable class thread local variable are allowed, not %s", type->toChars()); 1672 } 1673 else if (type->ty == Tpointer && type->nextOf()->ty == Tstruct && type->nextOf()->isMutable() &&!type->nextOf()->isShared()) 1674 { 1675 ExpInitializer *ei = _init->isExpInitializer(); 1676 if (ei && ei->exp->op == TOKaddress && ((AddrExp *)ei->exp)->e1->op == TOKstructliteral) 1677 { 1678 error("is a pointer to mutable struct. Only pointers to const, immutable or shared struct thread local variable are allowed, not %s", type->toChars()); 1679 } 1680 } 1681 } 1682 semanticRun = PASSsemantic2done; 1683 } 1684 1685 void VarDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion) 1686 { 1687 //printf("VarDeclaration::setFieldOffset(ad = %s) %s\n", ad->toChars(), toChars()); 1688 1689 if (aliassym) 1690 { 1691 // If this variable was really a tuple, set the offsets for the tuple fields 1692 TupleDeclaration *v2 = aliassym->isTupleDeclaration(); 1693 assert(v2); 1694 for (size_t i = 0; i < v2->objects->dim; i++) 1695 { 1696 RootObject *o = (*v2->objects)[i]; 1697 assert(o->dyncast() == DYNCAST_EXPRESSION); 1698 Expression *e = (Expression *)o; 1699 assert(e->op == TOKdsymbol); 1700 DsymbolExp *se = (DsymbolExp *)e; 1701 se->s->setFieldOffset(ad, poffset, isunion); 1702 } 1703 return; 1704 } 1705 1706 if (!isField()) 1707 return; 1708 assert(!(storage_class & (STCstatic | STCextern | STCparameter | STCtls))); 1709 1710 //printf("+VarDeclaration::setFieldOffset(ad = %s) %s\n", ad->toChars(), toChars()); 1711 1712 /* Fields that are tuples appear both as part of TupleDeclarations and 1713 * as members. That means ignore them if they are already a field. 1714 */ 1715 if (offset) 1716 { 1717 // already a field 1718 *poffset = ad->structsize; // Bugzilla 13613 1719 return; 1720 } 1721 for (size_t i = 0; i < ad->fields.dim; i++) 1722 { 1723 if (ad->fields[i] == this) 1724 { 1725 // already a field 1726 *poffset = ad->structsize; // Bugzilla 13613 1727 return; 1728 } 1729 } 1730 1731 // Check for forward referenced types which will fail the size() call 1732 Type *t = type->toBasetype(); 1733 if (storage_class & STCref) 1734 { 1735 // References are the size of a pointer 1736 t = Type::tvoidptr; 1737 } 1738 Type *tv = t->baseElemOf(); 1739 if (tv->ty == Tstruct) 1740 { 1741 TypeStruct *ts = (TypeStruct *)tv; 1742 assert(ts->sym != ad); // already checked in ad->determineFields() 1743 if (!ts->sym->determineSize(loc)) 1744 { 1745 type = Type::terror; 1746 errors = true; 1747 return; 1748 } 1749 } 1750 1751 // List in ad->fields. Even if the type is error, it's necessary to avoid 1752 // pointless error diagnostic "more initializers than fields" on struct literal. 1753 ad->fields.push(this); 1754 1755 if (t->ty == Terror) 1756 return; 1757 1758 const d_uns64 sz = t->size(loc); 1759 assert(sz != SIZE_INVALID && sz < UINT32_MAX); 1760 unsigned memsize = (unsigned)sz; // size of member 1761 unsigned memalignsize = Target::fieldalign(t); // size of member for alignment purposes 1762 1763 offset = AggregateDeclaration::placeField(poffset, memsize, memalignsize, alignment, 1764 &ad->structsize, &ad->alignsize, isunion); 1765 1766 //printf("\t%s: memalignsize = %d\n", toChars(), memalignsize); 1767 1768 //printf(" addField '%s' to '%s' at offset %d, size = %d\n", toChars(), ad->toChars(), offset, memsize); 1769 } 1770 1771 const char *VarDeclaration::kind() const 1772 { 1773 return "variable"; 1774 } 1775 1776 Dsymbol *VarDeclaration::toAlias() 1777 { 1778 //printf("VarDeclaration::toAlias('%s', this = %p, aliassym = %p)\n", toChars(), this, aliassym); 1779 if ((!type || !type->deco) && _scope) 1780 semantic(_scope); 1781 1782 assert(this != aliassym); 1783 Dsymbol *s = aliassym ? aliassym->toAlias() : this; 1784 return s; 1785 } 1786 1787 AggregateDeclaration *VarDeclaration::isThis() 1788 { 1789 AggregateDeclaration *ad = NULL; 1790 1791 if (!(storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter | 1792 STCtls | STCgshared | STCctfe))) 1793 { 1794 for (Dsymbol *s = this; s; s = s->parent) 1795 { 1796 ad = s->isMember(); 1797 if (ad) 1798 break; 1799 if (!s->parent || !s->parent->isTemplateMixin()) break; 1800 } 1801 } 1802 return ad; 1803 } 1804 1805 bool VarDeclaration::needThis() 1806 { 1807 //printf("VarDeclaration::needThis(%s, x%x)\n", toChars(), storage_class); 1808 return isField(); 1809 } 1810 1811 bool VarDeclaration::isExport() const 1812 { 1813 return protection.kind == PROTexport; 1814 } 1815 1816 bool VarDeclaration::isImportedSymbol() const 1817 { 1818 if (protection.kind == PROTexport && !_init && 1819 (storage_class & STCstatic || parent->isModule())) 1820 return true; 1821 return false; 1822 } 1823 1824 /******************************************* 1825 * Helper function for the expansion of manifest constant. 1826 */ 1827 Expression *VarDeclaration::expandInitializer(Loc loc) 1828 { 1829 assert((storage_class & STCmanifest) && _init); 1830 1831 Expression *e = getConstInitializer(); 1832 if (!e) 1833 { 1834 ::error(loc, "cannot make expression out of initializer for %s", toChars()); 1835 return new ErrorExp(); 1836 } 1837 1838 e = e->copy(); 1839 e->loc = loc; // for better error message 1840 return e; 1841 } 1842 1843 void VarDeclaration::checkCtorConstInit() 1844 { 1845 #if 0 /* doesn't work if more than one static ctor */ 1846 if (ctorinit == 0 && isCtorinit() && !isField()) 1847 error("missing initializer in static constructor for const variable"); 1848 #endif 1849 } 1850 1851 bool lambdaCheckForNestedRef(Expression *e, Scope *sc); 1852 1853 /************************************ 1854 * Check to see if this variable is actually in an enclosing function 1855 * rather than the current one. 1856 * Returns true if error occurs. 1857 */ 1858 bool VarDeclaration::checkNestedReference(Scope *sc, Loc loc) 1859 { 1860 //printf("VarDeclaration::checkNestedReference() %s\n", toChars()); 1861 if (sc->intypeof == 1 || (sc->flags & SCOPEctfe)) 1862 return false; 1863 if (!parent || parent == sc->parent) 1864 return false; 1865 if (isDataseg() || (storage_class & STCmanifest)) 1866 return false; 1867 1868 // The current function 1869 FuncDeclaration *fdthis = sc->parent->isFuncDeclaration(); 1870 if (!fdthis) 1871 return false; // out of function scope 1872 1873 Dsymbol *p = toParent2(); 1874 1875 // Function literals from fdthis to p must be delegates 1876 checkNestedRef(fdthis, p); 1877 1878 // The function that this variable is in 1879 FuncDeclaration *fdv = p->isFuncDeclaration(); 1880 if (!fdv || fdv == fdthis) 1881 return false; 1882 1883 // Add fdthis to nestedrefs[] if not already there 1884 for (size_t i = 0; 1; i++) 1885 { 1886 if (i == nestedrefs.dim) 1887 { 1888 nestedrefs.push(fdthis); 1889 break; 1890 } 1891 if (nestedrefs[i] == fdthis) 1892 break; 1893 } 1894 1895 /* __require and __ensure will always get called directly, 1896 * so they never make outer functions closure. 1897 */ 1898 if (fdthis->ident == Id::require || fdthis->ident == Id::ensure) 1899 return false; 1900 1901 //printf("\tfdv = %s\n", fdv->toChars()); 1902 //printf("\tfdthis = %s\n", fdthis->toChars()); 1903 if (loc.filename) 1904 { 1905 int lv = fdthis->getLevel(loc, sc, fdv); 1906 if (lv == -2) // error 1907 return true; 1908 } 1909 1910 // Add this to fdv->closureVars[] if not already there 1911 for (size_t i = 0; 1; i++) 1912 { 1913 if (i == fdv->closureVars.dim) 1914 { 1915 if (!sc->intypeof && !(sc->flags & SCOPEcompile)) 1916 fdv->closureVars.push(this); 1917 break; 1918 } 1919 if (fdv->closureVars[i] == this) 1920 break; 1921 } 1922 1923 //printf("fdthis is %s\n", fdthis->toChars()); 1924 //printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars()); 1925 // __dollar creates problems because it isn't a real variable Bugzilla 3326 1926 if (ident == Id::dollar) 1927 { 1928 ::error(loc, "cannnot use $ inside a function literal"); 1929 return true; 1930 } 1931 1932 if (ident == Id::withSym) // Bugzilla 1759 1933 { 1934 ExpInitializer *ez = _init->isExpInitializer(); 1935 assert(ez); 1936 Expression *e = ez->exp; 1937 if (e->op == TOKconstruct || e->op == TOKblit) 1938 e = ((AssignExp *)e)->e2; 1939 return lambdaCheckForNestedRef(e, sc); 1940 } 1941 1942 return false; 1943 } 1944 1945 /******************************************* 1946 * If variable has a constant expression initializer, get it. 1947 * Otherwise, return NULL. 1948 */ 1949 1950 Expression *VarDeclaration::getConstInitializer(bool needFullType) 1951 { 1952 assert(type && _init); 1953 1954 // Ungag errors when not speculative 1955 unsigned oldgag = global.gag; 1956 if (global.gag) 1957 { 1958 Dsymbol *sym = toParent()->isAggregateDeclaration(); 1959 if (sym && !sym->isSpeculative()) 1960 global.gag = 0; 1961 } 1962 1963 if (_scope) 1964 { 1965 inuse++; 1966 _init = ::semantic(_init, _scope, type, INITinterpret); 1967 _scope = NULL; 1968 inuse--; 1969 } 1970 Expression *e = initializerToExpression(_init, needFullType ? type : NULL); 1971 1972 global.gag = oldgag; 1973 return e; 1974 } 1975 1976 /************************************* 1977 * Return true if we can take the address of this variable. 1978 */ 1979 1980 bool VarDeclaration::canTakeAddressOf() 1981 { 1982 return !(storage_class & STCmanifest); 1983 } 1984 1985 1986 /******************************* 1987 * Does symbol go into data segment? 1988 * Includes extern variables. 1989 */ 1990 1991 bool VarDeclaration::isDataseg() 1992 { 1993 if (isdataseg == 0) // the value is not cached 1994 { 1995 isdataseg = 2; // The Variables does not go into the datasegment 1996 1997 if (!canTakeAddressOf()) 1998 { 1999 return false; 2000 } 2001 2002 Dsymbol *parent = toParent(); 2003 if (!parent && !(storage_class & STCstatic)) 2004 { 2005 error("forward referenced"); 2006 type = Type::terror; 2007 } 2008 else if (storage_class & (STCstatic | STCextern | STCtls | STCgshared) || 2009 parent->isModule() || parent->isTemplateInstance() || parent->isNspace()) 2010 { 2011 assert(!isParameter() && !isResult()); 2012 isdataseg = 1; // It is in the DataSegment 2013 } 2014 } 2015 2016 return (isdataseg == 1); 2017 } 2018 2019 /************************************ 2020 * Does symbol go into thread local storage? 2021 */ 2022 2023 bool VarDeclaration::isThreadlocal() 2024 { 2025 //printf("VarDeclaration::isThreadlocal(%p, '%s')\n", this, toChars()); 2026 /* Data defaults to being thread-local. It is not thread-local 2027 * if it is immutable, const or shared. 2028 */ 2029 bool i = isDataseg() && 2030 !(storage_class & (STCimmutable | STCconst | STCshared | STCgshared)); 2031 //printf("\treturn %d\n", i); 2032 return i; 2033 } 2034 2035 /******************************************** 2036 * Can variable be read and written by CTFE? 2037 */ 2038 2039 bool VarDeclaration::isCTFE() 2040 { 2041 return (storage_class & STCctfe) != 0; // || !isDataseg(); 2042 } 2043 2044 bool VarDeclaration::isOverlappedWith(VarDeclaration *v) 2045 { 2046 const d_uns64 vsz = v->type->size(); 2047 const d_uns64 tsz = type->size(); 2048 assert(vsz != SIZE_INVALID && tsz != SIZE_INVALID); 2049 return offset < v->offset + vsz && 2050 v->offset < offset + tsz; 2051 } 2052 2053 bool VarDeclaration::hasPointers() 2054 { 2055 //printf("VarDeclaration::hasPointers() %s, ty = %d\n", toChars(), type->ty); 2056 return (!isDataseg() && type->hasPointers()); 2057 } 2058 2059 /****************************************** 2060 * Return true if variable needs to call the destructor. 2061 */ 2062 2063 bool VarDeclaration::needsScopeDtor() 2064 { 2065 //printf("VarDeclaration::needsScopeDtor() %s\n", toChars()); 2066 return edtor && !(storage_class & STCnodtor); 2067 } 2068 2069 2070 /****************************************** 2071 * If a variable has a scope destructor call, return call for it. 2072 * Otherwise, return NULL. 2073 */ 2074 2075 Expression *VarDeclaration::callScopeDtor(Scope *) 2076 { 2077 //printf("VarDeclaration::callScopeDtor() %s\n", toChars()); 2078 2079 // Destruction of STCfield's is handled by buildDtor() 2080 if (storage_class & (STCnodtor | STCref | STCout | STCfield)) 2081 { 2082 return NULL; 2083 } 2084 2085 Expression *e = NULL; 2086 2087 // Destructors for structs and arrays of structs 2088 Type *tv = type->baseElemOf(); 2089 if (tv->ty == Tstruct) 2090 { 2091 StructDeclaration *sd = ((TypeStruct *)tv)->sym; 2092 if (!sd->dtor || sd->errors) 2093 return NULL; 2094 2095 const d_uns64 sz = type->size(); 2096 assert(sz != SIZE_INVALID); 2097 if (!sz) 2098 return NULL; 2099 2100 if (type->toBasetype()->ty == Tstruct) 2101 { 2102 // v.__xdtor() 2103 e = new VarExp(loc, this); 2104 2105 /* This is a hack so we can call destructors on const/immutable objects. 2106 * Need to add things like "const ~this()" and "immutable ~this()" to 2107 * fix properly. 2108 */ 2109 e->type = e->type->mutableOf(); 2110 2111 // Enable calling destructors on shared objects. 2112 // The destructor is always a single, non-overloaded function, 2113 // and must serve both shared and non-shared objects. 2114 e->type = e->type->unSharedOf(); 2115 2116 e = new DotVarExp(loc, e, sd->dtor, false); 2117 e = new CallExp(loc, e); 2118 } 2119 else 2120 { 2121 // __ArrayDtor(v[0 .. n]) 2122 e = new VarExp(loc, this); 2123 2124 const d_uns64 sdsz = sd->type->size(); 2125 assert(sdsz != SIZE_INVALID && sdsz != 0); 2126 const d_uns64 n = sz / sdsz; 2127 e = new SliceExp(loc, e, new IntegerExp(loc, 0, Type::tsize_t), 2128 new IntegerExp(loc, n, Type::tsize_t)); 2129 // Prevent redundant bounds check 2130 ((SliceExp *)e)->upperIsInBounds = true; 2131 ((SliceExp *)e)->lowerIsLessThanUpper = true; 2132 2133 // This is a hack so we can call destructors on const/immutable objects. 2134 e->type = sd->type->arrayOf(); 2135 2136 e = new CallExp(loc, new IdentifierExp(loc, Id::__ArrayDtor), e); 2137 } 2138 return e; 2139 } 2140 2141 // Destructors for classes 2142 if (storage_class & (STCauto | STCscope) && !(storage_class & STCparameter)) 2143 { 2144 for (ClassDeclaration *cd = type->isClassHandle(); 2145 cd; 2146 cd = cd->baseClass) 2147 { 2148 /* We can do better if there's a way with onstack 2149 * classes to determine if there's no way the monitor 2150 * could be set. 2151 */ 2152 //if (cd->isInterfaceDeclaration()) 2153 //error("interface %s cannot be scope", cd->toChars()); 2154 2155 // Destroying C++ scope classes crashes currently. Since C++ class dtors are not currently supported, simply do not run dtors for them. 2156 // See https://issues.dlang.org/show_bug.cgi?id=13182 2157 if (cd->cpp) 2158 { 2159 break; 2160 } 2161 if (mynew || onstack) // if any destructors 2162 { 2163 // delete this; 2164 Expression *ec; 2165 2166 ec = new VarExp(loc, this); 2167 e = new DeleteExp(loc, ec, true); 2168 e->type = Type::tvoid; 2169 break; 2170 } 2171 } 2172 } 2173 return e; 2174 } 2175 2176 /********************************** 2177 * Determine if `this` has a lifetime that lasts past 2178 * the destruction of `v` 2179 * Params: 2180 * v = variable to test against 2181 * Returns: 2182 * true if it does 2183 */ 2184 bool VarDeclaration::enclosesLifetimeOf(VarDeclaration *v) const 2185 { 2186 return sequenceNumber < v->sequenceNumber; 2187 } 2188 2189 /****************************************** 2190 */ 2191 2192 void ObjectNotFound(Identifier *id) 2193 { 2194 Type::error(Loc(), "%s not found. object.d may be incorrectly installed or corrupt.", id->toChars()); 2195 fatal(); 2196 } 2197 2198 /******************************** SymbolDeclaration ********************************/ 2199 2200 SymbolDeclaration::SymbolDeclaration(Loc loc, StructDeclaration *dsym) 2201 : Declaration(dsym->ident) 2202 { 2203 this->loc = loc; 2204 this->dsym = dsym; 2205 storage_class |= STCconst; 2206 } 2207 2208 /********************************* TypeInfoDeclaration ****************************/ 2209 2210 TypeInfoDeclaration::TypeInfoDeclaration(Type *tinfo) 2211 : VarDeclaration(Loc(), Type::dtypeinfo->type, tinfo->getTypeInfoIdent(), NULL) 2212 { 2213 this->tinfo = tinfo; 2214 storage_class = STCstatic | STCgshared; 2215 protection = Prot(PROTpublic); 2216 linkage = LINKc; 2217 alignment = Target::ptrsize; 2218 } 2219 2220 TypeInfoDeclaration *TypeInfoDeclaration::create(Type *tinfo) 2221 { 2222 return new TypeInfoDeclaration(tinfo); 2223 } 2224 2225 Dsymbol *TypeInfoDeclaration::syntaxCopy(Dsymbol *) 2226 { 2227 assert(0); // should never be produced by syntax 2228 return NULL; 2229 } 2230 2231 void TypeInfoDeclaration::semantic(Scope *) 2232 { 2233 assert(linkage == LINKc); 2234 } 2235 2236 const char *TypeInfoDeclaration::toChars() 2237 { 2238 //printf("TypeInfoDeclaration::toChars() tinfo = %s\n", tinfo->toChars()); 2239 OutBuffer buf; 2240 buf.writestring("typeid("); 2241 buf.writestring(tinfo->toChars()); 2242 buf.writeByte(')'); 2243 return buf.extractString(); 2244 } 2245 2246 /***************************** TypeInfoConstDeclaration **********************/ 2247 2248 TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo) 2249 : TypeInfoDeclaration(tinfo) 2250 { 2251 if (!Type::typeinfoconst) 2252 { 2253 ObjectNotFound(Id::TypeInfo_Const); 2254 } 2255 type = Type::typeinfoconst->type; 2256 } 2257 2258 TypeInfoConstDeclaration *TypeInfoConstDeclaration::create(Type *tinfo) 2259 { 2260 return new TypeInfoConstDeclaration(tinfo); 2261 } 2262 2263 /***************************** TypeInfoInvariantDeclaration **********************/ 2264 2265 TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo) 2266 : TypeInfoDeclaration(tinfo) 2267 { 2268 if (!Type::typeinfoinvariant) 2269 { 2270 ObjectNotFound(Id::TypeInfo_Invariant); 2271 } 2272 type = Type::typeinfoinvariant->type; 2273 } 2274 2275 TypeInfoInvariantDeclaration *TypeInfoInvariantDeclaration::create(Type *tinfo) 2276 { 2277 return new TypeInfoInvariantDeclaration(tinfo); 2278 } 2279 2280 /***************************** TypeInfoSharedDeclaration **********************/ 2281 2282 TypeInfoSharedDeclaration::TypeInfoSharedDeclaration(Type *tinfo) 2283 : TypeInfoDeclaration(tinfo) 2284 { 2285 if (!Type::typeinfoshared) 2286 { 2287 ObjectNotFound(Id::TypeInfo_Shared); 2288 } 2289 type = Type::typeinfoshared->type; 2290 } 2291 2292 TypeInfoSharedDeclaration *TypeInfoSharedDeclaration::create(Type *tinfo) 2293 { 2294 return new TypeInfoSharedDeclaration(tinfo); 2295 } 2296 2297 /***************************** TypeInfoWildDeclaration **********************/ 2298 2299 TypeInfoWildDeclaration::TypeInfoWildDeclaration(Type *tinfo) 2300 : TypeInfoDeclaration(tinfo) 2301 { 2302 if (!Type::typeinfowild) 2303 { 2304 ObjectNotFound(Id::TypeInfo_Wild); 2305 } 2306 type = Type::typeinfowild->type; 2307 } 2308 2309 TypeInfoWildDeclaration *TypeInfoWildDeclaration::create(Type *tinfo) 2310 { 2311 return new TypeInfoWildDeclaration(tinfo); 2312 } 2313 2314 /***************************** TypeInfoStructDeclaration **********************/ 2315 2316 TypeInfoStructDeclaration::TypeInfoStructDeclaration(Type *tinfo) 2317 : TypeInfoDeclaration(tinfo) 2318 { 2319 if (!Type::typeinfostruct) 2320 { 2321 ObjectNotFound(Id::TypeInfo_Struct); 2322 } 2323 type = Type::typeinfostruct->type; 2324 } 2325 2326 TypeInfoStructDeclaration *TypeInfoStructDeclaration::create(Type *tinfo) 2327 { 2328 return new TypeInfoStructDeclaration(tinfo); 2329 } 2330 2331 /***************************** TypeInfoClassDeclaration ***********************/ 2332 2333 TypeInfoClassDeclaration::TypeInfoClassDeclaration(Type *tinfo) 2334 : TypeInfoDeclaration(tinfo) 2335 { 2336 if (!Type::typeinfoclass) 2337 { 2338 ObjectNotFound(Id::TypeInfo_Class); 2339 } 2340 type = Type::typeinfoclass->type; 2341 } 2342 2343 TypeInfoClassDeclaration *TypeInfoClassDeclaration::create(Type *tinfo) 2344 { 2345 return new TypeInfoClassDeclaration(tinfo); 2346 } 2347 2348 /***************************** TypeInfoInterfaceDeclaration *******************/ 2349 2350 TypeInfoInterfaceDeclaration::TypeInfoInterfaceDeclaration(Type *tinfo) 2351 : TypeInfoDeclaration(tinfo) 2352 { 2353 if (!Type::typeinfointerface) 2354 { 2355 ObjectNotFound(Id::TypeInfo_Interface); 2356 } 2357 type = Type::typeinfointerface->type; 2358 } 2359 2360 TypeInfoInterfaceDeclaration *TypeInfoInterfaceDeclaration::create(Type *tinfo) 2361 { 2362 return new TypeInfoInterfaceDeclaration(tinfo); 2363 } 2364 2365 /***************************** TypeInfoPointerDeclaration *********************/ 2366 2367 TypeInfoPointerDeclaration::TypeInfoPointerDeclaration(Type *tinfo) 2368 : TypeInfoDeclaration(tinfo) 2369 { 2370 if (!Type::typeinfopointer) 2371 { 2372 ObjectNotFound(Id::TypeInfo_Pointer); 2373 } 2374 type = Type::typeinfopointer->type; 2375 } 2376 2377 TypeInfoPointerDeclaration *TypeInfoPointerDeclaration::create(Type *tinfo) 2378 { 2379 return new TypeInfoPointerDeclaration(tinfo); 2380 } 2381 2382 /***************************** TypeInfoArrayDeclaration ***********************/ 2383 2384 TypeInfoArrayDeclaration::TypeInfoArrayDeclaration(Type *tinfo) 2385 : TypeInfoDeclaration(tinfo) 2386 { 2387 if (!Type::typeinfoarray) 2388 { 2389 ObjectNotFound(Id::TypeInfo_Array); 2390 } 2391 type = Type::typeinfoarray->type; 2392 } 2393 2394 TypeInfoArrayDeclaration *TypeInfoArrayDeclaration::create(Type *tinfo) 2395 { 2396 return new TypeInfoArrayDeclaration(tinfo); 2397 } 2398 2399 /***************************** TypeInfoStaticArrayDeclaration *****************/ 2400 2401 TypeInfoStaticArrayDeclaration::TypeInfoStaticArrayDeclaration(Type *tinfo) 2402 : TypeInfoDeclaration(tinfo) 2403 { 2404 if (!Type::typeinfostaticarray) 2405 { 2406 ObjectNotFound(Id::TypeInfo_StaticArray); 2407 } 2408 type = Type::typeinfostaticarray->type; 2409 } 2410 2411 TypeInfoStaticArrayDeclaration *TypeInfoStaticArrayDeclaration::create(Type *tinfo) 2412 { 2413 return new TypeInfoStaticArrayDeclaration(tinfo); 2414 } 2415 2416 /***************************** TypeInfoAssociativeArrayDeclaration ************/ 2417 2418 TypeInfoAssociativeArrayDeclaration::TypeInfoAssociativeArrayDeclaration(Type *tinfo) 2419 : TypeInfoDeclaration(tinfo) 2420 { 2421 if (!Type::typeinfoassociativearray) 2422 { 2423 ObjectNotFound(Id::TypeInfo_AssociativeArray); 2424 } 2425 type = Type::typeinfoassociativearray->type; 2426 } 2427 2428 TypeInfoAssociativeArrayDeclaration *TypeInfoAssociativeArrayDeclaration::create(Type *tinfo) 2429 { 2430 return new TypeInfoAssociativeArrayDeclaration(tinfo); 2431 } 2432 2433 /***************************** TypeInfoVectorDeclaration ***********************/ 2434 2435 TypeInfoVectorDeclaration::TypeInfoVectorDeclaration(Type *tinfo) 2436 : TypeInfoDeclaration(tinfo) 2437 { 2438 if (!Type::typeinfovector) 2439 { 2440 ObjectNotFound(Id::TypeInfo_Vector); 2441 } 2442 type = Type::typeinfovector->type; 2443 } 2444 2445 TypeInfoVectorDeclaration *TypeInfoVectorDeclaration::create(Type *tinfo) 2446 { 2447 return new TypeInfoVectorDeclaration(tinfo); 2448 } 2449 2450 /***************************** TypeInfoEnumDeclaration ***********************/ 2451 2452 TypeInfoEnumDeclaration::TypeInfoEnumDeclaration(Type *tinfo) 2453 : TypeInfoDeclaration(tinfo) 2454 { 2455 if (!Type::typeinfoenum) 2456 { 2457 ObjectNotFound(Id::TypeInfo_Enum); 2458 } 2459 type = Type::typeinfoenum->type; 2460 } 2461 2462 TypeInfoEnumDeclaration *TypeInfoEnumDeclaration::create(Type *tinfo) 2463 { 2464 return new TypeInfoEnumDeclaration(tinfo); 2465 } 2466 2467 /***************************** TypeInfoFunctionDeclaration ********************/ 2468 2469 TypeInfoFunctionDeclaration::TypeInfoFunctionDeclaration(Type *tinfo) 2470 : TypeInfoDeclaration(tinfo) 2471 { 2472 if (!Type::typeinfofunction) 2473 { 2474 ObjectNotFound(Id::TypeInfo_Function); 2475 } 2476 type = Type::typeinfofunction->type; 2477 } 2478 2479 TypeInfoFunctionDeclaration *TypeInfoFunctionDeclaration::create(Type *tinfo) 2480 { 2481 return new TypeInfoFunctionDeclaration(tinfo); 2482 } 2483 2484 /***************************** TypeInfoDelegateDeclaration ********************/ 2485 2486 TypeInfoDelegateDeclaration::TypeInfoDelegateDeclaration(Type *tinfo) 2487 : TypeInfoDeclaration(tinfo) 2488 { 2489 if (!Type::typeinfodelegate) 2490 { 2491 ObjectNotFound(Id::TypeInfo_Delegate); 2492 } 2493 type = Type::typeinfodelegate->type; 2494 } 2495 2496 TypeInfoDelegateDeclaration *TypeInfoDelegateDeclaration::create(Type *tinfo) 2497 { 2498 return new TypeInfoDelegateDeclaration(tinfo); 2499 } 2500 2501 /***************************** TypeInfoTupleDeclaration **********************/ 2502 2503 TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo) 2504 : TypeInfoDeclaration(tinfo) 2505 { 2506 if (!Type::typeinfotypelist) 2507 { 2508 ObjectNotFound(Id::TypeInfo_Tuple); 2509 } 2510 type = Type::typeinfotypelist->type; 2511 } 2512 2513 TypeInfoTupleDeclaration *TypeInfoTupleDeclaration::create(Type *tinfo) 2514 { 2515 return new TypeInfoTupleDeclaration(tinfo); 2516 } 2517 2518 /********************************* ThisDeclaration ****************************/ 2519 2520 // For the "this" parameter to member functions 2521 2522 ThisDeclaration::ThisDeclaration(Loc loc, Type *t) 2523 : VarDeclaration(loc, t, Id::This, NULL) 2524 { 2525 storage_class |= STCnodtor; 2526 } 2527 2528 Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *) 2529 { 2530 assert(0); // should never be produced by syntax 2531 return NULL; 2532 } 2533 2534