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