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/expression.c 9 */ 10 11 #include "root/dsystem.h" 12 #include "root/rmem.h" 13 #include "root/root.h" 14 15 #include "errors.h" 16 #include "mtype.h" 17 #include "init.h" 18 #include "expression.h" 19 #include "template.h" 20 #include "utf.h" 21 #include "enum.h" 22 #include "scope.h" 23 #include "statement.h" 24 #include "declaration.h" 25 #include "aggregate.h" 26 #include "import.h" 27 #include "id.h" 28 #include "dsymbol.h" 29 #include "module.h" 30 #include "attrib.h" 31 #include "hdrgen.h" 32 #include "parse.h" 33 #include "doc.h" 34 #include "root/aav.h" 35 #include "nspace.h" 36 #include "ctfe.h" 37 #include "target.h" 38 39 bool walkPostorder(Expression *e, StoppableVisitor *v); 40 bool checkParamArgumentEscape(Scope *sc, FuncDeclaration *fdc, Identifier *par, Expression *arg, bool gag); 41 bool checkAccess(AggregateDeclaration *ad, Loc loc, Scope *sc, Dsymbol *smember); 42 VarDeclaration *copyToTemp(StorageClass stc, const char *name, Expression *e); 43 Expression *extractSideEffect(Scope *sc, const char *name, Expression **e0, Expression *e, bool alwaysCopy = false); 44 char *MODtoChars(MOD mod); 45 bool MODimplicitConv(MOD modfrom, MOD modto); 46 MOD MODmerge(MOD mod1, MOD mod2); 47 void MODMatchToBuffer(OutBuffer *buf, unsigned char lhsMod, unsigned char rhsMod); 48 Expression *trySemantic(Expression *e, Scope *sc); 49 Expression *semantic(Expression *e, Scope *sc); 50 Expression *semanticX(DotIdExp *exp, Scope *sc); 51 Expression *semanticY(DotIdExp *exp, Scope *sc, int flag); 52 Expression *semanticY(DotTemplateInstanceExp *exp, Scope *sc, int flag); 53 Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads); 54 bool checkUnsafeAccess(Scope *sc, Expression *e, bool readonly, bool printmsg); 55 56 /************************************************************* 57 * Given var, we need to get the 58 * right 'this' pointer if var is in an outer class, but our 59 * existing 'this' pointer is in an inner class. 60 * Input: 61 * e1 existing 'this' 62 * ad struct or class we need the correct 'this' for 63 * var the specific member of ad we're accessing 64 */ 65 66 Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad, 67 Expression *e1, Declaration *var, int flag = 0) 68 { 69 //printf("\ngetRightThis(e1 = %s, ad = %s, var = %s)\n", e1->toChars(), ad->toChars(), var->toChars()); 70 L1: 71 Type *t = e1->type->toBasetype(); 72 //printf("e1->type = %s, var->type = %s\n", e1->type->toChars(), var->type->toChars()); 73 74 /* If e1 is not the 'this' pointer for ad 75 */ 76 if (ad && 77 !(t->ty == Tpointer && t->nextOf()->ty == Tstruct && 78 ((TypeStruct *)t->nextOf())->sym == ad) 79 && 80 !(t->ty == Tstruct && 81 ((TypeStruct *)t)->sym == ad) 82 ) 83 { 84 ClassDeclaration *cd = ad->isClassDeclaration(); 85 ClassDeclaration *tcd = t->isClassHandle(); 86 87 /* e1 is the right this if ad is a base class of e1 88 */ 89 if (!cd || !tcd || 90 !(tcd == cd || cd->isBaseOf(tcd, NULL)) 91 ) 92 { 93 /* Only classes can be inner classes with an 'outer' 94 * member pointing to the enclosing class instance 95 */ 96 if (tcd && tcd->isNested()) 97 { 98 /* e1 is the 'this' pointer for an inner class: tcd. 99 * Rewrite it as the 'this' pointer for the outer class. 100 */ 101 102 e1 = new DotVarExp(loc, e1, tcd->vthis); 103 e1->type = tcd->vthis->type; 104 e1->type = e1->type->addMod(t->mod); 105 // Do not call checkNestedRef() 106 //e1 = semantic(e1, sc); 107 108 // Skip up over nested functions, and get the enclosing 109 // class type. 110 int n = 0; 111 Dsymbol *s; 112 for (s = tcd->toParent(); 113 s && s->isFuncDeclaration(); 114 s = s->toParent()) 115 { 116 FuncDeclaration *f = s->isFuncDeclaration(); 117 if (f->vthis) 118 { 119 //printf("rewriting e1 to %s's this\n", f->toChars()); 120 n++; 121 e1 = new VarExp(loc, f->vthis); 122 } 123 else 124 { 125 e1->error("need 'this' of type %s to access member %s" 126 " from static function %s", 127 ad->toChars(), var->toChars(), f->toChars()); 128 e1 = new ErrorExp(); 129 return e1; 130 } 131 } 132 if (s && s->isClassDeclaration()) 133 { 134 e1->type = s->isClassDeclaration()->type; 135 e1->type = e1->type->addMod(t->mod); 136 if (n > 1) 137 e1 = semantic(e1, sc); 138 } 139 else 140 e1 = semantic(e1, sc); 141 goto L1; 142 } 143 144 /* Can't find a path from e1 to ad 145 */ 146 if (flag) 147 return NULL; 148 e1->error("this for %s needs to be type %s not type %s", 149 var->toChars(), ad->toChars(), t->toChars()); 150 return new ErrorExp(); 151 } 152 } 153 return e1; 154 } 155 156 /***************************************** 157 * Determine if 'this' is available. 158 * If it is, return the FuncDeclaration that has it. 159 */ 160 161 FuncDeclaration *hasThis(Scope *sc) 162 { 163 //printf("hasThis()\n"); 164 Dsymbol *p = sc->parent; 165 while (p && p->isTemplateMixin()) 166 p = p->parent; 167 FuncDeclaration *fdthis = p ? p->isFuncDeclaration() : NULL; 168 //printf("fdthis = %p, '%s'\n", fdthis, fdthis ? fdthis->toChars() : ""); 169 170 // Go upwards until we find the enclosing member function 171 FuncDeclaration *fd = fdthis; 172 while (1) 173 { 174 if (!fd) 175 { 176 goto Lno; 177 } 178 if (!fd->isNested()) 179 break; 180 181 Dsymbol *parent = fd->parent; 182 while (1) 183 { 184 if (!parent) 185 goto Lno; 186 TemplateInstance *ti = parent->isTemplateInstance(); 187 if (ti) 188 parent = ti->parent; 189 else 190 break; 191 } 192 fd = parent->isFuncDeclaration(); 193 } 194 195 if (!fd->isThis()) 196 { //printf("test '%s'\n", fd->toChars()); 197 goto Lno; 198 } 199 200 assert(fd->vthis); 201 return fd; 202 203 Lno: 204 return NULL; // don't have 'this' available 205 } 206 207 bool isNeedThisScope(Scope *sc, Declaration *d) 208 { 209 if (sc->intypeof == 1) 210 return false; 211 212 AggregateDeclaration *ad = d->isThis(); 213 if (!ad) 214 return false; 215 //printf("d = %s, ad = %s\n", d->toChars(), ad->toChars()); 216 217 for (Dsymbol *s = sc->parent; s; s = s->toParent2()) 218 { 219 //printf("\ts = %s %s, toParent2() = %p\n", s->kind(), s->toChars(), s->toParent2()); 220 if (AggregateDeclaration *ad2 = s->isAggregateDeclaration()) 221 { 222 if (ad2 == ad) 223 return false; 224 else if (ad2->isNested()) 225 continue; 226 else 227 return true; 228 } 229 if (FuncDeclaration *f = s->isFuncDeclaration()) 230 { 231 if (f->isMember2()) 232 break; 233 } 234 } 235 return true; 236 } 237 238 /*************************************** 239 * Pull out any properties. 240 */ 241 242 Expression *resolvePropertiesX(Scope *sc, Expression *e1, Expression *e2 = NULL) 243 { 244 //printf("resolvePropertiesX, e1 = %s %s, e2 = %s\n", Token::toChars(e1->op), e1->toChars(), e2 ? e2->toChars() : NULL); 245 Loc loc = e1->loc; 246 247 OverloadSet *os; 248 Dsymbol *s; 249 Objects *tiargs; 250 Type *tthis; 251 if (e1->op == TOKdot) 252 { 253 DotExp *de = (DotExp *)e1; 254 if (de->e2->op == TOKoverloadset) 255 { 256 tiargs = NULL; 257 tthis = de->e1->type; 258 os = ((OverExp *)de->e2)->vars; 259 goto Los; 260 } 261 } 262 else if (e1->op == TOKoverloadset) 263 { 264 tiargs = NULL; 265 tthis = NULL; 266 os = ((OverExp *)e1)->vars; 267 Los: 268 assert(os); 269 FuncDeclaration *fd = NULL; 270 if (e2) 271 { 272 e2 = semantic(e2, sc); 273 if (e2->op == TOKerror) 274 return new ErrorExp(); 275 e2 = resolveProperties(sc, e2); 276 277 Expressions a; 278 a.push(e2); 279 280 for (size_t i = 0; i < os->a.dim; i++) 281 { 282 FuncDeclaration *f = resolveFuncCall(loc, sc, os->a[i], tiargs, tthis, &a, 1); 283 if (f) 284 { 285 if (f->errors) 286 return new ErrorExp(); 287 fd = f; 288 assert(fd->type->ty == Tfunction); 289 } 290 } 291 if (fd) 292 { 293 Expression *e = new CallExp(loc, e1, e2); 294 return semantic(e, sc); 295 } 296 } 297 { 298 for (size_t i = 0; i < os->a.dim; i++) 299 { 300 FuncDeclaration *f = resolveFuncCall(loc, sc, os->a[i], tiargs, tthis, NULL, 1); 301 if (f) 302 { 303 if (f->errors) 304 return new ErrorExp(); 305 fd = f; 306 assert(fd->type->ty == Tfunction); 307 TypeFunction *tf = (TypeFunction *)fd->type; 308 if (!tf->isref && e2) 309 goto Leproplvalue; 310 } 311 } 312 if (fd) 313 { 314 Expression *e = new CallExp(loc, e1); 315 if (e2) 316 e = new AssignExp(loc, e, e2); 317 return semantic(e, sc); 318 } 319 } 320 if (e2) 321 goto Leprop; 322 } 323 else if (e1->op == TOKdotti) 324 { 325 DotTemplateInstanceExp* dti = (DotTemplateInstanceExp *)e1; 326 if (!dti->findTempDecl(sc)) 327 goto Leprop; 328 if (!dti->ti->semanticTiargs(sc)) 329 goto Leprop; 330 tiargs = dti->ti->tiargs; 331 tthis = dti->e1->type; 332 if ((os = dti->ti->tempdecl->isOverloadSet()) != NULL) 333 goto Los; 334 if ((s = dti->ti->tempdecl) != NULL) 335 goto Lfd; 336 } 337 else if (e1->op == TOKdottd) 338 { 339 DotTemplateExp *dte = (DotTemplateExp *)e1; 340 s = dte->td; 341 tiargs = NULL; 342 tthis = dte->e1->type; 343 goto Lfd; 344 } 345 else if (e1->op == TOKscope) 346 { 347 s = ((ScopeExp *)e1)->sds; 348 TemplateInstance *ti = s->isTemplateInstance(); 349 if (ti && !ti->semanticRun && ti->tempdecl) 350 { 351 //assert(ti->needsTypeInference(sc)); 352 if (!ti->semanticTiargs(sc)) 353 goto Leprop; 354 tiargs = ti->tiargs; 355 tthis = NULL; 356 if ((os = ti->tempdecl->isOverloadSet()) != NULL) 357 goto Los; 358 if ((s = ti->tempdecl) != NULL) 359 goto Lfd; 360 } 361 } 362 else if (e1->op == TOKtemplate) 363 { 364 s = ((TemplateExp *)e1)->td; 365 tiargs = NULL; 366 tthis = NULL; 367 goto Lfd; 368 } 369 else if (e1->op == TOKdotvar && e1->type && e1->type->toBasetype()->ty == Tfunction) 370 { 371 DotVarExp *dve = (DotVarExp *)e1; 372 s = dve->var->isFuncDeclaration(); 373 tiargs = NULL; 374 tthis = dve->e1->type; 375 goto Lfd; 376 } 377 else if (e1->op == TOKvar && e1->type && e1->type->toBasetype()->ty == Tfunction) 378 { 379 s = ((VarExp *)e1)->var->isFuncDeclaration(); 380 tiargs = NULL; 381 tthis = NULL; 382 Lfd: 383 assert(s); 384 if (e2) 385 { 386 e2 = semantic(e2, sc); 387 if (e2->op == TOKerror) 388 return new ErrorExp(); 389 e2 = resolveProperties(sc, e2); 390 391 Expressions a; 392 a.push(e2); 393 394 FuncDeclaration *fd = resolveFuncCall(loc, sc, s, tiargs, tthis, &a, 1); 395 if (fd && fd->type) 396 { 397 if (fd->errors) 398 return new ErrorExp(); 399 assert(fd->type->ty == Tfunction); 400 Expression *e = new CallExp(loc, e1, e2); 401 return semantic(e, sc); 402 } 403 } 404 { 405 FuncDeclaration *fd = resolveFuncCall(loc, sc, s, tiargs, tthis, NULL, 1); 406 if (fd && fd->type) 407 { 408 if (fd->errors) 409 return new ErrorExp(); 410 assert(fd->type->ty == Tfunction); 411 TypeFunction *tf = (TypeFunction *)fd->type; 412 if (!e2 || tf->isref) 413 { 414 Expression *e = new CallExp(loc, e1); 415 if (e2) 416 e = new AssignExp(loc, e, e2); 417 return semantic(e, sc); 418 } 419 } 420 } 421 if (FuncDeclaration *fd = s->isFuncDeclaration()) 422 { 423 // Keep better diagnostic message for invalid property usage of functions 424 assert(fd->type->ty == Tfunction); 425 Expression *e = new CallExp(loc, e1, e2); 426 return semantic(e, sc); 427 } 428 if (e2) 429 goto Leprop; 430 } 431 if (e1->op == TOKvar) 432 { 433 VarExp *ve = (VarExp *)e1; 434 VarDeclaration *v = ve->var->isVarDeclaration(); 435 if (v && ve->checkPurity(sc, v)) 436 return new ErrorExp(); 437 } 438 if (e2) 439 return NULL; 440 441 if (e1->type && 442 e1->op != TOKtype) // function type is not a property 443 { 444 /* Look for e1 being a lazy parameter; rewrite as delegate call 445 */ 446 if (e1->op == TOKvar) 447 { 448 VarExp *ve = (VarExp *)e1; 449 450 if (ve->var->storage_class & STClazy) 451 { 452 Expression *e = new CallExp(loc, e1); 453 return semantic(e, sc); 454 } 455 } 456 else if (e1->op == TOKdotvar) 457 { 458 // Check for reading overlapped pointer field in @safe code. 459 if (checkUnsafeAccess(sc, e1, true, true)) 460 return new ErrorExp(); 461 } 462 else if (e1->op == TOKdot) 463 { 464 e1->error("expression has no value"); 465 return new ErrorExp(); 466 } 467 else if (e1->op == TOKcall) 468 { 469 CallExp *ce = (CallExp *)e1; 470 // Check for reading overlapped pointer field in @safe code. 471 if (checkUnsafeAccess(sc, ce->e1, true, true)) 472 return new ErrorExp(); 473 } 474 } 475 476 if (!e1->type) 477 { 478 error(loc, "cannot resolve type for %s", e1->toChars()); 479 e1 = new ErrorExp(); 480 } 481 return e1; 482 483 Leprop: 484 error(loc, "not a property %s", e1->toChars()); 485 return new ErrorExp(); 486 487 Leproplvalue: 488 error(loc, "%s is not an lvalue", e1->toChars()); 489 return new ErrorExp(); 490 } 491 492 Expression *resolveProperties(Scope *sc, Expression *e) 493 { 494 //printf("resolveProperties(%s)\n", e->toChars()); 495 496 e = resolvePropertiesX(sc, e); 497 if (e->checkRightThis(sc)) 498 return new ErrorExp(); 499 return e; 500 } 501 502 /****************************** 503 * Check the tail CallExp is really property function call. 504 */ 505 static bool checkPropertyCall(Expression *e) 506 { 507 while (e->op == TOKcomma) 508 e = ((CommaExp *)e)->e2; 509 510 if (e->op == TOKcall) 511 { 512 CallExp *ce = (CallExp *)e; 513 TypeFunction *tf; 514 if (ce->f) 515 { 516 tf = (TypeFunction *)ce->f->type; 517 /* If a forward reference to ce->f, try to resolve it 518 */ 519 if (!tf->deco && ce->f->_scope) 520 { 521 ce->f->semantic(ce->f->_scope); 522 tf = (TypeFunction *)ce->f->type; 523 } 524 } 525 else if (ce->e1->type->ty == Tfunction) 526 tf = (TypeFunction *)ce->e1->type; 527 else if (ce->e1->type->ty == Tdelegate) 528 tf = (TypeFunction *)ce->e1->type->nextOf(); 529 else if (ce->e1->type->ty == Tpointer && ce->e1->type->nextOf()->ty == Tfunction) 530 tf = (TypeFunction *)ce->e1->type->nextOf(); 531 else 532 assert(0); 533 } 534 return false; 535 } 536 537 /****************************** 538 * If e1 is a property function (template), resolve it. 539 */ 540 541 Expression *resolvePropertiesOnly(Scope *sc, Expression *e1) 542 { 543 //printf("e1 = %s %s\n", Token::toChars(e1->op), e1->toChars()); 544 OverloadSet *os; 545 FuncDeclaration *fd; 546 TemplateDeclaration *td; 547 548 if (e1->op == TOKdot) 549 { 550 DotExp *de = (DotExp *)e1; 551 if (de->e2->op == TOKoverloadset) 552 { 553 os = ((OverExp *)de->e2)->vars; 554 goto Los; 555 } 556 } 557 else if (e1->op == TOKoverloadset) 558 { 559 os = ((OverExp *)e1)->vars; 560 Los: 561 assert(os); 562 for (size_t i = 0; i < os->a.dim; i++) 563 { 564 Dsymbol *s = os->a[i]; 565 fd = s->isFuncDeclaration(); 566 td = s->isTemplateDeclaration(); 567 if (fd) 568 { 569 if (((TypeFunction *)fd->type)->isproperty) 570 return resolveProperties(sc, e1); 571 } 572 else if (td && td->onemember && 573 (fd = td->onemember->isFuncDeclaration()) != NULL) 574 { 575 if (((TypeFunction *)fd->type)->isproperty || 576 (fd->storage_class2 & STCproperty) || 577 (td->_scope->stc & STCproperty)) 578 { 579 return resolveProperties(sc, e1); 580 } 581 } 582 } 583 } 584 else if (e1->op == TOKdotti) 585 { 586 DotTemplateInstanceExp* dti = (DotTemplateInstanceExp *)e1; 587 if (dti->ti->tempdecl && (td = dti->ti->tempdecl->isTemplateDeclaration()) != NULL) 588 goto Ltd; 589 } 590 else if (e1->op == TOKdottd) 591 { 592 td = ((DotTemplateExp *)e1)->td; 593 goto Ltd; 594 } 595 else if (e1->op == TOKscope) 596 { 597 Dsymbol *s = ((ScopeExp *)e1)->sds; 598 TemplateInstance *ti = s->isTemplateInstance(); 599 if (ti && !ti->semanticRun && ti->tempdecl) 600 { 601 if ((td = ti->tempdecl->isTemplateDeclaration()) != NULL) 602 goto Ltd; 603 } 604 } 605 else if (e1->op == TOKtemplate) 606 { 607 td = ((TemplateExp *)e1)->td; 608 Ltd: 609 assert(td); 610 if (td->onemember && 611 (fd = td->onemember->isFuncDeclaration()) != NULL) 612 { 613 if (((TypeFunction *)fd->type)->isproperty || 614 (fd->storage_class2 & STCproperty) || 615 (td->_scope->stc & STCproperty)) 616 { 617 return resolveProperties(sc, e1); 618 } 619 } 620 } 621 else if (e1->op == TOKdotvar && e1->type->ty == Tfunction) 622 { 623 DotVarExp *dve = (DotVarExp *)e1; 624 fd = dve->var->isFuncDeclaration(); 625 goto Lfd; 626 } 627 else if (e1->op == TOKvar && e1->type->ty == Tfunction && 628 (sc->intypeof || !((VarExp *)e1)->var->needThis())) 629 { 630 fd = ((VarExp *)e1)->var->isFuncDeclaration(); 631 Lfd: 632 assert(fd); 633 if (((TypeFunction *)fd->type)->isproperty) 634 return resolveProperties(sc, e1); 635 } 636 return e1; 637 } 638 639 640 // TODO: merge with Scope::search::searchScopes() 641 static Dsymbol *searchScopes(Scope *sc, Loc loc, Identifier *ident, int flags) 642 { 643 Dsymbol *s = NULL; 644 for (Scope *scx = sc; scx; scx = scx->enclosing) 645 { 646 if (!scx->scopesym) 647 continue; 648 if (scx->scopesym->isModule()) 649 flags |= SearchUnqualifiedModule; // tell Module.search() that SearchLocalsOnly is to be obeyed 650 s = scx->scopesym->search(loc, ident, flags); 651 if (s) 652 { 653 // overload set contains only module scope symbols. 654 if (s->isOverloadSet()) 655 break; 656 // selective/renamed imports also be picked up 657 if (AliasDeclaration *ad = s->isAliasDeclaration()) 658 { 659 if (ad->_import) 660 break; 661 } 662 // See only module scope symbols for UFCS target. 663 Dsymbol *p = s->toParent2(); 664 if (p && p->isModule()) 665 break; 666 } 667 s = NULL; 668 669 // Stop when we hit a module, but keep going if that is not just under the global scope 670 if (scx->scopesym->isModule() && !(scx->enclosing && !scx->enclosing->enclosing)) 671 break; 672 } 673 return s; 674 } 675 676 /****************************** 677 * Find symbol in accordance with the UFCS name look up rule 678 */ 679 680 Expression *searchUFCS(Scope *sc, UnaExp *ue, Identifier *ident) 681 { 682 //printf("searchUFCS(ident = %s)\n", ident->toChars()); 683 Loc loc = ue->loc; 684 int flags = 0; 685 Dsymbol *s = NULL; 686 687 if (sc->flags & SCOPEignoresymbolvisibility) 688 flags |= IgnoreSymbolVisibility; 689 690 Dsymbol *sold = NULL; 691 if (global.params.bug10378 || global.params.check10378) 692 { 693 sold = searchScopes(sc, loc, ident, flags | IgnoreSymbolVisibility); 694 if (!global.params.check10378) 695 { 696 s = sold; 697 goto Lsearchdone; 698 } 699 } 700 701 // First look in local scopes 702 s = searchScopes(sc, loc, ident, flags | SearchLocalsOnly); 703 if (!s) 704 { 705 // Second look in imported modules 706 s = searchScopes(sc, loc, ident, flags | SearchImportsOnly); 707 708 /** Still find private symbols, so that symbols that weren't access 709 * checked by the compiler remain usable. Once the deprecation is over, 710 * this should be moved to search_correct instead. 711 */ 712 if (!s && !(flags & IgnoreSymbolVisibility)) 713 { 714 s = searchScopes(sc, loc, ident, flags | SearchLocalsOnly | IgnoreSymbolVisibility); 715 if (!s) 716 s = searchScopes(sc, loc, ident, flags | SearchImportsOnly | IgnoreSymbolVisibility); 717 if (s) 718 ::deprecation(loc, "%s is not visible from module %s", s->toPrettyChars(), sc->_module->toChars()); 719 } 720 } 721 if (global.params.check10378) 722 { 723 Dsymbol *snew = s; 724 if (sold != snew) 725 Scope::deprecation10378(loc, sold, snew); 726 if (global.params.bug10378) 727 s = sold; 728 } 729 Lsearchdone: 730 731 if (!s) 732 return ue->e1->type->Type::getProperty(loc, ident, 0); 733 734 FuncDeclaration *f = s->isFuncDeclaration(); 735 if (f) 736 { 737 TemplateDeclaration *td = getFuncTemplateDecl(f); 738 if (td) 739 { 740 if (td->overroot) 741 td = td->overroot; 742 s = td; 743 } 744 } 745 746 if (ue->op == TOKdotti) 747 { 748 DotTemplateInstanceExp *dti = (DotTemplateInstanceExp *)ue; 749 TemplateInstance *ti = new TemplateInstance(loc, s->ident); 750 ti->tiargs = dti->ti->tiargs; // for better diagnostic message 751 if (!ti->updateTempDecl(sc, s)) 752 return new ErrorExp(); 753 return new ScopeExp(loc, ti); 754 } 755 else 756 { 757 //printf("-searchUFCS() %s\n", s->toChars()); 758 return new DsymbolExp(loc, s); 759 } 760 } 761 762 /****************************** 763 * check e is exp.opDispatch!(tiargs) or not 764 * It's used to switch to UFCS the semantic analysis path 765 */ 766 767 bool isDotOpDispatch(Expression *e) 768 { 769 return e->op == TOKdotti && 770 ((DotTemplateInstanceExp *)e)->ti->name == Id::opDispatch; 771 } 772 773 /****************************** 774 * Pull out callable entity with UFCS. 775 */ 776 777 Expression *resolveUFCS(Scope *sc, CallExp *ce) 778 { 779 Loc loc = ce->loc; 780 Expression *eleft; 781 Expression *e; 782 783 if (ce->e1->op == TOKdotid) 784 { 785 DotIdExp *die = (DotIdExp *)ce->e1; 786 Identifier *ident = die->ident; 787 788 Expression *ex = semanticX(die, sc); 789 if (ex != die) 790 { 791 ce->e1 = ex; 792 return NULL; 793 } 794 eleft = die->e1; 795 796 Type *t = eleft->type->toBasetype(); 797 if (t->ty == Tarray || t->ty == Tsarray || 798 t->ty == Tnull || (t->isTypeBasic() && t->ty != Tvoid)) 799 { 800 /* Built-in types and arrays have no callable properties, so do shortcut. 801 * It is necessary in: e.init() 802 */ 803 } 804 else if (t->ty == Taarray) 805 { 806 if (ident == Id::remove) 807 { 808 /* Transform: 809 * aa.remove(arg) into delete aa[arg] 810 */ 811 if (!ce->arguments || ce->arguments->dim != 1) 812 { 813 ce->error("expected key as argument to aa.remove()"); 814 return new ErrorExp(); 815 } 816 if (!eleft->type->isMutable()) 817 { 818 ce->error("cannot remove key from %s associative array %s", 819 MODtoChars(t->mod), eleft->toChars()); 820 return new ErrorExp(); 821 } 822 Expression *key = (*ce->arguments)[0]; 823 key = semantic(key, sc); 824 key = resolveProperties(sc, key); 825 826 TypeAArray *taa = (TypeAArray *)t; 827 key = key->implicitCastTo(sc, taa->index); 828 829 if (key->checkValue()) 830 return new ErrorExp(); 831 832 semanticTypeInfo(sc, taa->index); 833 834 return new RemoveExp(loc, eleft, key); 835 } 836 } 837 else 838 { 839 if (Expression *ey = semanticY(die, sc, 1)) 840 { 841 if (ey->op == TOKerror) 842 return ey; 843 ce->e1 = ey; 844 if (isDotOpDispatch(ey)) 845 { 846 unsigned errors = global.startGagging(); 847 e = semantic(ce->syntaxCopy(), sc); 848 if (!global.endGagging(errors)) 849 return e; 850 /* fall down to UFCS */ 851 } 852 else 853 return NULL; 854 } 855 } 856 e = searchUFCS(sc, die, ident); 857 } 858 else if (ce->e1->op == TOKdotti) 859 { 860 DotTemplateInstanceExp *dti = (DotTemplateInstanceExp *)ce->e1; 861 if (Expression *ey = semanticY(dti, sc, 1)) 862 { 863 ce->e1 = ey; 864 return NULL; 865 } 866 eleft = dti->e1; 867 e = searchUFCS(sc, dti, dti->ti->name); 868 } 869 else 870 return NULL; 871 872 // Rewrite 873 ce->e1 = e; 874 if (!ce->arguments) 875 ce->arguments = new Expressions(); 876 ce->arguments->shift(eleft); 877 878 return NULL; 879 } 880 881 /****************************** 882 * Pull out property with UFCS. 883 */ 884 885 Expression *resolveUFCSProperties(Scope *sc, Expression *e1, Expression *e2 = NULL) 886 { 887 Loc loc = e1->loc; 888 Expression *eleft; 889 Expression *e; 890 891 if (e1->op == TOKdotid) 892 { 893 DotIdExp *die = (DotIdExp *)e1; 894 eleft = die->e1; 895 e = searchUFCS(sc, die, die->ident); 896 } 897 else if (e1->op == TOKdotti) 898 { 899 DotTemplateInstanceExp *dti; 900 dti = (DotTemplateInstanceExp *)e1; 901 eleft = dti->e1; 902 e = searchUFCS(sc, dti, dti->ti->name); 903 } 904 else 905 return NULL; 906 907 if (e == NULL) 908 return NULL; 909 910 // Rewrite 911 if (e2) 912 { 913 // run semantic without gagging 914 e2 = semantic(e2, sc); 915 916 /* f(e1) = e2 917 */ 918 Expression *ex = e->copy(); 919 Expressions *a1 = new Expressions(); 920 a1->setDim(1); 921 (*a1)[0] = eleft; 922 ex = new CallExp(loc, ex, a1); 923 ex = trySemantic(ex, sc); 924 925 /* f(e1, e2) 926 */ 927 Expressions *a2 = new Expressions(); 928 a2->setDim(2); 929 (*a2)[0] = eleft; 930 (*a2)[1] = e2; 931 e = new CallExp(loc, e, a2); 932 if (ex) 933 { // if fallback setter exists, gag errors 934 e = trySemantic(e, sc); 935 if (!e) 936 { checkPropertyCall(ex); 937 ex = new AssignExp(loc, ex, e2); 938 return semantic(ex, sc); 939 } 940 } 941 else 942 { // strict setter prints errors if fails 943 e = semantic(e, sc); 944 } 945 checkPropertyCall(e); 946 return e; 947 } 948 else 949 { 950 /* f(e1) 951 */ 952 Expressions *arguments = new Expressions(); 953 arguments->setDim(1); 954 (*arguments)[0] = eleft; 955 e = new CallExp(loc, e, arguments); 956 e = semantic(e, sc); 957 checkPropertyCall(e); 958 return semantic(e, sc); 959 } 960 } 961 962 /****************************** 963 * Perform semantic() on an array of Expressions. 964 */ 965 966 bool arrayExpressionSemantic(Expressions *exps, Scope *sc, bool preserveErrors) 967 { 968 bool err = false; 969 if (exps) 970 { 971 for (size_t i = 0; i < exps->dim; i++) 972 { 973 Expression *e = (*exps)[i]; 974 if (e) 975 { 976 e = semantic(e, sc); 977 if (e->op == TOKerror) 978 err = true; 979 if (preserveErrors || e->op != TOKerror) 980 (*exps)[i] = e; 981 } 982 } 983 } 984 return err; 985 } 986 987 /**************************************** 988 * Expand tuples. 989 * Input: 990 * exps aray of Expressions 991 * Output: 992 * exps rewritten in place 993 */ 994 995 void expandTuples(Expressions *exps) 996 { 997 //printf("expandTuples()\n"); 998 if (exps) 999 { 1000 for (size_t i = 0; i < exps->dim; i++) 1001 { 1002 Expression *arg = (*exps)[i]; 1003 if (!arg) 1004 continue; 1005 1006 // Look for tuple with 0 members 1007 if (arg->op == TOKtype) 1008 { 1009 TypeExp *e = (TypeExp *)arg; 1010 if (e->type->toBasetype()->ty == Ttuple) 1011 { 1012 TypeTuple *tt = (TypeTuple *)e->type->toBasetype(); 1013 1014 if (!tt->arguments || tt->arguments->dim == 0) 1015 { 1016 exps->remove(i); 1017 if (i == exps->dim) 1018 return; 1019 i--; 1020 continue; 1021 } 1022 } 1023 } 1024 1025 // Inline expand all the tuples 1026 while (arg->op == TOKtuple) 1027 { 1028 TupleExp *te = (TupleExp *)arg; 1029 exps->remove(i); // remove arg 1030 exps->insert(i, te->exps); // replace with tuple contents 1031 if (i == exps->dim) 1032 return; // empty tuple, no more arguments 1033 (*exps)[i] = Expression::combine(te->e0, (*exps)[i]); 1034 arg = (*exps)[i]; 1035 } 1036 } 1037 } 1038 } 1039 1040 /**************************************** 1041 * Expand alias this tuples. 1042 */ 1043 1044 TupleDeclaration *isAliasThisTuple(Expression *e) 1045 { 1046 if (!e->type) 1047 return NULL; 1048 1049 Type *t = e->type->toBasetype(); 1050 Lagain: 1051 if (Dsymbol *s = t->toDsymbol(NULL)) 1052 { 1053 AggregateDeclaration *ad = s->isAggregateDeclaration(); 1054 if (ad) 1055 { 1056 s = ad->aliasthis; 1057 if (s && s->isVarDeclaration()) 1058 { 1059 TupleDeclaration *td = s->isVarDeclaration()->toAlias()->isTupleDeclaration(); 1060 if (td && td->isexp) 1061 return td; 1062 } 1063 if (Type *att = t->aliasthisOf()) 1064 { 1065 t = att; 1066 goto Lagain; 1067 } 1068 } 1069 } 1070 return NULL; 1071 } 1072 1073 int expandAliasThisTuples(Expressions *exps, size_t starti) 1074 { 1075 if (!exps || exps->dim == 0) 1076 return -1; 1077 1078 for (size_t u = starti; u < exps->dim; u++) 1079 { 1080 Expression *exp = (*exps)[u]; 1081 TupleDeclaration *td = isAliasThisTuple(exp); 1082 if (td) 1083 { 1084 exps->remove(u); 1085 for (size_t i = 0; i<td->objects->dim; ++i) 1086 { 1087 Expression *e = isExpression((*td->objects)[i]); 1088 assert(e); 1089 assert(e->op == TOKdsymbol); 1090 DsymbolExp *se = (DsymbolExp *)e; 1091 Declaration *d = se->s->isDeclaration(); 1092 assert(d); 1093 e = new DotVarExp(exp->loc, exp, d); 1094 assert(d->type); 1095 e->type = d->type; 1096 exps->insert(u + i, e); 1097 } 1098 return (int)u; 1099 } 1100 } 1101 1102 return -1; 1103 } 1104 1105 /**************************************** 1106 * The common type is determined by applying ?: to each pair. 1107 * Output: 1108 * exps[] properties resolved, implicitly cast to common type, rewritten in place 1109 * *pt if pt is not NULL, set to the common type 1110 * Returns: 1111 * true a semantic error was detected 1112 */ 1113 1114 bool arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt) 1115 { 1116 /* Still have a problem with: 1117 * ubyte[][] = [ cast(ubyte[])"hello", [1]]; 1118 * which works if the array literal is initialized top down with the ubyte[][] 1119 * type, but fails with this function doing bottom up typing. 1120 */ 1121 //printf("arrayExpressionToCommonType()\n"); 1122 IntegerExp integerexp(0); 1123 CondExp condexp(Loc(), &integerexp, NULL, NULL); 1124 1125 Type *t0 = NULL; 1126 Expression *e0 = NULL; // dead-store to prevent spurious warning 1127 size_t j0 = ~0; // dead-store to prevent spurious warning 1128 for (size_t i = 0; i < exps->dim; i++) 1129 { 1130 Expression *e = (*exps)[i]; 1131 if (!e) 1132 continue; 1133 1134 e = resolveProperties(sc, e); 1135 if (!e->type) 1136 { 1137 e->error("%s has no value", e->toChars()); 1138 t0 = Type::terror; 1139 continue; 1140 } 1141 if (e->op == TOKtype) 1142 { 1143 e->checkValue(); // report an error "type T has no value" 1144 t0 = Type::terror; 1145 continue; 1146 } 1147 if (e->type->ty == Tvoid) 1148 { 1149 // void expressions do not concur to the determination of the common 1150 // type. 1151 continue; 1152 } 1153 if (checkNonAssignmentArrayOp(e)) 1154 { 1155 t0 = Type::terror; 1156 continue; 1157 } 1158 1159 e = doCopyOrMove(sc, e); 1160 1161 if (t0 && !t0->equals(e->type)) 1162 { 1163 /* This applies ?: to merge the types. It's backwards; 1164 * ?: should call this function to merge types. 1165 */ 1166 condexp.type = NULL; 1167 condexp.e1 = e0; 1168 condexp.e2 = e; 1169 condexp.loc = e->loc; 1170 Expression *ex = semantic(&condexp, sc); 1171 if (ex->op == TOKerror) 1172 e = ex; 1173 else 1174 { 1175 (*exps)[j0] = condexp.e1; 1176 e = condexp.e2; 1177 } 1178 } 1179 j0 = i; 1180 e0 = e; 1181 t0 = e->type; 1182 if (e->op != TOKerror) 1183 (*exps)[i] = e; 1184 } 1185 1186 if (!t0) 1187 t0 = Type::tvoid; // [] is typed as void[] 1188 else if (t0->ty != Terror) 1189 { 1190 for (size_t i = 0; i < exps->dim; i++) 1191 { 1192 Expression *e = (*exps)[i]; 1193 if (!e) 1194 continue; 1195 1196 e = e->implicitCastTo(sc, t0); 1197 //assert(e->op != TOKerror); 1198 if (e->op == TOKerror) 1199 { 1200 /* Bugzilla 13024: a workaround for the bug in typeMerge - 1201 * it should paint e1 and e2 by deduced common type, 1202 * but doesn't in this particular case. 1203 */ 1204 t0 = Type::terror; 1205 break; 1206 } 1207 (*exps)[i] = e; 1208 } 1209 } 1210 if (pt) 1211 *pt = t0; 1212 1213 return (t0 == Type::terror); 1214 } 1215 1216 /**************************************** 1217 * Get TemplateDeclaration enclosing FuncDeclaration. 1218 */ 1219 1220 TemplateDeclaration *getFuncTemplateDecl(Dsymbol *s) 1221 { 1222 FuncDeclaration *f = s->isFuncDeclaration(); 1223 if (f && f->parent) 1224 { 1225 TemplateInstance *ti = f->parent->isTemplateInstance(); 1226 if (ti && !ti->isTemplateMixin() && 1227 ti->tempdecl && ((TemplateDeclaration *)ti->tempdecl)->onemember && 1228 ti->tempdecl->ident == f->ident) 1229 { 1230 return (TemplateDeclaration *)ti->tempdecl; 1231 } 1232 } 1233 return NULL; 1234 } 1235 1236 /************************************************ 1237 * If we want the value of this expression, but do not want to call 1238 * the destructor on it. 1239 */ 1240 1241 Expression *valueNoDtor(Expression *e) 1242 { 1243 if (e->op == TOKcall) 1244 { 1245 /* The struct value returned from the function is transferred 1246 * so do not call the destructor on it. 1247 * Recognize: 1248 * ((S _ctmp = S.init), _ctmp).this(...) 1249 * and make sure the destructor is not called on _ctmp 1250 * BUG: if e is a CommaExp, we should go down the right side. 1251 */ 1252 CallExp *ce = (CallExp *)e; 1253 if (ce->e1->op == TOKdotvar) 1254 { 1255 DotVarExp *dve = (DotVarExp *)ce->e1; 1256 if (dve->var->isCtorDeclaration()) 1257 { 1258 // It's a constructor call 1259 if (dve->e1->op == TOKcomma) 1260 { 1261 CommaExp *comma = (CommaExp *)dve->e1; 1262 if (comma->e2->op == TOKvar) 1263 { 1264 VarExp *ve = (VarExp *)comma->e2; 1265 VarDeclaration *ctmp = ve->var->isVarDeclaration(); 1266 if (ctmp) 1267 { 1268 ctmp->storage_class |= STCnodtor; 1269 assert(!ce->isLvalue()); 1270 } 1271 } 1272 } 1273 } 1274 } 1275 } 1276 else if (e->op == TOKvar) 1277 { 1278 VarDeclaration *vtmp = ((VarExp *)e)->var->isVarDeclaration(); 1279 if (vtmp && vtmp->storage_class & STCrvalue) 1280 { 1281 vtmp->storage_class |= STCnodtor; 1282 } 1283 } 1284 return e; 1285 } 1286 1287 /******************************************** 1288 * Issue an error if default construction is disabled for type t. 1289 * Default construction is required for arrays and 'out' parameters. 1290 * Returns: 1291 * true an error was issued 1292 */ 1293 bool checkDefCtor(Loc loc, Type *t) 1294 { 1295 t = t->baseElemOf(); 1296 if (t->ty == Tstruct) 1297 { 1298 StructDeclaration *sd = ((TypeStruct *)t)->sym; 1299 if (sd->noDefaultCtor) 1300 { 1301 sd->error(loc, "default construction is disabled"); 1302 return true; 1303 } 1304 } 1305 return false; 1306 } 1307 1308 /********************************************* 1309 * If e is an instance of a struct, and that struct has a copy constructor, 1310 * rewrite e as: 1311 * (tmp = e),tmp 1312 * Input: 1313 * sc just used to specify the scope of created temporary variable 1314 */ 1315 Expression *callCpCtor(Scope *sc, Expression *e) 1316 { 1317 Type *tv = e->type->baseElemOf(); 1318 if (tv->ty == Tstruct) 1319 { 1320 StructDeclaration *sd = ((TypeStruct *)tv)->sym; 1321 if (sd->postblit) 1322 { 1323 /* Create a variable tmp, and replace the argument e with: 1324 * (tmp = e),tmp 1325 * and let AssignExp() handle the construction. 1326 * This is not the most efficent, ideally tmp would be constructed 1327 * directly onto the stack. 1328 */ 1329 VarDeclaration *tmp = copyToTemp(STCrvalue, "__copytmp", e); 1330 tmp->storage_class |= STCnodtor; 1331 tmp->semantic(sc); 1332 Expression *de = new DeclarationExp(e->loc, tmp); 1333 Expression *ve = new VarExp(e->loc, tmp); 1334 de->type = Type::tvoid; 1335 ve->type = e->type; 1336 e = Expression::combine(de, ve); 1337 } 1338 } 1339 return e; 1340 } 1341 1342 /************************************************ 1343 * Handle the postblit call on lvalue, or the move of rvalue. 1344 */ 1345 Expression *doCopyOrMove(Scope *sc, Expression *e) 1346 { 1347 if (e->op == TOKquestion) 1348 { 1349 CondExp *ce = (CondExp *)e; 1350 ce->e1 = doCopyOrMove(sc, ce->e1); 1351 ce->e2 = doCopyOrMove(sc, ce->e2); 1352 } 1353 else 1354 { 1355 e = e->isLvalue() ? callCpCtor(sc, e) : valueNoDtor(e); 1356 } 1357 return e; 1358 } 1359 1360 /**************************************** 1361 * Now that we know the exact type of the function we're calling, 1362 * the arguments[] need to be adjusted: 1363 * 1. implicitly convert argument to the corresponding parameter type 1364 * 2. add default arguments for any missing arguments 1365 * 3. do default promotions on arguments corresponding to ... 1366 * 4. add hidden _arguments[] argument 1367 * 5. call copy constructor for struct value arguments 1368 * Input: 1369 * tf type of the function 1370 * fd the function being called, NULL if called indirectly 1371 * Output: 1372 * *prettype return type of function 1373 * *peprefix expression to execute before arguments[] are evaluated, NULL if none 1374 * Returns: 1375 * true errors happened 1376 */ 1377 1378 bool functionParameters(Loc loc, Scope *sc, TypeFunction *tf, 1379 Type *tthis, Expressions *arguments, FuncDeclaration *fd, Type **prettype, Expression **peprefix) 1380 { 1381 //printf("functionParameters()\n"); 1382 assert(arguments); 1383 assert(fd || tf->next); 1384 size_t nargs = arguments ? arguments->dim : 0; 1385 size_t nparams = Parameter::dim(tf->parameters); 1386 unsigned olderrors = global.errors; 1387 bool err = false; 1388 *prettype = Type::terror; 1389 Expression *eprefix = NULL; 1390 *peprefix = NULL; 1391 1392 if (nargs > nparams && tf->varargs == 0) 1393 { 1394 error(loc, "expected %llu arguments, not %llu for non-variadic function type %s", (ulonglong)nparams, (ulonglong)nargs, tf->toChars()); 1395 return true; 1396 } 1397 1398 // If inferring return type, and semantic3() needs to be run if not already run 1399 if (!tf->next && fd->inferRetType) 1400 { 1401 fd->functionSemantic(); 1402 } 1403 else if (fd && fd->parent) 1404 { 1405 TemplateInstance *ti = fd->parent->isTemplateInstance(); 1406 if (ti && ti->tempdecl) 1407 { 1408 fd->functionSemantic3(); 1409 } 1410 } 1411 bool isCtorCall = fd && fd->needThis() && fd->isCtorDeclaration(); 1412 1413 size_t n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams) 1414 1415 /* If the function return type has wildcards in it, we'll need to figure out the actual type 1416 * based on the actual argument types. 1417 */ 1418 MOD wildmatch = 0; 1419 if (tthis && tf->isWild() && !isCtorCall) 1420 { 1421 Type *t = tthis; 1422 if (t->isImmutable()) 1423 wildmatch = MODimmutable; 1424 else if (t->isWildConst()) 1425 wildmatch = MODwildconst; 1426 else if (t->isWild()) 1427 wildmatch = MODwild; 1428 else if (t->isConst()) 1429 wildmatch = MODconst; 1430 else 1431 wildmatch = MODmutable; 1432 } 1433 1434 int done = 0; 1435 for (size_t i = 0; i < n; i++) 1436 { 1437 Expression *arg; 1438 1439 if (i < nargs) 1440 arg = (*arguments)[i]; 1441 else 1442 arg = NULL; 1443 1444 if (i < nparams) 1445 { 1446 Parameter *p = Parameter::getNth(tf->parameters, i); 1447 1448 if (!arg) 1449 { 1450 if (!p->defaultArg) 1451 { 1452 if (tf->varargs == 2 && i + 1 == nparams) 1453 goto L2; 1454 error(loc, "expected %llu function arguments, not %llu", (ulonglong)nparams, (ulonglong)nargs); 1455 return true; 1456 } 1457 arg = p->defaultArg; 1458 arg = inlineCopy(arg, sc); 1459 // __FILE__, __LINE__, __MODULE__, __FUNCTION__, and __PRETTY_FUNCTION__ 1460 arg = arg->resolveLoc(loc, sc); 1461 arguments->push(arg); 1462 nargs++; 1463 } 1464 1465 if (tf->varargs == 2 && i + 1 == nparams) 1466 { 1467 //printf("\t\tvarargs == 2, p->type = '%s'\n", p->type->toChars()); 1468 { 1469 MATCH m; 1470 if ((m = arg->implicitConvTo(p->type)) > MATCHnomatch) 1471 { 1472 if (p->type->nextOf() && arg->implicitConvTo(p->type->nextOf()) >= m) 1473 goto L2; 1474 else if (nargs != nparams) 1475 { error(loc, "expected %llu function arguments, not %llu", (ulonglong)nparams, (ulonglong)nargs); 1476 return true; 1477 } 1478 goto L1; 1479 } 1480 } 1481 L2: 1482 Type *tb = p->type->toBasetype(); 1483 Type *tret = p->isLazyArray(); 1484 switch (tb->ty) 1485 { 1486 case Tsarray: 1487 case Tarray: 1488 { 1489 /* Create a static array variable v of type arg->type: 1490 * T[dim] __arrayArg = [ arguments[i], ..., arguments[nargs-1] ]; 1491 * 1492 * The array literal in the initializer of the hidden variable 1493 * is now optimized. See Bugzilla 2356. 1494 */ 1495 Type *tbn = ((TypeArray *)tb)->next; 1496 1497 Expressions *elements = new Expressions(); 1498 elements->setDim(nargs - i); 1499 for (size_t u = 0; u < elements->dim; u++) 1500 { 1501 Expression *a = (*arguments)[i + u]; 1502 if (tret && a->implicitConvTo(tret)) 1503 { 1504 a = a->implicitCastTo(sc, tret); 1505 a = a->optimize(WANTvalue); 1506 a = toDelegate(a, a->type, sc); 1507 } 1508 else 1509 a = a->implicitCastTo(sc, tbn); 1510 (*elements)[u] = a; 1511 } 1512 // Bugzilla 14395: Convert to a static array literal, or its slice. 1513 arg = new ArrayLiteralExp(loc, tbn->sarrayOf(nargs - i), elements); 1514 if (tb->ty == Tarray) 1515 { 1516 arg = new SliceExp(loc, arg, NULL, NULL); 1517 arg->type = p->type; 1518 } 1519 break; 1520 } 1521 case Tclass: 1522 { 1523 /* Set arg to be: 1524 * new Tclass(arg0, arg1, ..., argn) 1525 */ 1526 Expressions *args = new Expressions(); 1527 args->setDim(nargs - i); 1528 for (size_t u = i; u < nargs; u++) 1529 (*args)[u - i] = (*arguments)[u]; 1530 arg = new NewExp(loc, NULL, NULL, p->type, args); 1531 break; 1532 } 1533 default: 1534 if (!arg) 1535 { 1536 error(loc, "not enough arguments"); 1537 return true; 1538 } 1539 break; 1540 } 1541 arg = semantic(arg, sc); 1542 //printf("\targ = '%s'\n", arg->toChars()); 1543 arguments->setDim(i + 1); 1544 (*arguments)[i] = arg; 1545 nargs = i + 1; 1546 done = 1; 1547 } 1548 1549 L1: 1550 if (!(p->storageClass & STClazy && p->type->ty == Tvoid)) 1551 { 1552 bool isRef = (p->storageClass & (STCref | STCout)) != 0; 1553 if (unsigned char wm = arg->type->deduceWild(p->type, isRef)) 1554 { 1555 if (wildmatch) 1556 wildmatch = MODmerge(wildmatch, wm); 1557 else 1558 wildmatch = wm; 1559 //printf("[%d] p = %s, a = %s, wm = %d, wildmatch = %d\n", i, p->type->toChars(), arg->type->toChars(), wm, wildmatch); 1560 } 1561 } 1562 } 1563 if (done) 1564 break; 1565 } 1566 if ((wildmatch == MODmutable || wildmatch == MODimmutable) && 1567 tf->next->hasWild() && 1568 (tf->isref || !tf->next->implicitConvTo(tf->next->immutableOf()))) 1569 { 1570 if (fd) 1571 { 1572 /* If the called function may return the reference to 1573 * outer inout data, it should be rejected. 1574 * 1575 * void foo(ref inout(int) x) { 1576 * ref inout(int) bar(inout(int)) { return x; } 1577 * struct S { ref inout(int) bar() inout { return x; } } 1578 * bar(int.init) = 1; // bad! 1579 * S().bar() = 1; // bad! 1580 * } 1581 */ 1582 Dsymbol *s = NULL; 1583 if (fd->isThis() || fd->isNested()) 1584 s = fd->toParent2(); 1585 for (; s; s = s->toParent2()) 1586 { 1587 if (AggregateDeclaration *ad = s->isAggregateDeclaration()) 1588 { 1589 if (ad->isNested()) 1590 continue; 1591 break; 1592 } 1593 if (FuncDeclaration *ff = s->isFuncDeclaration()) 1594 { 1595 if (((TypeFunction *)ff->type)->iswild) 1596 goto Linouterr; 1597 1598 if (ff->isNested() || ff->isThis()) 1599 continue; 1600 } 1601 break; 1602 } 1603 } 1604 else if (tf->isWild()) 1605 { 1606 Linouterr: 1607 const char *s = wildmatch == MODmutable ? "mutable" : MODtoChars(wildmatch); 1608 error(loc, "modify inout to %s is not allowed inside inout function", s); 1609 return true; 1610 } 1611 } 1612 1613 assert(nargs >= nparams); 1614 for (size_t i = 0; i < nargs; i++) 1615 { 1616 Expression *arg = (*arguments)[i]; 1617 assert(arg); 1618 if (i < nparams) 1619 { 1620 Parameter *p = Parameter::getNth(tf->parameters, i); 1621 1622 if (!(p->storageClass & STClazy && p->type->ty == Tvoid)) 1623 { 1624 Type *tprm = p->type; 1625 if (p->type->hasWild()) 1626 tprm = p->type->substWildTo(wildmatch); 1627 if (!tprm->equals(arg->type)) 1628 { 1629 //printf("arg->type = %s, p->type = %s\n", arg->type->toChars(), p->type->toChars()); 1630 arg = arg->implicitCastTo(sc, tprm); 1631 arg = arg->optimize(WANTvalue, (p->storageClass & (STCref | STCout)) != 0); 1632 } 1633 } 1634 if (p->storageClass & STCref) 1635 { 1636 arg = arg->toLvalue(sc, arg); 1637 1638 // Look for mutable misaligned pointer, etc., in @safe mode 1639 err |= checkUnsafeAccess(sc, arg, false, true); 1640 } 1641 else if (p->storageClass & STCout) 1642 { 1643 Type *t = arg->type; 1644 if (!t->isMutable() || !t->isAssignable()) // check blit assignable 1645 { 1646 arg->error("cannot modify struct %s with immutable members", arg->toChars()); 1647 err = true; 1648 } 1649 else 1650 { 1651 // Look for misaligned pointer, etc., in @safe mode 1652 err |= checkUnsafeAccess(sc, arg, false, true); 1653 err |= checkDefCtor(arg->loc, t); // t must be default constructible 1654 } 1655 arg = arg->toLvalue(sc, arg); 1656 } 1657 else if (p->storageClass & STClazy) 1658 { 1659 // Convert lazy argument to a delegate 1660 if (p->type->ty == Tvoid) 1661 arg = toDelegate(arg, p->type, sc); 1662 else 1663 arg = toDelegate(arg, arg->type, sc); 1664 } 1665 1666 //printf("arg: %s\n", arg->toChars()); 1667 //printf("type: %s\n", arg->type->toChars()); 1668 if (tf->parameterEscapes(p)) 1669 { 1670 /* Argument value can escape from the called function. 1671 * Check arg to see if it matters. 1672 */ 1673 if (global.params.vsafe) 1674 err |= checkParamArgumentEscape(sc, fd, p->ident, arg, false); 1675 } 1676 else 1677 { 1678 /* Argument value cannot escape from the called function. 1679 */ 1680 Expression *a = arg; 1681 if (a->op == TOKcast) 1682 a = ((CastExp *)a)->e1; 1683 1684 if (a->op == TOKfunction) 1685 { 1686 /* Function literals can only appear once, so if this 1687 * appearance was scoped, there cannot be any others. 1688 */ 1689 FuncExp *fe = (FuncExp *)a; 1690 fe->fd->tookAddressOf = 0; 1691 } 1692 else if (a->op == TOKdelegate) 1693 { 1694 /* For passing a delegate to a scoped parameter, 1695 * this doesn't count as taking the address of it. 1696 * We only worry about 'escaping' references to the function. 1697 */ 1698 DelegateExp *de = (DelegateExp *)a; 1699 if (de->e1->op == TOKvar) 1700 { VarExp *ve = (VarExp *)de->e1; 1701 FuncDeclaration *f = ve->var->isFuncDeclaration(); 1702 if (f) 1703 { f->tookAddressOf--; 1704 //printf("tookAddressOf = %d\n", f->tookAddressOf); 1705 } 1706 } 1707 } 1708 } 1709 arg = arg->optimize(WANTvalue, (p->storageClass & (STCref | STCout)) != 0); 1710 } 1711 else 1712 { 1713 // These will be the trailing ... arguments 1714 1715 // If not D linkage, do promotions 1716 if (tf->linkage != LINKd) 1717 { 1718 // Promote bytes, words, etc., to ints 1719 arg = integralPromotions(arg, sc); 1720 1721 // Promote floats to doubles 1722 switch (arg->type->ty) 1723 { 1724 case Tfloat32: 1725 arg = arg->castTo(sc, Type::tfloat64); 1726 break; 1727 1728 case Timaginary32: 1729 arg = arg->castTo(sc, Type::timaginary64); 1730 break; 1731 } 1732 1733 if (tf->varargs == 1) 1734 { 1735 const char *p = tf->linkage == LINKc ? "extern(C)" : "extern(C++)"; 1736 if (arg->type->ty == Tarray) 1737 { 1738 arg->error("cannot pass dynamic arrays to %s vararg functions", p); 1739 err = true; 1740 } 1741 if (arg->type->ty == Tsarray) 1742 { 1743 arg->error("cannot pass static arrays to %s vararg functions", p); 1744 err = true; 1745 } 1746 } 1747 } 1748 1749 // Do not allow types that need destructors 1750 if (arg->type->needsDestruction()) 1751 { 1752 arg->error("cannot pass types that need destruction as variadic arguments"); 1753 err = true; 1754 } 1755 1756 // Convert static arrays to dynamic arrays 1757 // BUG: I don't think this is right for D2 1758 Type *tb = arg->type->toBasetype(); 1759 if (tb->ty == Tsarray) 1760 { 1761 TypeSArray *ts = (TypeSArray *)tb; 1762 Type *ta = ts->next->arrayOf(); 1763 if (ts->size(arg->loc) == 0) 1764 arg = new NullExp(arg->loc, ta); 1765 else 1766 arg = arg->castTo(sc, ta); 1767 } 1768 if (tb->ty == Tstruct) 1769 { 1770 //arg = callCpCtor(sc, arg); 1771 } 1772 1773 // Give error for overloaded function addresses 1774 if (arg->op == TOKsymoff) 1775 { SymOffExp *se = (SymOffExp *)arg; 1776 if (se->hasOverloads && 1777 !se->var->isFuncDeclaration()->isUnique()) 1778 { arg->error("function %s is overloaded", arg->toChars()); 1779 err = true; 1780 } 1781 } 1782 if (arg->checkValue()) 1783 err = true; 1784 arg = arg->optimize(WANTvalue); 1785 } 1786 (*arguments)[i] = arg; 1787 } 1788 1789 /* Remaining problems: 1790 * 1. order of evaluation - some function push L-to-R, others R-to-L. Until we resolve what array assignment does (which is 1791 * implemented by calling a function) we'll defer this for now. 1792 * 2. value structs (or static arrays of them) that need to be copy constructed 1793 * 3. value structs (or static arrays of them) that have destructors, and subsequent arguments that may throw before the 1794 * function gets called (functions normally destroy their parameters) 1795 * 2 and 3 are handled by doing the argument construction in 'eprefix' so that if a later argument throws, they are cleaned 1796 * up properly. Pushing arguments on the stack then cannot fail. 1797 */ 1798 if (1) 1799 { 1800 /* TODO: tackle problem 1) 1801 */ 1802 const bool leftToRight = true; // TODO: something like !fd.isArrayOp 1803 if (!leftToRight) 1804 assert(nargs == nparams); // no variadics for RTL order, as they would probably be evaluated LTR and so add complexity 1805 1806 const ptrdiff_t start = (leftToRight ? 0 : (ptrdiff_t)nargs - 1); 1807 const ptrdiff_t end = (leftToRight ? (ptrdiff_t)nargs : -1); 1808 const ptrdiff_t step = (leftToRight ? 1 : -1); 1809 1810 /* Compute indices of last throwing argument and first arg needing destruction. 1811 * Used to not set up destructors unless an arg needs destruction on a throw 1812 * in a later argument. 1813 */ 1814 ptrdiff_t lastthrow = -1; 1815 ptrdiff_t firstdtor = -1; 1816 for (ptrdiff_t i = start; i != end; i += step) 1817 { 1818 Expression *arg = (*arguments)[i]; 1819 if (canThrow(arg, sc->func, false)) 1820 lastthrow = i; 1821 if (firstdtor == -1 && arg->type->needsDestruction()) 1822 { 1823 Parameter *p = (i >= (ptrdiff_t)nparams ? NULL : Parameter::getNth(tf->parameters, i)); 1824 if (!(p && (p->storageClass & (STClazy | STCref | STCout)))) 1825 firstdtor = i; 1826 } 1827 } 1828 1829 /* Does problem 3) apply to this call? 1830 */ 1831 const bool needsPrefix = (firstdtor >= 0 && lastthrow >= 0 1832 && (lastthrow - firstdtor) * step > 0); 1833 1834 /* If so, initialize 'eprefix' by declaring the gate 1835 */ 1836 VarDeclaration *gate = NULL; 1837 if (needsPrefix) 1838 { 1839 // eprefix => bool __gate [= false] 1840 Identifier *idtmp = Identifier::generateId("__gate"); 1841 gate = new VarDeclaration(loc, Type::tbool, idtmp, NULL); 1842 gate->storage_class |= STCtemp | STCctfe | STCvolatile; 1843 gate->semantic(sc); 1844 1845 Expression *ae = new DeclarationExp(loc, gate); 1846 eprefix = semantic(ae, sc); 1847 } 1848 1849 for (ptrdiff_t i = start; i != end; i += step) 1850 { 1851 Expression *arg = (*arguments)[i]; 1852 1853 Parameter *parameter = (i >= (ptrdiff_t)nparams ? NULL : Parameter::getNth(tf->parameters, i)); 1854 const bool isRef = (parameter && (parameter->storageClass & (STCref | STCout))); 1855 const bool isLazy = (parameter && (parameter->storageClass & STClazy)); 1856 1857 /* Skip lazy parameters 1858 */ 1859 if (isLazy) 1860 continue; 1861 1862 /* Do we have a gate? Then we have a prefix and we're not yet past the last throwing arg. 1863 * Declare a temporary variable for this arg and append that declaration to 'eprefix', 1864 * which will implicitly take care of potential problem 2) for this arg. 1865 * 'eprefix' will therefore finally contain all args up to and including the last 1866 * potentially throwing arg, excluding all lazy parameters. 1867 */ 1868 if (gate) 1869 { 1870 const bool needsDtor = (!isRef && arg->type->needsDestruction() && i != lastthrow); 1871 1872 /* Declare temporary 'auto __pfx = arg' (needsDtor) or 'auto __pfy = arg' (!needsDtor) 1873 */ 1874 VarDeclaration *tmp = copyToTemp(0, 1875 needsDtor ? "__pfx" : "__pfy", 1876 !isRef ? arg : arg->addressOf()); 1877 tmp->semantic(sc); 1878 1879 /* Modify the destructor so it only runs if gate==false, i.e., 1880 * only if there was a throw while constructing the args 1881 */ 1882 if (!needsDtor) 1883 { 1884 if (tmp->edtor) 1885 { 1886 assert(i == lastthrow); 1887 tmp->edtor = NULL; 1888 } 1889 } 1890 else 1891 { 1892 // edtor => (__gate || edtor) 1893 assert(tmp->edtor); 1894 Expression *e = tmp->edtor; 1895 e = new OrOrExp(e->loc, new VarExp(e->loc, gate), e); 1896 tmp->edtor = semantic(e, sc); 1897 //printf("edtor: %s\n", tmp->edtor->toChars()); 1898 } 1899 1900 // eprefix => (eprefix, auto __pfx/y = arg) 1901 DeclarationExp *ae = new DeclarationExp(loc, tmp); 1902 eprefix = Expression::combine(eprefix, semantic(ae, sc)); 1903 1904 // arg => __pfx/y 1905 arg = new VarExp(loc, tmp); 1906 arg = semantic(arg, sc); 1907 if (isRef) 1908 { 1909 arg = new PtrExp(loc, arg); 1910 arg = semantic(arg, sc); 1911 } 1912 1913 /* Last throwing arg? Then finalize eprefix => (eprefix, gate = true), 1914 * i.e., disable the dtors right after constructing the last throwing arg. 1915 * From now on, the callee will take care of destructing the args because 1916 * the args are implicitly moved into function parameters. 1917 * 1918 * Set gate to null to let the next iterations know they don't need to 1919 * append to eprefix anymore. 1920 */ 1921 if (i == lastthrow) 1922 { 1923 Expression *e = new AssignExp(gate->loc, new VarExp(gate->loc, gate), new IntegerExp(gate->loc, 1, Type::tbool)); 1924 eprefix = Expression::combine(eprefix, semantic(e, sc)); 1925 gate = NULL; 1926 } 1927 } 1928 else 1929 { 1930 /* No gate, no prefix to append to. 1931 * Handle problem 2) by calling the copy constructor for value structs 1932 * (or static arrays of them) if appropriate. 1933 */ 1934 Type *tv = arg->type->baseElemOf(); 1935 if (!isRef && tv->ty == Tstruct) 1936 arg = doCopyOrMove(sc, arg); 1937 } 1938 1939 (*arguments)[i] = arg; 1940 } 1941 } 1942 //if (eprefix) printf("eprefix: %s\n", eprefix->toChars()); 1943 1944 // If D linkage and variadic, add _arguments[] as first argument 1945 if (tf->linkage == LINKd && tf->varargs == 1) 1946 { 1947 assert(arguments->dim >= nparams); 1948 1949 Parameters *args = new Parameters; 1950 args->setDim(arguments->dim - nparams); 1951 for (size_t i = 0; i < arguments->dim - nparams; i++) 1952 { 1953 Parameter *arg = new Parameter(STCin, (*arguments)[nparams + i]->type, NULL, NULL); 1954 (*args)[i] = arg; 1955 } 1956 1957 TypeTuple *tup = new TypeTuple(args); 1958 Expression *e = new TypeidExp(loc, tup); 1959 e = semantic(e, sc); 1960 arguments->insert(0, e); 1961 } 1962 1963 Type *tret = tf->next; 1964 if (isCtorCall) 1965 { 1966 //printf("[%s] fd = %s %s, %d %d %d\n", loc.toChars(), fd->toChars(), fd->type->toChars(), 1967 // wildmatch, tf->isWild(), fd->isolateReturn()); 1968 if (!tthis) 1969 { 1970 assert(sc->intypeof || global.errors); 1971 tthis = fd->isThis()->type->addMod(fd->type->mod); 1972 } 1973 if (tf->isWild() && !fd->isolateReturn()) 1974 { 1975 if (wildmatch) 1976 tret = tret->substWildTo(wildmatch); 1977 int offset; 1978 if (!tret->implicitConvTo(tthis) && 1979 !(MODimplicitConv(tret->mod, tthis->mod) && tret->isBaseOf(tthis, &offset) && offset == 0)) 1980 { 1981 const char* s1 = tret ->isNaked() ? " mutable" : tret ->modToChars(); 1982 const char* s2 = tthis->isNaked() ? " mutable" : tthis->modToChars(); 1983 ::error(loc, "inout constructor %s creates%s object, not%s", 1984 fd->toPrettyChars(), s1, s2); 1985 err = true; 1986 } 1987 } 1988 tret = tthis; 1989 } 1990 else if (wildmatch && tret) 1991 { 1992 /* Adjust function return type based on wildmatch 1993 */ 1994 //printf("wildmatch = x%x, tret = %s\n", wildmatch, tret->toChars()); 1995 tret = tret->substWildTo(wildmatch); 1996 } 1997 *prettype = tret; 1998 *peprefix = eprefix; 1999 return (err || olderrors != global.errors); 2000 } 2001 2002 /******************************** Expression **************************/ 2003 2004 Expression::Expression(Loc loc, TOK op, int size) 2005 { 2006 //printf("Expression::Expression(op = %d) this = %p\n", op, this); 2007 this->loc = loc; 2008 this->op = op; 2009 this->size = (unsigned char)size; 2010 this->parens = 0; 2011 type = NULL; 2012 } 2013 2014 void Expression::_init() 2015 { 2016 CTFEExp::cantexp = new CTFEExp(TOKcantexp); 2017 CTFEExp::voidexp = new CTFEExp(TOKvoidexp); 2018 CTFEExp::breakexp = new CTFEExp(TOKbreak); 2019 CTFEExp::continueexp = new CTFEExp(TOKcontinue); 2020 CTFEExp::gotoexp = new CTFEExp(TOKgoto); 2021 } 2022 2023 Expression *Expression::syntaxCopy() 2024 { 2025 //printf("Expression::syntaxCopy()\n"); 2026 //print(); 2027 return copy(); 2028 } 2029 2030 /********************************* 2031 * Does *not* do a deep copy. 2032 */ 2033 2034 Expression *Expression::copy() 2035 { 2036 Expression *e; 2037 if (!size) 2038 { 2039 assert(0); 2040 } 2041 void *pe = mem.xmalloc(size); 2042 //printf("Expression::copy(op = %d) e = %p\n", op, pe); 2043 e = (Expression *)memcpy(pe, (void *)this, size); 2044 return e; 2045 } 2046 2047 void Expression::print() 2048 { 2049 fprintf(stderr, "%s\n", toChars()); 2050 fflush(stderr); 2051 } 2052 2053 const char *Expression::toChars() 2054 { 2055 OutBuffer buf; 2056 HdrGenState hgs; 2057 toCBuffer(this, &buf, &hgs); 2058 return buf.extractString(); 2059 } 2060 2061 void Expression::error(const char *format, ...) const 2062 { 2063 if (type != Type::terror) 2064 { 2065 va_list ap; 2066 va_start(ap, format); 2067 ::verror(loc, format, ap); 2068 va_end( ap ); 2069 } 2070 } 2071 2072 void Expression::warning(const char *format, ...) const 2073 { 2074 if (type != Type::terror) 2075 { 2076 va_list ap; 2077 va_start(ap, format); 2078 ::vwarning(loc, format, ap); 2079 va_end( ap ); 2080 } 2081 } 2082 2083 void Expression::deprecation(const char *format, ...) const 2084 { 2085 if (type != Type::terror) 2086 { 2087 va_list ap; 2088 va_start(ap, format); 2089 ::vdeprecation(loc, format, ap); 2090 va_end( ap ); 2091 } 2092 } 2093 2094 /********************************** 2095 * Combine e1 and e2 by CommaExp if both are not NULL. 2096 */ 2097 Expression *Expression::combine(Expression *e1, Expression *e2) 2098 { 2099 if (e1) 2100 { 2101 if (e2) 2102 { 2103 e1 = new CommaExp(e1->loc, e1, e2); 2104 e1->type = e2->type; 2105 } 2106 } 2107 else 2108 e1 = e2; 2109 return e1; 2110 } 2111 2112 /********************************** 2113 * If 'e' is a tree of commas, returns the leftmost expression 2114 * by stripping off it from the tree. The remained part of the tree 2115 * is returned via *pe0. 2116 * Otherwise 'e' is directly returned and *pe0 is set to NULL. 2117 */ 2118 Expression *Expression::extractLast(Expression *e, Expression **pe0) 2119 { 2120 if (e->op != TOKcomma) 2121 { 2122 *pe0 = NULL; 2123 return e; 2124 } 2125 2126 CommaExp *ce = (CommaExp *)e; 2127 if (ce->e2->op != TOKcomma) 2128 { 2129 *pe0 = ce->e1; 2130 return ce->e2; 2131 } 2132 else 2133 { 2134 *pe0 = e; 2135 2136 Expression **pce = &ce->e2; 2137 while (((CommaExp *)(*pce))->e2->op == TOKcomma) 2138 { 2139 pce = &((CommaExp *)(*pce))->e2; 2140 } 2141 assert((*pce)->op == TOKcomma); 2142 ce = (CommaExp *)(*pce); 2143 *pce = ce->e1; 2144 2145 return ce->e2; 2146 } 2147 } 2148 2149 dinteger_t Expression::toInteger() 2150 { 2151 //printf("Expression %s\n", Token::toChars(op)); 2152 error("integer constant expression expected instead of %s", toChars()); 2153 return 0; 2154 } 2155 2156 uinteger_t Expression::toUInteger() 2157 { 2158 //printf("Expression %s\n", Token::toChars(op)); 2159 return (uinteger_t)toInteger(); 2160 } 2161 2162 real_t Expression::toReal() 2163 { 2164 error("floating point constant expression expected instead of %s", toChars()); 2165 return CTFloat::zero; 2166 } 2167 2168 real_t Expression::toImaginary() 2169 { 2170 error("floating point constant expression expected instead of %s", toChars()); 2171 return CTFloat::zero; 2172 } 2173 2174 complex_t Expression::toComplex() 2175 { 2176 error("floating point constant expression expected instead of %s", toChars()); 2177 return complex_t(CTFloat::zero); 2178 } 2179 2180 StringExp *Expression::toStringExp() 2181 { 2182 return NULL; 2183 } 2184 2185 /*************************************** 2186 * Return !=0 if expression is an lvalue. 2187 */ 2188 2189 bool Expression::isLvalue() 2190 { 2191 return false; 2192 } 2193 2194 /******************************* 2195 * Give error if we're not an lvalue. 2196 * If we can, convert expression to be an lvalue. 2197 */ 2198 2199 Expression *Expression::toLvalue(Scope *, Expression *e) 2200 { 2201 if (!e) 2202 e = this; 2203 else if (!loc.filename) 2204 loc = e->loc; 2205 2206 if (e->op == TOKtype) 2207 error("%s '%s' is a type, not an lvalue", e->type->kind(), e->type->toChars()); 2208 else 2209 error("%s is not an lvalue", e->toChars()); 2210 2211 return new ErrorExp(); 2212 } 2213 2214 /*************************************** 2215 * Parameters: 2216 * sc: scope 2217 * flag: 1: do not issue error message for invalid modification 2218 * Returns: 2219 * 0: is not modifiable 2220 * 1: is modifiable in default == being related to type->isMutable() 2221 * 2: is modifiable, because this is a part of initializing. 2222 */ 2223 2224 int Expression::checkModifiable(Scope *, int) 2225 { 2226 return type ? 1 : 0; // default modifiable 2227 } 2228 2229 Expression *Expression::modifiableLvalue(Scope *sc, Expression *e) 2230 { 2231 //printf("Expression::modifiableLvalue() %s, type = %s\n", toChars(), type->toChars()); 2232 2233 // See if this expression is a modifiable lvalue (i.e. not const) 2234 if (checkModifiable(sc) == 1) 2235 { 2236 assert(type); 2237 if (!type->isMutable()) 2238 { 2239 error("cannot modify %s expression %s", MODtoChars(type->mod), toChars()); 2240 return new ErrorExp(); 2241 } 2242 else if (!type->isAssignable()) 2243 { 2244 error("cannot modify struct %s %s with immutable members", toChars(), type->toChars()); 2245 return new ErrorExp(); 2246 } 2247 } 2248 return toLvalue(sc, e); 2249 } 2250 2251 /**************************************** 2252 * Check that the expression has a valid type. 2253 * If not, generates an error "... has no type". 2254 * Returns: 2255 * true if the expression is not valid. 2256 * Note: 2257 * When this function returns true, `checkValue()` should also return true. 2258 */ 2259 bool Expression::checkType() 2260 { 2261 return false; 2262 } 2263 2264 /**************************************** 2265 * Check that the expression has a valid value. 2266 * If not, generates an error "... has no value". 2267 * Returns: 2268 * true if the expression is not valid or has void type. 2269 */ 2270 bool Expression::checkValue() 2271 { 2272 if (type && type->toBasetype()->ty == Tvoid) 2273 { 2274 error("expression %s is void and has no value", toChars()); 2275 //print(); halt(); 2276 if (!global.gag) 2277 type = Type::terror; 2278 return true; 2279 } 2280 return false; 2281 } 2282 2283 bool Expression::checkScalar() 2284 { 2285 if (op == TOKerror) 2286 return true; 2287 if (type->toBasetype()->ty == Terror) 2288 return true; 2289 if (!type->isscalar()) 2290 { 2291 error("'%s' is not a scalar, it is a %s", toChars(), type->toChars()); 2292 return true; 2293 } 2294 return checkValue(); 2295 } 2296 2297 bool Expression::checkNoBool() 2298 { 2299 if (op == TOKerror) 2300 return true; 2301 if (type->toBasetype()->ty == Terror) 2302 return true; 2303 if (type->toBasetype()->ty == Tbool) 2304 { 2305 error("operation not allowed on bool '%s'", toChars()); 2306 return true; 2307 } 2308 return false; 2309 } 2310 2311 bool Expression::checkIntegral() 2312 { 2313 if (op == TOKerror) 2314 return true; 2315 if (type->toBasetype()->ty == Terror) 2316 return true; 2317 if (!type->isintegral()) 2318 { 2319 error("'%s' is not of integral type, it is a %s", toChars(), type->toChars()); 2320 return true; 2321 } 2322 return checkValue(); 2323 } 2324 2325 bool Expression::checkArithmetic() 2326 { 2327 if (op == TOKerror) 2328 return true; 2329 if (type->toBasetype()->ty == Terror) 2330 return true; 2331 if (!type->isintegral() && !type->isfloating()) 2332 { 2333 error("'%s' is not of arithmetic type, it is a %s", toChars(), type->toChars()); 2334 return true; 2335 } 2336 return checkValue(); 2337 } 2338 2339 void Expression::checkDeprecated(Scope *sc, Dsymbol *s) 2340 { 2341 s->checkDeprecated(loc, sc); 2342 } 2343 2344 /********************************************* 2345 * Calling function f. 2346 * Check the purity, i.e. if we're in a pure function 2347 * we can only call other pure functions. 2348 * Returns true if error occurs. 2349 */ 2350 bool Expression::checkPurity(Scope *sc, FuncDeclaration *f) 2351 { 2352 if (!sc->func) 2353 return false; 2354 if (sc->func == f) 2355 return false; 2356 if (sc->intypeof == 1) 2357 return false; 2358 if (sc->flags & (SCOPEctfe | SCOPEdebug)) 2359 return false; 2360 2361 /* Given: 2362 * void f() { 2363 * pure void g() { 2364 * /+pure+/ void h() { 2365 * /+pure+/ void i() { } 2366 * } 2367 * } 2368 * } 2369 * g() can call h() but not f() 2370 * i() can call h() and g() but not f() 2371 */ 2372 2373 // Find the closest pure parent of the calling function 2374 FuncDeclaration *outerfunc = sc->func; 2375 FuncDeclaration *calledparent = f; 2376 2377 if (outerfunc->isInstantiated()) 2378 { 2379 // The attributes of outerfunc should be inferred from the call of f. 2380 } 2381 else if (f->isInstantiated()) 2382 { 2383 // The attributes of f are inferred from its body. 2384 } 2385 else if (f->isFuncLiteralDeclaration()) 2386 { 2387 // The attributes of f are always inferred in its declared place. 2388 } 2389 else 2390 { 2391 /* Today, static local functions are impure by default, but they cannot 2392 * violate purity of enclosing functions. 2393 * 2394 * auto foo() pure { // non instantiated funciton 2395 * static auto bar() { // static, without pure attribute 2396 * impureFunc(); // impure call 2397 * // Although impureFunc is called inside bar, f(= impureFunc) 2398 * // is not callable inside pure outerfunc(= foo <- bar). 2399 * } 2400 * 2401 * bar(); 2402 * // Although bar is called inside foo, f(= bar) is callable 2403 * // bacause calledparent(= foo) is same with outerfunc(= foo). 2404 * } 2405 */ 2406 2407 while (outerfunc->toParent2() && 2408 outerfunc->isPureBypassingInference() == PUREimpure && 2409 outerfunc->toParent2()->isFuncDeclaration()) 2410 { 2411 outerfunc = outerfunc->toParent2()->isFuncDeclaration(); 2412 if (outerfunc->type->ty == Terror) 2413 return true; 2414 } 2415 while (calledparent->toParent2() && 2416 calledparent->isPureBypassingInference() == PUREimpure && 2417 calledparent->toParent2()->isFuncDeclaration()) 2418 { 2419 calledparent = calledparent->toParent2()->isFuncDeclaration(); 2420 if (calledparent->type->ty == Terror) 2421 return true; 2422 } 2423 } 2424 2425 // If the caller has a pure parent, then either the called func must be pure, 2426 // OR, they must have the same pure parent. 2427 if (!f->isPure() && calledparent != outerfunc) 2428 { 2429 FuncDeclaration *ff = outerfunc; 2430 if (sc->flags & SCOPEcompile ? ff->isPureBypassingInference() >= PUREweak : ff->setImpure()) 2431 { 2432 error("pure %s '%s' cannot call impure %s '%s'", 2433 ff->kind(), ff->toPrettyChars(), f->kind(), f->toPrettyChars()); 2434 return true; 2435 } 2436 } 2437 return false; 2438 } 2439 2440 /******************************************* 2441 * Accessing variable v. 2442 * Check for purity and safety violations. 2443 * Returns true if error occurs. 2444 */ 2445 bool Expression::checkPurity(Scope *sc, VarDeclaration *v) 2446 { 2447 //printf("v = %s %s\n", v->type->toChars(), v->toChars()); 2448 2449 /* Look for purity and safety violations when accessing variable v 2450 * from current function. 2451 */ 2452 if (!sc->func) 2453 return false; 2454 if (sc->intypeof == 1) 2455 return false; // allow violations inside typeof(expression) 2456 if (sc->flags & (SCOPEctfe | SCOPEdebug)) 2457 return false; // allow violations inside compile-time evaluated expressions and debug conditionals 2458 if (v->ident == Id::ctfe) 2459 return false; // magic variable never violates pure and safe 2460 if (v->isImmutable()) 2461 return false; // always safe and pure to access immutables... 2462 if (v->isConst() && !v->isRef() && (v->isDataseg() || v->isParameter()) && 2463 v->type->implicitConvTo(v->type->immutableOf())) 2464 return false; // or const global/parameter values which have no mutable indirections 2465 if (v->storage_class & STCmanifest) 2466 return false; // ...or manifest constants 2467 2468 bool err = false; 2469 if (v->isDataseg()) 2470 { 2471 // Bugzilla 7533: Accessing implicit generated __gate is pure. 2472 if (v->ident == Id::gate) 2473 return false; 2474 2475 /* Accessing global mutable state. 2476 * Therefore, this function and all its immediately enclosing 2477 * functions must be pure. 2478 */ 2479 /* Today, static local functions are impure by default, but they cannot 2480 * violate purity of enclosing functions. 2481 * 2482 * auto foo() pure { // non instantiated funciton 2483 * static auto bar() { // static, without pure attribute 2484 * globalData++; // impure access 2485 * // Although globalData is accessed inside bar, 2486 * // it is not accessible inside pure foo. 2487 * } 2488 * } 2489 */ 2490 for (Dsymbol *s = sc->func; s; s = s->toParent2()) 2491 { 2492 FuncDeclaration *ff = s->isFuncDeclaration(); 2493 if (!ff) 2494 break; 2495 if (sc->flags & SCOPEcompile ? ff->isPureBypassingInference() >= PUREweak : ff->setImpure()) 2496 { 2497 error("pure %s '%s' cannot access mutable static data '%s'", 2498 ff->kind(), ff->toPrettyChars(), v->toChars()); 2499 err = true; 2500 break; 2501 } 2502 /* If the enclosing is an instantiated function or a lambda, its 2503 * attribute inference result is preferred. 2504 */ 2505 if (ff->isInstantiated()) 2506 break; 2507 if (ff->isFuncLiteralDeclaration()) 2508 break; 2509 } 2510 } 2511 else 2512 { 2513 /* Given: 2514 * void f() { 2515 * int fx; 2516 * pure void g() { 2517 * int gx; 2518 * /+pure+/ void h() { 2519 * int hx; 2520 * /+pure+/ void i() { } 2521 * } 2522 * } 2523 * } 2524 * i() can modify hx and gx but not fx 2525 */ 2526 2527 Dsymbol *vparent = v->toParent2(); 2528 for (Dsymbol *s = sc->func; !err && s; s = s->toParent2()) 2529 { 2530 if (s == vparent) 2531 break; 2532 2533 if (AggregateDeclaration *ad = s->isAggregateDeclaration()) 2534 { 2535 if (ad->isNested()) 2536 continue; 2537 break; 2538 } 2539 FuncDeclaration *ff = s->isFuncDeclaration(); 2540 if (!ff) 2541 break; 2542 if (ff->isNested() || ff->isThis()) 2543 { 2544 if (ff->type->isImmutable() || 2545 (ff->type->isShared() && !MODimplicitConv(ff->type->mod, v->type->mod))) 2546 { 2547 OutBuffer ffbuf; 2548 OutBuffer vbuf; 2549 MODMatchToBuffer(&ffbuf, ff->type->mod, v->type->mod); 2550 MODMatchToBuffer(&vbuf, v->type->mod, ff->type->mod); 2551 error("%s%s '%s' cannot access %sdata '%s'", 2552 ffbuf.peekString(), ff->kind(), ff->toPrettyChars(), vbuf.peekString(), v->toChars()); 2553 err = true; 2554 break; 2555 } 2556 continue; 2557 } 2558 break; 2559 } 2560 } 2561 2562 /* Do not allow safe functions to access __gshared data 2563 */ 2564 if (v->storage_class & STCgshared) 2565 { 2566 if (sc->func->setUnsafe()) 2567 { 2568 error("safe %s '%s' cannot access __gshared data '%s'", 2569 sc->func->kind(), sc->func->toChars(), v->toChars()); 2570 err = true; 2571 } 2572 } 2573 2574 return err; 2575 } 2576 2577 /********************************************* 2578 * Calling function f. 2579 * Check the safety, i.e. if we're in a @safe function 2580 * we can only call @safe or @trusted functions. 2581 * Returns true if error occurs. 2582 */ 2583 bool Expression::checkSafety(Scope *sc, FuncDeclaration *f) 2584 { 2585 if (!sc->func) 2586 return false; 2587 if (sc->func == f) 2588 return false; 2589 if (sc->intypeof == 1) 2590 return false; 2591 if (sc->flags & SCOPEctfe) 2592 return false; 2593 2594 if (!f->isSafe() && !f->isTrusted()) 2595 { 2596 if (sc->flags & SCOPEcompile ? sc->func->isSafeBypassingInference() : sc->func->setUnsafe()) 2597 { 2598 if (loc.linnum == 0) // e.g. implicitly generated dtor 2599 loc = sc->func->loc; 2600 2601 error("@safe %s '%s' cannot call @system %s '%s'", 2602 sc->func->kind(), sc->func->toPrettyChars(), f->kind(), f->toPrettyChars()); 2603 return true; 2604 } 2605 } 2606 return false; 2607 } 2608 2609 /********************************************* 2610 * Calling function f. 2611 * Check the @nogc-ness, i.e. if we're in a @nogc function 2612 * we can only call other @nogc functions. 2613 * Returns true if error occurs. 2614 */ 2615 bool Expression::checkNogc(Scope *sc, FuncDeclaration *f) 2616 { 2617 if (!sc->func) 2618 return false; 2619 if (sc->func == f) 2620 return false; 2621 if (sc->intypeof == 1) 2622 return false; 2623 if (sc->flags & SCOPEctfe) 2624 return false; 2625 2626 if (!f->isNogc()) 2627 { 2628 if (sc->flags & SCOPEcompile ? sc->func->isNogcBypassingInference() : sc->func->setGC()) 2629 { 2630 if (loc.linnum == 0) // e.g. implicitly generated dtor 2631 loc = sc->func->loc; 2632 2633 error("@nogc %s '%s' cannot call non-@nogc %s '%s'", 2634 sc->func->kind(), sc->func->toPrettyChars(), f->kind(), f->toPrettyChars()); 2635 return true; 2636 } 2637 } 2638 return false; 2639 } 2640 2641 /******************************************** 2642 * Check that the postblit is callable if t is an array of structs. 2643 * Returns true if error happens. 2644 */ 2645 bool Expression::checkPostblit(Scope *sc, Type *t) 2646 { 2647 t = t->baseElemOf(); 2648 if (t->ty == Tstruct) 2649 { 2650 // Bugzilla 11395: Require TypeInfo generation for array concatenation 2651 semanticTypeInfo(sc, t); 2652 2653 StructDeclaration *sd = ((TypeStruct *)t)->sym; 2654 if (sd->postblit) 2655 { 2656 if (sd->postblit->storage_class & STCdisable) 2657 { 2658 sd->error(loc, "is not copyable because it is annotated with @disable"); 2659 return true; 2660 } 2661 //checkDeprecated(sc, sd->postblit); // necessary? 2662 checkPurity(sc, sd->postblit); 2663 checkSafety(sc, sd->postblit); 2664 checkNogc(sc, sd->postblit); 2665 //checkAccess(sd, loc, sc, sd->postblit); // necessary? 2666 return false; 2667 } 2668 } 2669 return false; 2670 } 2671 2672 bool Expression::checkRightThis(Scope *sc) 2673 { 2674 if (op == TOKerror) 2675 return true; 2676 if (op == TOKvar && type->ty != Terror) 2677 { 2678 VarExp *ve = (VarExp *)this; 2679 if (isNeedThisScope(sc, ve->var)) 2680 { 2681 //printf("checkRightThis sc->intypeof = %d, ad = %p, func = %p, fdthis = %p\n", 2682 // sc->intypeof, sc->getStructClassScope(), func, fdthis); 2683 error("need 'this' for '%s' of type '%s'", ve->var->toChars(), ve->var->type->toChars()); 2684 return true; 2685 } 2686 } 2687 return false; 2688 } 2689 2690 /******************************* 2691 * Check whether the expression allows RMW operations, error with rmw operator diagnostic if not. 2692 * ex is the RHS expression, or NULL if ++/-- is used (for diagnostics) 2693 * Returns true if error occurs. 2694 */ 2695 bool Expression::checkReadModifyWrite(TOK rmwOp, Expression *ex) 2696 { 2697 //printf("Expression::checkReadModifyWrite() %s %s", toChars(), ex ? ex->toChars() : ""); 2698 if (!type || !type->isShared()) 2699 return false; 2700 2701 // atomicOp uses opAssign (+=/-=) rather than opOp (++/--) for the CT string literal. 2702 switch (rmwOp) 2703 { 2704 case TOKplusplus: 2705 case TOKpreplusplus: 2706 rmwOp = TOKaddass; 2707 break; 2708 2709 case TOKminusminus: 2710 case TOKpreminusminus: 2711 rmwOp = TOKminass; 2712 break; 2713 2714 default: 2715 break; 2716 } 2717 2718 deprecation("read-modify-write operations are not allowed for shared variables. " 2719 "Use core.atomic.atomicOp!\"%s\"(%s, %s) instead.", 2720 Token::tochars[rmwOp], toChars(), ex ? ex->toChars() : "1"); 2721 return false; 2722 2723 // note: enable when deprecation becomes an error. 2724 // return true; 2725 } 2726 2727 /***************************** 2728 * If expression can be tested for true or false, 2729 * returns the modified expression. 2730 * Otherwise returns ErrorExp. 2731 */ 2732 Expression *Expression::toBoolean(Scope *sc) 2733 { 2734 // Default is 'yes' - do nothing 2735 Expression *e = this; 2736 Type *t = type; 2737 Type *tb = type->toBasetype(); 2738 Type *att = NULL; 2739 Lagain: 2740 // Structs can be converted to bool using opCast(bool)() 2741 if (tb->ty == Tstruct) 2742 { 2743 AggregateDeclaration *ad = ((TypeStruct *)tb)->sym; 2744 /* Don't really need to check for opCast first, but by doing so we 2745 * get better error messages if it isn't there. 2746 */ 2747 Dsymbol *fd = search_function(ad, Id::_cast); 2748 if (fd) 2749 { 2750 e = new CastExp(loc, e, Type::tbool); 2751 e = semantic(e, sc); 2752 return e; 2753 } 2754 2755 // Forward to aliasthis. 2756 if (ad->aliasthis && tb != att) 2757 { 2758 if (!att && tb->checkAliasThisRec()) 2759 att = tb; 2760 e = resolveAliasThis(sc, e); 2761 t = e->type; 2762 tb = e->type->toBasetype(); 2763 goto Lagain; 2764 } 2765 } 2766 2767 if (!t->isBoolean()) 2768 { 2769 if (tb != Type::terror) 2770 error("expression %s of type %s does not have a boolean value", toChars(), t->toChars()); 2771 return new ErrorExp(); 2772 } 2773 return e; 2774 } 2775 2776 /****************************** 2777 * Take address of expression. 2778 */ 2779 2780 Expression *Expression::addressOf() 2781 { 2782 //printf("Expression::addressOf()\n"); 2783 Expression *e = new AddrExp(loc, this); 2784 e->type = type->pointerTo(); 2785 return e; 2786 } 2787 2788 /****************************** 2789 * If this is a reference, dereference it. 2790 */ 2791 2792 Expression *Expression::deref() 2793 { 2794 //printf("Expression::deref()\n"); 2795 // type could be null if forward referencing an 'auto' variable 2796 if (type && type->ty == Treference) 2797 { 2798 Expression *e = new PtrExp(loc, this); 2799 e->type = ((TypeReference *)type)->next; 2800 return e; 2801 } 2802 return this; 2803 } 2804 2805 /******************************** 2806 * Does this expression statically evaluate to a boolean 'result' (true or false)? 2807 */ 2808 bool Expression::isBool(bool) 2809 { 2810 return false; 2811 } 2812 2813 /**************************************** 2814 * Resolve __FILE__, __LINE__, __MODULE__, __FUNCTION__, __PRETTY_FUNCTION__ to loc. 2815 */ 2816 2817 Expression *Expression::resolveLoc(Loc, Scope *) 2818 { 2819 return this; 2820 } 2821 2822 Expressions *Expression::arraySyntaxCopy(Expressions *exps) 2823 { 2824 Expressions *a = NULL; 2825 if (exps) 2826 { 2827 a = new Expressions(); 2828 a->setDim(exps->dim); 2829 for (size_t i = 0; i < a->dim; i++) 2830 { 2831 Expression *e = (*exps)[i]; 2832 (*a)[i] = e ? e->syntaxCopy() : NULL; 2833 } 2834 } 2835 return a; 2836 } 2837 2838 /************************************************ 2839 * Destructors are attached to VarDeclarations. 2840 * Hence, if expression returns a temp that needs a destructor, 2841 * make sure and create a VarDeclaration for that temp. 2842 */ 2843 2844 Expression *Expression::addDtorHook(Scope *) 2845 { 2846 return this; 2847 } 2848 2849 /******************************** IntegerExp **************************/ 2850 2851 IntegerExp::IntegerExp(Loc loc, dinteger_t value, Type *type) 2852 : Expression(loc, TOKint64, sizeof(IntegerExp)) 2853 { 2854 //printf("IntegerExp(value = %lld, type = '%s')\n", value, type ? type->toChars() : ""); 2855 assert(type); 2856 if (!type->isscalar()) 2857 { 2858 //printf("%s, loc = %d\n", toChars(), loc.linnum); 2859 if (type->ty != Terror) 2860 error("integral constant must be scalar type, not %s", type->toChars()); 2861 type = Type::terror; 2862 } 2863 this->type = type; 2864 setInteger(value); 2865 } 2866 2867 IntegerExp::IntegerExp(dinteger_t value) 2868 : Expression(Loc(), TOKint64, sizeof(IntegerExp)) 2869 { 2870 this->type = Type::tint32; 2871 this->value = (d_int32) value; 2872 } 2873 2874 IntegerExp *IntegerExp::create(Loc loc, dinteger_t value, Type *type) 2875 { 2876 return new IntegerExp(loc, value, type); 2877 } 2878 2879 bool IntegerExp::equals(RootObject *o) 2880 { 2881 if (this == o) 2882 return true; 2883 if (((Expression *)o)->op == TOKint64) 2884 { 2885 IntegerExp *ne = (IntegerExp *)o; 2886 if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) && 2887 value == ne->value) 2888 { 2889 return true; 2890 } 2891 } 2892 return false; 2893 } 2894 2895 void IntegerExp::setInteger(dinteger_t value) 2896 { 2897 this->value = value; 2898 normalize(); 2899 } 2900 2901 void IntegerExp::normalize() 2902 { 2903 /* 'Normalize' the value of the integer to be in range of the type 2904 */ 2905 switch (type->toBasetype()->ty) 2906 { 2907 case Tbool: value = (value != 0); break; 2908 case Tint8: value = (d_int8) value; break; 2909 case Tchar: 2910 case Tuns8: value = (d_uns8) value; break; 2911 case Tint16: value = (d_int16) value; break; 2912 case Twchar: 2913 case Tuns16: value = (d_uns16) value; break; 2914 case Tint32: value = (d_int32) value; break; 2915 case Tdchar: 2916 case Tuns32: value = (d_uns32) value; break; 2917 case Tint64: value = (d_int64) value; break; 2918 case Tuns64: value = (d_uns64) value; break; 2919 case Tpointer: 2920 if (Target::ptrsize == 4) 2921 value = (d_uns32) value; 2922 else if (Target::ptrsize == 8) 2923 value = (d_uns64) value; 2924 else 2925 assert(0); 2926 break; 2927 default: 2928 break; 2929 } 2930 } 2931 2932 dinteger_t IntegerExp::toInteger() 2933 { 2934 normalize(); // necessary until we fix all the paints of 'type' 2935 return value; 2936 } 2937 2938 real_t IntegerExp::toReal() 2939 { 2940 normalize(); // necessary until we fix all the paints of 'type' 2941 Type *t = type->toBasetype(); 2942 if (t->ty == Tuns64) 2943 return ldouble((d_uns64)value); 2944 else 2945 return ldouble((d_int64)value); 2946 } 2947 2948 real_t IntegerExp::toImaginary() 2949 { 2950 return CTFloat::zero; 2951 } 2952 2953 complex_t IntegerExp::toComplex() 2954 { 2955 return (complex_t)toReal(); 2956 } 2957 2958 bool IntegerExp::isBool(bool result) 2959 { 2960 bool r = toInteger() != 0; 2961 return result ? r : !r; 2962 } 2963 2964 Expression *IntegerExp::toLvalue(Scope *, Expression *e) 2965 { 2966 if (!e) 2967 e = this; 2968 else if (!loc.filename) 2969 loc = e->loc; 2970 e->error("constant %s is not an lvalue", e->toChars()); 2971 return new ErrorExp(); 2972 } 2973 2974 /******************************** ErrorExp **************************/ 2975 2976 /* Use this expression for error recovery. 2977 * It should behave as a 'sink' to prevent further cascaded error messages. 2978 */ 2979 2980 ErrorExp::ErrorExp() 2981 : Expression(Loc(), TOKerror, sizeof(ErrorExp)) 2982 { 2983 type = Type::terror; 2984 } 2985 2986 Expression *ErrorExp::toLvalue(Scope *, Expression *) 2987 { 2988 return this; 2989 } 2990 2991 /******************************** RealExp **************************/ 2992 2993 RealExp::RealExp(Loc loc, real_t value, Type *type) 2994 : Expression(loc, TOKfloat64, sizeof(RealExp)) 2995 { 2996 //printf("RealExp::RealExp(%Lg)\n", value); 2997 this->value = value; 2998 this->type = type; 2999 } 3000 3001 RealExp *RealExp::create(Loc loc, real_t value, Type *type) 3002 { 3003 return new RealExp(loc, value,type); 3004 } 3005 3006 dinteger_t RealExp::toInteger() 3007 { 3008 return (sinteger_t) toReal(); 3009 } 3010 3011 uinteger_t RealExp::toUInteger() 3012 { 3013 return (uinteger_t) toReal(); 3014 } 3015 3016 real_t RealExp::toReal() 3017 { 3018 return type->isreal() ? value : CTFloat::zero; 3019 } 3020 3021 real_t RealExp::toImaginary() 3022 { 3023 return type->isreal() ? CTFloat::zero : value; 3024 } 3025 3026 complex_t RealExp::toComplex() 3027 { 3028 return complex_t(toReal(), toImaginary()); 3029 } 3030 3031 /******************************** 3032 * Test to see if two reals are the same. 3033 * Regard NaN's as equivalent. 3034 * Regard +0 and -0 as different. 3035 */ 3036 3037 int RealEquals(real_t x1, real_t x2) 3038 { 3039 return (CTFloat::isNaN(x1) && CTFloat::isNaN(x2)) || 3040 CTFloat::isIdentical(x1, x2); 3041 } 3042 3043 bool RealExp::equals(RootObject *o) 3044 { 3045 if (this == o) 3046 return true; 3047 if (((Expression *)o)->op == TOKfloat64) 3048 { 3049 RealExp *ne = (RealExp *)o; 3050 if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) && 3051 RealEquals(value, ne->value)) 3052 { 3053 return true; 3054 } 3055 } 3056 return false; 3057 } 3058 3059 bool RealExp::isBool(bool result) 3060 { 3061 return result ? (bool)value : !(bool)value; 3062 } 3063 3064 /******************************** ComplexExp **************************/ 3065 3066 ComplexExp::ComplexExp(Loc loc, complex_t value, Type *type) 3067 : Expression(loc, TOKcomplex80, sizeof(ComplexExp)), value(value) 3068 { 3069 this->type = type; 3070 //printf("ComplexExp::ComplexExp(%s)\n", toChars()); 3071 } 3072 3073 ComplexExp *ComplexExp::create(Loc loc, complex_t value, Type *type) 3074 { 3075 return new ComplexExp(loc, value, type); 3076 } 3077 3078 dinteger_t ComplexExp::toInteger() 3079 { 3080 return (sinteger_t) toReal(); 3081 } 3082 3083 uinteger_t ComplexExp::toUInteger() 3084 { 3085 return (uinteger_t) toReal(); 3086 } 3087 3088 real_t ComplexExp::toReal() 3089 { 3090 return creall(value); 3091 } 3092 3093 real_t ComplexExp::toImaginary() 3094 { 3095 return cimagl(value); 3096 } 3097 3098 complex_t ComplexExp::toComplex() 3099 { 3100 return value; 3101 } 3102 3103 bool ComplexExp::equals(RootObject *o) 3104 { 3105 if (this == o) 3106 return true; 3107 if (((Expression *)o)->op == TOKcomplex80) 3108 { 3109 ComplexExp *ne = (ComplexExp *)o; 3110 if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) && 3111 RealEquals(creall(value), creall(ne->value)) && 3112 RealEquals(cimagl(value), cimagl(ne->value))) 3113 { 3114 return true; 3115 } 3116 } 3117 return false; 3118 } 3119 3120 bool ComplexExp::isBool(bool result) 3121 { 3122 if (result) 3123 return (bool)(value); 3124 else 3125 return !value; 3126 } 3127 3128 /******************************** IdentifierExp **************************/ 3129 3130 IdentifierExp::IdentifierExp(Loc loc, Identifier *ident) 3131 : Expression(loc, TOKidentifier, sizeof(IdentifierExp)) 3132 { 3133 this->ident = ident; 3134 } 3135 3136 IdentifierExp *IdentifierExp::create(Loc loc, Identifier *ident) 3137 { 3138 return new IdentifierExp(loc, ident); 3139 } 3140 3141 bool IdentifierExp::isLvalue() 3142 { 3143 return true; 3144 } 3145 3146 Expression *IdentifierExp::toLvalue(Scope *, Expression *) 3147 { 3148 return this; 3149 } 3150 3151 /******************************** DollarExp **************************/ 3152 3153 DollarExp::DollarExp(Loc loc) 3154 : IdentifierExp(loc, Id::dollar) 3155 { 3156 } 3157 3158 /******************************** DsymbolExp **************************/ 3159 3160 DsymbolExp::DsymbolExp(Loc loc, Dsymbol *s, bool hasOverloads) 3161 : Expression(loc, TOKdsymbol, sizeof(DsymbolExp)) 3162 { 3163 this->s = s; 3164 this->hasOverloads = hasOverloads; 3165 } 3166 3167 /**************************************** 3168 * Resolve a symbol `s` and wraps it in an expression object. 3169 * Params: 3170 * hasOverloads = works if the aliased symbol is a function. 3171 * true: it's overloaded and will be resolved later. 3172 * false: it's exact function symbol. 3173 */ 3174 Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads) 3175 { 3176 Lagain: 3177 Expression *e; 3178 3179 //printf("DsymbolExp:: %p '%s' is a symbol\n", this, toChars()); 3180 //printf("s = '%s', s->kind = '%s'\n", s->toChars(), s->kind()); 3181 Dsymbol *olds = s; 3182 Declaration *d = s->isDeclaration(); 3183 if (d && (d->storage_class & STCtemplateparameter)) 3184 { 3185 s = s->toAlias(); 3186 } 3187 else 3188 { 3189 if (!s->isFuncDeclaration()) // functions are checked after overloading 3190 s->checkDeprecated(loc, sc); 3191 3192 // Bugzilla 12023: if 's' is a tuple variable, the tuple is returned. 3193 s = s->toAlias(); 3194 3195 //printf("s = '%s', s->kind = '%s', s->needThis() = %p\n", s->toChars(), s->kind(), s->needThis()); 3196 if (s != olds && !s->isFuncDeclaration()) 3197 s->checkDeprecated(loc, sc); 3198 } 3199 3200 if (EnumMember *em = s->isEnumMember()) 3201 { 3202 return em->getVarExp(loc, sc); 3203 } 3204 if (VarDeclaration *v = s->isVarDeclaration()) 3205 { 3206 //printf("Identifier '%s' is a variable, type '%s'\n", toChars(), v->type->toChars()); 3207 if (!v->type || // during variable type inference 3208 (!v->type->deco && v->inuse)) // during variable type semantic 3209 { 3210 if (v->inuse) // variable type depends on the variable itself 3211 ::error(loc, "circular reference to %s '%s'", v->kind(), v->toPrettyChars()); 3212 else // variable type cannot be determined 3213 ::error(loc, "forward reference to %s '%s'", v->kind(), v->toPrettyChars()); 3214 return new ErrorExp(); 3215 } 3216 if (v->type->ty == Terror) 3217 return new ErrorExp(); 3218 3219 if ((v->storage_class & STCmanifest) && v->_init) 3220 { 3221 if (v->inuse) 3222 { 3223 ::error(loc, "circular initialization of %s '%s'", v->kind(), v->toPrettyChars()); 3224 return new ErrorExp(); 3225 } 3226 3227 e = v->expandInitializer(loc); 3228 v->inuse++; 3229 e = semantic(e, sc); 3230 v->inuse--; 3231 return e; 3232 } 3233 3234 // Change the ancestor lambdas to delegate before hasThis(sc) call. 3235 if (v->checkNestedReference(sc, loc)) 3236 return new ErrorExp(); 3237 3238 if (v->needThis() && hasThis(sc)) 3239 e = new DotVarExp(loc, new ThisExp(loc), v); 3240 else 3241 e = new VarExp(loc, v); 3242 e = semantic(e, sc); 3243 return e; 3244 } 3245 if (FuncLiteralDeclaration *fld = s->isFuncLiteralDeclaration()) 3246 { 3247 //printf("'%s' is a function literal\n", fld->toChars()); 3248 e = new FuncExp(loc, fld); 3249 return semantic(e, sc); 3250 } 3251 if (FuncDeclaration *f = s->isFuncDeclaration()) 3252 { 3253 f = f->toAliasFunc(); 3254 if (!f->functionSemantic()) 3255 return new ErrorExp(); 3256 3257 if (!hasOverloads && f->checkForwardRef(loc)) 3258 return new ErrorExp(); 3259 3260 FuncDeclaration *fd = s->isFuncDeclaration(); 3261 fd->type = f->type; 3262 return new VarExp(loc, fd, hasOverloads); 3263 } 3264 if (OverDeclaration *od = s->isOverDeclaration()) 3265 { 3266 e = new VarExp(loc, od, true); 3267 e->type = Type::tvoid; 3268 return e; 3269 } 3270 if (OverloadSet *o = s->isOverloadSet()) 3271 { 3272 //printf("'%s' is an overload set\n", o->toChars()); 3273 return new OverExp(loc, o); 3274 } 3275 3276 if (Import *imp = s->isImport()) 3277 { 3278 if (!imp->pkg) 3279 { 3280 ::error(loc, "forward reference of import %s", imp->toChars()); 3281 return new ErrorExp(); 3282 } 3283 ScopeExp *ie = new ScopeExp(loc, imp->pkg); 3284 return semantic(ie, sc); 3285 } 3286 if (Package *pkg = s->isPackage()) 3287 { 3288 ScopeExp *ie = new ScopeExp(loc, pkg); 3289 return semantic(ie, sc); 3290 } 3291 if (Module *mod = s->isModule()) 3292 { 3293 ScopeExp *ie = new ScopeExp(loc, mod); 3294 return semantic(ie, sc); 3295 } 3296 3297 if (Nspace *ns = s->isNspace()) 3298 { 3299 ScopeExp *ie = new ScopeExp(loc, ns); 3300 return semantic(ie, sc); 3301 } 3302 3303 if (Type *t = s->getType()) 3304 { 3305 return semantic(new TypeExp(loc, t), sc); 3306 } 3307 3308 if (TupleDeclaration *tup = s->isTupleDeclaration()) 3309 { 3310 if (tup->needThis() && hasThis(sc)) 3311 e = new DotVarExp(loc, new ThisExp(loc), tup); 3312 else 3313 e = new TupleExp(loc, tup); 3314 e = semantic(e, sc); 3315 return e; 3316 } 3317 3318 if (TemplateInstance *ti = s->isTemplateInstance()) 3319 { 3320 ti->semantic(sc); 3321 if (!ti->inst || ti->errors) 3322 return new ErrorExp(); 3323 s = ti->toAlias(); 3324 if (!s->isTemplateInstance()) 3325 goto Lagain; 3326 e = new ScopeExp(loc, ti); 3327 e = semantic(e, sc); 3328 return e; 3329 } 3330 if (TemplateDeclaration *td = s->isTemplateDeclaration()) 3331 { 3332 Dsymbol *p = td->toParent2(); 3333 FuncDeclaration *fdthis = hasThis(sc); 3334 AggregateDeclaration *ad = p ? p->isAggregateDeclaration() : NULL; 3335 if (fdthis && ad && isAggregate(fdthis->vthis->type) == ad && 3336 (td->_scope->stc & STCstatic) == 0) 3337 { 3338 e = new DotTemplateExp(loc, new ThisExp(loc), td); 3339 } 3340 else 3341 e = new TemplateExp(loc, td); 3342 e = semantic(e, sc); 3343 return e; 3344 } 3345 3346 ::error(loc, "%s '%s' is not a variable", s->kind(), s->toChars()); 3347 return new ErrorExp(); 3348 } 3349 3350 bool DsymbolExp::isLvalue() 3351 { 3352 return true; 3353 } 3354 3355 Expression *DsymbolExp::toLvalue(Scope *, Expression *) 3356 { 3357 return this; 3358 } 3359 3360 /******************************** ThisExp **************************/ 3361 3362 ThisExp::ThisExp(Loc loc) 3363 : Expression(loc, TOKthis, sizeof(ThisExp)) 3364 { 3365 //printf("ThisExp::ThisExp() loc = %d\n", loc.linnum); 3366 var = NULL; 3367 } 3368 3369 bool ThisExp::isBool(bool result) 3370 { 3371 return result ? true : false; 3372 } 3373 3374 bool ThisExp::isLvalue() 3375 { 3376 // Class `this` should be an rvalue; struct `this` should be an lvalue. 3377 return type->toBasetype()->ty != Tclass; 3378 } 3379 3380 Expression *ThisExp::toLvalue(Scope *sc, Expression *e) 3381 { 3382 if (type->toBasetype()->ty == Tclass) 3383 { 3384 // Class `this` is an rvalue; struct `this` is an lvalue. 3385 return Expression::toLvalue(sc, e); 3386 } 3387 return this; 3388 } 3389 3390 /******************************** SuperExp **************************/ 3391 3392 SuperExp::SuperExp(Loc loc) 3393 : ThisExp(loc) 3394 { 3395 op = TOKsuper; 3396 } 3397 3398 /******************************** NullExp **************************/ 3399 3400 NullExp::NullExp(Loc loc, Type *type) 3401 : Expression(loc, TOKnull, sizeof(NullExp)) 3402 { 3403 committed = 0; 3404 this->type = type; 3405 } 3406 3407 bool NullExp::equals(RootObject *o) 3408 { 3409 if (o && o->dyncast() == DYNCAST_EXPRESSION) 3410 { 3411 Expression *e = (Expression *)o; 3412 if (e->op == TOKnull && 3413 type->equals(e->type)) 3414 { 3415 return true; 3416 } 3417 } 3418 return false; 3419 } 3420 3421 bool NullExp::isBool(bool result) 3422 { 3423 return result ? false : true; 3424 } 3425 3426 StringExp *NullExp::toStringExp() 3427 { 3428 if (implicitConvTo(Type::tstring)) 3429 { 3430 StringExp *se = new StringExp(loc, (char*)mem.xcalloc(1, 1), 0); 3431 se->type = Type::tstring; 3432 return se; 3433 } 3434 return NULL; 3435 } 3436 3437 /******************************** StringExp **************************/ 3438 3439 StringExp::StringExp(Loc loc, char *string) 3440 : Expression(loc, TOKstring, sizeof(StringExp)) 3441 { 3442 this->string = string; 3443 this->len = strlen(string); 3444 this->sz = 1; 3445 this->committed = 0; 3446 this->postfix = 0; 3447 this->ownedByCtfe = OWNEDcode; 3448 } 3449 3450 StringExp::StringExp(Loc loc, void *string, size_t len) 3451 : Expression(loc, TOKstring, sizeof(StringExp)) 3452 { 3453 this->string = string; 3454 this->len = len; 3455 this->sz = 1; 3456 this->committed = 0; 3457 this->postfix = 0; 3458 this->ownedByCtfe = OWNEDcode; 3459 } 3460 3461 StringExp::StringExp(Loc loc, void *string, size_t len, utf8_t postfix) 3462 : Expression(loc, TOKstring, sizeof(StringExp)) 3463 { 3464 this->string = string; 3465 this->len = len; 3466 this->sz = 1; 3467 this->committed = 0; 3468 this->postfix = postfix; 3469 this->ownedByCtfe = OWNEDcode; 3470 } 3471 3472 StringExp *StringExp::create(Loc loc, char *s) 3473 { 3474 return new StringExp(loc, s); 3475 } 3476 3477 StringExp *StringExp::create(Loc loc, void *string, size_t len) 3478 { 3479 return new StringExp(loc, string, len); 3480 } 3481 3482 bool StringExp::equals(RootObject *o) 3483 { 3484 //printf("StringExp::equals('%s') %s\n", o->toChars(), toChars()); 3485 if (o && o->dyncast() == DYNCAST_EXPRESSION) 3486 { 3487 Expression *e = (Expression *)o; 3488 if (e->op == TOKstring) 3489 { 3490 return compare(o) == 0; 3491 } 3492 } 3493 return false; 3494 } 3495 3496 /********************************** 3497 * Return the number of code units the string would be if it were re-encoded 3498 * as tynto. 3499 * Params: 3500 * tynto = code unit type of the target encoding 3501 * Returns: 3502 * number of code units 3503 */ 3504 3505 size_t StringExp::numberOfCodeUnits(int tynto) const 3506 { 3507 int encSize; 3508 switch (tynto) 3509 { 3510 case 0: return len; 3511 case Tchar: encSize = 1; break; 3512 case Twchar: encSize = 2; break; 3513 case Tdchar: encSize = 4; break; 3514 default: 3515 assert(0); 3516 } 3517 if (sz == encSize) 3518 return len; 3519 3520 size_t result = 0; 3521 dchar_t c; 3522 3523 switch (sz) 3524 { 3525 case 1: 3526 for (size_t u = 0; u < len;) 3527 { 3528 if (const char *p = utf_decodeChar((utf8_t *)string, len, &u, &c)) 3529 { 3530 error("%s", p); 3531 return 0; 3532 } 3533 result += utf_codeLength(encSize, c); 3534 } 3535 break; 3536 3537 case 2: 3538 for (size_t u = 0; u < len;) 3539 { 3540 if (const char *p = utf_decodeWchar((utf16_t *)string, len, &u, &c)) 3541 { 3542 error("%s", p); 3543 return 0; 3544 } 3545 result += utf_codeLength(encSize, c); 3546 } 3547 break; 3548 3549 case 4: 3550 for (size_t u = 0; u < len;) 3551 { 3552 c = *((utf32_t *)((char *)string + u)); 3553 u += 4; 3554 result += utf_codeLength(encSize, c); 3555 } 3556 break; 3557 3558 default: 3559 assert(0); 3560 } 3561 return result; 3562 } 3563 3564 /********************************************** 3565 * Write the contents of the string to dest. 3566 * Use numberOfCodeUnits() to determine size of result. 3567 * Params: 3568 * dest = destination 3569 * tyto = encoding type of the result 3570 * zero = add terminating 0 3571 */ 3572 void StringExp::writeTo(void *dest, bool zero, int tyto) const 3573 { 3574 int encSize; 3575 switch (tyto) 3576 { 3577 case 0: encSize = sz; break; 3578 case Tchar: encSize = 1; break; 3579 case Twchar: encSize = 2; break; 3580 case Tdchar: encSize = 4; break; 3581 default: 3582 assert(0); 3583 } 3584 if (sz == encSize) 3585 { 3586 memcpy(dest, string, len * sz); 3587 if (zero) 3588 memset((char *)dest + len * sz, 0, sz); 3589 } 3590 else 3591 assert(0); 3592 } 3593 3594 /************************************************** 3595 * If the string data is UTF-8 and can be accessed directly, 3596 * return a pointer to it. 3597 * Do not assume a terminating 0. 3598 * Returns: 3599 * pointer to string data if possible, null if not 3600 */ 3601 char *StringExp::toPtr() 3602 { 3603 return (sz == 1) ? (char*)string : NULL; 3604 } 3605 3606 StringExp *StringExp::toStringExp() 3607 { 3608 return this; 3609 } 3610 3611 /**************************************** 3612 * Convert string to char[]. 3613 */ 3614 3615 StringExp *StringExp::toUTF8(Scope *sc) 3616 { 3617 if (sz != 1) 3618 { // Convert to UTF-8 string 3619 committed = 0; 3620 Expression *e = castTo(sc, Type::tchar->arrayOf()); 3621 e = e->optimize(WANTvalue); 3622 assert(e->op == TOKstring); 3623 StringExp *se = (StringExp *)e; 3624 assert(se->sz == 1); 3625 return se; 3626 } 3627 return this; 3628 } 3629 3630 int StringExp::compare(RootObject *obj) 3631 { 3632 //printf("StringExp::compare()\n"); 3633 // Used to sort case statement expressions so we can do an efficient lookup 3634 StringExp *se2 = (StringExp *)(obj); 3635 3636 // This is a kludge so isExpression() in template.c will return 5 3637 // for StringExp's. 3638 if (!se2) 3639 return 5; 3640 3641 assert(se2->op == TOKstring); 3642 3643 size_t len1 = len; 3644 size_t len2 = se2->len; 3645 3646 //printf("sz = %d, len1 = %d, len2 = %d\n", sz, (int)len1, (int)len2); 3647 if (len1 == len2) 3648 { 3649 switch (sz) 3650 { 3651 case 1: 3652 return memcmp((char *)string, (char *)se2->string, len1); 3653 3654 case 2: 3655 { 3656 d_uns16 *s1 = (d_uns16 *)string; 3657 d_uns16 *s2 = (d_uns16 *)se2->string; 3658 3659 for (size_t u = 0; u < len; u++) 3660 { 3661 if (s1[u] != s2[u]) 3662 return s1[u] - s2[u]; 3663 } 3664 } 3665 break; 3666 3667 case 4: 3668 { 3669 d_uns32 *s1 = (d_uns32 *)string; 3670 d_uns32 *s2 = (d_uns32 *)se2->string; 3671 3672 for (size_t u = 0; u < len; u++) 3673 { 3674 if (s1[u] != s2[u]) 3675 return s1[u] - s2[u]; 3676 } 3677 } 3678 break; 3679 3680 default: 3681 assert(0); 3682 } 3683 } 3684 return (int)(len1 - len2); 3685 } 3686 3687 bool StringExp::isBool(bool result) 3688 { 3689 return result ? true : false; 3690 } 3691 3692 3693 bool StringExp::isLvalue() 3694 { 3695 /* string literal is rvalue in default, but 3696 * conversion to reference of static array is only allowed. 3697 */ 3698 return (type && type->toBasetype()->ty == Tsarray); 3699 } 3700 3701 Expression *StringExp::toLvalue(Scope *sc, Expression *e) 3702 { 3703 //printf("StringExp::toLvalue(%s) type = %s\n", toChars(), type ? type->toChars() : NULL); 3704 return (type && type->toBasetype()->ty == Tsarray) 3705 ? this : Expression::toLvalue(sc, e); 3706 } 3707 3708 Expression *StringExp::modifiableLvalue(Scope *, Expression *) 3709 { 3710 error("cannot modify string literal %s", toChars()); 3711 return new ErrorExp(); 3712 } 3713 3714 unsigned StringExp::charAt(uinteger_t i) const 3715 { unsigned value; 3716 3717 switch (sz) 3718 { 3719 case 1: 3720 value = ((utf8_t *)string)[(size_t)i]; 3721 break; 3722 3723 case 2: 3724 value = ((unsigned short *)string)[(size_t)i]; 3725 break; 3726 3727 case 4: 3728 value = ((unsigned int *)string)[(size_t)i]; 3729 break; 3730 3731 default: 3732 assert(0); 3733 break; 3734 } 3735 return value; 3736 } 3737 3738 /************************ ArrayLiteralExp ************************************/ 3739 3740 // [ e1, e2, e3, ... ] 3741 3742 ArrayLiteralExp::ArrayLiteralExp(Loc loc, Type *type, Expressions *elements) 3743 : Expression(loc, TOKarrayliteral, sizeof(ArrayLiteralExp)) 3744 { 3745 this->basis = NULL; 3746 this->type = type; 3747 this->elements = elements; 3748 this->ownedByCtfe = OWNEDcode; 3749 } 3750 3751 ArrayLiteralExp::ArrayLiteralExp(Loc loc, Type *type, Expression *e) 3752 : Expression(loc, TOKarrayliteral, sizeof(ArrayLiteralExp)) 3753 { 3754 this->basis = NULL; 3755 this->type = type; 3756 elements = new Expressions; 3757 elements->push(e); 3758 this->ownedByCtfe = OWNEDcode; 3759 } 3760 3761 ArrayLiteralExp::ArrayLiteralExp(Loc loc, Type *type, Expression *basis, Expressions *elements) 3762 : Expression(loc, TOKarrayliteral, sizeof(ArrayLiteralExp)) 3763 { 3764 this->basis = basis; 3765 this->type = type; 3766 this->elements = elements; 3767 this->ownedByCtfe = OWNEDcode; 3768 } 3769 3770 ArrayLiteralExp *ArrayLiteralExp::create(Loc loc, Expressions *elements) 3771 { 3772 return new ArrayLiteralExp(loc, NULL, elements); 3773 } 3774 3775 bool ArrayLiteralExp::equals(RootObject *o) 3776 { 3777 if (this == o) 3778 return true; 3779 if (o && o->dyncast() == DYNCAST_EXPRESSION && 3780 ((Expression *)o)->op == TOKarrayliteral) 3781 { 3782 ArrayLiteralExp *ae = (ArrayLiteralExp *)o; 3783 if (elements->dim != ae->elements->dim) 3784 return false; 3785 if (elements->dim == 0 && 3786 !type->equals(ae->type)) 3787 { 3788 return false; 3789 } 3790 for (size_t i = 0; i < elements->dim; i++) 3791 { 3792 Expression *e1 = (*elements)[i]; 3793 Expression *e2 = (*ae->elements)[i]; 3794 if (!e1) 3795 e1 = basis; 3796 if (!e2) 3797 e2 = basis; 3798 if (e1 != e2 && 3799 (!e1 || !e2 || !e1->equals(e2))) 3800 return false; 3801 } 3802 return true; 3803 } 3804 return false; 3805 } 3806 3807 Expression *ArrayLiteralExp::syntaxCopy() 3808 { 3809 return new ArrayLiteralExp(loc, 3810 NULL, 3811 basis ? basis->syntaxCopy() : NULL, 3812 arraySyntaxCopy(elements)); 3813 } 3814 3815 Expression *ArrayLiteralExp::getElement(d_size_t i) 3816 { 3817 Expression *el = (*elements)[i]; 3818 if (!el) 3819 el = basis; 3820 return el; 3821 } 3822 3823 static void appendArrayLiteral(Expressions *elems, ArrayLiteralExp *ale) 3824 { 3825 if (!ale->elements) 3826 return; 3827 size_t d = elems->dim; 3828 elems->append(ale->elements); 3829 for (size_t i = d; i < elems->dim; i++) 3830 { 3831 Expression *el = (*elems)[i]; 3832 if (!el) 3833 (*elems)[i] = ale->basis; 3834 } 3835 } 3836 3837 /* Copy element `Expressions` in the parameters when they're `ArrayLiteralExp`s. 3838 * Params: 3839 * e1 = If it's ArrayLiteralExp, its `elements` will be copied. 3840 * Otherwise, `e1` itself will be pushed into the new `Expressions`. 3841 * e2 = If it's not `null`, it will be pushed/appended to the new 3842 * `Expressions` by the same way with `e1`. 3843 * Returns: 3844 * Newly allocated `Expressions`. Note that it points to the original 3845 * `Expression` values in e1 and e2. 3846 */ 3847 Expressions* ArrayLiteralExp::copyElements(Expression *e1, Expression *e2) 3848 { 3849 Expressions *elems = new Expressions(); 3850 3851 if (e1->op == TOKarrayliteral) 3852 appendArrayLiteral(elems, (ArrayLiteralExp *)e1); 3853 else 3854 elems->push(e1); 3855 3856 if (e2) 3857 { 3858 if (e2->op == TOKarrayliteral) 3859 appendArrayLiteral(elems, (ArrayLiteralExp *)e2); 3860 else 3861 elems->push(e2); 3862 } 3863 3864 return elems; 3865 } 3866 3867 bool ArrayLiteralExp::isBool(bool result) 3868 { 3869 size_t dim = elements ? elements->dim : 0; 3870 return result ? (dim != 0) : (dim == 0); 3871 } 3872 3873 StringExp *ArrayLiteralExp::toStringExp() 3874 { 3875 TY telem = type->nextOf()->toBasetype()->ty; 3876 3877 if (telem == Tchar || telem == Twchar || telem == Tdchar || 3878 (telem == Tvoid && (!elements || elements->dim == 0))) 3879 { 3880 unsigned char sz = 1; 3881 if (telem == Twchar) sz = 2; 3882 else if (telem == Tdchar) sz = 4; 3883 3884 OutBuffer buf; 3885 if (elements) 3886 { 3887 for (size_t i = 0; i < elements->dim; ++i) 3888 { 3889 Expression *ch = getElement(i); 3890 if (ch->op != TOKint64) 3891 return NULL; 3892 if (sz == 1) 3893 buf.writeByte((unsigned)ch->toInteger()); 3894 else if (sz == 2) 3895 buf.writeword((unsigned)ch->toInteger()); 3896 else 3897 buf.write4((unsigned)ch->toInteger()); 3898 } 3899 } 3900 char prefix; 3901 if (sz == 1) { prefix = 'c'; buf.writeByte(0); } 3902 else if (sz == 2) { prefix = 'w'; buf.writeword(0); } 3903 else { prefix = 'd'; buf.write4(0); } 3904 3905 const size_t len = buf.offset / sz - 1; 3906 StringExp *se = new StringExp(loc, buf.extractData(), len, prefix); 3907 se->sz = sz; 3908 se->type = type; 3909 return se; 3910 } 3911 return NULL; 3912 } 3913 3914 /************************ AssocArrayLiteralExp ************************************/ 3915 3916 // [ key0 : value0, key1 : value1, ... ] 3917 3918 AssocArrayLiteralExp::AssocArrayLiteralExp(Loc loc, 3919 Expressions *keys, Expressions *values) 3920 : Expression(loc, TOKassocarrayliteral, sizeof(AssocArrayLiteralExp)) 3921 { 3922 assert(keys->dim == values->dim); 3923 this->keys = keys; 3924 this->values = values; 3925 this->ownedByCtfe = OWNEDcode; 3926 } 3927 3928 bool AssocArrayLiteralExp::equals(RootObject *o) 3929 { 3930 if (this == o) 3931 return true; 3932 if (o && o->dyncast() == DYNCAST_EXPRESSION && 3933 ((Expression *)o)->op == TOKassocarrayliteral) 3934 { 3935 AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)o; 3936 if (keys->dim != ae->keys->dim) 3937 return false; 3938 size_t count = 0; 3939 for (size_t i = 0; i < keys->dim; i++) 3940 { 3941 for (size_t j = 0; j < ae->keys->dim; j++) 3942 { 3943 if ((*keys)[i]->equals((*ae->keys)[j])) 3944 { 3945 if (!(*values)[i]->equals((*ae->values)[j])) 3946 return false; 3947 ++count; 3948 } 3949 } 3950 } 3951 return count == keys->dim; 3952 } 3953 return false; 3954 } 3955 3956 Expression *AssocArrayLiteralExp::syntaxCopy() 3957 { 3958 return new AssocArrayLiteralExp(loc, 3959 arraySyntaxCopy(keys), arraySyntaxCopy(values)); 3960 } 3961 3962 bool AssocArrayLiteralExp::isBool(bool result) 3963 { 3964 size_t dim = keys->dim; 3965 return result ? (dim != 0) : (dim == 0); 3966 } 3967 3968 /************************ StructLiteralExp ************************************/ 3969 3970 // sd( e1, e2, e3, ... ) 3971 3972 StructLiteralExp::StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions *elements, Type *stype) 3973 : Expression(loc, TOKstructliteral, sizeof(StructLiteralExp)) 3974 { 3975 this->sd = sd; 3976 if (!elements) 3977 elements = new Expressions(); 3978 this->elements = elements; 3979 this->stype = stype; 3980 this->useStaticInit = false; 3981 this->sym = NULL; 3982 this->ownedByCtfe = OWNEDcode; 3983 this->origin = this; 3984 this->stageflags = 0; 3985 this->inlinecopy = NULL; 3986 //printf("StructLiteralExp::StructLiteralExp(%s)\n", toChars()); 3987 } 3988 3989 StructLiteralExp *StructLiteralExp::create(Loc loc, StructDeclaration *sd, void *elements, Type *stype) 3990 { 3991 return new StructLiteralExp(loc, sd, (Expressions *)elements, stype); 3992 } 3993 3994 bool StructLiteralExp::equals(RootObject *o) 3995 { 3996 if (this == o) 3997 return true; 3998 if (o && o->dyncast() == DYNCAST_EXPRESSION && 3999 ((Expression *)o)->op == TOKstructliteral) 4000 { 4001 StructLiteralExp *se = (StructLiteralExp *)o; 4002 if (!type->equals(se->type)) 4003 return false; 4004 if (elements->dim != se->elements->dim) 4005 return false; 4006 for (size_t i = 0; i < elements->dim; i++) 4007 { 4008 Expression *e1 = (*elements)[i]; 4009 Expression *e2 = (*se->elements)[i]; 4010 if (e1 != e2 && 4011 (!e1 || !e2 || !e1->equals(e2))) 4012 return false; 4013 } 4014 return true; 4015 } 4016 return false; 4017 } 4018 4019 Expression *StructLiteralExp::syntaxCopy() 4020 { 4021 StructLiteralExp *exp = new StructLiteralExp(loc, sd, arraySyntaxCopy(elements), type ? type : stype); 4022 exp->origin = this; 4023 return exp; 4024 } 4025 4026 Expression *StructLiteralExp::addDtorHook(Scope *sc) 4027 { 4028 /* If struct requires a destructor, rewrite as: 4029 * (S tmp = S()),tmp 4030 * so that the destructor can be hung on tmp. 4031 */ 4032 if (sd->dtor && sc->func) 4033 { 4034 /* Make an identifier for the temporary of the form: 4035 * __sl%s%d, where %s is the struct name 4036 */ 4037 const size_t len = 10; 4038 char buf[len + 1]; 4039 buf[len] = 0; 4040 strcpy(buf, "__sl"); 4041 strncat(buf, sd->ident->toChars(), len - 4 - 1); 4042 assert(buf[len] == 0); 4043 4044 VarDeclaration *tmp = copyToTemp(0, buf, this); 4045 Expression *ae = new DeclarationExp(loc, tmp); 4046 Expression *e = new CommaExp(loc, ae, new VarExp(loc, tmp)); 4047 e = semantic(e, sc); 4048 return e; 4049 } 4050 return this; 4051 } 4052 4053 /************************************** 4054 * Gets expression at offset of type. 4055 * Returns NULL if not found. 4056 */ 4057 4058 Expression *StructLiteralExp::getField(Type *type, unsigned offset) 4059 { 4060 //printf("StructLiteralExp::getField(this = %s, type = %s, offset = %u)\n", 4061 // /*toChars()*/"", type->toChars(), offset); 4062 Expression *e = NULL; 4063 int i = getFieldIndex(type, offset); 4064 4065 if (i != -1) 4066 { 4067 //printf("\ti = %d\n", i); 4068 if (i == (int)sd->fields.dim - 1 && sd->isNested()) 4069 return NULL; 4070 4071 assert(i < (int)elements->dim); 4072 e = (*elements)[i]; 4073 if (e) 4074 { 4075 //printf("e = %s, e->type = %s\n", e->toChars(), e->type->toChars()); 4076 4077 /* If type is a static array, and e is an initializer for that array, 4078 * then the field initializer should be an array literal of e. 4079 */ 4080 if (e->type->castMod(0) != type->castMod(0) && type->ty == Tsarray) 4081 { TypeSArray *tsa = (TypeSArray *)type; 4082 size_t length = (size_t)tsa->dim->toInteger(); 4083 Expressions *z = new Expressions; 4084 z->setDim(length); 4085 for (size_t q = 0; q < length; ++q) 4086 (*z)[q] = e->copy(); 4087 e = new ArrayLiteralExp(loc, type, z); 4088 } 4089 else 4090 { 4091 e = e->copy(); 4092 e->type = type; 4093 } 4094 if (useStaticInit && e->op == TOKstructliteral && 4095 e->type->needsNested()) 4096 { 4097 StructLiteralExp *se = (StructLiteralExp *)e; 4098 se->useStaticInit = true; 4099 } 4100 } 4101 } 4102 return e; 4103 } 4104 4105 /************************************ 4106 * Get index of field. 4107 * Returns -1 if not found. 4108 */ 4109 4110 int StructLiteralExp::getFieldIndex(Type *type, unsigned offset) 4111 { 4112 /* Find which field offset is by looking at the field offsets 4113 */ 4114 if (elements->dim) 4115 { 4116 for (size_t i = 0; i < sd->fields.dim; i++) 4117 { 4118 VarDeclaration *v = sd->fields[i]; 4119 4120 if (offset == v->offset && 4121 type->size() == v->type->size()) 4122 { 4123 /* context field might not be filled. */ 4124 if (i == sd->fields.dim - 1 && sd->isNested()) 4125 return (int)i; 4126 Expression *e = (*elements)[i]; 4127 if (e) 4128 { 4129 return (int)i; 4130 } 4131 break; 4132 } 4133 } 4134 } 4135 return -1; 4136 } 4137 4138 /************************ TypeDotIdExp ************************************/ 4139 4140 /* Things like: 4141 * int.size 4142 * foo.size 4143 * (foo).size 4144 * cast(foo).size 4145 */ 4146 4147 DotIdExp *typeDotIdExp(Loc loc, Type *type, Identifier *ident) 4148 { 4149 return new DotIdExp(loc, new TypeExp(loc, type), ident); 4150 } 4151 4152 4153 /************************************************************/ 4154 4155 // Mainly just a placeholder 4156 4157 TypeExp::TypeExp(Loc loc, Type *type) 4158 : Expression(loc, TOKtype, sizeof(TypeExp)) 4159 { 4160 //printf("TypeExp::TypeExp(%s)\n", type->toChars()); 4161 this->type = type; 4162 } 4163 4164 Expression *TypeExp::syntaxCopy() 4165 { 4166 return new TypeExp(loc, type->syntaxCopy()); 4167 } 4168 4169 bool TypeExp::checkType() 4170 { 4171 error("type %s is not an expression", toChars()); 4172 return true; 4173 } 4174 4175 bool TypeExp::checkValue() 4176 { 4177 error("type %s has no value", toChars()); 4178 return true; 4179 } 4180 4181 /************************************************************/ 4182 4183 /*********************************************************** 4184 * Mainly just a placeholder of 4185 * Package, Module, Nspace, and TemplateInstance (including TemplateMixin) 4186 * 4187 * A template instance that requires IFTI: 4188 * foo!tiargs(fargs) // foo!tiargs 4189 * is left until CallExp::semantic() or resolveProperties() 4190 */ 4191 ScopeExp::ScopeExp(Loc loc, ScopeDsymbol *sds) 4192 : Expression(loc, TOKscope, sizeof(ScopeExp)) 4193 { 4194 //printf("ScopeExp::ScopeExp(sds = '%s')\n", sds->toChars()); 4195 //static int count; if (++count == 38) *(char*)0=0; 4196 this->sds = sds; 4197 assert(!sds->isTemplateDeclaration()); // instead, you should use TemplateExp 4198 } 4199 4200 Expression *ScopeExp::syntaxCopy() 4201 { 4202 return new ScopeExp(loc, (ScopeDsymbol *)sds->syntaxCopy(NULL)); 4203 } 4204 4205 bool ScopeExp::checkType() 4206 { 4207 if (sds->isPackage()) 4208 { 4209 error("%s %s has no type", sds->kind(), sds->toChars()); 4210 return true; 4211 } 4212 if (TemplateInstance *ti = sds->isTemplateInstance()) 4213 { 4214 //assert(ti->needsTypeInference(sc)); 4215 if (ti->tempdecl && 4216 ti->semantictiargsdone && 4217 ti->semanticRun == PASSinit) 4218 { 4219 error("partial %s %s has no type", sds->kind(), toChars()); 4220 return true; 4221 } 4222 } 4223 return false; 4224 } 4225 4226 bool ScopeExp::checkValue() 4227 { 4228 error("%s %s has no value", sds->kind(), sds->toChars()); 4229 return true; 4230 } 4231 4232 /********************** TemplateExp **************************************/ 4233 4234 // Mainly just a placeholder 4235 4236 TemplateExp::TemplateExp(Loc loc, TemplateDeclaration *td, FuncDeclaration *fd) 4237 : Expression(loc, TOKtemplate, sizeof(TemplateExp)) 4238 { 4239 //printf("TemplateExp(): %s\n", td->toChars()); 4240 this->td = td; 4241 this->fd = fd; 4242 } 4243 4244 bool TemplateExp::checkType() 4245 { 4246 error("%s %s has no type", td->kind(), toChars()); 4247 return true; 4248 } 4249 4250 bool TemplateExp::checkValue() 4251 { 4252 error("%s %s has no value", td->kind(), toChars()); 4253 return true; 4254 } 4255 4256 bool TemplateExp::isLvalue() 4257 { 4258 return fd != NULL; 4259 } 4260 4261 Expression *TemplateExp::toLvalue(Scope *sc, Expression *e) 4262 { 4263 if (!fd) 4264 return Expression::toLvalue(sc, e); 4265 4266 assert(sc); 4267 return resolve(loc, sc, fd, true); 4268 } 4269 4270 /********************** NewExp **************************************/ 4271 4272 /* thisexp.new(newargs) newtype(arguments) */ 4273 4274 NewExp::NewExp(Loc loc, Expression *thisexp, Expressions *newargs, 4275 Type *newtype, Expressions *arguments) 4276 : Expression(loc, TOKnew, sizeof(NewExp)) 4277 { 4278 this->thisexp = thisexp; 4279 this->newargs = newargs; 4280 this->newtype = newtype; 4281 this->arguments = arguments; 4282 argprefix = NULL; 4283 member = NULL; 4284 allocator = NULL; 4285 onstack = 0; 4286 } 4287 4288 NewExp *NewExp::create(Loc loc, Expression *thisexp, Expressions *newargs, 4289 Type *newtype, Expressions *arguments) 4290 { 4291 return new NewExp(loc, thisexp, newargs, newtype, arguments); 4292 } 4293 4294 Expression *NewExp::syntaxCopy() 4295 { 4296 return new NewExp(loc, 4297 thisexp ? thisexp->syntaxCopy() : NULL, 4298 arraySyntaxCopy(newargs), 4299 newtype->syntaxCopy(), arraySyntaxCopy(arguments)); 4300 } 4301 4302 /********************** NewAnonClassExp **************************************/ 4303 4304 NewAnonClassExp::NewAnonClassExp(Loc loc, Expression *thisexp, 4305 Expressions *newargs, ClassDeclaration *cd, Expressions *arguments) 4306 : Expression(loc, TOKnewanonclass, sizeof(NewAnonClassExp)) 4307 { 4308 this->thisexp = thisexp; 4309 this->newargs = newargs; 4310 this->cd = cd; 4311 this->arguments = arguments; 4312 } 4313 4314 Expression *NewAnonClassExp::syntaxCopy() 4315 { 4316 return new NewAnonClassExp(loc, 4317 thisexp ? thisexp->syntaxCopy() : NULL, 4318 arraySyntaxCopy(newargs), 4319 (ClassDeclaration *)cd->syntaxCopy(NULL), 4320 arraySyntaxCopy(arguments)); 4321 } 4322 4323 /********************** SymbolExp **************************************/ 4324 4325 SymbolExp::SymbolExp(Loc loc, TOK op, int size, Declaration *var, bool hasOverloads) 4326 : Expression(loc, op, size) 4327 { 4328 assert(var); 4329 this->var = var; 4330 this->hasOverloads = hasOverloads; 4331 } 4332 4333 /********************** SymOffExp **************************************/ 4334 4335 SymOffExp::SymOffExp(Loc loc, Declaration *var, dinteger_t offset, bool hasOverloads) 4336 : SymbolExp(loc, TOKsymoff, sizeof(SymOffExp), var, 4337 var->isVarDeclaration() ? false : hasOverloads) 4338 { 4339 if (VarDeclaration *v = var->isVarDeclaration()) 4340 { 4341 // FIXME: This error report will never be handled anyone. 4342 // It should be done before the SymOffExp construction. 4343 if (v->needThis()) 4344 ::error(loc, "need 'this' for address of %s", v->toChars()); 4345 } 4346 this->offset = offset; 4347 } 4348 4349 bool SymOffExp::isBool(bool result) 4350 { 4351 return result ? true : false; 4352 } 4353 4354 /******************************** VarExp **************************/ 4355 4356 VarExp::VarExp(Loc loc, Declaration *var, bool hasOverloads) 4357 : SymbolExp(loc, TOKvar, sizeof(VarExp), var, 4358 var->isVarDeclaration() ? false : hasOverloads) 4359 { 4360 //printf("VarExp(this = %p, '%s', loc = %s)\n", this, var->toChars(), loc.toChars()); 4361 //if (strcmp(var->ident->toChars(), "func") == 0) halt(); 4362 this->type = var->type; 4363 } 4364 4365 VarExp *VarExp::create(Loc loc, Declaration *var, bool hasOverloads) 4366 { 4367 return new VarExp(loc, var, hasOverloads); 4368 } 4369 4370 bool VarExp::equals(RootObject *o) 4371 { 4372 if (this == o) 4373 return true; 4374 if (((Expression *)o)->op == TOKvar) 4375 { 4376 VarExp *ne = (VarExp *)o; 4377 if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) && 4378 var == ne->var) 4379 { 4380 return true; 4381 } 4382 } 4383 return false; 4384 } 4385 4386 bool VarExp::isLvalue() 4387 { 4388 if (var->storage_class & (STClazy | STCrvalue | STCmanifest)) 4389 return false; 4390 return true; 4391 } 4392 4393 Expression *VarExp::toLvalue(Scope *, Expression *) 4394 { 4395 if (var->storage_class & STCmanifest) 4396 { 4397 error("manifest constant '%s' is not lvalue", var->toChars()); 4398 return new ErrorExp(); 4399 } 4400 if (var->storage_class & STClazy) 4401 { 4402 error("lazy variables cannot be lvalues"); 4403 return new ErrorExp(); 4404 } 4405 if (var->ident == Id::ctfe) 4406 { 4407 error("compiler-generated variable __ctfe is not an lvalue"); 4408 return new ErrorExp(); 4409 } 4410 if (var->ident == Id::dollar) // Bugzilla 13574 4411 { 4412 error("'$' is not an lvalue"); 4413 return new ErrorExp(); 4414 } 4415 return this; 4416 } 4417 4418 int VarExp::checkModifiable(Scope *sc, int flag) 4419 { 4420 //printf("VarExp::checkModifiable %s", toChars()); 4421 assert(type); 4422 return var->checkModify(loc, sc, type, NULL, flag); 4423 } 4424 4425 Expression *VarExp::modifiableLvalue(Scope *sc, Expression *e) 4426 { 4427 //printf("VarExp::modifiableLvalue('%s')\n", var->toChars()); 4428 if (var->storage_class & STCmanifest) 4429 { 4430 error("cannot modify manifest constant '%s'", toChars()); 4431 return new ErrorExp(); 4432 } 4433 // See if this expression is a modifiable lvalue (i.e. not const) 4434 return Expression::modifiableLvalue(sc, e); 4435 } 4436 4437 4438 /******************************** OverExp **************************/ 4439 4440 OverExp::OverExp(Loc loc, OverloadSet *s) 4441 : Expression(loc, TOKoverloadset, sizeof(OverExp)) 4442 { 4443 //printf("OverExp(this = %p, '%s')\n", this, var->toChars()); 4444 vars = s; 4445 type = Type::tvoid; 4446 } 4447 4448 bool OverExp::isLvalue() 4449 { 4450 return true; 4451 } 4452 4453 Expression *OverExp::toLvalue(Scope *, Expression *) 4454 { 4455 return this; 4456 } 4457 4458 /******************************** TupleExp **************************/ 4459 4460 TupleExp::TupleExp(Loc loc, Expression *e0, Expressions *exps) 4461 : Expression(loc, TOKtuple, sizeof(TupleExp)) 4462 { 4463 //printf("TupleExp(this = %p)\n", this); 4464 this->e0 = e0; 4465 this->exps = exps; 4466 } 4467 4468 TupleExp::TupleExp(Loc loc, Expressions *exps) 4469 : Expression(loc, TOKtuple, sizeof(TupleExp)) 4470 { 4471 //printf("TupleExp(this = %p)\n", this); 4472 this->e0 = NULL; 4473 this->exps = exps; 4474 } 4475 4476 TupleExp::TupleExp(Loc loc, TupleDeclaration *tup) 4477 : Expression(loc, TOKtuple, sizeof(TupleExp)) 4478 { 4479 this->e0 = NULL; 4480 this->exps = new Expressions(); 4481 4482 this->exps->reserve(tup->objects->dim); 4483 for (size_t i = 0; i < tup->objects->dim; i++) 4484 { RootObject *o = (*tup->objects)[i]; 4485 if (Dsymbol *s = getDsymbol(o)) 4486 { 4487 /* If tuple element represents a symbol, translate to DsymbolExp 4488 * to supply implicit 'this' if needed later. 4489 */ 4490 Expression *e = new DsymbolExp(loc, s); 4491 this->exps->push(e); 4492 } 4493 else if (o->dyncast() == DYNCAST_EXPRESSION) 4494 { 4495 Expression *e = ((Expression *)o)->copy(); 4496 e->loc = loc; // Bugzilla 15669 4497 this->exps->push(e); 4498 } 4499 else if (o->dyncast() == DYNCAST_TYPE) 4500 { 4501 Type *t = (Type *)o; 4502 Expression *e = new TypeExp(loc, t); 4503 this->exps->push(e); 4504 } 4505 else 4506 { 4507 error("%s is not an expression", o->toChars()); 4508 } 4509 } 4510 } 4511 4512 bool TupleExp::equals(RootObject *o) 4513 { 4514 if (this == o) 4515 return true; 4516 if (((Expression *)o)->op == TOKtuple) 4517 { 4518 TupleExp *te = (TupleExp *)o; 4519 if (exps->dim != te->exps->dim) 4520 return false; 4521 if ((e0 && !e0->equals(te->e0)) || (!e0 && te->e0)) 4522 return false; 4523 for (size_t i = 0; i < exps->dim; i++) 4524 { 4525 Expression *e1 = (*exps)[i]; 4526 Expression *e2 = (*te->exps)[i]; 4527 if (!e1->equals(e2)) 4528 return false; 4529 } 4530 return true; 4531 } 4532 return false; 4533 } 4534 4535 Expression *TupleExp::syntaxCopy() 4536 { 4537 return new TupleExp(loc, e0 ? e0->syntaxCopy() : NULL, arraySyntaxCopy(exps)); 4538 } 4539 4540 /******************************** FuncExp *********************************/ 4541 4542 FuncExp::FuncExp(Loc loc, Dsymbol *s) 4543 : Expression(loc, TOKfunction, sizeof(FuncExp)) 4544 { 4545 this->td = s->isTemplateDeclaration(); 4546 this->fd = s->isFuncLiteralDeclaration(); 4547 if (td) 4548 { 4549 assert(td->literal); 4550 assert(td->members && td->members->dim == 1); 4551 fd = (*td->members)[0]->isFuncLiteralDeclaration(); 4552 } 4553 tok = fd->tok; // save original kind of function/delegate/(infer) 4554 assert(fd->fbody); 4555 } 4556 4557 bool FuncExp::equals(RootObject *o) 4558 { 4559 if (this == o) 4560 return true; 4561 if (o->dyncast() != DYNCAST_EXPRESSION) 4562 return false; 4563 if (((Expression *)o)->op == TOKfunction) 4564 { 4565 FuncExp *fe = (FuncExp *)o; 4566 return fd == fe->fd; 4567 } 4568 return false; 4569 } 4570 4571 void FuncExp::genIdent(Scope *sc) 4572 { 4573 if (fd->ident == Id::empty) 4574 { 4575 const char *s; 4576 if (fd->fes) s = "__foreachbody"; 4577 else if (fd->tok == TOKreserved) s = "__lambda"; 4578 else if (fd->tok == TOKdelegate) s = "__dgliteral"; 4579 else s = "__funcliteral"; 4580 4581 DsymbolTable *symtab; 4582 if (FuncDeclaration *func = sc->parent->isFuncDeclaration()) 4583 { 4584 if (func->localsymtab == NULL) 4585 { 4586 // Inside template constraint, symtab is not set yet. 4587 // Initialize it lazily. 4588 func->localsymtab = new DsymbolTable(); 4589 } 4590 symtab = func->localsymtab; 4591 } 4592 else 4593 { 4594 ScopeDsymbol *sds = sc->parent->isScopeDsymbol(); 4595 if (!sds->symtab) 4596 { 4597 // Inside template constraint, symtab may not be set yet. 4598 // Initialize it lazily. 4599 assert(sds->isTemplateInstance()); 4600 sds->symtab = new DsymbolTable(); 4601 } 4602 symtab = sds->symtab; 4603 } 4604 assert(symtab); 4605 int num = (int)dmd_aaLen(symtab->tab) + 1; 4606 Identifier *id = Identifier::generateId(s, num); 4607 fd->ident = id; 4608 if (td) td->ident = id; 4609 symtab->insert(td ? (Dsymbol *)td : (Dsymbol *)fd); 4610 } 4611 } 4612 4613 Expression *FuncExp::syntaxCopy() 4614 { 4615 if (td) 4616 return new FuncExp(loc, td->syntaxCopy(NULL)); 4617 else if (fd->semanticRun == PASSinit) 4618 return new FuncExp(loc, fd->syntaxCopy(NULL)); 4619 else // Bugzilla 13481: Prevent multiple semantic analysis of lambda body. 4620 return new FuncExp(loc, fd); 4621 } 4622 4623 MATCH FuncExp::matchType(Type *to, Scope *sc, FuncExp **presult, int flag) 4624 { 4625 //printf("FuncExp::matchType('%s'), to=%s\n", type ? type->toChars() : "null", to->toChars()); 4626 if (presult) 4627 *presult = NULL; 4628 4629 TypeFunction *tof = NULL; 4630 if (to->ty == Tdelegate) 4631 { 4632 if (tok == TOKfunction) 4633 { 4634 if (!flag) 4635 error("cannot match function literal to delegate type '%s'", to->toChars()); 4636 return MATCHnomatch; 4637 } 4638 tof = (TypeFunction *)to->nextOf(); 4639 } 4640 else if (to->ty == Tpointer && to->nextOf()->ty == Tfunction) 4641 { 4642 if (tok == TOKdelegate) 4643 { 4644 if (!flag) 4645 error("cannot match delegate literal to function pointer type '%s'", to->toChars()); 4646 return MATCHnomatch; 4647 } 4648 tof = (TypeFunction *)to->nextOf(); 4649 } 4650 4651 if (td) 4652 { 4653 if (!tof) 4654 { 4655 L1: 4656 if (!flag) 4657 error("cannot infer parameter types from %s", to->toChars()); 4658 return MATCHnomatch; 4659 } 4660 4661 // Parameter types inference from 'tof' 4662 assert(td->_scope); 4663 TypeFunction *tf = (TypeFunction *)fd->type; 4664 //printf("\ttof = %s\n", tof->toChars()); 4665 //printf("\ttf = %s\n", tf->toChars()); 4666 size_t dim = Parameter::dim(tf->parameters); 4667 4668 if (Parameter::dim(tof->parameters) != dim || 4669 tof->varargs != tf->varargs) 4670 goto L1; 4671 4672 Objects *tiargs = new Objects(); 4673 tiargs->reserve(td->parameters->dim); 4674 4675 for (size_t i = 0; i < td->parameters->dim; i++) 4676 { 4677 TemplateParameter *tp = (*td->parameters)[i]; 4678 size_t u = 0; 4679 for (; u < dim; u++) 4680 { 4681 Parameter *p = Parameter::getNth(tf->parameters, u); 4682 if (p->type->ty == Tident && 4683 ((TypeIdentifier *)p->type)->ident == tp->ident) 4684 { 4685 break; 4686 } 4687 } 4688 assert(u < dim); 4689 Parameter *pto = Parameter::getNth(tof->parameters, u); 4690 Type *t = pto->type; 4691 if (t->ty == Terror) 4692 goto L1; 4693 tiargs->push(t); 4694 } 4695 4696 // Set target of return type inference 4697 if (!tf->next && tof->next) 4698 fd->treq = to; 4699 4700 TemplateInstance *ti = new TemplateInstance(loc, td, tiargs); 4701 Expression *ex = new ScopeExp(loc, ti); 4702 ex = ::semantic(ex, td->_scope); 4703 4704 // Reset inference target for the later re-semantic 4705 fd->treq = NULL; 4706 4707 if (ex->op == TOKerror) 4708 return MATCHnomatch; 4709 if (ex->op != TOKfunction) 4710 goto L1; 4711 return ((FuncExp *)ex)->matchType(to, sc, presult, flag); 4712 } 4713 4714 if (!tof || !tof->next) 4715 return MATCHnomatch; 4716 4717 assert(type && type != Type::tvoid); 4718 TypeFunction *tfx = (TypeFunction *)fd->type; 4719 bool convertMatch = (type->ty != to->ty); 4720 4721 if (fd->inferRetType && tfx->next->implicitConvTo(tof->next) == MATCHconvert) 4722 { 4723 /* If return type is inferred and covariant return, 4724 * tweak return statements to required return type. 4725 * 4726 * interface I {} 4727 * class C : Object, I{} 4728 * 4729 * I delegate() dg = delegate() { return new class C(); } 4730 */ 4731 convertMatch = true; 4732 4733 TypeFunction *tfy = new TypeFunction(tfx->parameters, tof->next, tfx->varargs, tfx->linkage, STCundefined); 4734 tfy->mod = tfx->mod; 4735 tfy->isnothrow = tfx->isnothrow; 4736 tfy->isnogc = tfx->isnogc; 4737 tfy->purity = tfx->purity; 4738 tfy->isproperty = tfx->isproperty; 4739 tfy->isref = tfx->isref; 4740 tfy->iswild = tfx->iswild; 4741 tfy->deco = tfy->merge()->deco; 4742 4743 tfx = tfy; 4744 } 4745 4746 Type *tx; 4747 if (tok == TOKdelegate || 4748 (tok == TOKreserved && (type->ty == Tdelegate || 4749 (type->ty == Tpointer && to->ty == Tdelegate)))) 4750 { 4751 // Allow conversion from implicit function pointer to delegate 4752 tx = new TypeDelegate(tfx); 4753 tx->deco = tx->merge()->deco; 4754 } 4755 else 4756 { 4757 assert(tok == TOKfunction || 4758 (tok == TOKreserved && type->ty == Tpointer)); 4759 tx = tfx->pointerTo(); 4760 } 4761 //printf("\ttx = %s, to = %s\n", tx->toChars(), to->toChars()); 4762 4763 MATCH m = tx->implicitConvTo(to); 4764 if (m > MATCHnomatch) 4765 { 4766 // MATCHexact: exact type match 4767 // MATCHconst: covairiant type match (eg. attributes difference) 4768 // MATCHconvert: context conversion 4769 m = convertMatch ? MATCHconvert : tx->equals(to) ? MATCHexact : MATCHconst; 4770 4771 if (presult) 4772 { 4773 (*presult) = (FuncExp *)copy(); 4774 (*presult)->type = to; 4775 4776 // Bugzilla 12508: Tweak function body for covariant returns. 4777 (*presult)->fd->modifyReturns(sc, tof->next); 4778 } 4779 } 4780 else if (!flag) 4781 { 4782 error("cannot implicitly convert expression (%s) of type %s to %s", 4783 toChars(), tx->toChars(), to->toChars()); 4784 } 4785 return m; 4786 } 4787 4788 const char *FuncExp::toChars() 4789 { 4790 return fd->toChars(); 4791 } 4792 4793 bool FuncExp::checkType() 4794 { 4795 if (td) 4796 { 4797 error("template lambda has no type"); 4798 return true; 4799 } 4800 return false; 4801 } 4802 4803 bool FuncExp::checkValue() 4804 { 4805 if (td) 4806 { 4807 error("template lambda has no value"); 4808 return true; 4809 } 4810 return false; 4811 } 4812 4813 /******************************** DeclarationExp **************************/ 4814 4815 DeclarationExp::DeclarationExp(Loc loc, Dsymbol *declaration) 4816 : Expression(loc, TOKdeclaration, sizeof(DeclarationExp)) 4817 { 4818 this->declaration = declaration; 4819 } 4820 4821 Expression *DeclarationExp::syntaxCopy() 4822 { 4823 return new DeclarationExp(loc, declaration->syntaxCopy(NULL)); 4824 } 4825 4826 bool DeclarationExp::hasCode() 4827 { 4828 if (VarDeclaration *vd = declaration->isVarDeclaration()) 4829 { 4830 return !(vd->storage_class & (STCmanifest | STCstatic)); 4831 } 4832 return false; 4833 } 4834 4835 /************************ TypeidExp ************************************/ 4836 4837 /* 4838 * typeid(int) 4839 */ 4840 4841 TypeidExp::TypeidExp(Loc loc, RootObject *o) 4842 : Expression(loc, TOKtypeid, sizeof(TypeidExp)) 4843 { 4844 this->obj = o; 4845 } 4846 4847 Expression *TypeidExp::syntaxCopy() 4848 { 4849 return new TypeidExp(loc, objectSyntaxCopy(obj)); 4850 } 4851 4852 /************************ TraitsExp ************************************/ 4853 /* 4854 * __traits(identifier, args...) 4855 */ 4856 4857 TraitsExp::TraitsExp(Loc loc, Identifier *ident, Objects *args) 4858 : Expression(loc, TOKtraits, sizeof(TraitsExp)) 4859 { 4860 this->ident = ident; 4861 this->args = args; 4862 } 4863 4864 Expression *TraitsExp::syntaxCopy() 4865 { 4866 return new TraitsExp(loc, ident, TemplateInstance::arraySyntaxCopy(args)); 4867 } 4868 4869 /************************************************************/ 4870 4871 HaltExp::HaltExp(Loc loc) 4872 : Expression(loc, TOKhalt, sizeof(HaltExp)) 4873 { 4874 } 4875 4876 /************************************************************/ 4877 4878 IsExp::IsExp(Loc loc, Type *targ, Identifier *id, TOK tok, 4879 Type *tspec, TOK tok2, TemplateParameters *parameters) 4880 : Expression(loc, TOKis, sizeof(IsExp)) 4881 { 4882 this->targ = targ; 4883 this->id = id; 4884 this->tok = tok; 4885 this->tspec = tspec; 4886 this->tok2 = tok2; 4887 this->parameters = parameters; 4888 } 4889 4890 Expression *IsExp::syntaxCopy() 4891 { 4892 // This section is identical to that in TemplateDeclaration::syntaxCopy() 4893 TemplateParameters *p = NULL; 4894 if (parameters) 4895 { 4896 p = new TemplateParameters(); 4897 p->setDim(parameters->dim); 4898 for (size_t i = 0; i < p->dim; i++) 4899 (*p)[i] = (*parameters)[i]->syntaxCopy(); 4900 } 4901 return new IsExp(loc, 4902 targ->syntaxCopy(), 4903 id, 4904 tok, 4905 tspec ? tspec->syntaxCopy() : NULL, 4906 tok2, 4907 p); 4908 } 4909 4910 void unSpeculative(Scope *sc, RootObject *o); 4911 4912 /************************************************************/ 4913 4914 UnaExp::UnaExp(Loc loc, TOK op, int size, Expression *e1) 4915 : Expression(loc, op, size) 4916 { 4917 this->e1 = e1; 4918 this->att1 = NULL; 4919 } 4920 4921 Expression *UnaExp::syntaxCopy() 4922 { 4923 UnaExp *e = (UnaExp *)copy(); 4924 e->type = NULL; 4925 e->e1 = e->e1->syntaxCopy(); 4926 return e; 4927 } 4928 4929 /******************************** 4930 * The type for a unary expression is incompatible. 4931 * Print error message. 4932 * Returns: 4933 * ErrorExp 4934 */ 4935 Expression *UnaExp::incompatibleTypes() 4936 { 4937 if (e1->type->toBasetype() == Type::terror) 4938 return e1; 4939 4940 if (e1->op == TOKtype) 4941 { 4942 error("incompatible type for (%s(%s)): cannot use '%s' with types", 4943 Token::toChars(op), e1->toChars(), Token::toChars(op)); 4944 } 4945 else 4946 { 4947 error("incompatible type for (%s(%s)): '%s'", 4948 Token::toChars(op), e1->toChars(), e1->type->toChars()); 4949 } 4950 return new ErrorExp(); 4951 } 4952 4953 Expression *UnaExp::resolveLoc(Loc loc, Scope *sc) 4954 { 4955 e1 = e1->resolveLoc(loc, sc); 4956 return this; 4957 } 4958 4959 /************************************************************/ 4960 4961 BinExp::BinExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2) 4962 : Expression(loc, op, size) 4963 { 4964 this->e1 = e1; 4965 this->e2 = e2; 4966 4967 this->att1 = NULL; 4968 this->att2 = NULL; 4969 } 4970 4971 Expression *BinExp::syntaxCopy() 4972 { 4973 BinExp *e = (BinExp *)copy(); 4974 e->type = NULL; 4975 e->e1 = e->e1->syntaxCopy(); 4976 e->e2 = e->e2->syntaxCopy(); 4977 return e; 4978 } 4979 4980 Expression *BinExp::checkOpAssignTypes(Scope *sc) 4981 { 4982 // At that point t1 and t2 are the merged types. type is the original type of the lhs. 4983 Type *t1 = e1->type; 4984 Type *t2 = e2->type; 4985 4986 // T opAssign floating yields a floating. Prevent truncating conversions (float to int). 4987 // See issue 3841. 4988 // Should we also prevent double to float (type->isfloating() && type->size() < t2 ->size()) ? 4989 if (op == TOKaddass || op == TOKminass || 4990 op == TOKmulass || op == TOKdivass || op == TOKmodass || 4991 op == TOKpowass) 4992 { 4993 if ((type->isintegral() && t2->isfloating())) 4994 { 4995 warning("%s %s %s is performing truncating conversion", 4996 type->toChars(), Token::toChars(op), t2->toChars()); 4997 } 4998 } 4999 5000 // generate an error if this is a nonsensical *=,/=, or %=, eg real *= imaginary 5001 if (op == TOKmulass || op == TOKdivass || op == TOKmodass) 5002 { 5003 // Any multiplication by an imaginary or complex number yields a complex result. 5004 // r *= c, i*=c, r*=i, i*=i are all forbidden operations. 5005 const char *opstr = Token::toChars(op); 5006 if (t1->isreal() && t2->iscomplex()) 5007 { 5008 error("%s %s %s is undefined. Did you mean %s %s %s.re ?", 5009 t1->toChars(), opstr, t2->toChars(), 5010 t1->toChars(), opstr, t2->toChars()); 5011 return new ErrorExp(); 5012 } 5013 else if (t1->isimaginary() && t2->iscomplex()) 5014 { 5015 error("%s %s %s is undefined. Did you mean %s %s %s.im ?", 5016 t1->toChars(), opstr, t2->toChars(), 5017 t1->toChars(), opstr, t2->toChars()); 5018 return new ErrorExp(); 5019 } 5020 else if ((t1->isreal() || t1->isimaginary()) && 5021 t2->isimaginary()) 5022 { 5023 error("%s %s %s is an undefined operation", t1->toChars(), opstr, t2->toChars()); 5024 return new ErrorExp(); 5025 } 5026 } 5027 5028 // generate an error if this is a nonsensical += or -=, eg real += imaginary 5029 if (op == TOKaddass || op == TOKminass) 5030 { 5031 // Addition or subtraction of a real and an imaginary is a complex result. 5032 // Thus, r+=i, r+=c, i+=r, i+=c are all forbidden operations. 5033 if ((t1->isreal() && (t2->isimaginary() || t2->iscomplex())) || 5034 (t1->isimaginary() && (t2->isreal() || t2->iscomplex()))) 5035 { 5036 error("%s %s %s is undefined (result is complex)", 5037 t1->toChars(), Token::toChars(op), t2->toChars()); 5038 return new ErrorExp(); 5039 } 5040 if (type->isreal() || type->isimaginary()) 5041 { 5042 assert(global.errors || t2->isfloating()); 5043 e2 = e2->castTo(sc, t1); 5044 } 5045 } 5046 5047 if (op == TOKmulass) 5048 { 5049 if (t2->isfloating()) 5050 { 5051 if (t1->isreal()) 5052 { 5053 if (t2->isimaginary() || t2->iscomplex()) 5054 { 5055 e2 = e2->castTo(sc, t1); 5056 } 5057 } 5058 else if (t1->isimaginary()) 5059 { 5060 if (t2->isimaginary() || t2->iscomplex()) 5061 { 5062 switch (t1->ty) 5063 { 5064 case Timaginary32: t2 = Type::tfloat32; break; 5065 case Timaginary64: t2 = Type::tfloat64; break; 5066 case Timaginary80: t2 = Type::tfloat80; break; 5067 default: 5068 assert(0); 5069 } 5070 e2 = e2->castTo(sc, t2); 5071 } 5072 } 5073 } 5074 } 5075 else if (op == TOKdivass) 5076 { 5077 if (t2->isimaginary()) 5078 { 5079 if (t1->isreal()) 5080 { 5081 // x/iv = i(-x/v) 5082 // Therefore, the result is 0 5083 e2 = new CommaExp(loc, e2, new RealExp(loc, CTFloat::zero, t1)); 5084 e2->type = t1; 5085 Expression *e = new AssignExp(loc, e1, e2); 5086 e->type = t1; 5087 return e; 5088 } 5089 else if (t1->isimaginary()) 5090 { 5091 Type *t3; 5092 switch (t1->ty) 5093 { 5094 case Timaginary32: t3 = Type::tfloat32; break; 5095 case Timaginary64: t3 = Type::tfloat64; break; 5096 case Timaginary80: t3 = Type::tfloat80; break; 5097 default: 5098 assert(0); 5099 } 5100 e2 = e2->castTo(sc, t3); 5101 Expression *e = new AssignExp(loc, e1, e2); 5102 e->type = t1; 5103 return e; 5104 } 5105 } 5106 } 5107 else if (op == TOKmodass) 5108 { 5109 if (t2->iscomplex()) 5110 { 5111 error("cannot perform modulo complex arithmetic"); 5112 return new ErrorExp(); 5113 } 5114 } 5115 return this; 5116 } 5117 5118 /******************************** 5119 * The types for a binary expression are incompatible. 5120 * Print error message. 5121 * Returns: 5122 * ErrorExp 5123 */ 5124 Expression *BinExp::incompatibleTypes() 5125 { 5126 if (e1->type->toBasetype() == Type::terror) 5127 return e1; 5128 if (e2->type->toBasetype() == Type::terror) 5129 return e2; 5130 5131 // CondExp uses 'a ? b : c' but we're comparing 'b : c' 5132 TOK thisOp = (op == TOKquestion) ? TOKcolon : op; 5133 if (e1->op == TOKtype || e2->op == TOKtype) 5134 { 5135 error("incompatible types for ((%s) %s (%s)): cannot use '%s' with types", 5136 e1->toChars(), Token::toChars(thisOp), e2->toChars(), Token::toChars(op)); 5137 } 5138 else 5139 { 5140 error("incompatible types for ((%s) %s (%s)): '%s' and '%s'", 5141 e1->toChars(), Token::toChars(thisOp), e2->toChars(), 5142 e1->type->toChars(), e2->type->toChars()); 5143 } 5144 return new ErrorExp(); 5145 } 5146 5147 bool BinExp::checkIntegralBin() 5148 { 5149 bool r1 = e1->checkIntegral(); 5150 bool r2 = e2->checkIntegral(); 5151 return (r1 || r2); 5152 } 5153 5154 bool BinExp::checkArithmeticBin() 5155 { 5156 bool r1 = e1->checkArithmetic(); 5157 bool r2 = e2->checkArithmetic(); 5158 return (r1 || r2); 5159 } 5160 5161 /********************** BinAssignExp **************************************/ 5162 5163 BinAssignExp::BinAssignExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2) 5164 : BinExp(loc, op, size, e1, e2) 5165 { 5166 } 5167 5168 bool BinAssignExp::isLvalue() 5169 { 5170 return true; 5171 } 5172 5173 Expression *BinAssignExp::toLvalue(Scope *, Expression *) 5174 { 5175 // Lvalue-ness will be handled in glue layer. 5176 return this; 5177 } 5178 5179 Expression *BinAssignExp::modifiableLvalue(Scope *sc, Expression *) 5180 { 5181 // should check e1->checkModifiable() ? 5182 return toLvalue(sc, this); 5183 } 5184 5185 /************************************************************/ 5186 5187 CompileExp::CompileExp(Loc loc, Expression *e) 5188 : UnaExp(loc, TOKmixin, sizeof(CompileExp), e) 5189 { 5190 } 5191 5192 /************************************************************/ 5193 5194 ImportExp::ImportExp(Loc loc, Expression *e) 5195 : UnaExp(loc, TOKimport, sizeof(ImportExp), e) 5196 { 5197 } 5198 5199 /************************************************************/ 5200 5201 AssertExp::AssertExp(Loc loc, Expression *e, Expression *msg) 5202 : UnaExp(loc, TOKassert, sizeof(AssertExp), e) 5203 { 5204 this->msg = msg; 5205 } 5206 5207 Expression *AssertExp::syntaxCopy() 5208 { 5209 return new AssertExp(loc, e1->syntaxCopy(), msg ? msg->syntaxCopy() : NULL); 5210 } 5211 5212 /************************************************************/ 5213 5214 DotIdExp::DotIdExp(Loc loc, Expression *e, Identifier *ident) 5215 : UnaExp(loc, TOKdotid, sizeof(DotIdExp), e) 5216 { 5217 this->ident = ident; 5218 this->wantsym = false; 5219 this->noderef = false; 5220 } 5221 5222 DotIdExp *DotIdExp::create(Loc loc, Expression *e, Identifier *ident) 5223 { 5224 return new DotIdExp(loc, e, ident); 5225 } 5226 5227 /********************** DotTemplateExp ***********************************/ 5228 5229 // Mainly just a placeholder 5230 5231 DotTemplateExp::DotTemplateExp(Loc loc, Expression *e, TemplateDeclaration *td) 5232 : UnaExp(loc, TOKdottd, sizeof(DotTemplateExp), e) 5233 5234 { 5235 this->td = td; 5236 } 5237 5238 /************************************************************/ 5239 5240 DotVarExp::DotVarExp(Loc loc, Expression *e, Declaration *var, bool hasOverloads) 5241 : UnaExp(loc, TOKdotvar, sizeof(DotVarExp), e) 5242 { 5243 //printf("DotVarExp()\n"); 5244 this->var = var; 5245 this->hasOverloads = var->isVarDeclaration() ? false : hasOverloads; 5246 } 5247 5248 bool DotVarExp::isLvalue() 5249 { 5250 return true; 5251 } 5252 5253 Expression *DotVarExp::toLvalue(Scope *, Expression *) 5254 { 5255 //printf("DotVarExp::toLvalue(%s)\n", toChars()); 5256 return this; 5257 } 5258 5259 /*********************************************** 5260 * Mark variable v as modified if it is inside a constructor that var 5261 * is a field in. 5262 */ 5263 int modifyFieldVar(Loc loc, Scope *sc, VarDeclaration *var, Expression *e1) 5264 { 5265 //printf("modifyFieldVar(var = %s)\n", var->toChars()); 5266 Dsymbol *s = sc->func; 5267 while (1) 5268 { 5269 FuncDeclaration *fd = NULL; 5270 if (s) 5271 fd = s->isFuncDeclaration(); 5272 if (fd && 5273 ((fd->isCtorDeclaration() && var->isField()) || 5274 (fd->isStaticCtorDeclaration() && !var->isField())) && 5275 fd->toParent2() == var->toParent2() && 5276 (!e1 || e1->op == TOKthis) 5277 ) 5278 { 5279 bool result = true; 5280 5281 var->ctorinit = true; 5282 //printf("setting ctorinit\n"); 5283 5284 if (var->isField() && sc->fieldinit && !sc->intypeof) 5285 { 5286 assert(e1); 5287 bool mustInit = ((var->storage_class & STCnodefaultctor) != 0 || 5288 var->type->needsNested()); 5289 5290 size_t dim = sc->fieldinit_dim; 5291 AggregateDeclaration *ad = fd->isMember2(); 5292 assert(ad); 5293 size_t i; 5294 for (i = 0; i < dim; i++) // same as findFieldIndexByName in ctfeexp.c ? 5295 { 5296 if (ad->fields[i] == var) 5297 break; 5298 } 5299 assert(i < dim); 5300 unsigned fi = sc->fieldinit[i]; 5301 5302 if (fi & CSXthis_ctor) 5303 { 5304 if (var->type->isMutable() && e1->type->isMutable()) 5305 result = false; 5306 else 5307 { 5308 const char *modStr = !var->type->isMutable() ? MODtoChars(var->type->mod) : MODtoChars(e1->type->mod); 5309 ::error(loc, "%s field '%s' initialized multiple times", modStr, var->toChars()); 5310 } 5311 } 5312 else if (sc->noctor || (fi & CSXlabel)) 5313 { 5314 if (!mustInit && var->type->isMutable() && e1->type->isMutable()) 5315 result = false; 5316 else 5317 { 5318 const char *modStr = !var->type->isMutable() ? MODtoChars(var->type->mod) : MODtoChars(e1->type->mod); 5319 ::error(loc, "%s field '%s' initialization is not allowed in loops or after labels", modStr, var->toChars()); 5320 } 5321 } 5322 sc->fieldinit[i] |= CSXthis_ctor; 5323 if (var->overlapped) // Bugzilla 15258 5324 { 5325 for (size_t j = 0; j < ad->fields.dim; j++) 5326 { 5327 VarDeclaration *v = ad->fields[j]; 5328 if (v == var || !var->isOverlappedWith(v)) 5329 continue; 5330 v->ctorinit = true; 5331 sc->fieldinit[j] = CSXthis_ctor; 5332 } 5333 } 5334 } 5335 else if (fd != sc->func) 5336 { 5337 if (var->type->isMutable()) 5338 result = false; 5339 else if (sc->func->fes) 5340 { 5341 const char *p = var->isField() ? "field" : var->kind(); 5342 ::error(loc, "%s %s '%s' initialization is not allowed in foreach loop", 5343 MODtoChars(var->type->mod), p, var->toChars()); 5344 } 5345 else 5346 { 5347 const char *p = var->isField() ? "field" : var->kind(); 5348 ::error(loc, "%s %s '%s' initialization is not allowed in nested function '%s'", 5349 MODtoChars(var->type->mod), p, var->toChars(), sc->func->toChars()); 5350 } 5351 } 5352 return result; 5353 } 5354 else 5355 { 5356 if (s) 5357 { 5358 s = s->toParent2(); 5359 continue; 5360 } 5361 } 5362 break; 5363 } 5364 return false; 5365 } 5366 5367 int DotVarExp::checkModifiable(Scope *sc, int flag) 5368 { 5369 //printf("DotVarExp::checkModifiable %s %s\n", toChars(), type->toChars()); 5370 if (checkUnsafeAccess(sc, this, false, !flag)) 5371 return 2; 5372 5373 if (e1->op == TOKthis) 5374 return var->checkModify(loc, sc, type, e1, flag); 5375 5376 //printf("\te1 = %s\n", e1->toChars()); 5377 return e1->checkModifiable(sc, flag); 5378 } 5379 5380 Expression *DotVarExp::modifiableLvalue(Scope *sc, Expression *e) 5381 { 5382 return Expression::modifiableLvalue(sc, e); 5383 } 5384 5385 /************************************************************/ 5386 5387 /* Things like: 5388 * foo.bar!(args) 5389 */ 5390 5391 DotTemplateInstanceExp::DotTemplateInstanceExp(Loc loc, Expression *e, Identifier *name, Objects *tiargs) 5392 : UnaExp(loc, TOKdotti, sizeof(DotTemplateInstanceExp), e) 5393 { 5394 //printf("DotTemplateInstanceExp()\n"); 5395 this->ti = new TemplateInstance(loc, name); 5396 this->ti->tiargs = tiargs; 5397 } 5398 5399 DotTemplateInstanceExp::DotTemplateInstanceExp(Loc loc, Expression *e, TemplateInstance *ti) 5400 : UnaExp(loc, TOKdotti, sizeof(DotTemplateInstanceExp), e) 5401 { 5402 this->ti = ti; 5403 } 5404 5405 Expression *DotTemplateInstanceExp::syntaxCopy() 5406 { 5407 return new DotTemplateInstanceExp(loc, 5408 e1->syntaxCopy(), 5409 ti->name, 5410 TemplateInstance::arraySyntaxCopy(ti->tiargs)); 5411 } 5412 5413 bool DotTemplateInstanceExp::findTempDecl(Scope *sc) 5414 { 5415 if (ti->tempdecl) 5416 return true; 5417 5418 Expression *e = new DotIdExp(loc, e1, ti->name); 5419 e = semantic(e, sc); 5420 if (e->op == TOKdot) 5421 e = ((DotExp *)e)->e2; 5422 5423 Dsymbol *s = NULL; 5424 switch (e->op) 5425 { 5426 case TOKoverloadset: s = ((OverExp *)e)->vars; break; 5427 case TOKdottd: s = ((DotTemplateExp *)e)->td; break; 5428 case TOKscope: s = ((ScopeExp *)e)->sds; break; 5429 case TOKdotvar: s = ((DotVarExp *)e)->var; break; 5430 case TOKvar: s = ((VarExp *)e)->var; break; 5431 default: return false; 5432 } 5433 return ti->updateTempDecl(sc, s); 5434 } 5435 5436 /************************************************************/ 5437 5438 DelegateExp::DelegateExp(Loc loc, Expression *e, FuncDeclaration *f, bool hasOverloads) 5439 : UnaExp(loc, TOKdelegate, sizeof(DelegateExp), e) 5440 { 5441 this->func = f; 5442 this->hasOverloads = hasOverloads; 5443 } 5444 5445 /************************************************************/ 5446 5447 DotTypeExp::DotTypeExp(Loc loc, Expression *e, Dsymbol *s) 5448 : UnaExp(loc, TOKdottype, sizeof(DotTypeExp), e) 5449 { 5450 this->sym = s; 5451 this->type = NULL; 5452 } 5453 5454 /************************************************************/ 5455 5456 CallExp::CallExp(Loc loc, Expression *e, Expressions *exps) 5457 : UnaExp(loc, TOKcall, sizeof(CallExp), e) 5458 { 5459 this->arguments = exps; 5460 this->f = NULL; 5461 this->directcall = false; 5462 } 5463 5464 CallExp::CallExp(Loc loc, Expression *e) 5465 : UnaExp(loc, TOKcall, sizeof(CallExp), e) 5466 { 5467 this->arguments = NULL; 5468 this->f = NULL; 5469 this->directcall = false; 5470 } 5471 5472 CallExp::CallExp(Loc loc, Expression *e, Expression *earg1) 5473 : UnaExp(loc, TOKcall, sizeof(CallExp), e) 5474 { 5475 Expressions *arguments = new Expressions(); 5476 if (earg1) 5477 { 5478 arguments->setDim(1); 5479 (*arguments)[0] = earg1; 5480 } 5481 this->arguments = arguments; 5482 this->f = NULL; 5483 this->directcall = false; 5484 } 5485 5486 CallExp::CallExp(Loc loc, Expression *e, Expression *earg1, Expression *earg2) 5487 : UnaExp(loc, TOKcall, sizeof(CallExp), e) 5488 { 5489 Expressions *arguments = new Expressions(); 5490 arguments->setDim(2); 5491 (*arguments)[0] = earg1; 5492 (*arguments)[1] = earg2; 5493 5494 this->arguments = arguments; 5495 this->f = NULL; 5496 this->directcall = false; 5497 } 5498 5499 CallExp *CallExp::create(Loc loc, Expression *e, Expressions *exps) 5500 { 5501 return new CallExp(loc, e, exps); 5502 } 5503 5504 CallExp *CallExp::create(Loc loc, Expression *e) 5505 { 5506 return new CallExp(loc, e); 5507 } 5508 5509 CallExp *CallExp::create(Loc loc, Expression *e, Expression *earg1) 5510 { 5511 return new CallExp(loc, e, earg1); 5512 } 5513 5514 Expression *CallExp::syntaxCopy() 5515 { 5516 return new CallExp(loc, e1->syntaxCopy(), arraySyntaxCopy(arguments)); 5517 } 5518 5519 bool CallExp::isLvalue() 5520 { 5521 Type *tb = e1->type->toBasetype(); 5522 if (tb->ty == Tdelegate || tb->ty == Tpointer) 5523 tb = tb->nextOf(); 5524 if (tb->ty == Tfunction && ((TypeFunction *)tb)->isref) 5525 { 5526 if (e1->op == TOKdotvar) 5527 if (((DotVarExp *)e1)->var->isCtorDeclaration()) 5528 return false; 5529 return true; // function returns a reference 5530 } 5531 return false; 5532 } 5533 5534 Expression *CallExp::toLvalue(Scope *sc, Expression *e) 5535 { 5536 if (isLvalue()) 5537 return this; 5538 return Expression::toLvalue(sc, e); 5539 } 5540 5541 Expression *CallExp::addDtorHook(Scope *sc) 5542 { 5543 /* Only need to add dtor hook if it's a type that needs destruction. 5544 * Use same logic as VarDeclaration::callScopeDtor() 5545 */ 5546 5547 if (e1->type && e1->type->ty == Tfunction) 5548 { 5549 TypeFunction *tf = (TypeFunction *)e1->type; 5550 if (tf->isref) 5551 return this; 5552 } 5553 5554 Type *tv = type->baseElemOf(); 5555 if (tv->ty == Tstruct) 5556 { 5557 TypeStruct *ts = (TypeStruct *)tv; 5558 StructDeclaration *sd = ts->sym; 5559 if (sd->dtor) 5560 { 5561 /* Type needs destruction, so declare a tmp 5562 * which the back end will recognize and call dtor on 5563 */ 5564 VarDeclaration *tmp = copyToTemp(0, "__tmpfordtor", this); 5565 DeclarationExp *de = new DeclarationExp(loc, tmp); 5566 VarExp *ve = new VarExp(loc, tmp); 5567 Expression *e = new CommaExp(loc, de, ve); 5568 e = semantic(e, sc); 5569 return e; 5570 } 5571 } 5572 return this; 5573 } 5574 5575 FuncDeclaration *isFuncAddress(Expression *e, bool *hasOverloads = NULL) 5576 { 5577 if (e->op == TOKaddress) 5578 { 5579 Expression *ae1 = ((AddrExp *)e)->e1; 5580 if (ae1->op == TOKvar) 5581 { 5582 VarExp *ve = (VarExp *)ae1; 5583 if (hasOverloads) 5584 *hasOverloads = ve->hasOverloads; 5585 return ve->var->isFuncDeclaration(); 5586 } 5587 if (ae1->op == TOKdotvar) 5588 { 5589 DotVarExp *dve = (DotVarExp *)ae1; 5590 if (hasOverloads) 5591 *hasOverloads = dve->hasOverloads; 5592 return dve->var->isFuncDeclaration(); 5593 } 5594 } 5595 else 5596 { 5597 if (e->op == TOKsymoff) 5598 { 5599 SymOffExp *soe = (SymOffExp *)e; 5600 if (hasOverloads) 5601 *hasOverloads = soe->hasOverloads; 5602 return soe->var->isFuncDeclaration(); 5603 } 5604 if (e->op == TOKdelegate) 5605 { 5606 DelegateExp *dge = (DelegateExp *)e; 5607 if (hasOverloads) 5608 *hasOverloads = dge->hasOverloads; 5609 return dge->func->isFuncDeclaration(); 5610 } 5611 } 5612 return NULL; 5613 } 5614 5615 /************************************************************/ 5616 5617 AddrExp::AddrExp(Loc loc, Expression *e) 5618 : UnaExp(loc, TOKaddress, sizeof(AddrExp), e) 5619 { 5620 } 5621 5622 AddrExp::AddrExp(Loc loc, Expression *e, Type *t) 5623 : UnaExp(loc, TOKaddress, sizeof(AddrExp), e) 5624 { 5625 type = t; 5626 } 5627 5628 /************************************************************/ 5629 5630 PtrExp::PtrExp(Loc loc, Expression *e) 5631 : UnaExp(loc, TOKstar, sizeof(PtrExp), e) 5632 { 5633 // if (e->type) 5634 // type = ((TypePointer *)e->type)->next; 5635 } 5636 5637 PtrExp::PtrExp(Loc loc, Expression *e, Type *t) 5638 : UnaExp(loc, TOKstar, sizeof(PtrExp), e) 5639 { 5640 type = t; 5641 } 5642 5643 bool PtrExp::isLvalue() 5644 { 5645 return true; 5646 } 5647 5648 Expression *PtrExp::toLvalue(Scope *, Expression *) 5649 { 5650 return this; 5651 } 5652 5653 int PtrExp::checkModifiable(Scope *sc, int flag) 5654 { 5655 if (e1->op == TOKsymoff) 5656 { SymOffExp *se = (SymOffExp *)e1; 5657 return se->var->checkModify(loc, sc, type, NULL, flag); 5658 } 5659 else if (e1->op == TOKaddress) 5660 { 5661 AddrExp *ae = (AddrExp *)e1; 5662 return ae->e1->checkModifiable(sc, flag); 5663 } 5664 return 1; 5665 } 5666 5667 Expression *PtrExp::modifiableLvalue(Scope *sc, Expression *e) 5668 { 5669 //printf("PtrExp::modifiableLvalue() %s, type %s\n", toChars(), type->toChars()); 5670 return Expression::modifiableLvalue(sc, e); 5671 } 5672 5673 /************************************************************/ 5674 5675 NegExp::NegExp(Loc loc, Expression *e) 5676 : UnaExp(loc, TOKneg, sizeof(NegExp), e) 5677 { 5678 } 5679 5680 /************************************************************/ 5681 5682 UAddExp::UAddExp(Loc loc, Expression *e) 5683 : UnaExp(loc, TOKuadd, sizeof(UAddExp), e) 5684 { 5685 } 5686 5687 /************************************************************/ 5688 5689 ComExp::ComExp(Loc loc, Expression *e) 5690 : UnaExp(loc, TOKtilde, sizeof(ComExp), e) 5691 { 5692 } 5693 5694 /************************************************************/ 5695 5696 NotExp::NotExp(Loc loc, Expression *e) 5697 : UnaExp(loc, TOKnot, sizeof(NotExp), e) 5698 { 5699 } 5700 5701 /************************************************************/ 5702 5703 DeleteExp::DeleteExp(Loc loc, Expression *e, bool isRAII) 5704 : UnaExp(loc, TOKdelete, sizeof(DeleteExp), e) 5705 { 5706 this->isRAII = isRAII; 5707 } 5708 5709 Expression *DeleteExp::toBoolean(Scope *) 5710 { 5711 error("delete does not give a boolean result"); 5712 return new ErrorExp(); 5713 } 5714 5715 /************************************************************/ 5716 5717 CastExp::CastExp(Loc loc, Expression *e, Type *t) 5718 : UnaExp(loc, TOKcast, sizeof(CastExp), e) 5719 { 5720 this->to = t; 5721 this->mod = (unsigned char)~0; 5722 } 5723 5724 /* For cast(const) and cast(immutable) 5725 */ 5726 CastExp::CastExp(Loc loc, Expression *e, unsigned char mod) 5727 : UnaExp(loc, TOKcast, sizeof(CastExp), e) 5728 { 5729 this->to = NULL; 5730 this->mod = mod; 5731 } 5732 5733 Expression *CastExp::syntaxCopy() 5734 { 5735 return to ? new CastExp(loc, e1->syntaxCopy(), to->syntaxCopy()) 5736 : new CastExp(loc, e1->syntaxCopy(), mod); 5737 } 5738 5739 /************************************************************/ 5740 5741 VectorExp::VectorExp(Loc loc, Expression *e, Type *t) 5742 : UnaExp(loc, TOKvector, sizeof(VectorExp), e) 5743 { 5744 assert(t->ty == Tvector); 5745 to = (TypeVector *)t; 5746 dim = ~0; 5747 ownedByCtfe = OWNEDcode; 5748 } 5749 5750 VectorExp *VectorExp::create(Loc loc, Expression *e, Type *t) 5751 { 5752 return new VectorExp(loc, e, t); 5753 } 5754 5755 Expression *VectorExp::syntaxCopy() 5756 { 5757 return new VectorExp(loc, e1->syntaxCopy(), to->syntaxCopy()); 5758 } 5759 5760 /************************************************************/ 5761 5762 VectorArrayExp::VectorArrayExp(Loc loc, Expression *e1) 5763 : UnaExp(loc, TOKvectorarray, sizeof(VectorExp), e1) 5764 { 5765 } 5766 5767 bool VectorArrayExp::isLvalue() 5768 { 5769 return e1->isLvalue(); 5770 } 5771 5772 Expression *VectorArrayExp::toLvalue(Scope *sc, Expression *e) 5773 { 5774 e1 = e1->toLvalue(sc, e); 5775 return this; 5776 } 5777 5778 /************************************************************/ 5779 5780 SliceExp::SliceExp(Loc loc, Expression *e1, IntervalExp *ie) 5781 : UnaExp(loc, TOKslice, sizeof(SliceExp), e1) 5782 { 5783 this->upr = ie ? ie->upr : NULL; 5784 this->lwr = ie ? ie->lwr : NULL; 5785 lengthVar = NULL; 5786 upperIsInBounds = false; 5787 lowerIsLessThanUpper = false; 5788 arrayop = false; 5789 } 5790 5791 SliceExp::SliceExp(Loc loc, Expression *e1, Expression *lwr, Expression *upr) 5792 : UnaExp(loc, TOKslice, sizeof(SliceExp), e1) 5793 { 5794 this->upr = upr; 5795 this->lwr = lwr; 5796 lengthVar = NULL; 5797 upperIsInBounds = false; 5798 lowerIsLessThanUpper = false; 5799 arrayop = false; 5800 } 5801 5802 Expression *SliceExp::syntaxCopy() 5803 { 5804 SliceExp *se = new SliceExp(loc, e1->syntaxCopy(), 5805 lwr ? lwr->syntaxCopy() : NULL, 5806 upr ? upr->syntaxCopy() : NULL); 5807 se->lengthVar = this->lengthVar; // bug7871 5808 return se; 5809 } 5810 5811 int SliceExp::checkModifiable(Scope *sc, int flag) 5812 { 5813 //printf("SliceExp::checkModifiable %s\n", toChars()); 5814 if (e1->type->ty == Tsarray || 5815 (e1->op == TOKindex && e1->type->ty != Tarray) || 5816 e1->op == TOKslice) 5817 { 5818 return e1->checkModifiable(sc, flag); 5819 } 5820 return 1; 5821 } 5822 5823 bool SliceExp::isLvalue() 5824 { 5825 /* slice expression is rvalue in default, but 5826 * conversion to reference of static array is only allowed. 5827 */ 5828 return (type && type->toBasetype()->ty == Tsarray); 5829 } 5830 5831 Expression *SliceExp::toLvalue(Scope *sc, Expression *e) 5832 { 5833 //printf("SliceExp::toLvalue(%s) type = %s\n", toChars(), type ? type->toChars() : NULL); 5834 return (type && type->toBasetype()->ty == Tsarray) 5835 ? this : Expression::toLvalue(sc, e); 5836 } 5837 5838 Expression *SliceExp::modifiableLvalue(Scope *, Expression *) 5839 { 5840 error("slice expression %s is not a modifiable lvalue", toChars()); 5841 return this; 5842 } 5843 5844 bool SliceExp::isBool(bool result) 5845 { 5846 return e1->isBool(result); 5847 } 5848 5849 /********************** ArrayLength **************************************/ 5850 5851 ArrayLengthExp::ArrayLengthExp(Loc loc, Expression *e1) 5852 : UnaExp(loc, TOKarraylength, sizeof(ArrayLengthExp), e1) 5853 { 5854 } 5855 5856 Expression *opAssignToOp(Loc loc, TOK op, Expression *e1, Expression *e2) 5857 { Expression *e; 5858 5859 switch (op) 5860 { 5861 case TOKaddass: e = new AddExp(loc, e1, e2); break; 5862 case TOKminass: e = new MinExp(loc, e1, e2); break; 5863 case TOKmulass: e = new MulExp(loc, e1, e2); break; 5864 case TOKdivass: e = new DivExp(loc, e1, e2); break; 5865 case TOKmodass: e = new ModExp(loc, e1, e2); break; 5866 case TOKandass: e = new AndExp(loc, e1, e2); break; 5867 case TOKorass: e = new OrExp (loc, e1, e2); break; 5868 case TOKxorass: e = new XorExp(loc, e1, e2); break; 5869 case TOKshlass: e = new ShlExp(loc, e1, e2); break; 5870 case TOKshrass: e = new ShrExp(loc, e1, e2); break; 5871 case TOKushrass: e = new UshrExp(loc, e1, e2); break; 5872 default: assert(0); 5873 } 5874 return e; 5875 } 5876 5877 /********************* 5878 * Rewrite: 5879 * array.length op= e2 5880 * as: 5881 * array.length = array.length op e2 5882 * or: 5883 * auto tmp = &array; 5884 * (*tmp).length = (*tmp).length op e2 5885 */ 5886 5887 Expression *ArrayLengthExp::rewriteOpAssign(BinExp *exp) 5888 { 5889 Expression *e; 5890 5891 assert(exp->e1->op == TOKarraylength); 5892 ArrayLengthExp *ale = (ArrayLengthExp *)exp->e1; 5893 if (ale->e1->op == TOKvar) 5894 { 5895 e = opAssignToOp(exp->loc, exp->op, ale, exp->e2); 5896 e = new AssignExp(exp->loc, ale->syntaxCopy(), e); 5897 } 5898 else 5899 { 5900 /* auto tmp = &array; 5901 * (*tmp).length = (*tmp).length op e2 5902 */ 5903 VarDeclaration *tmp = copyToTemp(0, "__arraylength", new AddrExp(ale->loc, ale->e1)); 5904 5905 Expression *e1 = new ArrayLengthExp(ale->loc, new PtrExp(ale->loc, new VarExp(ale->loc, tmp))); 5906 Expression *elvalue = e1->syntaxCopy(); 5907 e = opAssignToOp(exp->loc, exp->op, e1, exp->e2); 5908 e = new AssignExp(exp->loc, elvalue, e); 5909 e = new CommaExp(exp->loc, new DeclarationExp(ale->loc, tmp), e); 5910 } 5911 return e; 5912 } 5913 5914 /*********************** IntervalExp ********************************/ 5915 5916 // Mainly just a placeholder 5917 5918 IntervalExp::IntervalExp(Loc loc, Expression *lwr, Expression *upr) 5919 : Expression(loc, TOKinterval, sizeof(IntervalExp)) 5920 { 5921 this->lwr = lwr; 5922 this->upr = upr; 5923 } 5924 5925 Expression *IntervalExp::syntaxCopy() 5926 { 5927 return new IntervalExp(loc, lwr->syntaxCopy(), upr->syntaxCopy()); 5928 } 5929 5930 /********************** DelegatePtrExp **************************************/ 5931 5932 DelegatePtrExp::DelegatePtrExp(Loc loc, Expression *e1) 5933 : UnaExp(loc, TOKdelegateptr, sizeof(DelegatePtrExp), e1) 5934 { 5935 } 5936 5937 bool DelegatePtrExp::isLvalue() 5938 { 5939 return e1->isLvalue(); 5940 } 5941 5942 Expression *DelegatePtrExp::toLvalue(Scope *sc, Expression *e) 5943 { 5944 e1 = e1->toLvalue(sc, e); 5945 return this; 5946 } 5947 5948 Expression *DelegatePtrExp::modifiableLvalue(Scope *sc, Expression *e) 5949 { 5950 if (sc->func->setUnsafe()) 5951 { 5952 error("cannot modify delegate pointer in @safe code %s", toChars()); 5953 return new ErrorExp(); 5954 } 5955 return Expression::modifiableLvalue(sc, e); 5956 } 5957 5958 /********************** DelegateFuncptrExp **************************************/ 5959 5960 DelegateFuncptrExp::DelegateFuncptrExp(Loc loc, Expression *e1) 5961 : UnaExp(loc, TOKdelegatefuncptr, sizeof(DelegateFuncptrExp), e1) 5962 { 5963 } 5964 5965 bool DelegateFuncptrExp::isLvalue() 5966 { 5967 return e1->isLvalue(); 5968 } 5969 5970 Expression *DelegateFuncptrExp::toLvalue(Scope *sc, Expression *e) 5971 { 5972 e1 = e1->toLvalue(sc, e); 5973 return this; 5974 } 5975 5976 Expression *DelegateFuncptrExp::modifiableLvalue(Scope *sc, Expression *e) 5977 { 5978 if (sc->func->setUnsafe()) 5979 { 5980 error("cannot modify delegate function pointer in @safe code %s", toChars()); 5981 return new ErrorExp(); 5982 } 5983 return Expression::modifiableLvalue(sc, e); 5984 } 5985 5986 /*********************** ArrayExp *************************************/ 5987 5988 // e1 [ i1, i2, i3, ... ] 5989 5990 ArrayExp::ArrayExp(Loc loc, Expression *e1, Expression *index) 5991 : UnaExp(loc, TOKarray, sizeof(ArrayExp), e1) 5992 { 5993 arguments = new Expressions(); 5994 if (index) 5995 arguments->push(index); 5996 lengthVar = NULL; 5997 currentDimension = 0; 5998 } 5999 6000 ArrayExp::ArrayExp(Loc loc, Expression *e1, Expressions *args) 6001 : UnaExp(loc, TOKarray, sizeof(ArrayExp), e1) 6002 { 6003 arguments = args; 6004 lengthVar = NULL; 6005 currentDimension = 0; 6006 } 6007 6008 Expression *ArrayExp::syntaxCopy() 6009 { 6010 ArrayExp *ae = new ArrayExp(loc, e1->syntaxCopy(), arraySyntaxCopy(arguments)); 6011 ae->lengthVar = this->lengthVar; // bug7871 6012 return ae; 6013 } 6014 6015 bool ArrayExp::isLvalue() 6016 { 6017 if (type && type->toBasetype()->ty == Tvoid) 6018 return false; 6019 return true; 6020 } 6021 6022 Expression *ArrayExp::toLvalue(Scope *, Expression *) 6023 { 6024 if (type && type->toBasetype()->ty == Tvoid) 6025 error("voids have no value"); 6026 return this; 6027 } 6028 6029 /************************* DotExp ***********************************/ 6030 6031 DotExp::DotExp(Loc loc, Expression *e1, Expression *e2) 6032 : BinExp(loc, TOKdot, sizeof(DotExp), e1, e2) 6033 { 6034 } 6035 6036 /************************* CommaExp ***********************************/ 6037 6038 CommaExp::CommaExp(Loc loc, Expression *e1, Expression *e2, bool generated) 6039 : BinExp(loc, TOKcomma, sizeof(CommaExp), e1, e2) 6040 { 6041 isGenerated = generated; 6042 allowCommaExp = generated; 6043 } 6044 6045 bool CommaExp::isLvalue() 6046 { 6047 return e2->isLvalue(); 6048 } 6049 6050 Expression *CommaExp::toLvalue(Scope *sc, Expression *) 6051 { 6052 e2 = e2->toLvalue(sc, NULL); 6053 return this; 6054 } 6055 6056 int CommaExp::checkModifiable(Scope *sc, int flag) 6057 { 6058 return e2->checkModifiable(sc, flag); 6059 } 6060 6061 Expression *CommaExp::modifiableLvalue(Scope *sc, Expression *e) 6062 { 6063 e2 = e2->modifiableLvalue(sc, e); 6064 return this; 6065 } 6066 6067 bool CommaExp::isBool(bool result) 6068 { 6069 return e2->isBool(result); 6070 } 6071 6072 Expression *CommaExp::toBoolean(Scope *sc) 6073 { 6074 Expression *ex2 = e2->toBoolean(sc); 6075 if (ex2->op == TOKerror) 6076 return ex2; 6077 e2 = ex2; 6078 type = e2->type; 6079 return this; 6080 } 6081 6082 Expression *CommaExp::addDtorHook(Scope *sc) 6083 { 6084 e2 = e2->addDtorHook(sc); 6085 return this; 6086 } 6087 6088 /************************** IndexExp **********************************/ 6089 6090 // e1 [ e2 ] 6091 6092 IndexExp::IndexExp(Loc loc, Expression *e1, Expression *e2) 6093 : BinExp(loc, TOKindex, sizeof(IndexExp), e1, e2) 6094 { 6095 //printf("IndexExp::IndexExp('%s')\n", toChars()); 6096 lengthVar = NULL; 6097 modifiable = false; // assume it is an rvalue 6098 indexIsInBounds = false; 6099 } 6100 6101 Expression *IndexExp::syntaxCopy() 6102 { 6103 IndexExp *ie = new IndexExp(loc, e1->syntaxCopy(), e2->syntaxCopy()); 6104 ie->lengthVar = this->lengthVar; // bug7871 6105 return ie; 6106 } 6107 6108 bool IndexExp::isLvalue() 6109 { 6110 return true; 6111 } 6112 6113 Expression *IndexExp::toLvalue(Scope *, Expression *) 6114 { 6115 return this; 6116 } 6117 6118 int IndexExp::checkModifiable(Scope *sc, int flag) 6119 { 6120 if (e1->type->ty == Tsarray || 6121 e1->type->ty == Taarray || 6122 (e1->op == TOKindex && e1->type->ty != Tarray) || 6123 e1->op == TOKslice) 6124 { 6125 return e1->checkModifiable(sc, flag); 6126 } 6127 return 1; 6128 } 6129 6130 Expression *IndexExp::modifiableLvalue(Scope *sc, Expression *e) 6131 { 6132 //printf("IndexExp::modifiableLvalue(%s)\n", toChars()); 6133 Expression *ex = markSettingAAElem(); 6134 if (ex->op == TOKerror) 6135 return ex; 6136 6137 return Expression::modifiableLvalue(sc, e); 6138 } 6139 6140 Expression *IndexExp::markSettingAAElem() 6141 { 6142 if (e1->type->toBasetype()->ty == Taarray) 6143 { 6144 Type *t2b = e2->type->toBasetype(); 6145 if (t2b->ty == Tarray && t2b->nextOf()->isMutable()) 6146 { 6147 error("associative arrays can only be assigned values with immutable keys, not %s", e2->type->toChars()); 6148 return new ErrorExp(); 6149 } 6150 modifiable = true; 6151 6152 if (e1->op == TOKindex) 6153 { 6154 Expression *ex = ((IndexExp *)e1)->markSettingAAElem(); 6155 if (ex->op == TOKerror) 6156 return ex; 6157 assert(ex == e1); 6158 } 6159 } 6160 return this; 6161 } 6162 6163 /************************* PostExp ***********************************/ 6164 6165 PostExp::PostExp(TOK op, Loc loc, Expression *e) 6166 : BinExp(loc, op, sizeof(PostExp), e, 6167 new IntegerExp(loc, 1, Type::tint32)) 6168 { 6169 } 6170 6171 /************************* PreExp ***********************************/ 6172 6173 PreExp::PreExp(TOK op, Loc loc, Expression *e) 6174 : UnaExp(loc, op, sizeof(PreExp), e) 6175 { 6176 } 6177 6178 /************************************************************/ 6179 6180 /* op can be TOKassign, TOKconstruct, or TOKblit */ 6181 6182 AssignExp::AssignExp(Loc loc, Expression *e1, Expression *e2) 6183 : BinExp(loc, TOKassign, sizeof(AssignExp), e1, e2) 6184 { 6185 memset = 0; 6186 } 6187 6188 bool AssignExp::isLvalue() 6189 { 6190 // Array-op 'x[] = y[]' should make an rvalue. 6191 // Setting array length 'x.length = v' should make an rvalue. 6192 if (e1->op == TOKslice || 6193 e1->op == TOKarraylength) 6194 { 6195 return false; 6196 } 6197 return true; 6198 } 6199 6200 Expression *AssignExp::toLvalue(Scope *sc, Expression *ex) 6201 { 6202 if (e1->op == TOKslice || 6203 e1->op == TOKarraylength) 6204 { 6205 return Expression::toLvalue(sc, ex); 6206 } 6207 6208 /* In front-end level, AssignExp should make an lvalue of e1. 6209 * Taking the address of e1 will be handled in low level layer, 6210 * so this function does nothing. 6211 */ 6212 return this; 6213 } 6214 6215 Expression *AssignExp::toBoolean(Scope *) 6216 { 6217 // Things like: 6218 // if (a = b) ... 6219 // are usually mistakes. 6220 6221 error("assignment cannot be used as a condition, perhaps == was meant?"); 6222 return new ErrorExp(); 6223 } 6224 6225 /************************************************************/ 6226 6227 ConstructExp::ConstructExp(Loc loc, Expression *e1, Expression *e2) 6228 : AssignExp(loc, e1, e2) 6229 { 6230 op = TOKconstruct; 6231 } 6232 6233 ConstructExp::ConstructExp(Loc loc, VarDeclaration *v, Expression *e2) 6234 : AssignExp(loc, new VarExp(loc, v), e2) 6235 { 6236 assert(v->type && e1->type); 6237 op = TOKconstruct; 6238 6239 if (v->storage_class & (STCref | STCout)) 6240 memset |= referenceInit; 6241 } 6242 6243 /************************************************************/ 6244 6245 BlitExp::BlitExp(Loc loc, Expression *e1, Expression *e2) 6246 : AssignExp(loc, e1, e2) 6247 { 6248 op = TOKblit; 6249 } 6250 6251 BlitExp::BlitExp(Loc loc, VarDeclaration *v, Expression *e2) 6252 : AssignExp(loc, new VarExp(loc, v), e2) 6253 { 6254 assert(v->type && e1->type); 6255 op = TOKblit; 6256 6257 if (v->storage_class & (STCref | STCout)) 6258 memset |= referenceInit; 6259 } 6260 6261 /************************************************************/ 6262 6263 AddAssignExp::AddAssignExp(Loc loc, Expression *e1, Expression *e2) 6264 : BinAssignExp(loc, TOKaddass, sizeof(AddAssignExp), e1, e2) 6265 { 6266 } 6267 6268 /************************************************************/ 6269 6270 MinAssignExp::MinAssignExp(Loc loc, Expression *e1, Expression *e2) 6271 : BinAssignExp(loc, TOKminass, sizeof(MinAssignExp), e1, e2) 6272 { 6273 } 6274 6275 /************************************************************/ 6276 6277 CatAssignExp::CatAssignExp(Loc loc, Expression *e1, Expression *e2) 6278 : BinAssignExp(loc, TOKcatass, sizeof(CatAssignExp), e1, e2) 6279 { 6280 } 6281 6282 /************************************************************/ 6283 6284 MulAssignExp::MulAssignExp(Loc loc, Expression *e1, Expression *e2) 6285 : BinAssignExp(loc, TOKmulass, sizeof(MulAssignExp), e1, e2) 6286 { 6287 } 6288 6289 /************************************************************/ 6290 6291 DivAssignExp::DivAssignExp(Loc loc, Expression *e1, Expression *e2) 6292 : BinAssignExp(loc, TOKdivass, sizeof(DivAssignExp), e1, e2) 6293 { 6294 } 6295 6296 /************************************************************/ 6297 6298 ModAssignExp::ModAssignExp(Loc loc, Expression *e1, Expression *e2) 6299 : BinAssignExp(loc, TOKmodass, sizeof(ModAssignExp), e1, e2) 6300 { 6301 } 6302 6303 /************************************************************/ 6304 6305 ShlAssignExp::ShlAssignExp(Loc loc, Expression *e1, Expression *e2) 6306 : BinAssignExp(loc, TOKshlass, sizeof(ShlAssignExp), e1, e2) 6307 { 6308 } 6309 6310 /************************************************************/ 6311 6312 ShrAssignExp::ShrAssignExp(Loc loc, Expression *e1, Expression *e2) 6313 : BinAssignExp(loc, TOKshrass, sizeof(ShrAssignExp), e1, e2) 6314 { 6315 } 6316 6317 /************************************************************/ 6318 6319 UshrAssignExp::UshrAssignExp(Loc loc, Expression *e1, Expression *e2) 6320 : BinAssignExp(loc, TOKushrass, sizeof(UshrAssignExp), e1, e2) 6321 { 6322 } 6323 6324 /************************************************************/ 6325 6326 AndAssignExp::AndAssignExp(Loc loc, Expression *e1, Expression *e2) 6327 : BinAssignExp(loc, TOKandass, sizeof(AndAssignExp), e1, e2) 6328 { 6329 } 6330 6331 /************************************************************/ 6332 6333 OrAssignExp::OrAssignExp(Loc loc, Expression *e1, Expression *e2) 6334 : BinAssignExp(loc, TOKorass, sizeof(OrAssignExp), e1, e2) 6335 { 6336 } 6337 6338 /************************************************************/ 6339 6340 XorAssignExp::XorAssignExp(Loc loc, Expression *e1, Expression *e2) 6341 : BinAssignExp(loc, TOKxorass, sizeof(XorAssignExp), e1, e2) 6342 { 6343 } 6344 6345 /***************** PowAssignExp *******************************************/ 6346 6347 PowAssignExp::PowAssignExp(Loc loc, Expression *e1, Expression *e2) 6348 : BinAssignExp(loc, TOKpowass, sizeof(PowAssignExp), e1, e2) 6349 { 6350 } 6351 6352 /************************* AddExp *****************************/ 6353 6354 AddExp::AddExp(Loc loc, Expression *e1, Expression *e2) 6355 : BinExp(loc, TOKadd, sizeof(AddExp), e1, e2) 6356 { 6357 } 6358 6359 /************************************************************/ 6360 6361 MinExp::MinExp(Loc loc, Expression *e1, Expression *e2) 6362 : BinExp(loc, TOKmin, sizeof(MinExp), e1, e2) 6363 { 6364 } 6365 6366 /************************* CatExp *****************************/ 6367 6368 CatExp::CatExp(Loc loc, Expression *e1, Expression *e2) 6369 : BinExp(loc, TOKcat, sizeof(CatExp), e1, e2) 6370 { 6371 } 6372 6373 /************************************************************/ 6374 6375 MulExp::MulExp(Loc loc, Expression *e1, Expression *e2) 6376 : BinExp(loc, TOKmul, sizeof(MulExp), e1, e2) 6377 { 6378 } 6379 6380 /************************************************************/ 6381 6382 DivExp::DivExp(Loc loc, Expression *e1, Expression *e2) 6383 : BinExp(loc, TOKdiv, sizeof(DivExp), e1, e2) 6384 { 6385 } 6386 6387 /************************************************************/ 6388 6389 ModExp::ModExp(Loc loc, Expression *e1, Expression *e2) 6390 : BinExp(loc, TOKmod, sizeof(ModExp), e1, e2) 6391 { 6392 } 6393 6394 /************************************************************/ 6395 6396 PowExp::PowExp(Loc loc, Expression *e1, Expression *e2) 6397 : BinExp(loc, TOKpow, sizeof(PowExp), e1, e2) 6398 { 6399 } 6400 6401 /************************************************************/ 6402 6403 ShlExp::ShlExp(Loc loc, Expression *e1, Expression *e2) 6404 : BinExp(loc, TOKshl, sizeof(ShlExp), e1, e2) 6405 { 6406 } 6407 6408 /************************************************************/ 6409 6410 ShrExp::ShrExp(Loc loc, Expression *e1, Expression *e2) 6411 : BinExp(loc, TOKshr, sizeof(ShrExp), e1, e2) 6412 { 6413 } 6414 6415 /************************************************************/ 6416 6417 UshrExp::UshrExp(Loc loc, Expression *e1, Expression *e2) 6418 : BinExp(loc, TOKushr, sizeof(UshrExp), e1, e2) 6419 { 6420 } 6421 6422 /************************************************************/ 6423 6424 AndExp::AndExp(Loc loc, Expression *e1, Expression *e2) 6425 : BinExp(loc, TOKand, sizeof(AndExp), e1, e2) 6426 { 6427 } 6428 6429 /************************************************************/ 6430 6431 OrExp::OrExp(Loc loc, Expression *e1, Expression *e2) 6432 : BinExp(loc, TOKor, sizeof(OrExp), e1, e2) 6433 { 6434 } 6435 6436 /************************************************************/ 6437 6438 XorExp::XorExp(Loc loc, Expression *e1, Expression *e2) 6439 : BinExp(loc, TOKxor, sizeof(XorExp), e1, e2) 6440 { 6441 } 6442 6443 /************************************************************/ 6444 6445 OrOrExp::OrOrExp(Loc loc, Expression *e1, Expression *e2) 6446 : BinExp(loc, TOKoror, sizeof(OrOrExp), e1, e2) 6447 { 6448 } 6449 6450 Expression *OrOrExp::toBoolean(Scope *sc) 6451 { 6452 Expression *ex2 = e2->toBoolean(sc); 6453 if (ex2->op == TOKerror) 6454 return ex2; 6455 e2 = ex2; 6456 return this; 6457 } 6458 6459 /************************************************************/ 6460 6461 AndAndExp::AndAndExp(Loc loc, Expression *e1, Expression *e2) 6462 : BinExp(loc, TOKandand, sizeof(AndAndExp), e1, e2) 6463 { 6464 } 6465 6466 Expression *AndAndExp::toBoolean(Scope *sc) 6467 { 6468 Expression *ex2 = e2->toBoolean(sc); 6469 if (ex2->op == TOKerror) 6470 return ex2; 6471 e2 = ex2; 6472 return this; 6473 } 6474 6475 /************************************************************/ 6476 6477 InExp::InExp(Loc loc, Expression *e1, Expression *e2) 6478 : BinExp(loc, TOKin, sizeof(InExp), e1, e2) 6479 { 6480 } 6481 6482 /************************************************************/ 6483 6484 /* This deletes the key e1 from the associative array e2 6485 */ 6486 6487 RemoveExp::RemoveExp(Loc loc, Expression *e1, Expression *e2) 6488 : BinExp(loc, TOKremove, sizeof(RemoveExp), e1, e2) 6489 { 6490 type = Type::tbool; 6491 } 6492 6493 /************************************************************/ 6494 6495 CmpExp::CmpExp(TOK op, Loc loc, Expression *e1, Expression *e2) 6496 : BinExp(loc, op, sizeof(CmpExp), e1, e2) 6497 { 6498 } 6499 6500 /************************************************************/ 6501 6502 EqualExp::EqualExp(TOK op, Loc loc, Expression *e1, Expression *e2) 6503 : BinExp(loc, op, sizeof(EqualExp), e1, e2) 6504 { 6505 assert(op == TOKequal || op == TOKnotequal); 6506 } 6507 6508 /************************************************************/ 6509 6510 IdentityExp::IdentityExp(TOK op, Loc loc, Expression *e1, Expression *e2) 6511 : BinExp(loc, op, sizeof(IdentityExp), e1, e2) 6512 { 6513 } 6514 6515 /****************************************************************/ 6516 6517 CondExp::CondExp(Loc loc, Expression *econd, Expression *e1, Expression *e2) 6518 : BinExp(loc, TOKquestion, sizeof(CondExp), e1, e2) 6519 { 6520 this->econd = econd; 6521 } 6522 6523 Expression *CondExp::syntaxCopy() 6524 { 6525 return new CondExp(loc, econd->syntaxCopy(), e1->syntaxCopy(), e2->syntaxCopy()); 6526 } 6527 6528 void CondExp::hookDtors(Scope *sc) 6529 { 6530 class DtorVisitor : public StoppableVisitor 6531 { 6532 public: 6533 Scope *sc; 6534 CondExp *ce; 6535 VarDeclaration *vcond; 6536 bool isThen; 6537 6538 DtorVisitor(Scope *sc, CondExp *ce) 6539 { 6540 this->sc = sc; 6541 this->ce = ce; 6542 this->vcond = NULL; 6543 } 6544 6545 void visit(Expression *) 6546 { 6547 //printf("(e = %s)\n", e->toChars()); 6548 } 6549 6550 void visit(DeclarationExp *e) 6551 { 6552 VarDeclaration *v = e->declaration->isVarDeclaration(); 6553 if (v && !v->isDataseg()) 6554 { 6555 if (v->_init) 6556 { 6557 ExpInitializer *ei = v->_init->isExpInitializer(); 6558 if (ei) 6559 ei->exp->accept(this); 6560 } 6561 6562 if (v->needsScopeDtor()) 6563 { 6564 if (!vcond) 6565 { 6566 vcond = copyToTemp(STCvolatile, "__cond", ce->econd); 6567 vcond->semantic(sc); 6568 6569 Expression *de = new DeclarationExp(ce->econd->loc, vcond); 6570 de = semantic(de, sc); 6571 6572 Expression *ve = new VarExp(ce->econd->loc, vcond); 6573 ce->econd = Expression::combine(de, ve); 6574 } 6575 6576 //printf("\t++v = %s, v->edtor = %s\n", v->toChars(), v->edtor->toChars()); 6577 Expression *ve = new VarExp(vcond->loc, vcond); 6578 if (isThen) 6579 v->edtor = new AndAndExp(v->edtor->loc, ve, v->edtor); 6580 else 6581 v->edtor = new OrOrExp(v->edtor->loc, ve, v->edtor); 6582 v->edtor = semantic(v->edtor, sc); 6583 //printf("\t--v = %s, v->edtor = %s\n", v->toChars(), v->edtor->toChars()); 6584 } 6585 } 6586 } 6587 }; 6588 6589 DtorVisitor v(sc, this); 6590 //printf("+%s\n", toChars()); 6591 v.isThen = true; walkPostorder(e1, &v); 6592 v.isThen = false; walkPostorder(e2, &v); 6593 //printf("-%s\n", toChars()); 6594 } 6595 6596 bool CondExp::isLvalue() 6597 { 6598 return e1->isLvalue() && e2->isLvalue(); 6599 } 6600 6601 6602 Expression *CondExp::toLvalue(Scope *sc, Expression *) 6603 { 6604 // convert (econd ? e1 : e2) to *(econd ? &e1 : &e2) 6605 CondExp *e = (CondExp *)copy(); 6606 e->e1 = e1->toLvalue(sc, NULL)->addressOf(); 6607 e->e2 = e2->toLvalue(sc, NULL)->addressOf(); 6608 e->type = type->pointerTo(); 6609 return new PtrExp(loc, e, type); 6610 } 6611 6612 int CondExp::checkModifiable(Scope *sc, int flag) 6613 { 6614 return e1->checkModifiable(sc, flag) && e2->checkModifiable(sc, flag); 6615 } 6616 6617 Expression *CondExp::modifiableLvalue(Scope *sc, Expression *) 6618 { 6619 //error("conditional expression %s is not a modifiable lvalue", toChars()); 6620 e1 = e1->modifiableLvalue(sc, e1); 6621 e2 = e2->modifiableLvalue(sc, e2); 6622 return toLvalue(sc, this); 6623 } 6624 6625 Expression *CondExp::toBoolean(Scope *sc) 6626 { 6627 Expression *ex1 = e1->toBoolean(sc); 6628 Expression *ex2 = e2->toBoolean(sc); 6629 if (ex1->op == TOKerror) 6630 return ex1; 6631 if (ex2->op == TOKerror) 6632 return ex2; 6633 e1 = ex1; 6634 e2 = ex2; 6635 return this; 6636 } 6637 6638 /****************************************************************/ 6639 6640 DefaultInitExp::DefaultInitExp(Loc loc, TOK subop, int size) 6641 : Expression(loc, TOKdefault, size) 6642 { 6643 this->subop = subop; 6644 } 6645 6646 /****************************************************************/ 6647 6648 FileInitExp::FileInitExp(Loc loc, TOK tok) 6649 : DefaultInitExp(loc, tok, sizeof(FileInitExp)) 6650 { 6651 } 6652 6653 Expression *FileInitExp::resolveLoc(Loc loc, Scope *sc) 6654 { 6655 //printf("FileInitExp::resolve() %s\n", toChars()); 6656 const char *s = loc.filename ? loc.filename : sc->_module->ident->toChars(); 6657 if (subop == TOKfilefullpath) 6658 s = FileName::combine(sc->_module->srcfilePath, s); 6659 Expression *e = new StringExp(loc, const_cast<char *>(s)); 6660 e = semantic(e, sc); 6661 e = e->castTo(sc, type); 6662 return e; 6663 } 6664 6665 /****************************************************************/ 6666 6667 LineInitExp::LineInitExp(Loc loc) 6668 : DefaultInitExp(loc, TOKline, sizeof(LineInitExp)) 6669 { 6670 } 6671 6672 Expression *LineInitExp::resolveLoc(Loc loc, Scope *sc) 6673 { 6674 Expression *e = new IntegerExp(loc, loc.linnum, Type::tint32); 6675 e = e->castTo(sc, type); 6676 return e; 6677 } 6678 6679 /****************************************************************/ 6680 6681 ModuleInitExp::ModuleInitExp(Loc loc) 6682 : DefaultInitExp(loc, TOKmodulestring, sizeof(ModuleInitExp)) 6683 { 6684 } 6685 6686 Expression *ModuleInitExp::resolveLoc(Loc loc, Scope *sc) 6687 { 6688 const char *s; 6689 if (sc->callsc) 6690 s = sc->callsc->_module->toPrettyChars(); 6691 else 6692 s = sc->_module->toPrettyChars(); 6693 Expression *e = new StringExp(loc, const_cast<char *>(s)); 6694 e = semantic(e, sc); 6695 e = e->castTo(sc, type); 6696 return e; 6697 } 6698 6699 /****************************************************************/ 6700 6701 FuncInitExp::FuncInitExp(Loc loc) 6702 : DefaultInitExp(loc, TOKfuncstring, sizeof(FuncInitExp)) 6703 { 6704 } 6705 6706 Expression *FuncInitExp::resolveLoc(Loc loc, Scope *sc) 6707 { 6708 const char *s; 6709 if (sc->callsc && sc->callsc->func) 6710 s = sc->callsc->func->Dsymbol::toPrettyChars(); 6711 else if (sc->func) 6712 s = sc->func->Dsymbol::toPrettyChars(); 6713 else 6714 s = ""; 6715 Expression *e = new StringExp(loc, const_cast<char *>(s)); 6716 e = semantic(e, sc); 6717 e = e->castTo(sc, type); 6718 return e; 6719 } 6720 6721 /****************************************************************/ 6722 6723 PrettyFuncInitExp::PrettyFuncInitExp(Loc loc) 6724 : DefaultInitExp(loc, TOKprettyfunc, sizeof(PrettyFuncInitExp)) 6725 { 6726 } 6727 6728 Expression *PrettyFuncInitExp::resolveLoc(Loc loc, Scope *sc) 6729 { 6730 FuncDeclaration *fd; 6731 if (sc->callsc && sc->callsc->func) 6732 fd = sc->callsc->func; 6733 else 6734 fd = sc->func; 6735 6736 const char *s; 6737 if (fd) 6738 { 6739 const char *funcStr = fd->Dsymbol::toPrettyChars(); 6740 OutBuffer buf; 6741 functionToBufferWithIdent((TypeFunction *)fd->type, &buf, funcStr); 6742 s = buf.extractString(); 6743 } 6744 else 6745 { 6746 s = ""; 6747 } 6748 6749 Expression *e = new StringExp(loc, const_cast<char *>(s)); 6750 e = semantic(e, sc); 6751 e = e->castTo(sc, type); 6752 return e; 6753 } 6754 6755 /****************************************************************/ 6756 6757 Expression *extractOpDollarSideEffect(Scope *sc, UnaExp *ue) 6758 { 6759 Expression *e0; 6760 Expression *e1 = Expression::extractLast(ue->e1, &e0); 6761 // Bugzilla 12585: Extract the side effect part if ue->e1 is comma. 6762 6763 if (!isTrivialExp(e1)) 6764 { 6765 /* Even if opDollar is needed, 'e1' should be evaluate only once. So 6766 * Rewrite: 6767 * e1.opIndex( ... use of $ ... ) 6768 * e1.opSlice( ... use of $ ... ) 6769 * as: 6770 * (ref __dop = e1, __dop).opIndex( ... __dop.opDollar ...) 6771 * (ref __dop = e1, __dop).opSlice( ... __dop.opDollar ...) 6772 */ 6773 e1 = extractSideEffect(sc, "__dop", &e0, e1, false); 6774 assert(e1->op == TOKvar); 6775 VarExp *ve = (VarExp *)e1; 6776 ve->var->storage_class |= STCexptemp; // lifetime limited to expression 6777 } 6778 ue->e1 = e1; 6779 return e0; 6780 } 6781 6782 /************************************** 6783 * Runs semantic on ae->arguments. Declares temporary variables 6784 * if '$' was used. 6785 */ 6786 Expression *resolveOpDollar(Scope *sc, ArrayExp *ae, Expression **pe0) 6787 { 6788 assert(!ae->lengthVar); 6789 6790 *pe0 = NULL; 6791 6792 AggregateDeclaration *ad = isAggregate(ae->e1->type); 6793 Dsymbol *slice = search_function(ad, Id::slice); 6794 //printf("slice = %s %s\n", slice->kind(), slice->toChars()); 6795 6796 for (size_t i = 0; i < ae->arguments->dim; i++) 6797 { 6798 if (i == 0) 6799 *pe0 = extractOpDollarSideEffect(sc, ae); 6800 6801 Expression *e = (*ae->arguments)[i]; 6802 if (e->op == TOKinterval && !(slice && slice->isTemplateDeclaration())) 6803 { 6804 Lfallback: 6805 if (ae->arguments->dim == 1) 6806 return NULL; 6807 ae->error("multi-dimensional slicing requires template opSlice"); 6808 return new ErrorExp(); 6809 } 6810 //printf("[%d] e = %s\n", i, e->toChars()); 6811 6812 // Create scope for '$' variable for this dimension 6813 ArrayScopeSymbol *sym = new ArrayScopeSymbol(sc, ae); 6814 sym->loc = ae->loc; 6815 sym->parent = sc->scopesym; 6816 sc = sc->push(sym); 6817 ae->lengthVar = NULL; // Create it only if required 6818 ae->currentDimension = i; // Dimension for $, if required 6819 6820 e = semantic(e, sc); 6821 e = resolveProperties(sc, e); 6822 6823 if (ae->lengthVar && sc->func) 6824 { 6825 // If $ was used, declare it now 6826 Expression *de = new DeclarationExp(ae->loc, ae->lengthVar); 6827 de = semantic(de, sc); 6828 *pe0 = Expression::combine(*pe0, de); 6829 } 6830 sc = sc->pop(); 6831 6832 if (e->op == TOKinterval) 6833 { 6834 IntervalExp *ie = (IntervalExp *)e; 6835 6836 Objects *tiargs = new Objects(); 6837 Expression *edim = new IntegerExp(ae->loc, i, Type::tsize_t); 6838 edim = semantic(edim, sc); 6839 tiargs->push(edim); 6840 6841 Expressions *fargs = new Expressions(); 6842 fargs->push(ie->lwr); 6843 fargs->push(ie->upr); 6844 6845 unsigned xerrors = global.startGagging(); 6846 sc = sc->push(); 6847 FuncDeclaration *fslice = resolveFuncCall(ae->loc, sc, slice, tiargs, ae->e1->type, fargs, 1); 6848 sc = sc->pop(); 6849 global.endGagging(xerrors); 6850 if (!fslice) 6851 goto Lfallback; 6852 6853 e = new DotTemplateInstanceExp(ae->loc, ae->e1, slice->ident, tiargs); 6854 e = new CallExp(ae->loc, e, fargs); 6855 e = semantic(e, sc); 6856 } 6857 6858 if (!e->type) 6859 { 6860 ae->error("%s has no value", e->toChars()); 6861 e = new ErrorExp(); 6862 } 6863 if (e->op == TOKerror) 6864 return e; 6865 6866 (*ae->arguments)[i] = e; 6867 } 6868 6869 return ae; 6870 } 6871 6872 /*********************************************************** 6873 * Resolve `exp` as a compile-time known string. 6874 * Params: 6875 * sc = scope 6876 * exp = Expression which expected as a string 6877 * s = What the string is expected for, will be used in error diagnostic. 6878 * Returns: 6879 * String literal, or `null` if error happens. 6880 */ 6881 StringExp *semanticString(Scope *sc, Expression *exp, const char *s) 6882 { 6883 sc = sc->startCTFE(); 6884 exp = semantic(exp, sc); 6885 exp = resolveProperties(sc, exp); 6886 sc = sc->endCTFE(); 6887 6888 if (exp->op == TOKerror) 6889 return NULL; 6890 6891 Expression *e = exp; 6892 if (exp->type->isString()) 6893 { 6894 e = e->ctfeInterpret(); 6895 if (e->op == TOKerror) 6896 return NULL; 6897 } 6898 6899 StringExp *se = e->toStringExp(); 6900 if (!se) 6901 { 6902 exp->error("string expected for %s, not (%s) of type %s", 6903 s, exp->toChars(), exp->type->toChars()); 6904 return NULL; 6905 } 6906 return se; 6907 } 6908 6909 /************************************** 6910 * Runs semantic on se->lwr and se->upr. Declares a temporary variable 6911 * if '$' was used. 6912 */ 6913 Expression *resolveOpDollar(Scope *sc, ArrayExp *ae, IntervalExp *ie, Expression **pe0) 6914 { 6915 //assert(!ae->lengthVar); 6916 if (!ie) 6917 return ae; 6918 6919 VarDeclaration *lengthVar = ae->lengthVar; 6920 6921 // create scope for '$' 6922 ArrayScopeSymbol *sym = new ArrayScopeSymbol(sc, ae); 6923 sym->loc = ae->loc; 6924 sym->parent = sc->scopesym; 6925 sc = sc->push(sym); 6926 6927 for (size_t i = 0; i < 2; ++i) 6928 { 6929 Expression *e = i == 0 ? ie->lwr : ie->upr; 6930 e = semantic(e, sc); 6931 e = resolveProperties(sc, e); 6932 if (!e->type) 6933 { 6934 ae->error("%s has no value", e->toChars()); 6935 return new ErrorExp(); 6936 } 6937 (i == 0 ? ie->lwr : ie->upr) = e; 6938 } 6939 6940 if (lengthVar != ae->lengthVar && sc->func) 6941 { 6942 // If $ was used, declare it now 6943 Expression *de = new DeclarationExp(ae->loc, ae->lengthVar); 6944 de = semantic(de, sc); 6945 *pe0 = Expression::combine(*pe0, de); 6946 } 6947 sc = sc->pop(); 6948 6949 return ae; 6950 } 6951 6952 Expression *BinExp::reorderSettingAAElem(Scope *sc) 6953 { 6954 BinExp *be = this; 6955 6956 if (be->e1->op != TOKindex) 6957 return be; 6958 IndexExp *ie = (IndexExp *)be->e1; 6959 if (ie->e1->type->toBasetype()->ty != Taarray) 6960 return be; 6961 6962 /* Fix evaluation order of setting AA element. (Bugzilla 3825) 6963 * Rewrite: 6964 * aa[k1][k2][k3] op= val; 6965 * as: 6966 * auto ref __aatmp = aa; 6967 * auto ref __aakey3 = k1, __aakey2 = k2, __aakey1 = k3; 6968 * auto ref __aaval = val; 6969 * __aatmp[__aakey3][__aakey2][__aakey1] op= __aaval; // assignment 6970 */ 6971 6972 Expression *e0 = NULL; 6973 while (1) 6974 { 6975 Expression *de = NULL; 6976 ie->e2 = extractSideEffect(sc, "__aakey", &de, ie->e2); 6977 e0 = Expression::combine(de, e0); 6978 6979 Expression *ie1 = ie->e1; 6980 if (ie1->op != TOKindex || 6981 ((IndexExp *)ie1)->e1->type->toBasetype()->ty != Taarray) 6982 { 6983 break; 6984 } 6985 ie = (IndexExp *)ie1; 6986 } 6987 assert(ie->e1->type->toBasetype()->ty == Taarray); 6988 6989 Expression *de = NULL; 6990 ie->e1 = extractSideEffect(sc, "__aatmp", &de, ie->e1); 6991 e0 = Expression::combine(de, e0); 6992 6993 be->e2 = extractSideEffect(sc, "__aaval", &e0, be->e2, true); 6994 6995 //printf("-e0 = %s, be = %s\n", e0->toChars(), be->toChars()); 6996 return Expression::combine(e0, be); 6997 } 6998