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 */ 9 10 #include "root/dsystem.h" 11 #include "root/rmem.h" 12 #include "root/root.h" 13 14 #include "mars.h" 15 #include "mangle.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 "nspace.h" 34 #include "ctfe.h" 35 #include "target.h" 36 37 bool typeMerge(Scope *sc, TOK op, Type **pt, Expression **pe1, Expression **pe2); 38 bool isArrayOpValid(Expression *e); 39 Expression *expandVar(int result, VarDeclaration *v); 40 TypeTuple *toArgTypes(Type *t); 41 bool checkAssignEscape(Scope *sc, Expression *e, bool gag); 42 bool checkParamArgumentEscape(Scope *sc, FuncDeclaration *fdc, Identifier *par, Expression *arg, bool gag); 43 bool checkAccess(AggregateDeclaration *ad, Loc loc, Scope *sc, Dsymbol *smember); 44 bool checkNestedRef(Dsymbol *s, Dsymbol *p); 45 bool checkFrameAccess(Loc loc, Scope *sc, AggregateDeclaration *ad, size_t istart = 0); 46 bool symbolIsVisible(Module *mod, Dsymbol *s); 47 VarDeclaration *copyToTemp(StorageClass stc, const char *name, Expression *e); 48 Expression *extractSideEffect(Scope *sc, const char *name, Expression **e0, Expression *e, bool alwaysCopy = false); 49 Type *getTypeInfoType(Loc loc, Type *t, Scope *sc); 50 bool MODimplicitConv(MOD modfrom, MOD modto); 51 MATCH MODmethodConv(MOD modfrom, MOD modto); 52 void MODMatchToBuffer(OutBuffer *buf, unsigned char lhsMod, unsigned char rhsMod); 53 54 void unSpeculative(Scope *sc, RootObject *o); 55 bool arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt); 56 bool checkDefCtor(Loc loc, Type *t); 57 bool isDotOpDispatch(Expression *e); 58 bool functionParameters(Loc loc, Scope *sc, TypeFunction *tf, Type *tthis, Expressions *arguments, FuncDeclaration *fd, Type **prettype, Expression **peprefix); 59 Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad, Expression *e1, Declaration *var, int flag = 0); 60 bool isNeedThisScope(Scope *sc, Declaration *d); 61 Expression *resolveUFCS(Scope *sc, CallExp *ce); 62 bool checkUnsafeAccess(Scope *sc, Expression *e, bool readonly, bool printmsg); 63 bool isSafeCast(Expression *e, Type *tfrom, Type *tto); 64 FuncDeclaration *isFuncAddress(Expression *e, bool *hasOverloads = NULL); 65 Expression *callCpCtor(Scope *sc, Expression *e); 66 67 Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads); 68 Expression *resolveUFCSProperties(Scope *sc, Expression *e1, Expression *e2 = NULL); 69 Expression *resolvePropertiesX(Scope *sc, Expression *e1, Expression *e2 = NULL); 70 Expression *trySemantic(Expression *e, Scope *sc); 71 Expression *unaSemantic(UnaExp *e, Scope *sc); 72 Expression *binSemantic(BinExp *e, Scope *sc); 73 Expression *binSemanticProp(BinExp *e, Scope *sc); 74 Expression *semantic(Expression *e, Scope *sc); 75 Expression *semanticY(DotIdExp *exp, Scope *sc, int flag); 76 Expression *semanticY(DotTemplateInstanceExp *exp, Scope *sc, int flag); 77 StringExp *semanticString(Scope *sc, Expression *exp, const char *s); 78 79 /**************************************** 80 * Preprocess arguments to function. 81 * Output: 82 * exps[] tuples expanded, properties resolved, rewritten in place 83 * Returns: 84 * true a semantic error occurred 85 */ 86 87 static bool preFunctionParameters(Scope *sc, Expressions *exps) 88 { 89 bool err = false; 90 if (exps) 91 { 92 expandTuples(exps); 93 94 for (size_t i = 0; i < exps->dim; i++) 95 { 96 Expression *arg = (*exps)[i]; 97 98 arg = resolveProperties(sc, arg); 99 if (arg->op == TOKtype) 100 { 101 arg->error("cannot pass type %s as a function argument", arg->toChars()); 102 arg = new ErrorExp(); 103 err = true; 104 } 105 else if (arg->type->toBasetype()->ty == Tfunction) 106 { 107 arg->error("cannot pass type %s as a function argument", arg->toChars()); 108 arg = new ErrorExp(); 109 err = true; 110 } 111 else if (checkNonAssignmentArrayOp(arg)) 112 { 113 arg = new ErrorExp(); 114 err = true; 115 } 116 (*exps)[i] = arg; 117 } 118 } 119 return err; 120 } 121 122 class ExpressionSemanticVisitor : public Visitor 123 { 124 public: 125 Expression *result; 126 Scope *sc; 127 128 ExpressionSemanticVisitor(Scope *sc) 129 { 130 this->result = NULL; 131 this->sc = sc; 132 } 133 134 private: 135 void setError() 136 { 137 result = new ErrorExp(); 138 } 139 140 /********************* 141 * Mark the operand as will never be dereferenced, 142 * which is useful info for @safe checks. 143 * Do before semantic() on operands rewrites them. 144 */ 145 static void setNoderefOperand(UnaExp *e) 146 { 147 if (e->e1->op == TOKdotid) 148 ((DotIdExp *)e->e1)->noderef = true; 149 } 150 151 /********************* 152 * Mark the operands as will never be dereferenced, 153 * which is useful info for @safe checks. 154 * Do before semantic() on operands rewrites them. 155 */ 156 static void setNoderefOperands(BinExp *e) 157 { 158 if (e->e1->op == TOKdotid) 159 ((DotIdExp *)e->e1)->noderef = true; 160 if (e->e2->op == TOKdotid) 161 ((DotIdExp *)e->e2)->noderef = true; 162 } 163 164 static FuncDeclaration *resolveOverloadSet(Loc loc, Scope *sc, 165 OverloadSet *os, Objects* tiargs, Type *tthis, Expressions *arguments) 166 { 167 FuncDeclaration *f = NULL; 168 for (size_t i = 0; i < os->a.dim; i++) 169 { 170 Dsymbol *s = os->a[i]; 171 if (tiargs && s->isFuncDeclaration()) 172 continue; 173 if (FuncDeclaration *f2 = resolveFuncCall(loc, sc, s, tiargs, tthis, arguments, 1)) 174 { 175 if (f2->errors) 176 return NULL; 177 if (f) 178 { 179 /* Error if match in more than one overload set, 180 * even if one is a 'better' match than the other. 181 */ 182 ScopeDsymbol::multiplyDefined(loc, f, f2); 183 } 184 else 185 f = f2; 186 } 187 } 188 if (!f) 189 ::error(loc, "no overload matches for %s", os->toChars()); 190 else if (f->errors) 191 f = NULL; 192 return f; 193 } 194 195 /**************************************************** 196 * Determine if `exp`, which takes the address of `v`, can do so safely. 197 * Params: 198 * sc = context 199 * exp = expression that takes the address of `v` 200 * v = the variable getting its address taken 201 * Returns: 202 * `true` if ok, `false` for error 203 */ 204 static bool checkAddressVar(Scope *sc, UnaExp *e, VarDeclaration *v) 205 { 206 if (v) 207 { 208 if (!v->canTakeAddressOf()) 209 { 210 e->error("cannot take address of %s", e->e1->toChars()); 211 return false; 212 } 213 if (sc->func && !sc->intypeof && !v->isDataseg()) 214 { 215 const char *p = v->isParameter() ? "parameter" : "local"; 216 if (global.params.vsafe) 217 { 218 // Taking the address of v means it cannot be set to 'scope' later 219 v->storage_class &= ~STCmaybescope; 220 v->doNotInferScope = true; 221 if (v->storage_class & STCscope && sc->func->setUnsafe()) 222 { 223 e->error("cannot take address of scope %s %s in @safe function %s", p, v->toChars(), sc->func->toChars()); 224 return false; 225 } 226 } 227 else if (sc->func->setUnsafe()) 228 { 229 e->error("cannot take address of %s %s in @safe function %s", p, v->toChars(), sc->func->toChars()); 230 return false; 231 } 232 } 233 } 234 return true; 235 } 236 237 static bool checkVectorElem(Expression *e, Expression *elem) 238 { 239 if (elem->isConst() == 1) 240 return false; 241 242 e->error("constant expression expected, not %s", elem->toChars()); 243 return true; 244 } 245 246 public: 247 void visit(Expression *e) 248 { 249 if (e->type) 250 e->type = e->type->semantic(e->loc, sc); 251 else 252 e->type = Type::tvoid; 253 result = e; 254 } 255 256 void visit(IntegerExp *e) 257 { 258 assert(e->type); 259 if (e->type->ty == Terror) 260 return setError(); 261 assert(e->type->deco); 262 e->normalize(); 263 result = e; 264 } 265 266 void visit(RealExp *e) 267 { 268 if (!e->type) 269 e->type = Type::tfloat64; 270 else 271 e->type = e->type->semantic(e->loc, sc); 272 result = e; 273 } 274 275 void visit(ComplexExp *e) 276 { 277 if (!e->type) 278 e->type = Type::tcomplex80; 279 else 280 e->type = e->type->semantic(e->loc, sc); 281 result = e; 282 } 283 284 void visit(IdentifierExp *exp) 285 { 286 if (exp->type) // This is used as the dummy expression 287 { 288 result = exp; 289 return; 290 } 291 292 Dsymbol *scopesym; 293 Dsymbol *s = sc->search(exp->loc, exp->ident, &scopesym); 294 if (s) 295 { 296 if (s->errors) 297 return setError(); 298 299 Expression *e; 300 301 /* See if the symbol was a member of an enclosing 'with' 302 */ 303 WithScopeSymbol *withsym = scopesym->isWithScopeSymbol(); 304 if (withsym && withsym->withstate->wthis) 305 { 306 /* Disallow shadowing 307 */ 308 // First find the scope of the with 309 Scope *scwith = sc; 310 while (scwith->scopesym != scopesym) 311 { 312 scwith = scwith->enclosing; 313 assert(scwith); 314 } 315 // Look at enclosing scopes for symbols with the same name, 316 // in the same function 317 for (Scope *scx = scwith; scx && scx->func == scwith->func; scx = scx->enclosing) 318 { 319 Dsymbol *s2; 320 if (scx->scopesym && scx->scopesym->symtab && 321 (s2 = scx->scopesym->symtab->lookup(s->ident)) != NULL && 322 s != s2) 323 { 324 exp->error("with symbol %s is shadowing local symbol %s", s->toPrettyChars(), s2->toPrettyChars()); 325 return setError(); 326 } 327 } 328 s = s->toAlias(); 329 330 // Same as wthis.ident 331 // TODO: DotIdExp.semantic will find 'ident' from 'wthis' again. 332 // The redudancy should be removed. 333 e = new VarExp(exp->loc, withsym->withstate->wthis); 334 e = new DotIdExp(exp->loc, e, exp->ident); 335 e = semantic(e, sc); 336 } 337 else 338 { 339 if (withsym) 340 { 341 Declaration *d = s->isDeclaration(); 342 if (d) 343 checkAccess(exp->loc, sc, NULL, d); 344 } 345 346 /* If f is really a function template, 347 * then replace f with the function template declaration. 348 */ 349 FuncDeclaration *f = s->isFuncDeclaration(); 350 if (f) 351 { 352 TemplateDeclaration *td = getFuncTemplateDecl(f); 353 if (td) 354 { 355 if (td->overroot) // if not start of overloaded list of TemplateDeclaration's 356 td = td->overroot; // then get the start 357 e = new TemplateExp(exp->loc, td, f); 358 e = semantic(e, sc); 359 result = e; 360 return; 361 } 362 } 363 // Haven't done overload resolution yet, so pass 1 364 e = resolve(exp->loc, sc, s, true); 365 } 366 result = e; 367 return; 368 } 369 370 if (hasThis(sc)) 371 { 372 AggregateDeclaration *ad = sc->getStructClassScope(); 373 if (ad && ad->aliasthis) 374 { 375 Expression *e; 376 e = new IdentifierExp(exp->loc, Id::This); 377 e = new DotIdExp(exp->loc, e, ad->aliasthis->ident); 378 e = new DotIdExp(exp->loc, e, exp->ident); 379 e = trySemantic(e, sc); 380 if (e) 381 { 382 result = e; 383 return; 384 } 385 } 386 } 387 388 if (exp->ident == Id::ctfe) 389 { 390 if (sc->flags & SCOPEctfe) 391 { 392 exp->error("variable __ctfe cannot be read at compile time"); 393 return setError(); 394 } 395 396 // Create the magic __ctfe bool variable 397 VarDeclaration *vd = new VarDeclaration(exp->loc, Type::tbool, Id::ctfe, NULL); 398 vd->storage_class |= STCtemp; 399 Expression *e = new VarExp(exp->loc, vd); 400 e = semantic(e, sc); 401 result = e; 402 return; 403 } 404 405 // If we've reached this point and are inside a with() scope then we may 406 // try one last attempt by checking whether the 'wthis' object supports 407 // dynamic dispatching via opDispatch. 408 // This is done by rewriting this expression as wthis.ident. 409 for (Scope *sc2 = sc; sc2; sc2 = sc2->enclosing) 410 { 411 if (!sc2->scopesym) 412 continue; 413 414 if (WithScopeSymbol *ss = sc2->scopesym->isWithScopeSymbol()) 415 { 416 if (ss->withstate->wthis) 417 { 418 Expression *e; 419 e = new VarExp(exp->loc, ss->withstate->wthis); 420 e = new DotIdExp(exp->loc, e, exp->ident); 421 e = trySemantic(e, sc); 422 if (e) 423 { 424 result = e; 425 return; 426 } 427 } 428 break; 429 } 430 } 431 432 /* Look for what user might have meant 433 */ 434 if (const char *n = importHint(exp->ident->toChars())) 435 exp->error("`%s` is not defined, perhaps `import %s;` is needed?", exp->ident->toChars(), n); 436 else if (Dsymbol *s2 = sc->search_correct(exp->ident)) 437 exp->error("undefined identifier `%s`, did you mean %s `%s`?", exp->ident->toChars(), s2->kind(), s2->toChars()); 438 else if (const char *p = Scope::search_correct_C(exp->ident)) 439 exp->error("undefined identifier `%s`, did you mean `%s`?", exp->ident->toChars(), p); 440 else 441 exp->error("undefined identifier `%s`", exp->ident->toChars()); 442 return setError(); 443 } 444 445 void visit(DsymbolExp *e) 446 { 447 result = resolve(e->loc, sc, e->s, e->hasOverloads); 448 } 449 450 void visit(ThisExp *e) 451 { 452 if (e->type) 453 { 454 result = e; 455 return; 456 } 457 458 FuncDeclaration *fd = hasThis(sc); // fd is the uplevel function with the 'this' variable 459 460 /* Special case for typeof(this) and typeof(super) since both 461 * should work even if they are not inside a non-static member function 462 */ 463 if (!fd && sc->intypeof == 1) 464 { 465 // Find enclosing struct or class 466 for (Dsymbol *s = sc->getStructClassScope(); 1; s = s->parent) 467 { 468 if (!s) 469 { 470 e->error("%s is not in a class or struct scope", e->toChars()); 471 goto Lerr; 472 } 473 ClassDeclaration *cd = s->isClassDeclaration(); 474 if (cd) 475 { 476 e->type = cd->type; 477 result = e; 478 return; 479 } 480 StructDeclaration *sd = s->isStructDeclaration(); 481 if (sd) 482 { 483 e->type = sd->type; 484 result = e; 485 return; 486 } 487 } 488 } 489 if (!fd) 490 goto Lerr; 491 492 assert(fd->vthis); 493 e->var = fd->vthis; 494 assert(e->var->parent); 495 e->type = e->var->type; 496 if (e->var->checkNestedReference(sc, e->loc)) 497 return setError(); 498 if (!sc->intypeof) 499 sc->callSuper |= CSXthis; 500 result = e; 501 return; 502 503 Lerr: 504 e->error("'this' is only defined in non-static member functions, not %s", sc->parent->toChars()); 505 return setError(); 506 } 507 508 void visit(SuperExp *e) 509 { 510 if (e->type) 511 { 512 result = e; 513 return; 514 } 515 516 FuncDeclaration *fd = hasThis(sc); 517 ClassDeclaration *cd; 518 Dsymbol *s; 519 520 /* Special case for typeof(this) and typeof(super) since both 521 * should work even if they are not inside a non-static member function 522 */ 523 if (!fd && sc->intypeof == 1) 524 { 525 // Find enclosing class 526 for (s = sc->getStructClassScope(); 1; s = s->parent) 527 { 528 if (!s) 529 { 530 e->error("%s is not in a class scope", e->toChars()); 531 goto Lerr; 532 } 533 cd = s->isClassDeclaration(); 534 if (cd) 535 { 536 cd = cd->baseClass; 537 if (!cd) 538 { 539 e->error("class %s has no 'super'", s->toChars()); 540 goto Lerr; 541 } 542 e->type = cd->type; 543 result = e; 544 return; 545 } 546 } 547 } 548 if (!fd) 549 goto Lerr; 550 551 e->var = fd->vthis; 552 assert(e->var && e->var->parent); 553 554 s = fd->toParent(); 555 while (s && s->isTemplateInstance()) 556 s = s->toParent(); 557 if (s->isTemplateDeclaration()) // allow inside template constraint 558 s = s->toParent(); 559 assert(s); 560 cd = s->isClassDeclaration(); 561 //printf("parent is %s %s\n", fd->toParent()->kind(), fd->toParent()->toChars()); 562 if (!cd) 563 goto Lerr; 564 if (!cd->baseClass) 565 { 566 e->error("no base class for %s", cd->toChars()); 567 e->type = e->var->type; 568 } 569 else 570 { 571 e->type = cd->baseClass->type; 572 e->type = e->type->castMod(e->var->type->mod); 573 } 574 575 if (e->var->checkNestedReference(sc, e->loc)) 576 return setError(); 577 578 if (!sc->intypeof) 579 sc->callSuper |= CSXsuper; 580 result = e; 581 return; 582 583 Lerr: 584 e->error("'super' is only allowed in non-static class member functions"); 585 return setError(); 586 } 587 588 void visit(NullExp *e) 589 { 590 // NULL is the same as (void *)0 591 if (e->type) 592 { 593 result = e; 594 return; 595 } 596 e->type = Type::tnull; 597 result = e; 598 } 599 600 void visit(StringExp *e) 601 { 602 if (e->type) 603 { 604 result = e; 605 return; 606 } 607 608 OutBuffer buffer; 609 size_t newlen = 0; 610 const char *p; 611 size_t u; 612 unsigned c; 613 614 switch (e->postfix) 615 { 616 case 'd': 617 for (u = 0; u < e->len;) 618 { 619 p = utf_decodeChar((utf8_t *)e->string, e->len, &u, &c); 620 if (p) 621 { 622 e->error("%s", p); 623 return setError(); 624 } 625 else 626 { 627 buffer.write4(c); 628 newlen++; 629 } 630 } 631 buffer.write4(0); 632 e->string = buffer.extractData(); 633 e->len = newlen; 634 e->sz = 4; 635 e->type = new TypeDArray(Type::tdchar->immutableOf()); 636 e->committed = 1; 637 break; 638 639 case 'w': 640 for (u = 0; u < e->len;) 641 { 642 p = utf_decodeChar((utf8_t *)e->string, e->len, &u, &c); 643 if (p) 644 { 645 e->error("%s", p); 646 return setError(); 647 } 648 else 649 { 650 buffer.writeUTF16(c); 651 newlen++; 652 if (c >= 0x10000) 653 newlen++; 654 } 655 } 656 buffer.writeUTF16(0); 657 e->string = buffer.extractData(); 658 e->len = newlen; 659 e->sz = 2; 660 e->type = new TypeDArray(Type::twchar->immutableOf()); 661 e->committed = 1; 662 break; 663 664 case 'c': 665 e->committed = 1; 666 /* fall through */ 667 668 default: 669 e->type = new TypeDArray(Type::tchar->immutableOf()); 670 break; 671 } 672 e->type = e->type->semantic(e->loc, sc); 673 //e->type = e->type->immutableOf(); 674 //printf("type = %s\n", e->type->toChars()); 675 676 result = e; 677 } 678 679 void visit(ArrayLiteralExp *e) 680 { 681 if (e->type) 682 { 683 result = e; 684 return; 685 } 686 687 /* Perhaps an empty array literal [ ] should be rewritten as null? 688 */ 689 690 if (e->basis) 691 e->basis = semantic(e->basis, sc); 692 if (arrayExpressionSemantic(e->elements, sc) || (e->basis && e->basis->op == TOKerror)) 693 return setError(); 694 expandTuples(e->elements); 695 696 Type *t0; 697 if (e->basis) 698 e->elements->push(e->basis); 699 bool err = arrayExpressionToCommonType(sc, e->elements, &t0); 700 if (e->basis) 701 e->elements->pop(); 702 if (err) 703 return setError(); 704 705 e->type = t0->arrayOf(); 706 e->type = e->type->semantic(e->loc, sc); 707 708 /* Disallow array literals of type void being used. 709 */ 710 if (e->elements->dim > 0 && t0->ty == Tvoid) 711 { 712 e->error("%s of type %s has no value", e->toChars(), e->type->toChars()); 713 return setError(); 714 } 715 716 if (global.params.useTypeInfo && Type::dtypeinfo) 717 semanticTypeInfo(sc, e->type); 718 719 result = e; 720 } 721 722 void visit(AssocArrayLiteralExp *e) 723 { 724 if (e->type) 725 { 726 result = e; 727 return; 728 } 729 730 // Run semantic() on each element 731 bool err_keys = arrayExpressionSemantic(e->keys, sc); 732 bool err_vals = arrayExpressionSemantic(e->values, sc); 733 if (err_keys || err_vals) 734 return setError(); 735 expandTuples(e->keys); 736 expandTuples(e->values); 737 if (e->keys->dim != e->values->dim) 738 { 739 e->error("number of keys is %u, must match number of values %u", e->keys->dim, e->values->dim); 740 return setError(); 741 } 742 743 Type *tkey = NULL; 744 Type *tvalue = NULL; 745 err_keys = arrayExpressionToCommonType(sc, e->keys, &tkey); 746 err_vals = arrayExpressionToCommonType(sc, e->values, &tvalue); 747 if (err_keys || err_vals) 748 return setError(); 749 750 if (tkey == Type::terror || tvalue == Type::terror) 751 return setError(); 752 753 e->type = new TypeAArray(tvalue, tkey); 754 e->type = e->type->semantic(e->loc, sc); 755 756 semanticTypeInfo(sc, e->type); 757 758 result = e; 759 } 760 761 void visit(StructLiteralExp *e) 762 { 763 if (e->type) 764 { 765 result = e; 766 return; 767 } 768 769 e->sd->size(e->loc); 770 if (e->sd->sizeok != SIZEOKdone) 771 return setError(); 772 773 if (arrayExpressionSemantic(e->elements, sc)) // run semantic() on each element 774 return setError(); 775 expandTuples(e->elements); 776 777 /* Fit elements[] to the corresponding type of field[]. 778 */ 779 if (!e->sd->fit(e->loc, sc, e->elements, e->stype)) 780 return setError(); 781 782 /* Fill out remainder of elements[] with default initializers for fields[] 783 */ 784 if (!e->sd->fill(e->loc, e->elements, false)) 785 { 786 /* An error in the initializer needs to be recorded as an error 787 * in the enclosing function or template, since the initializer 788 * will be part of the stuct declaration. 789 */ 790 global.increaseErrorCount(); 791 return setError(); 792 } 793 794 if (checkFrameAccess(e->loc, sc, e->sd, e->elements->dim)) 795 return setError(); 796 797 e->type = e->stype ? e->stype : e->sd->type; 798 result = e; 799 } 800 801 void visit(TypeExp *exp) 802 { 803 if (exp->type->ty == Terror) 804 return setError(); 805 806 //printf("TypeExp::semantic(%s)\n", exp->type->toChars()); 807 Expression *e; 808 Type *t; 809 Dsymbol *s; 810 811 exp->type->resolve(exp->loc, sc, &e, &t, &s, true); 812 if (e) 813 { 814 //printf("e = %s %s\n", Token::toChars(e->op), e->toChars()); 815 e = semantic(e, sc); 816 } 817 else if (t) 818 { 819 //printf("t = %d %s\n", t->ty, t->toChars()); 820 exp->type = t->semantic(exp->loc, sc); 821 e = exp; 822 } 823 else if (s) 824 { 825 //printf("s = %s %s\n", s->kind(), s->toChars()); 826 e = resolve(exp->loc, sc, s, true); 827 } 828 else 829 assert(0); 830 831 if (global.params.vcomplex) 832 exp->type->checkComplexTransition(exp->loc); 833 834 result = e; 835 } 836 837 void visit(ScopeExp *exp) 838 { 839 if (exp->type) 840 { 841 result = exp; 842 return; 843 } 844 845 ScopeDsymbol *sds2 = exp->sds; 846 TemplateInstance *ti = sds2->isTemplateInstance(); 847 while (ti) 848 { 849 WithScopeSymbol *withsym; 850 if (!ti->findTempDecl(sc, &withsym) || 851 !ti->semanticTiargs(sc)) 852 return setError(); 853 if (withsym && withsym->withstate->wthis) 854 { 855 Expression *e = new VarExp(exp->loc, withsym->withstate->wthis); 856 e = new DotTemplateInstanceExp(exp->loc, e, ti); 857 result = semantic(e, sc); 858 return; 859 } 860 if (ti->needsTypeInference(sc)) 861 { 862 if (TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration()) 863 { 864 Dsymbol *p = td->toParent2(); 865 FuncDeclaration *fdthis = hasThis(sc); 866 AggregateDeclaration *ad = p ? p->isAggregateDeclaration() : NULL; 867 if (fdthis && ad && isAggregate(fdthis->vthis->type) == ad && 868 (td->_scope->stc & STCstatic) == 0) 869 { 870 Expression *e = new DotTemplateInstanceExp(exp->loc, new ThisExp(exp->loc), ti->name, ti->tiargs); 871 result = semantic(e, sc); 872 return; 873 } 874 } 875 else if (OverloadSet *os = ti->tempdecl->isOverloadSet()) 876 { 877 FuncDeclaration *fdthis = hasThis(sc); 878 AggregateDeclaration *ad = os->parent->isAggregateDeclaration(); 879 if (fdthis && ad && isAggregate(fdthis->vthis->type) == ad) 880 { 881 Expression *e = new DotTemplateInstanceExp(exp->loc, new ThisExp(exp->loc), ti->name, ti->tiargs); 882 result = semantic(e, sc); 883 return; 884 } 885 } 886 // ti is an instance which requires IFTI. 887 exp->sds = ti; 888 exp->type = Type::tvoid; 889 result = exp; 890 return; 891 } 892 ti->semantic(sc); 893 if (!ti->inst || ti->errors) 894 return setError(); 895 896 Dsymbol *s = ti->toAlias(); 897 if (s == ti) 898 { 899 exp->sds = ti; 900 exp->type = Type::tvoid; 901 result = exp; 902 return; 903 } 904 sds2 = s->isScopeDsymbol(); 905 if (sds2) 906 { 907 ti = sds2->isTemplateInstance(); 908 //printf("+ sds2 = %s, '%s'\n", sds2->kind(), sds2->toChars()); 909 continue; 910 } 911 912 if (VarDeclaration *v = s->isVarDeclaration()) 913 { 914 if (!v->type) 915 { 916 exp->error("forward reference of %s %s", v->kind(), v->toChars()); 917 return setError(); 918 } 919 if ((v->storage_class & STCmanifest) && v->_init) 920 { 921 /* When an instance that will be converted to a constant exists, 922 * the instance representation "foo!tiargs" is treated like a 923 * variable name, and its recursive appearance check (note that 924 * it's equivalent with a recursive instantiation of foo) is done 925 * separately from the circular initialization check for the 926 * eponymous enum variable declaration. 927 * 928 * template foo(T) { 929 * enum bool foo = foo; // recursive definition check (v.inuse) 930 * } 931 * template bar(T) { 932 * enum bool bar = bar!T; // recursive instantiation check (ti.inuse) 933 * } 934 */ 935 if (ti->inuse) 936 { 937 exp->error("recursive expansion of %s '%s'", ti->kind(), ti->toPrettyChars()); 938 return setError(); 939 } 940 941 Expression *e = v->expandInitializer(exp->loc); 942 ti->inuse++; 943 e = semantic(e, sc); 944 ti->inuse--; 945 result = e; 946 return; 947 } 948 } 949 950 //printf("s = %s, '%s'\n", s->kind(), s->toChars()); 951 Expression *e = resolve(exp->loc, sc, s, true); 952 //printf("-1ScopeExp::semantic()\n"); 953 result = e; 954 return; 955 } 956 957 //printf("sds2 = %s, '%s'\n", sds2->kind(), sds2->toChars()); 958 //printf("\tparent = '%s'\n", sds2->parent->toChars()); 959 sds2->semantic(sc); 960 961 if (Type *t = sds2->getType()) // (Aggregate|Enum)Declaration 962 { 963 Expression *ex = new TypeExp(exp->loc, t); 964 result = semantic(ex, sc); 965 return; 966 } 967 968 if (TemplateDeclaration *td = sds2->isTemplateDeclaration()) 969 { 970 result = semantic(new TemplateExp(exp->loc, td), sc); 971 return; 972 } 973 974 exp->sds = sds2; 975 exp->type = Type::tvoid; 976 //printf("-2ScopeExp::semantic() %s\n", exp->toChars()); 977 result = exp; 978 } 979 980 void visit(NewExp *exp) 981 { 982 if (exp->type) // if semantic() already run 983 { 984 result = exp; 985 return; 986 } 987 988 // Bugzilla 11581: With the syntax `new T[edim]` or `thisexp.new T[edim]`, 989 // T should be analyzed first and edim should go into arguments iff it's 990 // not a tuple. 991 Expression *edim = NULL; 992 if (!exp->arguments && exp->newtype->ty == Tsarray) 993 { 994 edim = ((TypeSArray *)exp->newtype)->dim; 995 exp->newtype = ((TypeNext *)exp->newtype)->next; 996 } 997 998 ClassDeclaration *cdthis = NULL; 999 if (exp->thisexp) 1000 { 1001 exp->thisexp = semantic(exp->thisexp, sc); 1002 if (exp->thisexp->op == TOKerror) 1003 return setError(); 1004 cdthis = exp->thisexp->type->isClassHandle(); 1005 if (!cdthis) 1006 { 1007 exp->error("'this' for nested class must be a class type, not %s", exp->thisexp->type->toChars()); 1008 return setError(); 1009 } 1010 1011 sc = sc->push(cdthis); 1012 exp->type = exp->newtype->semantic(exp->loc, sc); 1013 sc = sc->pop(); 1014 } 1015 else 1016 { 1017 exp->type = exp->newtype->semantic(exp->loc, sc); 1018 } 1019 if (exp->type->ty == Terror) 1020 return setError(); 1021 1022 if (edim) 1023 { 1024 if (exp->type->toBasetype()->ty == Ttuple) 1025 { 1026 // --> new T[edim] 1027 exp->type = new TypeSArray(exp->type, edim); 1028 exp->type = exp->type->semantic(exp->loc, sc); 1029 if (exp->type->ty == Terror) 1030 return setError(); 1031 } 1032 else 1033 { 1034 // --> new T[](edim) 1035 exp->arguments = new Expressions(); 1036 exp->arguments->push(edim); 1037 exp->type = exp->type->arrayOf(); 1038 } 1039 } 1040 1041 exp->newtype = exp->type; // in case type gets cast to something else 1042 Type *tb = exp->type->toBasetype(); 1043 //printf("tb: %s, deco = %s\n", tb->toChars(), tb->deco); 1044 1045 if (arrayExpressionSemantic(exp->newargs, sc) || 1046 preFunctionParameters(sc, exp->newargs)) 1047 { 1048 return setError(); 1049 } 1050 if (arrayExpressionSemantic(exp->arguments, sc) || 1051 preFunctionParameters(sc, exp->arguments)) 1052 { 1053 return setError(); 1054 } 1055 1056 if (exp->thisexp && tb->ty != Tclass) 1057 { 1058 exp->error("e.new is only for allocating nested classes, not %s", tb->toChars()); 1059 return setError(); 1060 } 1061 1062 size_t nargs = exp->arguments ? exp->arguments->dim : 0; 1063 Expression *newprefix = NULL; 1064 1065 if (tb->ty == Tclass) 1066 { 1067 ClassDeclaration *cd = ((TypeClass *)tb)->sym; 1068 cd->size(exp->loc); 1069 if (cd->sizeok != SIZEOKdone) 1070 return setError(); 1071 if (!cd->ctor) 1072 cd->ctor = cd->searchCtor(); 1073 if (cd->noDefaultCtor && !nargs && !cd->defaultCtor) 1074 { 1075 exp->error("default construction is disabled for type %s", cd->type->toChars()); 1076 return setError(); 1077 } 1078 1079 if (cd->isInterfaceDeclaration()) 1080 { 1081 exp->error("cannot create instance of interface %s", cd->toChars()); 1082 return setError(); 1083 } 1084 if (cd->isAbstract()) 1085 { 1086 exp->error("cannot create instance of abstract class %s", cd->toChars()); 1087 for (size_t i = 0; i < cd->vtbl.dim; i++) 1088 { 1089 FuncDeclaration *fd = cd->vtbl[i]->isFuncDeclaration(); 1090 if (fd && fd->isAbstract()) 1091 errorSupplemental(exp->loc, "function '%s' is not implemented", fd->toFullSignature()); 1092 } 1093 return setError(); 1094 } 1095 // checkDeprecated() is already done in newtype->semantic(). 1096 1097 if (cd->isNested()) 1098 { 1099 /* We need a 'this' pointer for the nested class. 1100 * Ensure we have the right one. 1101 */ 1102 Dsymbol *s = cd->toParent2(); 1103 //printf("cd isNested, parent = %s '%s'\n", s->kind(), s->toPrettyChars()); 1104 if (ClassDeclaration *cdn = s->isClassDeclaration()) 1105 { 1106 if (!cdthis) 1107 { 1108 // Supply an implicit 'this' and try again 1109 exp->thisexp = new ThisExp(exp->loc); 1110 for (Dsymbol *sp = sc->parent; 1; sp = sp->parent) 1111 { 1112 if (!sp) 1113 { 1114 exp->error("outer class %s 'this' needed to 'new' nested class %s", cdn->toChars(), cd->toChars()); 1115 return setError(); 1116 } 1117 ClassDeclaration *cdp = sp->isClassDeclaration(); 1118 if (!cdp) 1119 continue; 1120 if (cdp == cdn || cdn->isBaseOf(cdp, NULL)) 1121 break; 1122 // Add a '.outer' and try again 1123 exp->thisexp = new DotIdExp(exp->loc, exp->thisexp, Id::outer); 1124 } 1125 exp->thisexp = semantic(exp->thisexp, sc); 1126 if (exp->thisexp->op == TOKerror) 1127 return setError(); 1128 cdthis = exp->thisexp->type->isClassHandle(); 1129 } 1130 if (cdthis != cdn && !cdn->isBaseOf(cdthis, NULL)) 1131 { 1132 //printf("cdthis = %s\n", cdthis->toChars()); 1133 exp->error("'this' for nested class must be of type %s, not %s", 1134 cdn->toChars(), exp->thisexp->type->toChars()); 1135 return setError(); 1136 } 1137 if (!MODimplicitConv(exp->thisexp->type->mod, exp->newtype->mod)) 1138 { 1139 exp->error("nested type %s should have the same or weaker constancy as enclosing type %s", 1140 exp->newtype->toChars(), exp->thisexp->type->toChars()); 1141 return setError(); 1142 } 1143 } 1144 else if (exp->thisexp) 1145 { 1146 exp->error("e.new is only for allocating nested classes"); 1147 return setError(); 1148 } 1149 else if (FuncDeclaration *fdn = s->isFuncDeclaration()) 1150 { 1151 // make sure the parent context fdn of cd is reachable from sc 1152 if (checkNestedRef(sc->parent, fdn)) 1153 { 1154 exp->error("outer function context of %s is needed to 'new' nested class %s", 1155 fdn->toPrettyChars(), cd->toPrettyChars()); 1156 return setError(); 1157 } 1158 } 1159 else 1160 assert(0); 1161 } 1162 else if (exp->thisexp) 1163 { 1164 exp->error("e.new is only for allocating nested classes"); 1165 return setError(); 1166 } 1167 1168 if (cd->aggNew) 1169 { 1170 // Prepend the size argument to newargs[] 1171 Expression *e = new IntegerExp(exp->loc, cd->size(exp->loc), Type::tsize_t); 1172 if (!exp->newargs) 1173 exp->newargs = new Expressions(); 1174 exp->newargs->shift(e); 1175 1176 FuncDeclaration *f = resolveFuncCall(exp->loc, sc, cd->aggNew, NULL, tb, exp->newargs); 1177 if (!f || f->errors) 1178 return setError(); 1179 exp->checkDeprecated(sc, f); 1180 exp->checkPurity(sc, f); 1181 exp->checkSafety(sc, f); 1182 exp->checkNogc(sc, f); 1183 checkAccess(cd, exp->loc, sc, f); 1184 1185 TypeFunction *tf = (TypeFunction *)f->type; 1186 Type *rettype; 1187 if (functionParameters(exp->loc, sc, tf, NULL, exp->newargs, f, &rettype, &newprefix)) 1188 return setError(); 1189 1190 exp->allocator = f->isNewDeclaration(); 1191 assert(exp->allocator); 1192 } 1193 else 1194 { 1195 if (exp->newargs && exp->newargs->dim) 1196 { 1197 exp->error("no allocator for %s", cd->toChars()); 1198 return setError(); 1199 } 1200 } 1201 1202 if (cd->ctor) 1203 { 1204 FuncDeclaration *f = resolveFuncCall(exp->loc, sc, cd->ctor, NULL, tb, exp->arguments, 0); 1205 if (!f || f->errors) 1206 return setError(); 1207 exp->checkDeprecated(sc, f); 1208 exp->checkPurity(sc, f); 1209 exp->checkSafety(sc, f); 1210 exp->checkNogc(sc, f); 1211 checkAccess(cd, exp->loc, sc, f); 1212 1213 TypeFunction *tf = (TypeFunction *)f->type; 1214 if (!exp->arguments) 1215 exp->arguments = new Expressions(); 1216 if (functionParameters(exp->loc, sc, tf, exp->type, exp->arguments, f, &exp->type, &exp->argprefix)) 1217 return setError(); 1218 1219 exp->member = f->isCtorDeclaration(); 1220 assert(exp->member); 1221 } 1222 else 1223 { 1224 if (nargs) 1225 { 1226 exp->error("no constructor for %s", cd->toChars()); 1227 return setError(); 1228 } 1229 } 1230 } 1231 else if (tb->ty == Tstruct) 1232 { 1233 StructDeclaration *sd = ((TypeStruct *)tb)->sym; 1234 sd->size(exp->loc); 1235 if (sd->sizeok != SIZEOKdone) 1236 return setError(); 1237 if (!sd->ctor) 1238 sd->ctor = sd->searchCtor(); 1239 if (sd->noDefaultCtor && !nargs) 1240 { 1241 exp->error("default construction is disabled for type %s", sd->type->toChars()); 1242 return setError(); 1243 } 1244 // checkDeprecated() is already done in newtype->semantic(). 1245 1246 if (sd->aggNew) 1247 { 1248 // Prepend the uint size argument to newargs[] 1249 Expression *e = new IntegerExp(exp->loc, sd->size(exp->loc), Type::tsize_t); 1250 if (!exp->newargs) 1251 exp->newargs = new Expressions(); 1252 exp->newargs->shift(e); 1253 1254 FuncDeclaration *f = resolveFuncCall(exp->loc, sc, sd->aggNew, NULL, tb, exp->newargs); 1255 if (!f || f->errors) 1256 return setError(); 1257 exp->checkDeprecated(sc, f); 1258 exp->checkPurity(sc, f); 1259 exp->checkSafety(sc, f); 1260 exp->checkNogc(sc, f); 1261 checkAccess(sd, exp->loc, sc, f); 1262 1263 TypeFunction *tf = (TypeFunction *)f->type; 1264 Type *rettype; 1265 if (functionParameters(exp->loc, sc, tf, NULL, exp->newargs, f, &rettype, &newprefix)) 1266 return setError(); 1267 1268 exp->allocator = f->isNewDeclaration(); 1269 assert(exp->allocator); 1270 } 1271 else 1272 { 1273 if (exp->newargs && exp->newargs->dim) 1274 { 1275 exp->error("no allocator for %s", sd->toChars()); 1276 return setError(); 1277 } 1278 } 1279 1280 if (sd->ctor && nargs) 1281 { 1282 FuncDeclaration *f = resolveFuncCall(exp->loc, sc, sd->ctor, NULL, tb, exp->arguments, 0); 1283 if (!f || f->errors) 1284 return setError(); 1285 exp->checkDeprecated(sc, f); 1286 exp->checkPurity(sc, f); 1287 exp->checkSafety(sc, f); 1288 exp->checkNogc(sc, f); 1289 checkAccess(sd, exp->loc, sc, f); 1290 1291 TypeFunction *tf = (TypeFunction *)f->type; 1292 if (!exp->arguments) 1293 exp->arguments = new Expressions(); 1294 if (functionParameters(exp->loc, sc, tf, exp->type, exp->arguments, f, &exp->type, &exp->argprefix)) 1295 return setError(); 1296 1297 exp->member = f->isCtorDeclaration(); 1298 assert(exp->member); 1299 1300 if (checkFrameAccess(exp->loc, sc, sd, sd->fields.dim)) 1301 return setError(); 1302 } 1303 else 1304 { 1305 if (!exp->arguments) 1306 exp->arguments = new Expressions(); 1307 1308 if (!sd->fit(exp->loc, sc, exp->arguments, tb)) 1309 return setError(); 1310 if (!sd->fill(exp->loc, exp->arguments, false)) 1311 return setError(); 1312 if (checkFrameAccess(exp->loc, sc, sd, exp->arguments ? exp->arguments->dim : 0)) 1313 return setError(); 1314 } 1315 1316 exp->type = exp->type->pointerTo(); 1317 } 1318 else if (tb->ty == Tarray && nargs) 1319 { 1320 Type *tn = tb->nextOf()->baseElemOf(); 1321 Dsymbol *s = tn->toDsymbol(sc); 1322 AggregateDeclaration *ad = s ? s->isAggregateDeclaration() : NULL; 1323 if (ad && ad->noDefaultCtor) 1324 { 1325 exp->error("default construction is disabled for type %s", tb->nextOf()->toChars()); 1326 return setError(); 1327 } 1328 for (size_t i = 0; i < nargs; i++) 1329 { 1330 if (tb->ty != Tarray) 1331 { 1332 exp->error("too many arguments for array"); 1333 return setError(); 1334 } 1335 1336 Expression *arg = (*exp->arguments)[i]; 1337 arg = resolveProperties(sc, arg); 1338 arg = arg->implicitCastTo(sc, Type::tsize_t); 1339 arg = arg->optimize(WANTvalue); 1340 if (arg->op == TOKint64 && (sinteger_t)arg->toInteger() < 0) 1341 { 1342 exp->error("negative array index %s", arg->toChars()); 1343 return setError(); 1344 } 1345 (*exp->arguments)[i] = arg; 1346 tb = ((TypeDArray *)tb)->next->toBasetype(); 1347 } 1348 } 1349 else if (tb->isscalar()) 1350 { 1351 if (!nargs) 1352 { 1353 } 1354 else if (nargs == 1) 1355 { 1356 Expression *e = (*exp->arguments)[0]; 1357 e = e->implicitCastTo(sc, tb); 1358 (*exp->arguments)[0] = e; 1359 } 1360 else 1361 { 1362 exp->error("more than one argument for construction of %s", exp->type->toChars()); 1363 return setError(); 1364 } 1365 1366 exp->type = exp->type->pointerTo(); 1367 } 1368 else 1369 { 1370 exp->error("new can only create structs, dynamic arrays or class objects, not %s's", exp->type->toChars()); 1371 return setError(); 1372 } 1373 1374 //printf("NewExp: '%s'\n", toChars()); 1375 //printf("NewExp:type '%s'\n", exp->type->toChars()); 1376 semanticTypeInfo(sc, exp->type); 1377 1378 if (newprefix) 1379 { 1380 result = Expression::combine(newprefix, exp); 1381 return; 1382 } 1383 result = exp; 1384 } 1385 1386 void visit(NewAnonClassExp *e) 1387 { 1388 Expression *d = new DeclarationExp(e->loc, e->cd); 1389 sc = sc->push(); // just create new scope 1390 sc->flags &= ~SCOPEctfe; // temporary stop CTFE 1391 d = semantic(d, sc); 1392 sc = sc->pop(); 1393 1394 if (!e->cd->errors && sc->intypeof && !sc->parent->inNonRoot()) 1395 { 1396 ScopeDsymbol *sds = sc->tinst ? (ScopeDsymbol *)sc->tinst : sc->_module; 1397 sds->members->push(e->cd); 1398 } 1399 1400 Expression *n = new NewExp(e->loc, e->thisexp, e->newargs, e->cd->type, e->arguments); 1401 1402 Expression *c = new CommaExp(e->loc, d, n); 1403 result = semantic(c, sc); 1404 } 1405 1406 void visit(SymOffExp *e) 1407 { 1408 //var->semantic(sc); 1409 if (!e->type) 1410 e->type = e->var->type->pointerTo(); 1411 if (VarDeclaration *v = e->var->isVarDeclaration()) 1412 { 1413 if (v->checkNestedReference(sc, e->loc)) 1414 return setError(); 1415 } 1416 else if (FuncDeclaration *f = e->var->isFuncDeclaration()) 1417 { 1418 if (f->checkNestedReference(sc, e->loc)) 1419 return setError(); 1420 } 1421 result = e; 1422 } 1423 1424 void visit(VarExp *e) 1425 { 1426 if (FuncDeclaration *fd = e->var->isFuncDeclaration()) 1427 { 1428 //printf("L%d fd = %s\n", __LINE__, f->toChars()); 1429 if (!fd->functionSemantic()) 1430 return setError(); 1431 } 1432 1433 if (!e->type) 1434 e->type = e->var->type; 1435 1436 if (e->type && !e->type->deco) 1437 e->type = e->type->semantic(e->loc, sc); 1438 1439 /* Fix for 1161 doesn't work because it causes protection 1440 * problems when instantiating imported templates passing private 1441 * variables as alias template parameters. 1442 */ 1443 //checkAccess(e->loc, sc, NULL, e->var); 1444 1445 if (VarDeclaration *vd = e->var->isVarDeclaration()) 1446 { 1447 if (vd->checkNestedReference(sc, e->loc)) 1448 return setError(); 1449 // Bugzilla 12025: If the variable is not actually used in runtime code, 1450 // the purity violation error is redundant. 1451 //checkPurity(sc, vd); 1452 } 1453 else if (FuncDeclaration *fd = e->var->isFuncDeclaration()) 1454 { 1455 // TODO: If fd isn't yet resolved its overload, the checkNestedReference 1456 // call would cause incorrect validation. 1457 // Maybe here should be moved in CallExp, or AddrExp for functions. 1458 if (fd->checkNestedReference(sc, e->loc)) 1459 return setError(); 1460 } 1461 else if (e->var->isOverDeclaration()) 1462 { 1463 e->type = Type::tvoid; // ambiguous type? 1464 } 1465 1466 result = e; 1467 } 1468 1469 void visit(TupleExp *exp) 1470 { 1471 if (exp->type) 1472 { 1473 result = exp; 1474 return; 1475 } 1476 1477 if (exp->e0) 1478 exp->e0 = semantic(exp->e0, sc); 1479 1480 // Run semantic() on each argument 1481 bool err = false; 1482 for (size_t i = 0; i < exp->exps->dim; i++) 1483 { 1484 Expression *e = (*exp->exps)[i]; 1485 e = semantic(e, sc); 1486 if (!e->type) 1487 { 1488 exp->error("%s has no value", e->toChars()); 1489 err = true; 1490 } 1491 else if (e->op == TOKerror) 1492 err = true; 1493 else 1494 (*exp->exps)[i] = e; 1495 } 1496 if (err) 1497 return setError(); 1498 1499 expandTuples(exp->exps); 1500 exp->type = new TypeTuple(exp->exps); 1501 exp->type = exp->type->semantic(exp->loc, sc); 1502 //printf("-TupleExp::semantic(%s)\n", exp->toChars()); 1503 result = exp; 1504 } 1505 1506 void visit(FuncExp *exp) 1507 { 1508 Expression *e = exp; 1509 1510 sc = sc->push(); // just create new scope 1511 sc->flags &= ~SCOPEctfe; // temporary stop CTFE 1512 sc->protection = Prot(PROTpublic); // Bugzilla 12506 1513 1514 if (!exp->type || exp->type == Type::tvoid) 1515 { 1516 /* fd->treq might be incomplete type, 1517 * so should not semantic it. 1518 * void foo(T)(T delegate(int) dg){} 1519 * foo(a=>a); // in IFTI, treq == T delegate(int) 1520 */ 1521 //if (exp->fd->treq) 1522 // exp->fd->treq = exp->fd->treq->semantic(exp->loc, sc); 1523 1524 exp->genIdent(sc); 1525 1526 // Set target of return type inference 1527 if (exp->fd->treq && !exp->fd->type->nextOf()) 1528 { 1529 TypeFunction *tfv = NULL; 1530 if (exp->fd->treq->ty == Tdelegate || 1531 (exp->fd->treq->ty == Tpointer && exp->fd->treq->nextOf()->ty == Tfunction)) 1532 tfv = (TypeFunction *)exp->fd->treq->nextOf(); 1533 if (tfv) 1534 { 1535 TypeFunction *tfl = (TypeFunction *)exp->fd->type; 1536 tfl->next = tfv->nextOf(); 1537 } 1538 } 1539 1540 //printf("td = %p, treq = %p\n", exp->td, exp->fd->treq); 1541 if (exp->td) 1542 { 1543 assert(exp->td->parameters && exp->td->parameters->dim); 1544 exp->td->semantic(sc); 1545 exp->type = Type::tvoid; // temporary type 1546 1547 if (exp->fd->treq) // defer type determination 1548 { 1549 FuncExp *fe; 1550 if (exp->matchType(exp->fd->treq, sc, &fe) > MATCHnomatch) 1551 e = fe; 1552 else 1553 e = new ErrorExp(); 1554 } 1555 goto Ldone; 1556 } 1557 1558 unsigned olderrors = global.errors; 1559 exp->fd->semantic(sc); 1560 if (olderrors == global.errors) 1561 { 1562 exp->fd->semantic2(sc); 1563 if (olderrors == global.errors) 1564 exp->fd->semantic3(sc); 1565 } 1566 if (olderrors != global.errors) 1567 { 1568 if (exp->fd->type && exp->fd->type->ty == Tfunction && !exp->fd->type->nextOf()) 1569 ((TypeFunction *)exp->fd->type)->next = Type::terror; 1570 e = new ErrorExp(); 1571 goto Ldone; 1572 } 1573 1574 // Type is a "delegate to" or "pointer to" the function literal 1575 if ((exp->fd->isNested() && exp->fd->tok == TOKdelegate) || 1576 (exp->tok == TOKreserved && exp->fd->treq && exp->fd->treq->ty == Tdelegate)) 1577 { 1578 exp->type = new TypeDelegate(exp->fd->type); 1579 exp->type = exp->type->semantic(exp->loc, sc); 1580 1581 exp->fd->tok = TOKdelegate; 1582 } 1583 else 1584 { 1585 exp->type = new TypePointer(exp->fd->type); 1586 exp->type = exp->type->semantic(exp->loc, sc); 1587 //exp->type = exp->fd->type->pointerTo(); 1588 1589 /* A lambda expression deduced to function pointer might become 1590 * to a delegate literal implicitly. 1591 * 1592 * auto foo(void function() fp) { return 1; } 1593 * assert(foo({}) == 1); 1594 * 1595 * So, should keep fd->tok == TOKreserve if fd->treq == NULL. 1596 */ 1597 if (exp->fd->treq && exp->fd->treq->ty == Tpointer) 1598 { 1599 // change to non-nested 1600 exp->fd->tok = TOKfunction; 1601 exp->fd->vthis = NULL; 1602 } 1603 } 1604 exp->fd->tookAddressOf++; 1605 } 1606 Ldone: 1607 sc = sc->pop(); 1608 result = e; 1609 } 1610 1611 // used from CallExp::semantic() 1612 Expression *callExpSemantic(FuncExp *exp, Scope *sc, Expressions *arguments) 1613 { 1614 if ((!exp->type || exp->type == Type::tvoid) && exp->td && arguments && arguments->dim) 1615 { 1616 for (size_t k = 0; k < arguments->dim; k++) 1617 { Expression *checkarg = (*arguments)[k]; 1618 if (checkarg->op == TOKerror) 1619 return checkarg; 1620 } 1621 1622 exp->genIdent(sc); 1623 1624 assert(exp->td->parameters && exp->td->parameters->dim); 1625 exp->td->semantic(sc); 1626 1627 TypeFunction *tfl = (TypeFunction *)exp->fd->type; 1628 size_t dim = Parameter::dim(tfl->parameters); 1629 if (arguments->dim < dim) 1630 { // Default arguments are always typed, so they don't need inference. 1631 Parameter *p = Parameter::getNth(tfl->parameters, arguments->dim); 1632 if (p->defaultArg) 1633 dim = arguments->dim; 1634 } 1635 1636 if ((!tfl->varargs && arguments->dim == dim) || 1637 ( tfl->varargs && arguments->dim >= dim)) 1638 { 1639 Objects *tiargs = new Objects(); 1640 tiargs->reserve(exp->td->parameters->dim); 1641 1642 for (size_t i = 0; i < exp->td->parameters->dim; i++) 1643 { 1644 TemplateParameter *tp = (*exp->td->parameters)[i]; 1645 for (size_t u = 0; u < dim; u++) 1646 { Parameter *p = Parameter::getNth(tfl->parameters, u); 1647 if (p->type->ty == Tident && 1648 ((TypeIdentifier *)p->type)->ident == tp->ident) 1649 { Expression *e = (*arguments)[u]; 1650 tiargs->push(e->type); 1651 u = dim; // break inner loop 1652 } 1653 } 1654 } 1655 1656 TemplateInstance *ti = new TemplateInstance(exp->loc, exp->td, tiargs); 1657 Expression *se = new ScopeExp(exp->loc, ti); 1658 return semantic(se, sc); 1659 } 1660 exp->error("cannot infer function literal type"); 1661 return new ErrorExp(); 1662 } 1663 return semantic(exp, sc); 1664 } 1665 1666 void visit(DeclarationExp *e) 1667 { 1668 if (e->type) 1669 { 1670 result = e; 1671 return; 1672 } 1673 1674 unsigned olderrors = global.errors; 1675 1676 /* This is here to support extern(linkage) declaration, 1677 * where the extern(linkage) winds up being an AttribDeclaration 1678 * wrapper. 1679 */ 1680 Dsymbol *s = e->declaration; 1681 1682 while (1) 1683 { 1684 AttribDeclaration *ad = s->isAttribDeclaration(); 1685 if (ad) 1686 { 1687 if (ad->decl && ad->decl->dim == 1) 1688 { 1689 s = (*ad->decl)[0]; 1690 continue; 1691 } 1692 } 1693 break; 1694 } 1695 1696 VarDeclaration *v = s->isVarDeclaration(); 1697 if (v) 1698 { 1699 // Do semantic() on initializer first, so: 1700 // int a = a; 1701 // will be illegal. 1702 e->declaration->semantic(sc); 1703 s->parent = sc->parent; 1704 } 1705 1706 //printf("inserting '%s' %p into sc = %p\n", s->toChars(), s, sc); 1707 // Insert into both local scope and function scope. 1708 // Must be unique in both. 1709 if (s->ident) 1710 { 1711 if (!sc->insert(s)) 1712 { 1713 e->error("declaration %s is already defined", s->toPrettyChars()); 1714 return setError(); 1715 } 1716 else if (sc->func) 1717 { 1718 // Bugzilla 11720 - include Dataseg variables 1719 if ((s->isFuncDeclaration() || 1720 s->isAggregateDeclaration() || 1721 s->isEnumDeclaration() || 1722 (v && v->isDataseg())) && 1723 !sc->func->localsymtab->insert(s)) 1724 { 1725 e->error("declaration %s is already defined in another scope in %s", 1726 s->toPrettyChars(), sc->func->toChars()); 1727 return setError(); 1728 } 1729 else 1730 { 1731 // Disallow shadowing 1732 for (Scope *scx = sc->enclosing; scx && scx->func == sc->func; scx = scx->enclosing) 1733 { 1734 Dsymbol *s2; 1735 if (scx->scopesym && scx->scopesym->symtab && 1736 (s2 = scx->scopesym->symtab->lookup(s->ident)) != NULL && 1737 s != s2) 1738 { 1739 e->error("%s %s is shadowing %s %s", s->kind(), s->ident->toChars(), s2->kind(), s2->toPrettyChars()); 1740 return setError(); 1741 } 1742 } 1743 } 1744 } 1745 } 1746 if (!s->isVarDeclaration()) 1747 { 1748 Scope *sc2 = sc; 1749 if (sc2->stc & (STCpure | STCnothrow | STCnogc)) 1750 sc2 = sc->push(); 1751 sc2->stc &= ~(STCpure | STCnothrow | STCnogc); 1752 e->declaration->semantic(sc2); 1753 if (sc2 != sc) 1754 sc2->pop(); 1755 s->parent = sc->parent; 1756 } 1757 if (global.errors == olderrors) 1758 { 1759 e->declaration->semantic2(sc); 1760 if (global.errors == olderrors) 1761 { 1762 e->declaration->semantic3(sc); 1763 } 1764 } 1765 // todo: error in declaration should be propagated. 1766 1767 e->type = Type::tvoid; 1768 result = e; 1769 } 1770 1771 void visit(TypeidExp *exp) 1772 { 1773 Type *ta = isType(exp->obj); 1774 Expression *ea = isExpression(exp->obj); 1775 Dsymbol *sa = isDsymbol(exp->obj); 1776 1777 //printf("ta %p ea %p sa %p\n", ta, ea, sa); 1778 1779 if (ta) 1780 { 1781 ta->resolve(exp->loc, sc, &ea, &ta, &sa, true); 1782 } 1783 1784 if (ea) 1785 { 1786 if (Dsymbol *sym = getDsymbol(ea)) 1787 ea = resolve(exp->loc, sc, sym, false); 1788 else 1789 ea = semantic(ea, sc); 1790 ea = resolveProperties(sc, ea); 1791 ta = ea->type; 1792 if (ea->op == TOKtype) 1793 ea = NULL; 1794 } 1795 1796 if (!ta) 1797 { 1798 //printf("ta %p ea %p sa %p\n", ta, ea, sa); 1799 exp->error("no type for typeid(%s)", ea ? ea->toChars() : (sa ? sa->toChars() : "")); 1800 return setError(); 1801 } 1802 1803 if (global.params.vcomplex) 1804 ta->checkComplexTransition(exp->loc); 1805 1806 Expression *e; 1807 if (ea && ta->toBasetype()->ty == Tclass) 1808 { 1809 /* Get the dynamic type, which is .classinfo 1810 */ 1811 ea = semantic(ea, sc); 1812 e = new TypeidExp(ea->loc, ea); 1813 e->type = Type::typeinfoclass->type; 1814 } 1815 else if (ta->ty == Terror) 1816 { 1817 e = new ErrorExp(); 1818 } 1819 else 1820 { 1821 // Handle this in the glue layer 1822 e = new TypeidExp(exp->loc, ta); 1823 e->type = getTypeInfoType(exp->loc, ta, sc); 1824 1825 semanticTypeInfo(sc, ta); 1826 1827 if (ea) 1828 { 1829 e = new CommaExp(exp->loc, ea, e); // execute ea 1830 e = semantic(e, sc); 1831 } 1832 } 1833 result = e; 1834 } 1835 1836 void visit(TraitsExp *e) 1837 { 1838 result = semanticTraits(e, sc); 1839 } 1840 1841 void visit(HaltExp *e) 1842 { 1843 e->type = Type::tvoid; 1844 result = e; 1845 } 1846 1847 void visit(IsExp *e) 1848 { 1849 /* is(targ id tok tspec) 1850 * is(targ id : tok2) 1851 * is(targ id == tok2) 1852 */ 1853 1854 //printf("IsExp::semantic(%s)\n", toChars()); 1855 if (e->id && !(sc->flags & SCOPEcondition)) 1856 { 1857 e->error("can only declare type aliases within static if conditionals or static asserts"); 1858 return setError(); 1859 } 1860 1861 Type *tded = NULL; 1862 Scope *sc2 = sc->copy(); // keep sc->flags 1863 sc2->tinst = NULL; 1864 sc2->minst = NULL; 1865 sc2->flags |= SCOPEfullinst; 1866 Type *t = e->targ->trySemantic(e->loc, sc2); 1867 sc2->pop(); 1868 if (!t) 1869 goto Lno; // errors, so condition is false 1870 e->targ = t; 1871 if (e->tok2 != TOKreserved) 1872 { 1873 switch (e->tok2) 1874 { 1875 case TOKstruct: 1876 if (e->targ->ty != Tstruct) 1877 goto Lno; 1878 if (((TypeStruct *)e->targ)->sym->isUnionDeclaration()) 1879 goto Lno; 1880 tded = e->targ; 1881 break; 1882 1883 case TOKunion: 1884 if (e->targ->ty != Tstruct) 1885 goto Lno; 1886 if (!((TypeStruct *)e->targ)->sym->isUnionDeclaration()) 1887 goto Lno; 1888 tded = e->targ; 1889 break; 1890 1891 case TOKclass: 1892 if (e->targ->ty != Tclass) 1893 goto Lno; 1894 if (((TypeClass *)e->targ)->sym->isInterfaceDeclaration()) 1895 goto Lno; 1896 tded = e->targ; 1897 break; 1898 1899 case TOKinterface: 1900 if (e->targ->ty != Tclass) 1901 goto Lno; 1902 if (!((TypeClass *)e->targ)->sym->isInterfaceDeclaration()) 1903 goto Lno; 1904 tded = e->targ; 1905 break; 1906 case TOKconst: 1907 if (!e->targ->isConst()) 1908 goto Lno; 1909 tded = e->targ; 1910 break; 1911 1912 case TOKimmutable: 1913 if (!e->targ->isImmutable()) 1914 goto Lno; 1915 tded = e->targ; 1916 break; 1917 1918 case TOKshared: 1919 if (!e->targ->isShared()) 1920 goto Lno; 1921 tded = e->targ; 1922 break; 1923 1924 case TOKwild: 1925 if (!e->targ->isWild()) 1926 goto Lno; 1927 tded = e->targ; 1928 break; 1929 1930 case TOKsuper: 1931 // If class or interface, get the base class and interfaces 1932 if (e->targ->ty != Tclass) 1933 goto Lno; 1934 else 1935 { 1936 ClassDeclaration *cd = ((TypeClass *)e->targ)->sym; 1937 Parameters *args = new Parameters; 1938 args->reserve(cd->baseclasses->dim); 1939 if (cd->_scope && !cd->symtab) 1940 cd->semantic(cd->_scope); 1941 for (size_t i = 0; i < cd->baseclasses->dim; i++) 1942 { 1943 BaseClass *b = (*cd->baseclasses)[i]; 1944 args->push(new Parameter(STCin, b->type, NULL, NULL)); 1945 } 1946 tded = new TypeTuple(args); 1947 } 1948 break; 1949 1950 case TOKenum: 1951 if (e->targ->ty != Tenum) 1952 goto Lno; 1953 if (e->id) 1954 tded = ((TypeEnum *)e->targ)->sym->getMemtype(e->loc); 1955 else 1956 tded = e->targ; 1957 if (tded->ty == Terror) 1958 return setError(); 1959 break; 1960 1961 case TOKdelegate: 1962 if (e->targ->ty != Tdelegate) 1963 goto Lno; 1964 tded = ((TypeDelegate *)e->targ)->next; // the underlying function type 1965 break; 1966 1967 case TOKfunction: 1968 case TOKparameters: 1969 { 1970 if (e->targ->ty != Tfunction) 1971 goto Lno; 1972 tded = e->targ; 1973 1974 /* Generate tuple from function parameter types. 1975 */ 1976 assert(tded->ty == Tfunction); 1977 Parameters *params = ((TypeFunction *)tded)->parameters; 1978 size_t dim = Parameter::dim(params); 1979 Parameters *args = new Parameters; 1980 args->reserve(dim); 1981 for (size_t i = 0; i < dim; i++) 1982 { 1983 Parameter *arg = Parameter::getNth(params, i); 1984 assert(arg && arg->type); 1985 /* If one of the default arguments was an error, 1986 don't return an invalid tuple 1987 */ 1988 if (e->tok2 == TOKparameters && arg->defaultArg && 1989 arg->defaultArg->op == TOKerror) 1990 return setError(); 1991 args->push(new Parameter(arg->storageClass, arg->type, 1992 (e->tok2 == TOKparameters) ? arg->ident : NULL, 1993 (e->tok2 == TOKparameters) ? arg->defaultArg : NULL)); 1994 } 1995 tded = new TypeTuple(args); 1996 break; 1997 } 1998 case TOKreturn: 1999 /* Get the 'return type' for the function, 2000 * delegate, or pointer to function. 2001 */ 2002 if (e->targ->ty == Tfunction) 2003 tded = ((TypeFunction *)e->targ)->next; 2004 else if (e->targ->ty == Tdelegate) 2005 { 2006 tded = ((TypeDelegate *)e->targ)->next; 2007 tded = ((TypeFunction *)tded)->next; 2008 } 2009 else if (e->targ->ty == Tpointer && 2010 ((TypePointer *)e->targ)->next->ty == Tfunction) 2011 { 2012 tded = ((TypePointer *)e->targ)->next; 2013 tded = ((TypeFunction *)tded)->next; 2014 } 2015 else 2016 goto Lno; 2017 break; 2018 2019 case TOKargTypes: 2020 /* Generate a type tuple of the equivalent types used to determine if a 2021 * function argument of this type can be passed in registers. 2022 * The results of this are highly platform dependent, and intended 2023 * primarly for use in implementing va_arg(). 2024 */ 2025 tded = toArgTypes(e->targ); 2026 if (!tded) 2027 goto Lno; // not valid for a parameter 2028 break; 2029 2030 case TOKvector: 2031 if (e->targ->ty != Tvector) 2032 goto Lno; 2033 tded = ((TypeVector *)e->targ)->basetype; 2034 break; 2035 2036 default: 2037 assert(0); 2038 } 2039 goto Lyes; 2040 } 2041 else if (e->tspec && !e->id && !(e->parameters && e->parameters->dim)) 2042 { 2043 /* Evaluate to true if targ matches tspec 2044 * is(targ == tspec) 2045 * is(targ : tspec) 2046 */ 2047 e->tspec = e->tspec->semantic(e->loc, sc); 2048 //printf("targ = %s, %s\n", e->targ->toChars(), e->targ->deco); 2049 //printf("tspec = %s, %s\n", e->tspec->toChars(), e->tspec->deco); 2050 if (e->tok == TOKcolon) 2051 { 2052 if (e->targ->implicitConvTo(e->tspec)) 2053 goto Lyes; 2054 else 2055 goto Lno; 2056 } 2057 else /* == */ 2058 { 2059 if (e->targ->equals(e->tspec)) 2060 goto Lyes; 2061 else 2062 goto Lno; 2063 } 2064 } 2065 else if (e->tspec) 2066 { 2067 /* Evaluate to true if targ matches tspec. 2068 * If true, declare id as an alias for the specialized type. 2069 * is(targ == tspec, tpl) 2070 * is(targ : tspec, tpl) 2071 * is(targ id == tspec) 2072 * is(targ id : tspec) 2073 * is(targ id == tspec, tpl) 2074 * is(targ id : tspec, tpl) 2075 */ 2076 2077 Identifier *tid = e->id ? e->id : Identifier::generateId("__isexp_id"); 2078 e->parameters->insert(0, new TemplateTypeParameter(e->loc, tid, NULL, NULL)); 2079 2080 Objects dedtypes; 2081 dedtypes.setDim(e->parameters->dim); 2082 dedtypes.zero(); 2083 2084 MATCH m = deduceType(e->targ, sc, e->tspec, e->parameters, &dedtypes); 2085 //printf("targ: %s\n", e->targ->toChars()); 2086 //printf("tspec: %s\n", e->tspec->toChars()); 2087 if (m <= MATCHnomatch || 2088 (m != MATCHexact && e->tok == TOKequal)) 2089 { 2090 goto Lno; 2091 } 2092 else 2093 { 2094 tded = (Type *)dedtypes[0]; 2095 if (!tded) 2096 tded = e->targ; 2097 Objects tiargs; 2098 tiargs.setDim(1); 2099 tiargs[0] = e->targ; 2100 2101 /* Declare trailing parameters 2102 */ 2103 for (size_t i = 1; i < e->parameters->dim; i++) 2104 { 2105 TemplateParameter *tp = (*e->parameters)[i]; 2106 Declaration *s = NULL; 2107 2108 m = tp->matchArg(e->loc, sc, &tiargs, i, e->parameters, &dedtypes, &s); 2109 if (m <= MATCHnomatch) 2110 goto Lno; 2111 s->semantic(sc); 2112 if (sc->sds) 2113 s->addMember(sc, sc->sds); 2114 else if (!sc->insert(s)) 2115 e->error("declaration %s is already defined", s->toChars()); 2116 2117 unSpeculative(sc, s); 2118 } 2119 goto Lyes; 2120 } 2121 } 2122 else if (e->id) 2123 { 2124 /* Declare id as an alias for type targ. Evaluate to true 2125 * is(targ id) 2126 */ 2127 tded = e->targ; 2128 goto Lyes; 2129 } 2130 2131 Lyes: 2132 if (e->id) 2133 { 2134 Dsymbol *s; 2135 Tuple *tup = isTuple(tded); 2136 if (tup) 2137 s = new TupleDeclaration(e->loc, e->id, &(tup->objects)); 2138 else 2139 s = new AliasDeclaration(e->loc, e->id, tded); 2140 s->semantic(sc); 2141 /* The reason for the !tup is unclear. It fails Phobos unittests if it is not there. 2142 * More investigation is needed. 2143 */ 2144 if (!tup && !sc->insert(s)) 2145 e->error("declaration %s is already defined", s->toChars()); 2146 if (sc->sds) 2147 s->addMember(sc, sc->sds); 2148 2149 unSpeculative(sc, s); 2150 } 2151 //printf("Lyes\n"); 2152 result = new IntegerExp(e->loc, 1, Type::tbool); 2153 return; 2154 2155 Lno: 2156 //printf("Lno\n"); 2157 result = new IntegerExp(e->loc, 0, Type::tbool); 2158 } 2159 2160 void visit(BinAssignExp *exp) 2161 { 2162 if (exp->type) 2163 { 2164 result = exp; 2165 return; 2166 } 2167 2168 Expression *e = exp->op_overload(sc); 2169 if (e) 2170 { 2171 result = e; 2172 return; 2173 } 2174 2175 if (exp->e1->checkReadModifyWrite(exp->op, exp->e2)) 2176 return setError(); 2177 2178 if (exp->e1->op == TOKarraylength) 2179 { 2180 // arr.length op= e2; 2181 e = ArrayLengthExp::rewriteOpAssign(exp); 2182 e = semantic(e, sc); 2183 result = e; 2184 return; 2185 } 2186 if (exp->e1->op == TOKslice || exp->e1->type->ty == Tarray || exp->e1->type->ty == Tsarray) 2187 { 2188 if (exp->e1->op == TOKslice) 2189 ((SliceExp *)exp->e1)->arrayop = true; 2190 2191 // T[] op= ... 2192 if (exp->e2->implicitConvTo(exp->e1->type->nextOf())) 2193 { 2194 // T[] op= T 2195 exp->e2 = exp->e2->castTo(sc, exp->e1->type->nextOf()); 2196 } 2197 else if (Expression *ex = typeCombine(exp, sc)) 2198 { 2199 result = ex; 2200 return; 2201 } 2202 exp->type = exp->e1->type; 2203 result = arrayOp(exp, sc); 2204 return; 2205 } 2206 2207 exp->e1 = semantic(exp->e1, sc); 2208 exp->e1 = exp->e1->optimize(WANTvalue); 2209 exp->e1 = exp->e1->modifiableLvalue(sc, exp->e1); 2210 exp->type = exp->e1->type; 2211 if (exp->checkScalar()) 2212 return setError(); 2213 2214 int arith = (exp->op == TOKaddass || exp->op == TOKminass || exp->op == TOKmulass || 2215 exp->op == TOKdivass || exp->op == TOKmodass || exp->op == TOKpowass); 2216 int bitwise = (exp->op == TOKandass || exp->op == TOKorass || exp->op == TOKxorass); 2217 int shift = (exp->op == TOKshlass || exp->op == TOKshrass || exp->op == TOKushrass); 2218 2219 if (bitwise && exp->type->toBasetype()->ty == Tbool) 2220 exp->e2 = exp->e2->implicitCastTo(sc, exp->type); 2221 else if (exp->checkNoBool()) 2222 return setError(); 2223 2224 if ((exp->op == TOKaddass || exp->op == TOKminass) && 2225 exp->e1->type->toBasetype()->ty == Tpointer && 2226 exp->e2->type->toBasetype()->isintegral()) 2227 { 2228 result = scaleFactor(exp, sc); 2229 return; 2230 } 2231 2232 if (Expression *ex = typeCombine(exp, sc)) 2233 { 2234 result = ex; 2235 return; 2236 } 2237 2238 if (arith && exp->checkArithmeticBin()) 2239 return setError(); 2240 if ((bitwise || shift) && exp->checkIntegralBin()) 2241 return setError(); 2242 if (shift) 2243 { 2244 if (exp->e2->type->toBasetype()->ty != Tvector) 2245 exp->e2 = exp->e2->castTo(sc, Type::tshiftcnt); 2246 } 2247 2248 if (!Target::isVectorOpSupported(exp->type->toBasetype(), exp->op, exp->e2->type->toBasetype())) 2249 { 2250 result = exp->incompatibleTypes(); 2251 return; 2252 } 2253 2254 if (exp->e1->op == TOKerror || exp->e2->op == TOKerror) 2255 return setError(); 2256 2257 e = exp->checkOpAssignTypes(sc); 2258 if (e->op == TOKerror) 2259 { 2260 result = e; 2261 return; 2262 } 2263 2264 assert(e->op == TOKassign || e == exp); 2265 result = ((BinExp *)e)->reorderSettingAAElem(sc); 2266 } 2267 2268 void visit(CompileExp *exp) 2269 { 2270 StringExp *se = semanticString(sc, exp->e1, "argument to mixin"); 2271 if (!se) 2272 return setError(); 2273 se = se->toUTF8(sc); 2274 unsigned errors = global.errors; 2275 Parser p(exp->loc, sc->_module, (utf8_t *)se->string, se->len, 0); 2276 p.nextToken(); 2277 //printf("p.loc.linnum = %d\n", p.loc.linnum); 2278 Expression *e = p.parseExpression(); 2279 if (p.errors) 2280 { 2281 assert(global.errors != errors); // should have caught all these cases 2282 return setError(); 2283 } 2284 if (p.token.value != TOKeof) 2285 { 2286 exp->error("incomplete mixin expression (%s)", se->toChars()); 2287 return setError(); 2288 } 2289 result = semantic(e, sc); 2290 } 2291 2292 void visit(ImportExp *e) 2293 { 2294 StringExp *se = semanticString(sc, e->e1, "file name argument"); 2295 if (!se) 2296 return setError(); 2297 se = se->toUTF8(sc); 2298 2299 const char *name = (char *)se->string; 2300 if (!global.params.fileImppath) 2301 { 2302 e->error("need -Jpath switch to import text file %s", name); 2303 return setError(); 2304 } 2305 2306 /* Be wary of CWE-22: Improper Limitation of a Pathname to a Restricted Directory 2307 * ('Path Traversal') attacks. 2308 * http://cwe.mitre.org/data/definitions/22.html 2309 */ 2310 2311 name = FileName::safeSearchPath(global.filePath, name); 2312 if (!name) 2313 { 2314 e->error("file %s cannot be found or not in a path specified with -J", se->toChars()); 2315 return setError(); 2316 } 2317 2318 if (global.params.verbose) 2319 message("file %.*s\t(%s)", (int)se->len, (char *)se->string, name); 2320 if (global.params.moduleDeps != NULL) 2321 { 2322 OutBuffer *ob = global.params.moduleDeps; 2323 Module* imod = sc->instantiatingModule(); 2324 2325 if (!global.params.moduleDepsFile) 2326 ob->writestring("depsFile "); 2327 ob->writestring(imod->toPrettyChars()); 2328 ob->writestring(" ("); 2329 escapePath(ob, imod->srcfile->toChars()); 2330 ob->writestring(") : "); 2331 if (global.params.moduleDepsFile) 2332 ob->writestring("string : "); 2333 ob->writestring((char *) se->string); 2334 ob->writestring(" ("); 2335 escapePath(ob, name); 2336 ob->writestring(")"); 2337 ob->writenl(); 2338 } 2339 2340 { 2341 File f(name); 2342 if (f.read()) 2343 { 2344 e->error("cannot read file %s", f.toChars()); 2345 return setError(); 2346 } 2347 else 2348 { 2349 f.ref = 1; 2350 se = new StringExp(e->loc, f.buffer, f.len); 2351 } 2352 } 2353 result = semantic(se, sc); 2354 } 2355 2356 void visit(AssertExp *exp) 2357 { 2358 if (Expression *ex = unaSemantic(exp, sc)) 2359 { 2360 result = ex; 2361 return; 2362 } 2363 exp->e1 = resolveProperties(sc, exp->e1); 2364 // BUG: see if we can do compile time elimination of the Assert 2365 exp->e1 = exp->e1->optimize(WANTvalue); 2366 exp->e1 = exp->e1->toBoolean(sc); 2367 if (exp->msg) 2368 { 2369 exp->msg = semantic(exp->msg, sc); 2370 exp->msg = resolveProperties(sc, exp->msg); 2371 exp->msg = exp->msg->implicitCastTo(sc, Type::tchar->constOf()->arrayOf()); 2372 exp->msg = exp->msg->optimize(WANTvalue); 2373 } 2374 2375 if (exp->e1->op == TOKerror) 2376 { 2377 result = exp->e1; 2378 return; 2379 } 2380 if (exp->msg && exp->msg->op == TOKerror) 2381 { 2382 result = exp->msg; 2383 return; 2384 } 2385 2386 bool f1 = checkNonAssignmentArrayOp(exp->e1); 2387 bool f2 = exp->msg && checkNonAssignmentArrayOp(exp->msg); 2388 if (f1 || f2) 2389 return setError(); 2390 2391 if (exp->e1->isBool(false)) 2392 { 2393 FuncDeclaration *fd = sc->parent->isFuncDeclaration(); 2394 if (fd) 2395 fd->hasReturnExp |= 4; 2396 sc->callSuper |= CSXhalt; 2397 if (sc->fieldinit) 2398 { 2399 for (size_t i = 0; i < sc->fieldinit_dim; i++) 2400 sc->fieldinit[i] |= CSXhalt; 2401 } 2402 2403 if (!global.params.useAssert) 2404 { 2405 Expression *e = new HaltExp(exp->loc); 2406 e = semantic(e, sc); 2407 result = e; 2408 return; 2409 } 2410 } 2411 exp->type = Type::tvoid; 2412 result = exp; 2413 } 2414 2415 void visit(DotIdExp *exp) 2416 { 2417 Expression *e = semanticY(exp, sc, 1); 2418 if (e && isDotOpDispatch(e)) 2419 { 2420 unsigned errors = global.startGagging(); 2421 e = resolvePropertiesX(sc, e); 2422 if (global.endGagging(errors)) 2423 e = NULL; /* fall down to UFCS */ 2424 else 2425 { 2426 result = e; 2427 return; 2428 } 2429 } 2430 if (!e) // if failed to find the property 2431 { 2432 /* If ident is not a valid property, rewrite: 2433 * e1.ident 2434 * as: 2435 * .ident(e1) 2436 */ 2437 e = resolveUFCSProperties(sc, exp); 2438 } 2439 result = e; 2440 } 2441 2442 void visit(DotTemplateExp *e) 2443 { 2444 if (Expression *ex = unaSemantic(e, sc)) 2445 { 2446 result = ex; 2447 return; 2448 } 2449 result = e; 2450 } 2451 2452 void visit(DotVarExp *exp) 2453 { 2454 if (exp->type) 2455 { 2456 result = exp; 2457 return; 2458 } 2459 2460 exp->var = exp->var->toAlias()->isDeclaration(); 2461 2462 exp->e1 = semantic(exp->e1, sc); 2463 2464 if (TupleDeclaration *tup = exp->var->isTupleDeclaration()) 2465 { 2466 /* Replace: 2467 * e1.tuple(a, b, c) 2468 * with: 2469 * tuple(e1.a, e1.b, e1.c) 2470 */ 2471 Expression *e0 = NULL; 2472 Expression *ev = sc->func ? extractSideEffect(sc, "__tup", &e0, exp->e1) : exp->e1; 2473 2474 Expressions *exps = new Expressions; 2475 exps->reserve(tup->objects->dim); 2476 for (size_t i = 0; i < tup->objects->dim; i++) 2477 { 2478 RootObject *o = (*tup->objects)[i]; 2479 Expression *e; 2480 if (o->dyncast() == DYNCAST_EXPRESSION) 2481 { 2482 e = (Expression *)o; 2483 if (e->op == TOKdsymbol) 2484 { 2485 Dsymbol *s = ((DsymbolExp *)e)->s; 2486 e = new DotVarExp(exp->loc, ev, s->isDeclaration()); 2487 } 2488 } 2489 else if (o->dyncast() == DYNCAST_DSYMBOL) 2490 { 2491 e = new DsymbolExp(exp->loc, (Dsymbol *)o); 2492 } 2493 else if (o->dyncast() == DYNCAST_TYPE) 2494 { 2495 e = new TypeExp(exp->loc, (Type *)o); 2496 } 2497 else 2498 { 2499 exp->error("%s is not an expression", o->toChars()); 2500 return setError(); 2501 } 2502 exps->push(e); 2503 } 2504 2505 Expression *e = new TupleExp(exp->loc, e0, exps); 2506 e = semantic(e, sc); 2507 result = e; 2508 return; 2509 } 2510 2511 exp->e1 = exp->e1->addDtorHook(sc); 2512 2513 Type *t1 = exp->e1->type; 2514 2515 if (FuncDeclaration *fd = exp->var->isFuncDeclaration()) 2516 { 2517 // for functions, do checks after overload resolution 2518 if (!fd->functionSemantic()) 2519 return setError(); 2520 2521 /* Bugzilla 13843: If fd obviously has no overloads, we should 2522 * normalize AST, and it will give a chance to wrap fd with FuncExp. 2523 */ 2524 if (fd->isNested() || fd->isFuncLiteralDeclaration()) 2525 { 2526 // (e1, fd) 2527 Expression *e = resolve(exp->loc, sc, fd, false); 2528 result = Expression::combine(exp->e1, e); 2529 return; 2530 } 2531 2532 exp->type = fd->type; 2533 assert(exp->type); 2534 } 2535 else if (exp->var->isOverDeclaration()) 2536 { 2537 exp->type = Type::tvoid; // ambiguous type? 2538 } 2539 else 2540 { 2541 exp->type = exp->var->type; 2542 if (!exp->type && global.errors) 2543 { 2544 // var is goofed up, just return 0 2545 return setError(); 2546 } 2547 assert(exp->type); 2548 2549 if (t1->ty == Tpointer) 2550 t1 = t1->nextOf(); 2551 2552 exp->type = exp->type->addMod(t1->mod); 2553 2554 Dsymbol *vparent = exp->var->toParent(); 2555 AggregateDeclaration *ad = vparent ? vparent->isAggregateDeclaration() : NULL; 2556 2557 if (Expression *e1x = getRightThis(exp->loc, sc, ad, exp->e1, exp->var, 1)) 2558 exp->e1 = e1x; 2559 else 2560 { 2561 /* Later checkRightThis will report correct error for invalid field variable access. 2562 */ 2563 Expression *e = new VarExp(exp->loc, exp->var); 2564 e = semantic(e, sc); 2565 result = e; 2566 return; 2567 } 2568 checkAccess(exp->loc, sc, exp->e1, exp->var); 2569 2570 VarDeclaration *v = exp->var->isVarDeclaration(); 2571 if (v && (v->isDataseg() || (v->storage_class & STCmanifest))) 2572 { 2573 Expression *e = expandVar(WANTvalue, v); 2574 if (e) 2575 { 2576 result = e; 2577 return; 2578 } 2579 } 2580 2581 if (v && v->isDataseg()) // fix bugzilla 8238 2582 { 2583 // (e1, v) 2584 checkAccess(exp->loc, sc, exp->e1, v); 2585 Expression *e = new VarExp(exp->loc, v); 2586 e = new CommaExp(exp->loc, exp->e1, e); 2587 e = semantic(e, sc); 2588 result = e; 2589 return; 2590 } 2591 } 2592 2593 //printf("-DotVarExp::semantic('%s')\n", exp->toChars()); 2594 result = exp; 2595 } 2596 2597 void visit(DotTemplateInstanceExp *exp) 2598 { 2599 // Indicate we need to resolve by UFCS. 2600 Expression *e = semanticY(exp, sc, 1); 2601 if (!e) 2602 e = resolveUFCSProperties(sc, exp); 2603 result = e; 2604 } 2605 2606 void visit(DelegateExp *e) 2607 { 2608 if (e->type) 2609 { 2610 result = e; 2611 return; 2612 } 2613 2614 e->e1 = semantic(e->e1, sc); 2615 e->type = new TypeDelegate(e->func->type); 2616 e->type = e->type->semantic(e->loc, sc); 2617 FuncDeclaration *f = e->func->toAliasFunc(); 2618 AggregateDeclaration *ad = f->toParent()->isAggregateDeclaration(); 2619 if (f->needThis()) 2620 e->e1 = getRightThis(e->loc, sc, ad, e->e1, f); 2621 if (f->type->ty == Tfunction) 2622 { 2623 TypeFunction *tf = (TypeFunction *)f->type; 2624 if (!MODmethodConv(e->e1->type->mod, f->type->mod)) 2625 { 2626 OutBuffer thisBuf, funcBuf; 2627 MODMatchToBuffer(&thisBuf, e->e1->type->mod, tf->mod); 2628 MODMatchToBuffer(&funcBuf, tf->mod, e->e1->type->mod); 2629 e->error("%smethod %s is not callable using a %s%s", 2630 funcBuf.peekString(), f->toPrettyChars(), thisBuf.peekString(), e->e1->toChars()); 2631 return setError(); 2632 } 2633 } 2634 if (ad && ad->isClassDeclaration() && ad->type != e->e1->type) 2635 { 2636 // A downcast is required for interfaces, see Bugzilla 3706 2637 e->e1 = new CastExp(e->loc, e->e1, ad->type); 2638 e->e1 = semantic(e->e1, sc); 2639 } 2640 result = e; 2641 } 2642 2643 void visit(DotTypeExp *exp) 2644 { 2645 if (exp->type) 2646 { 2647 result = exp; 2648 return; 2649 } 2650 2651 if (Expression *e = unaSemantic(exp, sc)) 2652 { 2653 result = e; 2654 return; 2655 } 2656 2657 exp->type = exp->sym->getType()->addMod(exp->e1->type->mod); 2658 result = exp; 2659 } 2660 2661 void visit(CallExp *exp) 2662 { 2663 if (exp->type) 2664 { 2665 result = exp; // semantic() already run 2666 return; 2667 } 2668 2669 Type *t1; 2670 Objects *tiargs = NULL; // initial list of template arguments 2671 Expression *ethis = NULL; 2672 Type *tthis = NULL; 2673 Expression *e1org = exp->e1; 2674 2675 if (exp->e1->op == TOKcomma) 2676 { 2677 /* Rewrite (a,b)(args) as (a,(b(args))) 2678 */ 2679 CommaExp *ce = (CommaExp *)exp->e1; 2680 exp->e1 = ce->e2; 2681 ce->e2 = exp; 2682 result = semantic(ce, sc); 2683 return; 2684 } 2685 2686 if (exp->e1->op == TOKdelegate) 2687 { 2688 DelegateExp *de = (DelegateExp *)exp->e1; 2689 exp->e1 = new DotVarExp(de->loc, de->e1, de->func, de->hasOverloads); 2690 result = semantic(exp, sc); 2691 return; 2692 } 2693 2694 if (exp->e1->op == TOKfunction) 2695 { 2696 if (arrayExpressionSemantic(exp->arguments, sc) || 2697 preFunctionParameters(sc, exp->arguments)) 2698 { 2699 return setError(); 2700 } 2701 2702 // Run e1 semantic even if arguments have any errors 2703 FuncExp *fe = (FuncExp *)exp->e1; 2704 exp->e1 = callExpSemantic(fe, sc, exp->arguments); 2705 if (exp->e1->op == TOKerror) 2706 { 2707 result = exp->e1; 2708 return; 2709 } 2710 } 2711 2712 if (Expression *ex = resolveUFCS(sc, exp)) 2713 { 2714 result = ex; 2715 return; 2716 } 2717 2718 /* This recognizes: 2719 * foo!(tiargs)(funcargs) 2720 */ 2721 if (exp->e1->op == TOKscope) 2722 { 2723 ScopeExp *se = (ScopeExp *)exp->e1; 2724 TemplateInstance *ti = se->sds->isTemplateInstance(); 2725 if (ti) 2726 { 2727 /* Attempt to instantiate ti. If that works, go with it. 2728 * If not, go with partial explicit specialization. 2729 */ 2730 WithScopeSymbol *withsym; 2731 if (!ti->findTempDecl(sc, &withsym) || 2732 !ti->semanticTiargs(sc)) 2733 { 2734 return setError(); 2735 } 2736 if (withsym && withsym->withstate->wthis) 2737 { 2738 exp->e1 = new VarExp(exp->e1->loc, withsym->withstate->wthis); 2739 exp->e1 = new DotTemplateInstanceExp(exp->e1->loc, exp->e1, ti); 2740 goto Ldotti; 2741 } 2742 if (ti->needsTypeInference(sc, 1)) 2743 { 2744 /* Go with partial explicit specialization 2745 */ 2746 tiargs = ti->tiargs; 2747 assert(ti->tempdecl); 2748 if (TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration()) 2749 exp->e1 = new TemplateExp(exp->loc, td); 2750 else if (OverDeclaration *od = ti->tempdecl->isOverDeclaration()) 2751 exp->e1 = new VarExp(exp->loc, od); 2752 else 2753 exp->e1 = new OverExp(exp->loc, ti->tempdecl->isOverloadSet()); 2754 } 2755 else 2756 { 2757 Expression *e1x = semantic(exp->e1, sc); 2758 if (e1x->op == TOKerror) 2759 { 2760 result = e1x; 2761 return; 2762 } 2763 exp->e1 = e1x; 2764 } 2765 } 2766 } 2767 2768 /* This recognizes: 2769 * expr.foo!(tiargs)(funcargs) 2770 */ 2771 Ldotti: 2772 if (exp->e1->op == TOKdotti && !exp->e1->type) 2773 { 2774 DotTemplateInstanceExp *se = (DotTemplateInstanceExp *)exp->e1; 2775 TemplateInstance *ti = se->ti; 2776 { 2777 /* Attempt to instantiate ti. If that works, go with it. 2778 * If not, go with partial explicit specialization. 2779 */ 2780 if (!se->findTempDecl(sc) || 2781 !ti->semanticTiargs(sc)) 2782 { 2783 return setError(); 2784 } 2785 if (ti->needsTypeInference(sc, 1)) 2786 { 2787 /* Go with partial explicit specialization 2788 */ 2789 tiargs = ti->tiargs; 2790 assert(ti->tempdecl); 2791 if (TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration()) 2792 exp->e1 = new DotTemplateExp(exp->loc, se->e1, td); 2793 else if (OverDeclaration *od = ti->tempdecl->isOverDeclaration()) 2794 { 2795 exp->e1 = new DotVarExp(exp->loc, se->e1, od, true); 2796 } 2797 else 2798 exp->e1 = new DotExp(exp->loc, se->e1, new OverExp(exp->loc, ti->tempdecl->isOverloadSet())); 2799 } 2800 else 2801 { 2802 Expression *e1x = semantic(exp->e1, sc); 2803 if (e1x->op == TOKerror) 2804 { 2805 result =e1x; 2806 return; 2807 } 2808 exp->e1 = e1x; 2809 } 2810 } 2811 } 2812 2813 Lagain: 2814 //printf("Lagain: %s\n", exp->toChars()); 2815 exp->f = NULL; 2816 if (exp->e1->op == TOKthis || exp->e1->op == TOKsuper) 2817 { 2818 // semantic() run later for these 2819 } 2820 else 2821 { 2822 if (exp->e1->op == TOKdotid) 2823 { 2824 DotIdExp *die = (DotIdExp *)exp->e1; 2825 exp->e1 = semantic(die, sc); 2826 /* Look for e1 having been rewritten to expr.opDispatch!(string) 2827 * We handle such earlier, so go back. 2828 * Note that in the rewrite, we carefully did not run semantic() on e1 2829 */ 2830 if (exp->e1->op == TOKdotti && !exp->e1->type) 2831 { 2832 goto Ldotti; 2833 } 2834 } 2835 else 2836 { 2837 static int nest; 2838 if (++nest > 500) 2839 { 2840 exp->error("recursive evaluation of %s", exp->toChars()); 2841 --nest; 2842 return setError(); 2843 } 2844 Expression *ex = unaSemantic(exp, sc); 2845 --nest; 2846 if (ex) 2847 { 2848 result = ex; 2849 return; 2850 } 2851 } 2852 2853 /* Look for e1 being a lazy parameter 2854 */ 2855 if (exp->e1->op == TOKvar) 2856 { 2857 VarExp *ve = (VarExp *)exp->e1; 2858 if (ve->var->storage_class & STClazy) 2859 { 2860 // lazy paramaters can be called without violating purity and safety 2861 Type *tw = ve->var->type; 2862 Type *tc = ve->var->type->substWildTo(MODconst); 2863 TypeFunction *tf = new TypeFunction(NULL, tc, 0, LINKd, STCsafe | STCpure); 2864 (tf = (TypeFunction *)tf->semantic(exp->loc, sc))->next = tw; // hack for bug7757 2865 TypeDelegate *t = new TypeDelegate(tf); 2866 ve->type = t->semantic(exp->loc, sc); 2867 } 2868 VarDeclaration *v = ve->var->isVarDeclaration(); 2869 if (v && ve->checkPurity(sc, v)) 2870 return setError(); 2871 } 2872 2873 if (exp->e1->op == TOKsymoff && ((SymOffExp *)exp->e1)->hasOverloads) 2874 { 2875 SymOffExp *se = (SymOffExp *)exp->e1; 2876 exp->e1 = new VarExp(se->loc, se->var, true); 2877 exp->e1 = semantic(exp->e1, sc); 2878 } 2879 else if (exp->e1->op == TOKdot) 2880 { 2881 DotExp *de = (DotExp *) exp->e1; 2882 2883 if (de->e2->op == TOKoverloadset) 2884 { 2885 ethis = de->e1; 2886 tthis = de->e1->type; 2887 exp->e1 = de->e2; 2888 } 2889 } 2890 else if (exp->e1->op == TOKstar && exp->e1->type->ty == Tfunction) 2891 { 2892 // Rewrite (*fp)(arguments) to fp(arguments) 2893 exp->e1 = ((PtrExp *)exp->e1)->e1; 2894 } 2895 } 2896 2897 t1 = exp->e1->type ? exp->e1->type->toBasetype() : NULL; 2898 2899 if (exp->e1->op == TOKerror) 2900 { 2901 result = exp->e1; 2902 return; 2903 } 2904 if (arrayExpressionSemantic(exp->arguments, sc) || 2905 preFunctionParameters(sc, exp->arguments)) 2906 { 2907 return setError(); 2908 } 2909 2910 // Check for call operator overload 2911 if (t1) 2912 { 2913 if (t1->ty == Tstruct) 2914 { 2915 StructDeclaration *sd = ((TypeStruct *)t1)->sym; 2916 sd->size(exp->loc); // Resolve forward references to construct object 2917 if (sd->sizeok != SIZEOKdone) 2918 return setError(); 2919 if (!sd->ctor) 2920 sd->ctor = sd->searchCtor(); 2921 2922 // First look for constructor 2923 if (exp->e1->op == TOKtype && sd->ctor) 2924 { 2925 if (!sd->noDefaultCtor && !(exp->arguments && exp->arguments->dim)) 2926 goto Lx; 2927 2928 StructLiteralExp *sle = new StructLiteralExp(exp->loc, sd, NULL, exp->e1->type); 2929 if (!sd->fill(exp->loc, sle->elements, true)) 2930 return setError(); 2931 if (checkFrameAccess(exp->loc, sc, sd, sle->elements->dim)) 2932 return setError(); 2933 // Bugzilla 14556: Set concrete type to avoid further redundant semantic(). 2934 sle->type = exp->e1->type; 2935 2936 /* Constructor takes a mutable object, so don't use 2937 * the immutable initializer symbol. 2938 */ 2939 sle->useStaticInit = false; 2940 2941 Expression *e = sle; 2942 if (CtorDeclaration *cf = sd->ctor->isCtorDeclaration()) 2943 { 2944 e = new DotVarExp(exp->loc, e, cf, true); 2945 } 2946 else if (TemplateDeclaration *td = sd->ctor->isTemplateDeclaration()) 2947 { 2948 e = new DotTemplateExp(exp->loc, e, td); 2949 } 2950 else if (OverloadSet *os = sd->ctor->isOverloadSet()) 2951 { 2952 e = new DotExp(exp->loc, e, new OverExp(exp->loc, os)); 2953 } 2954 else 2955 assert(0); 2956 e = new CallExp(exp->loc, e, exp->arguments); 2957 result = semantic(e, sc); 2958 return; 2959 } 2960 // No constructor, look for overload of opCall 2961 if (search_function(sd, Id::call)) 2962 goto L1; // overload of opCall, therefore it's a call 2963 2964 if (exp->e1->op != TOKtype) 2965 { 2966 if (sd->aliasthis && exp->e1->type != exp->att1) 2967 { 2968 if (!exp->att1 && exp->e1->type->checkAliasThisRec()) 2969 exp->att1 = exp->e1->type; 2970 exp->e1 = resolveAliasThis(sc, exp->e1); 2971 goto Lagain; 2972 } 2973 exp->error("%s %s does not overload ()", sd->kind(), sd->toChars()); 2974 return setError(); 2975 } 2976 2977 /* It's a struct literal 2978 */ 2979 Lx: 2980 Expression *e = new StructLiteralExp(exp->loc, sd, exp->arguments, exp->e1->type); 2981 result = semantic(e, sc); 2982 return; 2983 } 2984 else if (t1->ty == Tclass) 2985 { 2986 L1: 2987 // Rewrite as e1.call(arguments) 2988 Expression *e = new DotIdExp(exp->loc, exp->e1, Id::call); 2989 e = new CallExp(exp->loc, e, exp->arguments); 2990 result = semantic(e, sc); 2991 return; 2992 } 2993 else if (exp->e1->op == TOKtype && t1->isscalar()) 2994 { 2995 Expression *e; 2996 2997 // Make sure to use the the enum type itself rather than its 2998 // base type (see bugzilla 16346) 2999 if (exp->e1->type->ty == Tenum) 3000 { 3001 t1 = exp->e1->type; 3002 } 3003 3004 if (!exp->arguments || exp->arguments->dim == 0) 3005 { 3006 e = t1->defaultInitLiteral(exp->loc); 3007 } 3008 else if (exp->arguments->dim == 1) 3009 { 3010 e = (*exp->arguments)[0]; 3011 e = e->implicitCastTo(sc, t1); 3012 e = new CastExp(exp->loc, e, t1); 3013 } 3014 else 3015 { 3016 exp->error("more than one argument for construction of %s", t1->toChars()); 3017 e = new ErrorExp(); 3018 } 3019 result = semantic(e, sc); 3020 return; 3021 } 3022 } 3023 3024 if ((exp->e1->op == TOKdotvar && t1->ty == Tfunction) || 3025 exp->e1->op == TOKdottd) 3026 { 3027 UnaExp *ue = (UnaExp *)(exp->e1); 3028 3029 Expression *ue1 = ue->e1; 3030 Expression *ue1old = ue1; // need for 'right this' check 3031 VarDeclaration *v; 3032 if (ue1->op == TOKvar && 3033 (v = ((VarExp *)ue1)->var->isVarDeclaration()) != NULL && 3034 v->needThis()) 3035 { 3036 ue->e1 = new TypeExp(ue1->loc, ue1->type); 3037 ue1 = NULL; 3038 } 3039 3040 DotVarExp *dve; 3041 DotTemplateExp *dte; 3042 Dsymbol *s; 3043 if (exp->e1->op == TOKdotvar) 3044 { 3045 dve = (DotVarExp *)(exp->e1); 3046 dte = NULL; 3047 s = dve->var; 3048 tiargs = NULL; 3049 } 3050 else 3051 { 3052 dve = NULL; 3053 dte = (DotTemplateExp *)(exp->e1); 3054 s = dte->td; 3055 } 3056 3057 // Do overload resolution 3058 exp->f = resolveFuncCall(exp->loc, sc, s, tiargs, ue1 ? ue1->type : NULL, exp->arguments); 3059 if (!exp->f || exp->f->errors || exp->f->type->ty == Terror) 3060 return setError(); 3061 if (exp->f->interfaceVirtual) 3062 { 3063 /* Cast 'this' to the type of the interface, and replace f with the interface's equivalent 3064 */ 3065 BaseClass *b = exp->f->interfaceVirtual; 3066 ClassDeclaration *ad2 = b->sym; 3067 ue->e1 = ue->e1->castTo(sc, ad2->type->addMod(ue->e1->type->mod)); 3068 ue->e1 = semantic(ue->e1, sc); 3069 ue1 = ue->e1; 3070 int vi = exp->f->findVtblIndex((Dsymbols*)&ad2->vtbl, (int)ad2->vtbl.dim); 3071 assert(vi >= 0); 3072 exp->f = ad2->vtbl[vi]->isFuncDeclaration(); 3073 assert(exp->f); 3074 } 3075 if (exp->f->needThis()) 3076 { 3077 AggregateDeclaration *ad = exp->f->toParent2()->isAggregateDeclaration(); 3078 ue->e1 = getRightThis(exp->loc, sc, ad, ue->e1, exp->f); 3079 if (ue->e1->op == TOKerror) 3080 { 3081 result = ue->e1; 3082 return; 3083 } 3084 ethis = ue->e1; 3085 tthis = ue->e1->type; 3086 if (!(exp->f->type->ty == Tfunction && ((TypeFunction *)exp->f->type)->isscope)) 3087 { 3088 if (global.params.vsafe && checkParamArgumentEscape(sc, exp->f, Id::This, ethis, false)) 3089 return setError(); 3090 } 3091 } 3092 3093 /* Cannot call public functions from inside invariant 3094 * (because then the invariant would have infinite recursion) 3095 */ 3096 if (sc->func && sc->func->isInvariantDeclaration() && 3097 ue->e1->op == TOKthis && 3098 exp->f->addPostInvariant() 3099 ) 3100 { 3101 exp->error("cannot call public/export function %s from invariant", exp->f->toChars()); 3102 return setError(); 3103 } 3104 3105 exp->checkDeprecated(sc, exp->f); 3106 exp->checkPurity(sc, exp->f); 3107 exp->checkSafety(sc, exp->f); 3108 exp->checkNogc(sc, exp->f); 3109 checkAccess(exp->loc, sc, ue->e1, exp->f); 3110 if (!exp->f->needThis()) 3111 { 3112 exp->e1 = Expression::combine(ue->e1, new VarExp(exp->loc, exp->f, false)); 3113 } 3114 else 3115 { 3116 if (ue1old->checkRightThis(sc)) 3117 return setError(); 3118 if (exp->e1->op == TOKdotvar) 3119 { 3120 dve->var = exp->f; 3121 exp->e1->type = exp->f->type; 3122 } 3123 else 3124 { 3125 exp->e1 = new DotVarExp(exp->loc, dte->e1, exp->f, false); 3126 exp->e1 = semantic(exp->e1, sc); 3127 if (exp->e1->op == TOKerror) 3128 return setError(); 3129 ue = (UnaExp *)exp->e1; 3130 } 3131 3132 // See if we need to adjust the 'this' pointer 3133 AggregateDeclaration *ad = exp->f->isThis(); 3134 ClassDeclaration *cd = ue->e1->type->isClassHandle(); 3135 if (ad && cd && ad->isClassDeclaration()) 3136 { 3137 if (ue->e1->op == TOKdottype) 3138 { 3139 ue->e1 = ((DotTypeExp *)ue->e1)->e1; 3140 exp->directcall = true; 3141 } 3142 else if (ue->e1->op == TOKsuper) 3143 exp->directcall = true; 3144 else if ((cd->storage_class & STCfinal) != 0) // Bugzilla 14211 3145 exp->directcall = true; 3146 3147 if (ad != cd) 3148 { 3149 ue->e1 = ue->e1->castTo(sc, ad->type->addMod(ue->e1->type->mod)); 3150 ue->e1 = semantic(ue->e1, sc); 3151 } 3152 } 3153 } 3154 // If we've got a pointer to a function then deference it 3155 // https://issues.dlang.org/show_bug.cgi?id=16483 3156 if (exp->e1->type->ty == Tpointer && exp->e1->type->nextOf()->ty == Tfunction) 3157 { 3158 Expression *e = new PtrExp(exp->loc, exp->e1); 3159 e->type = exp->e1->type->nextOf(); 3160 exp->e1 = e; 3161 } 3162 t1 = exp->e1->type; 3163 } 3164 else if (exp->e1->op == TOKsuper) 3165 { 3166 // Base class constructor call 3167 AggregateDeclaration *ad = sc->func ? sc->func->isThis() : NULL; 3168 ClassDeclaration *cd = ad ? ad->isClassDeclaration() : NULL; 3169 if (!cd || !cd->baseClass || !sc->func->isCtorDeclaration()) 3170 { 3171 exp->error("super class constructor call must be in a constructor"); 3172 return setError(); 3173 } 3174 if (!cd->baseClass->ctor) 3175 { 3176 exp->error("no super class constructor for %s", cd->baseClass->toChars()); 3177 return setError(); 3178 } 3179 3180 if (!sc->intypeof && !(sc->callSuper & CSXhalt)) 3181 { 3182 if (sc->noctor || sc->callSuper & CSXlabel) 3183 exp->error("constructor calls not allowed in loops or after labels"); 3184 if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor)) 3185 exp->error("multiple constructor calls"); 3186 if ((sc->callSuper & CSXreturn) && !(sc->callSuper & CSXany_ctor)) 3187 exp->error("an earlier return statement skips constructor"); 3188 sc->callSuper |= CSXany_ctor | CSXsuper_ctor; 3189 } 3190 3191 tthis = cd->type->addMod(sc->func->type->mod); 3192 if (OverloadSet *os = cd->baseClass->ctor->isOverloadSet()) 3193 exp->f = resolveOverloadSet(exp->loc, sc, os, NULL, tthis, exp->arguments); 3194 else 3195 exp->f = resolveFuncCall(exp->loc, sc, cd->baseClass->ctor, NULL, tthis, exp->arguments, 0); 3196 if (!exp->f || exp->f->errors) 3197 return setError(); 3198 exp->checkDeprecated(sc, exp->f); 3199 exp->checkPurity(sc, exp->f); 3200 exp->checkSafety(sc, exp->f); 3201 exp->checkNogc(sc, exp->f); 3202 checkAccess(exp->loc, sc, NULL, exp->f); 3203 3204 exp->e1 = new DotVarExp(exp->e1->loc, exp->e1, exp->f, false); 3205 exp->e1 = semantic(exp->e1, sc); 3206 t1 = exp->e1->type; 3207 } 3208 else if (exp->e1->op == TOKthis) 3209 { 3210 // same class constructor call 3211 AggregateDeclaration *ad = sc->func ? sc->func->isThis() : NULL; 3212 if (!ad || !sc->func->isCtorDeclaration()) 3213 { 3214 exp->error("constructor call must be in a constructor"); 3215 return setError(); 3216 } 3217 3218 if (!sc->intypeof && !(sc->callSuper & CSXhalt)) 3219 { 3220 if (sc->noctor || sc->callSuper & CSXlabel) 3221 exp->error("constructor calls not allowed in loops or after labels"); 3222 if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor)) 3223 exp->error("multiple constructor calls"); 3224 if ((sc->callSuper & CSXreturn) && !(sc->callSuper & CSXany_ctor)) 3225 exp->error("an earlier return statement skips constructor"); 3226 sc->callSuper |= CSXany_ctor | CSXthis_ctor; 3227 } 3228 3229 tthis = ad->type->addMod(sc->func->type->mod); 3230 if (OverloadSet *os = ad->ctor->isOverloadSet()) 3231 exp->f = resolveOverloadSet(exp->loc, sc, os, NULL, tthis, exp->arguments); 3232 else 3233 exp->f = resolveFuncCall(exp->loc, sc, ad->ctor, NULL, tthis, exp->arguments, 0); 3234 if (!exp->f || exp->f->errors) 3235 return setError(); 3236 exp->checkDeprecated(sc, exp->f); 3237 exp->checkPurity(sc, exp->f); 3238 exp->checkSafety(sc, exp->f); 3239 exp->checkNogc(sc, exp->f); 3240 //checkAccess(exp->loc, sc, NULL, exp->f); // necessary? 3241 3242 exp->e1 = new DotVarExp(exp->e1->loc, exp->e1, exp->f, false); 3243 exp->e1 = semantic(exp->e1, sc); 3244 t1 = exp->e1->type; 3245 3246 // BUG: this should really be done by checking the static 3247 // call graph 3248 if (exp->f == sc->func) 3249 { 3250 exp->error("cyclic constructor call"); 3251 return setError(); 3252 } 3253 } 3254 else if (exp->e1->op == TOKoverloadset) 3255 { 3256 OverloadSet *os = ((OverExp *)exp->e1)->vars; 3257 exp->f = resolveOverloadSet(exp->loc, sc, os, tiargs, tthis, exp->arguments); 3258 if (!exp->f) 3259 return setError(); 3260 if (ethis) 3261 exp->e1 = new DotVarExp(exp->loc, ethis, exp->f, false); 3262 else 3263 exp->e1 = new VarExp(exp->loc, exp->f, false); 3264 goto Lagain; 3265 } 3266 else if (!t1) 3267 { 3268 exp->error("function expected before (), not '%s'", exp->e1->toChars()); 3269 return setError(); 3270 } 3271 else if (t1->ty == Terror) 3272 { 3273 return setError(); 3274 } 3275 else if (t1->ty != Tfunction) 3276 { 3277 TypeFunction *tf; 3278 const char *p; 3279 Dsymbol *s; 3280 exp->f = NULL; 3281 if (exp->e1->op == TOKfunction) 3282 { 3283 // function literal that direct called is always inferred. 3284 assert(((FuncExp *)exp->e1)->fd); 3285 exp->f = ((FuncExp *)exp->e1)->fd; 3286 tf = (TypeFunction *)exp->f->type; 3287 p = "function literal"; 3288 } 3289 else if (t1->ty == Tdelegate) 3290 { 3291 TypeDelegate *td = (TypeDelegate *)t1; 3292 assert(td->next->ty == Tfunction); 3293 tf = (TypeFunction *)(td->next); 3294 p = "delegate"; 3295 } 3296 else if (t1->ty == Tpointer && ((TypePointer *)t1)->next->ty == Tfunction) 3297 { 3298 tf = (TypeFunction *)(((TypePointer *)t1)->next); 3299 p = "function pointer"; 3300 } 3301 else if (exp->e1->op == TOKdotvar && 3302 ((DotVarExp *)exp->e1)->var->isOverDeclaration()) 3303 { 3304 DotVarExp *dve = (DotVarExp *)exp->e1; 3305 exp->f = resolveFuncCall(exp->loc, sc, dve->var, tiargs, dve->e1->type, exp->arguments, 2); 3306 if (!exp->f) 3307 return setError(); 3308 if (exp->f->needThis()) 3309 { 3310 dve->var = exp->f; 3311 dve->type = exp->f->type; 3312 dve->hasOverloads = false; 3313 goto Lagain; 3314 } 3315 exp->e1 = new VarExp(dve->loc, exp->f, false); 3316 Expression *e = new CommaExp(exp->loc, dve->e1, exp); 3317 result = semantic(e, sc); 3318 return; 3319 } 3320 else if (exp->e1->op == TOKvar && 3321 ((VarExp *)exp->e1)->var->isOverDeclaration()) 3322 { 3323 s = ((VarExp *)exp->e1)->var; 3324 goto L2; 3325 } 3326 else if (exp->e1->op == TOKtemplate) 3327 { 3328 s = ((TemplateExp *)exp->e1)->td; 3329 L2: 3330 exp->f = resolveFuncCall(exp->loc, sc, s, tiargs, NULL, exp->arguments); 3331 if (!exp->f || exp->f->errors) 3332 return setError(); 3333 if (exp->f->needThis()) 3334 { 3335 if (hasThis(sc)) 3336 { 3337 // Supply an implicit 'this', as in 3338 // this.ident 3339 Expression *ex = new ThisExp(exp->loc); 3340 ex = semantic(ex, sc); 3341 exp->e1 = new DotVarExp(exp->loc, ex, exp->f, false); 3342 goto Lagain; 3343 } 3344 else if (isNeedThisScope(sc, exp->f)) 3345 { 3346 exp->error("need 'this' for '%s' of type '%s'", exp->f->toChars(), exp->f->type->toChars()); 3347 return setError(); 3348 } 3349 } 3350 exp->e1 = new VarExp(exp->e1->loc, exp->f, false); 3351 goto Lagain; 3352 } 3353 else 3354 { 3355 exp->error("function expected before (), not %s of type %s", exp->e1->toChars(), exp->e1->type->toChars()); 3356 return setError(); 3357 } 3358 3359 if (!tf->callMatch(NULL, exp->arguments)) 3360 { 3361 OutBuffer buf; 3362 3363 buf.writeByte('('); 3364 argExpTypesToCBuffer(&buf, exp->arguments); 3365 buf.writeByte(')'); 3366 if (tthis) 3367 tthis->modToBuffer(&buf); 3368 3369 //printf("tf = %s, args = %s\n", tf->deco, (*exp->arguments)[0]->type->deco); 3370 ::error(exp->loc, "%s %s %s is not callable using argument types %s", 3371 p, exp->e1->toChars(), parametersTypeToChars(tf->parameters, tf->varargs), 3372 buf.peekString()); 3373 3374 return setError(); 3375 } 3376 3377 // Purity and safety check should run after testing arguments matching 3378 if (exp->f) 3379 { 3380 exp->checkPurity(sc, exp->f); 3381 exp->checkSafety(sc, exp->f); 3382 exp->checkNogc(sc, exp->f); 3383 if (exp->f->checkNestedReference(sc, exp->loc)) 3384 return setError(); 3385 } 3386 else if (sc->func && sc->intypeof != 1 && !(sc->flags & SCOPEctfe)) 3387 { 3388 bool err = false; 3389 if (!tf->purity && !(sc->flags & SCOPEdebug) && sc->func->setImpure()) 3390 { 3391 exp->error("pure %s '%s' cannot call impure %s '%s'", 3392 sc->func->kind(), sc->func->toPrettyChars(), p, exp->e1->toChars()); 3393 err = true; 3394 } 3395 if (!tf->isnogc && sc->func->setGC()) 3396 { 3397 exp->error("@nogc %s '%s' cannot call non-@nogc %s '%s'", 3398 sc->func->kind(), sc->func->toPrettyChars(), p, exp->e1->toChars()); 3399 err = true; 3400 } 3401 if (tf->trust <= TRUSTsystem && sc->func->setUnsafe()) 3402 { 3403 exp->error("@safe %s '%s' cannot call @system %s '%s'", 3404 sc->func->kind(), sc->func->toPrettyChars(), p, exp->e1->toChars()); 3405 err = true; 3406 } 3407 if (err) 3408 return setError(); 3409 } 3410 3411 if (t1->ty == Tpointer) 3412 { 3413 Expression *e = new PtrExp(exp->loc, exp->e1); 3414 e->type = tf; 3415 exp->e1 = e; 3416 } 3417 t1 = tf; 3418 } 3419 else if (exp->e1->op == TOKvar) 3420 { 3421 // Do overload resolution 3422 VarExp *ve = (VarExp *)exp->e1; 3423 3424 exp->f = ve->var->isFuncDeclaration(); 3425 assert(exp->f); 3426 tiargs = NULL; 3427 3428 if (ve->hasOverloads) 3429 exp->f = resolveFuncCall(exp->loc, sc, exp->f, tiargs, NULL, exp->arguments, 2); 3430 else 3431 { 3432 exp->f = exp->f->toAliasFunc(); 3433 TypeFunction *tf = (TypeFunction *)exp->f->type; 3434 if (!tf->callMatch(NULL, exp->arguments)) 3435 { 3436 OutBuffer buf; 3437 3438 buf.writeByte('('); 3439 argExpTypesToCBuffer(&buf, exp->arguments); 3440 buf.writeByte(')'); 3441 3442 //printf("tf = %s, args = %s\n", tf->deco, (*exp->arguments)[0]->type->deco); 3443 ::error(exp->loc, "%s %s is not callable using argument types %s", 3444 exp->e1->toChars(), parametersTypeToChars(tf->parameters, tf->varargs), 3445 buf.peekString()); 3446 3447 exp->f = NULL; 3448 } 3449 } 3450 if (!exp->f || exp->f->errors) 3451 return setError(); 3452 3453 if (exp->f->needThis()) 3454 { 3455 // Change the ancestor lambdas to delegate before hasThis(sc) call. 3456 if (exp->f->checkNestedReference(sc, exp->loc)) 3457 return setError(); 3458 3459 if (hasThis(sc)) 3460 { 3461 // Supply an implicit 'this', as in 3462 // this.ident 3463 3464 Expression *ex = new ThisExp(exp->loc); 3465 ex = semantic(ex, sc); 3466 exp->e1 = new DotVarExp(exp->loc, ex, ve->var); 3467 // Note: we cannot use f directly, because further overload resolution 3468 // through the supplied 'this' may cause different result. 3469 goto Lagain; 3470 } 3471 else if (isNeedThisScope(sc, exp->f)) 3472 { 3473 exp->error("need 'this' for '%s' of type '%s'", exp->f->toChars(), exp->f->type->toChars()); 3474 return setError(); 3475 } 3476 } 3477 3478 exp->checkDeprecated(sc, exp->f); 3479 exp->checkPurity(sc, exp->f); 3480 exp->checkSafety(sc, exp->f); 3481 exp->checkNogc(sc, exp->f); 3482 checkAccess(exp->loc, sc, NULL, exp->f); 3483 if (exp->f->checkNestedReference(sc, exp->loc)) 3484 return setError(); 3485 3486 ethis = NULL; 3487 tthis = NULL; 3488 3489 if (ve->hasOverloads) 3490 { 3491 exp->e1 = new VarExp(ve->loc, exp->f, false); 3492 exp->e1->type = exp->f->type; 3493 } 3494 t1 = exp->f->type; 3495 } 3496 assert(t1->ty == Tfunction); 3497 3498 Expression *argprefix; 3499 if (!exp->arguments) 3500 exp->arguments = new Expressions(); 3501 if (functionParameters(exp->loc, sc, (TypeFunction *)(t1), tthis, exp->arguments, exp->f, &exp->type, &argprefix)) 3502 return setError(); 3503 3504 if (!exp->type) 3505 { 3506 exp->e1 = e1org; // Bugzilla 10922, avoid recursive expression printing 3507 exp->error("forward reference to inferred return type of function call '%s'", exp->toChars()); 3508 return setError(); 3509 } 3510 3511 if (exp->f && exp->f->tintro) 3512 { 3513 Type *t = exp->type; 3514 int offset = 0; 3515 TypeFunction *tf = (TypeFunction *)exp->f->tintro; 3516 3517 if (tf->next->isBaseOf(t, &offset) && offset) 3518 { 3519 exp->type = tf->next; 3520 result = Expression::combine(argprefix, exp->castTo(sc, t)); 3521 return; 3522 } 3523 } 3524 3525 // Handle the case of a direct lambda call 3526 if (exp->f && exp->f->isFuncLiteralDeclaration() && 3527 sc->func && !sc->intypeof) 3528 { 3529 exp->f->tookAddressOf = 0; 3530 } 3531 3532 result = Expression::combine(argprefix, exp); 3533 } 3534 3535 void visit(AddrExp *exp) 3536 { 3537 if (exp->type) 3538 { 3539 result = exp; 3540 return; 3541 } 3542 3543 if (Expression *ex = unaSemantic(exp, sc)) 3544 { 3545 result = ex; 3546 return; 3547 } 3548 int wasCond = exp->e1->op == TOKquestion; 3549 if (exp->e1->op == TOKdotti) 3550 { 3551 DotTemplateInstanceExp* dti = (DotTemplateInstanceExp *)exp->e1; 3552 TemplateInstance *ti = dti->ti; 3553 { 3554 //assert(ti->needsTypeInference(sc)); 3555 ti->semantic(sc); 3556 if (!ti->inst || ti->errors) // if template failed to expand 3557 return setError(); 3558 Dsymbol *s = ti->toAlias(); 3559 FuncDeclaration *f = s->isFuncDeclaration(); 3560 if (f) 3561 { 3562 exp->e1 = new DotVarExp(exp->e1->loc, dti->e1, f); 3563 exp->e1 = semantic(exp->e1, sc); 3564 } 3565 } 3566 } 3567 else if (exp->e1->op == TOKscope) 3568 { 3569 TemplateInstance *ti = ((ScopeExp *)exp->e1)->sds->isTemplateInstance(); 3570 if (ti) 3571 { 3572 //assert(ti->needsTypeInference(sc)); 3573 ti->semantic(sc); 3574 if (!ti->inst || ti->errors) // if template failed to expand 3575 return setError(); 3576 Dsymbol *s = ti->toAlias(); 3577 FuncDeclaration *f = s->isFuncDeclaration(); 3578 if (f) 3579 { 3580 exp->e1 = new VarExp(exp->e1->loc, f); 3581 exp->e1 = semantic(exp->e1, sc); 3582 } 3583 } 3584 } 3585 exp->e1 = exp->e1->toLvalue(sc, NULL); 3586 if (exp->e1->op == TOKerror) 3587 { 3588 result = exp->e1; 3589 return; 3590 } 3591 if (checkNonAssignmentArrayOp(exp->e1)) 3592 return setError(); 3593 3594 if (!exp->e1->type) 3595 { 3596 exp->error("cannot take address of %s", exp->e1->toChars()); 3597 return setError(); 3598 } 3599 3600 bool hasOverloads = false; 3601 if (FuncDeclaration *f = isFuncAddress(exp, &hasOverloads)) 3602 { 3603 if (!hasOverloads && f->checkForwardRef(exp->loc)) 3604 return setError(); 3605 } 3606 else if (!exp->e1->type->deco) 3607 { 3608 if (exp->e1->op == TOKvar) 3609 { 3610 VarExp *ve = (VarExp *)exp->e1; 3611 Declaration *d = ve->var; 3612 exp->error("forward reference to %s %s", d->kind(), d->toChars()); 3613 } 3614 else 3615 exp->error("forward reference to %s", exp->e1->toChars()); 3616 return setError(); 3617 } 3618 3619 exp->type = exp->e1->type->pointerTo(); 3620 3621 // See if this should really be a delegate 3622 if (exp->e1->op == TOKdotvar) 3623 { 3624 DotVarExp *dve = (DotVarExp *)exp->e1; 3625 FuncDeclaration *f = dve->var->isFuncDeclaration(); 3626 if (f) 3627 { 3628 f = f->toAliasFunc(); // FIXME, should see overloads - Bugzilla 1983 3629 if (!dve->hasOverloads) 3630 f->tookAddressOf++; 3631 3632 Expression *e; 3633 if (f->needThis()) 3634 e = new DelegateExp(exp->loc, dve->e1, f, dve->hasOverloads); 3635 else // It is a function pointer. Convert &v.f() --> (v, &V.f()) 3636 e = new CommaExp(exp->loc, dve->e1, new AddrExp(exp->loc, new VarExp(exp->loc, f, dve->hasOverloads))); 3637 e = semantic(e, sc); 3638 result = e; 3639 return; 3640 } 3641 3642 // Look for misaligned pointer in @safe mode 3643 if (checkUnsafeAccess(sc, dve, !exp->type->isMutable(), true)) 3644 return setError(); 3645 3646 if (dve->e1->op == TOKvar && global.params.vsafe) 3647 { 3648 VarExp *ve = (VarExp *)dve->e1; 3649 VarDeclaration *v = ve->var->isVarDeclaration(); 3650 if (v) 3651 { 3652 if (!checkAddressVar(sc, exp, v)) 3653 return setError(); 3654 } 3655 } 3656 else if ((dve->e1->op == TOKthis || dve->e1->op == TOKsuper) && global.params.vsafe) 3657 { 3658 ThisExp *ve = (ThisExp *)dve->e1; 3659 VarDeclaration *v = ve->var->isVarDeclaration(); 3660 if (v && v->storage_class & STCref) 3661 { 3662 if (!checkAddressVar(sc, exp, v)) 3663 return setError(); 3664 } 3665 } 3666 } 3667 else if (exp->e1->op == TOKvar) 3668 { 3669 VarExp *ve = (VarExp *)exp->e1; 3670 3671 VarDeclaration *v = ve->var->isVarDeclaration(); 3672 if (v) 3673 { 3674 if (!checkAddressVar(sc, exp, v)) 3675 return setError(); 3676 3677 ve->checkPurity(sc, v); 3678 } 3679 3680 FuncDeclaration *f = ve->var->isFuncDeclaration(); 3681 if (f) 3682 { 3683 /* Because nested functions cannot be overloaded, 3684 * mark here that we took its address because castTo() 3685 * may not be called with an exact match. 3686 */ 3687 if (!ve->hasOverloads || f->isNested()) 3688 f->tookAddressOf++; 3689 if (f->isNested()) 3690 { 3691 if (f->isFuncLiteralDeclaration()) 3692 { 3693 if (!f->FuncDeclaration::isNested()) 3694 { 3695 /* Supply a 'null' for a this pointer if no this is available 3696 */ 3697 Expression *e = new DelegateExp(exp->loc, new NullExp(exp->loc, Type::tnull), f, ve->hasOverloads); 3698 e = semantic(e, sc); 3699 result = e; 3700 return; 3701 } 3702 } 3703 Expression *e = new DelegateExp(exp->loc, exp->e1, f, ve->hasOverloads); 3704 e = semantic(e, sc); 3705 result = e; 3706 return; 3707 } 3708 if (f->needThis()) 3709 { 3710 if (hasThis(sc)) 3711 { 3712 /* Should probably supply 'this' after overload resolution, 3713 * not before. 3714 */ 3715 Expression *ethis = new ThisExp(exp->loc); 3716 Expression *e = new DelegateExp(exp->loc, ethis, f, ve->hasOverloads); 3717 e = semantic(e, sc); 3718 result = e; 3719 return; 3720 } 3721 if (sc->func && !sc->intypeof) 3722 { 3723 if (sc->func->setUnsafe()) 3724 { 3725 exp->error("'this' reference necessary to take address of member %s in @safe function %s", 3726 f->toChars(), sc->func->toChars()); 3727 } 3728 } 3729 } 3730 } 3731 } 3732 else if ((exp->e1->op == TOKthis || exp->e1->op == TOKsuper) && global.params.vsafe) 3733 { 3734 ThisExp *ve = (ThisExp *)exp->e1; 3735 VarDeclaration *v = ve->var->isVarDeclaration(); 3736 if (v) 3737 { 3738 if (!checkAddressVar(sc, exp, v)) 3739 return setError(); 3740 } 3741 } 3742 else if (exp->e1->op == TOKcall) 3743 { 3744 CallExp *ce = (CallExp *)exp->e1; 3745 if (ce->e1->type->ty == Tfunction) 3746 { 3747 TypeFunction *tf = (TypeFunction *)ce->e1->type; 3748 if (tf->isref && sc->func && !sc->intypeof && sc->func->setUnsafe()) 3749 { 3750 exp->error("cannot take address of ref return of %s() in @safe function %s", 3751 ce->e1->toChars(), sc->func->toChars()); 3752 } 3753 } 3754 } 3755 else if (exp->e1->op == TOKindex) 3756 { 3757 /* For: 3758 * int[3] a; 3759 * &a[i] 3760 * check 'a' the same as for a regular variable 3761 */ 3762 IndexExp *ei = (IndexExp *)exp->e1; 3763 Type *tyi = ei->e1->type->toBasetype(); 3764 if (tyi->ty == Tsarray && ei->e1->op == TOKvar) 3765 { 3766 VarExp *ve = (VarExp *)ei->e1; 3767 VarDeclaration *v = ve->var->isVarDeclaration(); 3768 if (v) 3769 { 3770 if (!checkAddressVar(sc, exp, v)) 3771 return setError(); 3772 3773 ve->checkPurity(sc, v); 3774 } 3775 } 3776 } 3777 else if (wasCond) 3778 { 3779 /* a ? b : c was transformed to *(a ? &b : &c), but we still 3780 * need to do safety checks 3781 */ 3782 assert(exp->e1->op == TOKstar); 3783 PtrExp *pe = (PtrExp *)exp->e1; 3784 assert(pe->e1->op == TOKquestion); 3785 CondExp *ce = (CondExp *)pe->e1; 3786 assert(ce->e1->op == TOKaddress); 3787 assert(ce->e2->op == TOKaddress); 3788 3789 // Re-run semantic on the address expressions only 3790 ce->e1->type = NULL; 3791 ce->e1 = semantic(ce->e1, sc); 3792 ce->e2->type = NULL; 3793 ce->e2 = semantic(ce->e2, sc); 3794 } 3795 3796 result = exp->optimize(WANTvalue); 3797 } 3798 3799 void visit(PtrExp *exp) 3800 { 3801 if (exp->type) 3802 { 3803 result = exp; 3804 return; 3805 } 3806 3807 Expression *e = exp->op_overload(sc); 3808 if (e) 3809 { 3810 result = e; 3811 return; 3812 } 3813 3814 Type *tb = exp->e1->type->toBasetype(); 3815 switch (tb->ty) 3816 { 3817 case Tpointer: 3818 exp->type = ((TypePointer *)tb)->next; 3819 break; 3820 3821 case Tsarray: 3822 case Tarray: 3823 exp->error("using * on an array is no longer supported; use *(%s).ptr instead", exp->e1->toChars()); 3824 exp->type = ((TypeArray *)tb)->next; 3825 exp->e1 = exp->e1->castTo(sc, exp->type->pointerTo()); 3826 break; 3827 3828 default: 3829 exp->error("can only * a pointer, not a '%s'", exp->e1->type->toChars()); 3830 /* fall through */ 3831 3832 case Terror: 3833 return setError(); 3834 } 3835 if (exp->checkValue()) 3836 return setError(); 3837 3838 result = exp; 3839 } 3840 3841 void visit(NegExp *exp) 3842 { 3843 if (exp->type) 3844 { 3845 result = exp; 3846 return; 3847 } 3848 3849 Expression *e = exp->op_overload(sc); 3850 if (e) 3851 { 3852 result = e; 3853 return; 3854 } 3855 3856 exp->type = exp->e1->type; 3857 Type *tb = exp->type->toBasetype(); 3858 if (tb->ty == Tarray || tb->ty == Tsarray) 3859 { 3860 if (!isArrayOpValid(exp->e1)) 3861 { 3862 exp->error("invalid array operation %s (possible missing [])", exp->toChars()); 3863 return setError(); 3864 } 3865 result = exp; 3866 return; 3867 } 3868 3869 if (!Target::isVectorOpSupported(tb, exp->op)) 3870 { 3871 result = exp->incompatibleTypes(); 3872 return; 3873 } 3874 if (exp->e1->checkNoBool()) 3875 return setError(); 3876 if (exp->e1->checkArithmetic()) 3877 return setError(); 3878 3879 result = exp; 3880 } 3881 3882 void visit(UAddExp *exp) 3883 { 3884 assert(!exp->type); 3885 3886 Expression *e = exp->op_overload(sc); 3887 if (e) 3888 { 3889 result = e; 3890 return; 3891 } 3892 3893 if (!Target::isVectorOpSupported(exp->e1->type->toBasetype(), exp->op)) 3894 { 3895 result = exp->incompatibleTypes(); 3896 return; 3897 } 3898 if (exp->e1->checkNoBool()) 3899 return setError(); 3900 if (exp->e1->checkArithmetic()) 3901 return setError(); 3902 3903 result = exp->e1; 3904 } 3905 3906 void visit(ComExp *exp) 3907 { 3908 if (exp->type) 3909 { 3910 result = exp; 3911 return; 3912 } 3913 3914 Expression *e = exp->op_overload(sc); 3915 if (e) 3916 { 3917 result = e; 3918 return; 3919 } 3920 3921 exp->type = exp->e1->type; 3922 Type *tb = exp->type->toBasetype(); 3923 if (tb->ty == Tarray || tb->ty == Tsarray) 3924 { 3925 if (!isArrayOpValid(exp->e1)) 3926 { 3927 exp->error("invalid array operation %s (possible missing [])", exp->toChars()); 3928 return setError(); 3929 } 3930 result = exp; 3931 return; 3932 } 3933 3934 if (!Target::isVectorOpSupported(tb, exp->op)) 3935 { 3936 result = exp->incompatibleTypes(); 3937 return; 3938 } 3939 if (exp->e1->checkNoBool()) 3940 return setError(); 3941 if (exp->e1->checkIntegral()) 3942 return setError(); 3943 3944 result = exp; 3945 } 3946 3947 void visit(NotExp *e) 3948 { 3949 if (e->type) 3950 { 3951 result = e; 3952 return; 3953 } 3954 3955 setNoderefOperand(e); 3956 3957 // Note there is no operator overload 3958 if (Expression *ex = unaSemantic(e, sc)) 3959 { 3960 result = ex; 3961 return; 3962 } 3963 3964 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684 3965 if (e->e1->op == TOKtype) 3966 e->e1 = resolveAliasThis(sc, e->e1); 3967 3968 e->e1 = resolveProperties(sc, e->e1); 3969 e->e1 = e->e1->toBoolean(sc); 3970 if (e->e1->type == Type::terror) 3971 { 3972 result = e->e1; 3973 return; 3974 } 3975 3976 if (!Target::isVectorOpSupported(e->e1->type->toBasetype(), e->op)) 3977 { 3978 result = e->incompatibleTypes(); 3979 return; 3980 } 3981 // Bugzilla 13910: Today NotExp can take an array as its operand. 3982 if (checkNonAssignmentArrayOp(e->e1)) 3983 return setError(); 3984 3985 e->type = Type::tbool; 3986 result = e; 3987 } 3988 3989 void visit(DeleteExp *exp) 3990 { 3991 if (Expression *ex = unaSemantic(exp, sc)) 3992 { 3993 result = ex; 3994 return; 3995 } 3996 exp->e1 = resolveProperties(sc, exp->e1); 3997 exp->e1 = exp->e1->modifiableLvalue(sc, NULL); 3998 if (exp->e1->op == TOKerror) 3999 { 4000 result = exp->e1; 4001 return; 4002 } 4003 exp->type = Type::tvoid; 4004 4005 AggregateDeclaration *ad = NULL; 4006 Type *tb = exp->e1->type->toBasetype(); 4007 switch (tb->ty) 4008 { case Tclass: 4009 { 4010 ClassDeclaration *cd = ((TypeClass *)tb)->sym; 4011 4012 if (cd->isCOMinterface()) 4013 { /* Because COM classes are deleted by IUnknown.Release() 4014 */ 4015 exp->error("cannot delete instance of COM interface %s", cd->toChars()); 4016 return setError(); 4017 } 4018 4019 ad = cd; 4020 break; 4021 } 4022 case Tpointer: 4023 tb = ((TypePointer *)tb)->next->toBasetype(); 4024 if (tb->ty == Tstruct) 4025 { 4026 ad = ((TypeStruct *)tb)->sym; 4027 FuncDeclaration *f = ad->aggDelete; 4028 FuncDeclaration *fd = ad->dtor; 4029 4030 if (!f) 4031 { 4032 semanticTypeInfo(sc, tb); 4033 break; 4034 } 4035 4036 /* Construct: 4037 * ea = copy e1 to a tmp to do side effects only once 4038 * eb = call destructor 4039 * ec = call deallocator 4040 */ 4041 Expression *ea = NULL; 4042 Expression *eb = NULL; 4043 Expression *ec = NULL; 4044 VarDeclaration *v = NULL; 4045 4046 if (fd && f) 4047 { 4048 v = copyToTemp(0, "__tmpea", exp->e1); 4049 v->semantic(sc); 4050 ea = new DeclarationExp(exp->loc, v); 4051 ea->type = v->type; 4052 } 4053 4054 if (fd) 4055 { 4056 Expression *e = ea ? new VarExp(exp->loc, v) : exp->e1; 4057 e = new DotVarExp(Loc(), e, fd, false); 4058 eb = new CallExp(exp->loc, e); 4059 eb = semantic(eb, sc); 4060 } 4061 4062 if (f) 4063 { 4064 Type *tpv = Type::tvoid->pointerTo(); 4065 Expression *e = ea ? new VarExp(exp->loc, v) : exp->e1->castTo(sc, tpv); 4066 e = new CallExp(exp->loc, new VarExp(exp->loc, f, false), e); 4067 ec = semantic(e, sc); 4068 } 4069 ea = Expression::combine(ea, eb); 4070 ea = Expression::combine(ea, ec); 4071 assert(ea); 4072 result = ea; 4073 return; 4074 } 4075 break; 4076 4077 case Tarray: 4078 { 4079 Type *tv = tb->nextOf()->baseElemOf(); 4080 if (tv->ty == Tstruct) 4081 { 4082 ad = ((TypeStruct *)tv)->sym; 4083 if (ad->dtor) 4084 semanticTypeInfo(sc, ad->type); 4085 } 4086 break; 4087 } 4088 default: 4089 exp->error("cannot delete type %s", exp->e1->type->toChars()); 4090 return setError(); 4091 } 4092 4093 bool err = false; 4094 if (ad) 4095 { 4096 if (ad->dtor) 4097 { 4098 err |= exp->checkPurity(sc, ad->dtor); 4099 err |= exp->checkSafety(sc, ad->dtor); 4100 err |= exp->checkNogc(sc, ad->dtor); 4101 } 4102 if (ad->aggDelete && tb->ty != Tarray) 4103 { 4104 err |= exp->checkPurity(sc, ad->aggDelete); 4105 err |= exp->checkSafety(sc, ad->aggDelete); 4106 err |= exp->checkNogc(sc, ad->aggDelete); 4107 } 4108 if (err) 4109 return setError(); 4110 } 4111 4112 if (!sc->intypeof && sc->func && 4113 !exp->isRAII && 4114 sc->func->setUnsafe()) 4115 { 4116 exp->error("%s is not @safe but is used in @safe function %s", exp->toChars(), sc->func->toChars()); 4117 err = true; 4118 } 4119 if (err) 4120 return setError(); 4121 4122 result = exp; 4123 } 4124 4125 void visit(CastExp *exp) 4126 { 4127 //static int x; assert(++x < 10); 4128 if (exp->type) 4129 { 4130 result = exp; 4131 return; 4132 } 4133 4134 if (exp->to) 4135 { 4136 exp->to = exp->to->semantic(exp->loc, sc); 4137 if (exp->to == Type::terror) 4138 return setError(); 4139 4140 if (!exp->to->hasPointers()) 4141 setNoderefOperand(exp); 4142 4143 // When e1 is a template lambda, this cast may instantiate it with 4144 // the type 'to'. 4145 exp->e1 = inferType(exp->e1, exp->to); 4146 } 4147 4148 if (Expression *ex = unaSemantic(exp, sc)) 4149 { 4150 result = ex; 4151 return; 4152 } 4153 Expression *e1x = resolveProperties(sc, exp->e1); 4154 if (e1x->op == TOKerror) 4155 { 4156 result = e1x; 4157 return; 4158 } 4159 if (e1x->checkType()) 4160 return setError(); 4161 exp->e1 = e1x; 4162 4163 if (!exp->e1->type) 4164 { 4165 exp->error("cannot cast %s", exp->e1->toChars()); 4166 return setError(); 4167 } 4168 4169 if (!exp->to) // Handle cast(const) and cast(immutable), etc. 4170 { 4171 exp->to = exp->e1->type->castMod(exp->mod); 4172 exp->to = exp->to->semantic(exp->loc, sc); 4173 if (exp->to == Type::terror) 4174 return setError(); 4175 } 4176 4177 if (exp->to->ty == Ttuple) 4178 { 4179 exp->error("cannot cast %s to tuple type %s", exp->e1->toChars(), exp->to->toChars()); 4180 return setError(); 4181 } 4182 if (exp->e1->type->ty != Tvoid || 4183 (exp->e1->op == TOKfunction && exp->to->ty == Tvoid) || 4184 exp->e1->op == TOKtype || 4185 exp->e1->op == TOKtemplate) 4186 { 4187 if (exp->e1->checkValue()) 4188 return setError(); 4189 } 4190 4191 // cast(void) is used to mark e1 as unused, so it is safe 4192 if (exp->to->ty == Tvoid) 4193 { 4194 exp->type = exp->to; 4195 result = exp; 4196 return; 4197 } 4198 4199 if (!exp->to->equals(exp->e1->type) && exp->mod == (unsigned char)~0) 4200 { 4201 if (Expression *e = exp->op_overload(sc)) 4202 { 4203 result = e->implicitCastTo(sc, exp->to); 4204 return; 4205 } 4206 } 4207 4208 Type *t1b = exp->e1->type->toBasetype(); 4209 Type *tob = exp->to->toBasetype(); 4210 4211 if (tob->ty == Tstruct && !tob->equals(t1b)) 4212 { 4213 /* Look to replace: 4214 * cast(S)t 4215 * with: 4216 * S(t) 4217 */ 4218 4219 // Rewrite as to.call(e1) 4220 Expression *e = new TypeExp(exp->loc, exp->to); 4221 e = new CallExp(exp->loc, e, exp->e1); 4222 e = trySemantic(e, sc); 4223 if (e) 4224 { 4225 result = e; 4226 return; 4227 } 4228 } 4229 4230 if (!t1b->equals(tob) && (t1b->ty == Tarray || t1b->ty == Tsarray)) 4231 { 4232 if (checkNonAssignmentArrayOp(exp->e1)) 4233 return setError(); 4234 } 4235 4236 // Look for casting to a vector type 4237 if (tob->ty == Tvector && t1b->ty != Tvector) 4238 { 4239 result = new VectorExp(exp->loc, exp->e1, exp->to); 4240 return; 4241 } 4242 4243 Expression *ex = exp->e1->castTo(sc, exp->to); 4244 if (ex->op == TOKerror) 4245 { 4246 result = ex; 4247 return; 4248 } 4249 4250 // Check for unsafe casts 4251 if (sc->func && !sc->intypeof && 4252 !isSafeCast(ex, t1b, tob) && 4253 sc->func->setUnsafe()) 4254 { 4255 exp->error("cast from %s to %s not allowed in safe code", exp->e1->type->toChars(), exp->to->toChars()); 4256 return setError(); 4257 } 4258 4259 result = ex; 4260 } 4261 4262 void visit(VectorExp *exp) 4263 { 4264 if (exp->type) 4265 { 4266 result = exp; 4267 return; 4268 } 4269 4270 exp->e1 = semantic(exp->e1, sc); 4271 exp->type = exp->to->semantic(exp->loc, sc); 4272 if (exp->e1->op == TOKerror || exp->type->ty == Terror) 4273 { 4274 result = exp->e1; 4275 return; 4276 } 4277 4278 Type *tb = exp->type->toBasetype(); 4279 assert(tb->ty == Tvector); 4280 TypeVector *tv = (TypeVector *)tb; 4281 Type *te = tv->elementType(); 4282 exp->dim = (int)(tv->size(exp->loc) / te->size(exp->loc)); 4283 4284 exp->e1 = exp->e1->optimize(WANTvalue); 4285 bool res = false; 4286 if (exp->e1->op == TOKarrayliteral) 4287 { 4288 for (size_t i = 0; i < exp->dim; i++) 4289 { 4290 // Do not stop on first error - check all AST nodes even if error found 4291 res |= checkVectorElem(exp, ((ArrayLiteralExp *)exp->e1)->getElement(i)); 4292 } 4293 } 4294 else if (exp->e1->type->ty == Tvoid) 4295 res = checkVectorElem(exp, exp->e1); 4296 4297 Expression *e = exp; 4298 if (res) 4299 e = new ErrorExp(); 4300 result = e; 4301 } 4302 4303 void visit(VectorArrayExp *e) 4304 { 4305 if (!e->type) 4306 { 4307 unaSemantic(e, sc); 4308 e->e1 = resolveProperties(sc, e->e1); 4309 4310 if (e->e1->op == TOKerror) 4311 { 4312 result = e->e1; 4313 return; 4314 } 4315 assert(e->e1->type->ty == Tvector); 4316 TypeVector *tv = (TypeVector *)e->e1->type; 4317 e->type = tv->basetype; 4318 } 4319 result = e; 4320 } 4321 4322 void visit(SliceExp *exp) 4323 { 4324 if (exp->type) 4325 { 4326 result = exp; 4327 return; 4328 } 4329 4330 // operator overloading should be handled in ArrayExp already. 4331 4332 if (Expression *ex = unaSemantic(exp, sc)) 4333 { 4334 result = ex; 4335 return; 4336 } 4337 exp->e1 = resolveProperties(sc, exp->e1); 4338 if (exp->e1->op == TOKtype && exp->e1->type->ty != Ttuple) 4339 { 4340 if (exp->lwr || exp->upr) 4341 { 4342 exp->error("cannot slice type '%s'", exp->e1->toChars()); 4343 return setError(); 4344 } 4345 Expression *e = new TypeExp(exp->loc, exp->e1->type->arrayOf()); 4346 result = semantic(e, sc); 4347 return; 4348 } 4349 if (!exp->lwr && !exp->upr) 4350 { 4351 if (exp->e1->op == TOKarrayliteral) 4352 { 4353 // Convert [a,b,c][] to [a,b,c] 4354 Type *t1b = exp->e1->type->toBasetype(); 4355 Expression *e = exp->e1; 4356 if (t1b->ty == Tsarray) 4357 { 4358 e = e->copy(); 4359 e->type = t1b->nextOf()->arrayOf(); 4360 } 4361 result = e; 4362 return; 4363 } 4364 if (exp->e1->op == TOKslice) 4365 { 4366 // Convert e[][] to e[] 4367 SliceExp *se = (SliceExp *)exp->e1; 4368 if (!se->lwr && !se->upr) 4369 { 4370 result = se; 4371 return; 4372 } 4373 } 4374 if (isArrayOpOperand(exp->e1)) 4375 { 4376 // Convert (a[]+b[])[] to a[]+b[] 4377 result = exp->e1; 4378 return; 4379 } 4380 } 4381 if (exp->e1->op == TOKerror) 4382 { 4383 result = exp->e1; 4384 return; 4385 } 4386 if (exp->e1->type->ty == Terror) 4387 return setError(); 4388 4389 Type *t1b = exp->e1->type->toBasetype(); 4390 if (t1b->ty == Tpointer) 4391 { 4392 if (((TypePointer *)t1b)->next->ty == Tfunction) 4393 { 4394 exp->error("cannot slice function pointer %s", exp->e1->toChars()); 4395 return setError(); 4396 } 4397 if (!exp->lwr || !exp->upr) 4398 { 4399 exp->error("need upper and lower bound to slice pointer"); 4400 return setError(); 4401 } 4402 if (sc->func && !sc->intypeof && sc->func->setUnsafe()) 4403 { 4404 exp->error("pointer slicing not allowed in safe functions"); 4405 return setError(); 4406 } 4407 } 4408 else if (t1b->ty == Tarray) 4409 { 4410 } 4411 else if (t1b->ty == Tsarray) 4412 { 4413 if (!exp->arrayop && global.params.vsafe) 4414 { 4415 /* Slicing a static array is like taking the address of it. 4416 * Perform checks as if e[] was &e 4417 */ 4418 VarDeclaration *v = NULL; 4419 if (exp->e1->op == TOKdotvar) 4420 { 4421 DotVarExp *dve = (DotVarExp *)exp->e1; 4422 if (dve->e1->op == TOKvar) 4423 { 4424 VarExp *ve = (VarExp *)dve->e1; 4425 v = ve->var->isVarDeclaration(); 4426 } 4427 else if (dve->e1->op == TOKthis || dve->e1->op == TOKsuper) 4428 { 4429 ThisExp *ve = (ThisExp *)dve->e1; 4430 v = ve->var->isVarDeclaration(); 4431 if (v && !(v->storage_class & STCref)) 4432 v = NULL; 4433 } 4434 } 4435 else if (exp->e1->op == TOKvar) 4436 { 4437 VarExp *ve = (VarExp *)exp->e1; 4438 v = ve->var->isVarDeclaration(); 4439 } 4440 else if (exp->e1->op == TOKthis || exp->e1->op == TOKsuper) 4441 { 4442 ThisExp *ve = (ThisExp *)exp->e1; 4443 v = ve->var->isVarDeclaration(); 4444 } 4445 4446 if (v) 4447 { 4448 if (!checkAddressVar(sc, exp, v)) 4449 return setError(); 4450 } 4451 } 4452 } 4453 else if (t1b->ty == Ttuple) 4454 { 4455 if (!exp->lwr && !exp->upr) 4456 { 4457 result = exp->e1; 4458 return; 4459 } 4460 if (!exp->lwr || !exp->upr) 4461 { 4462 exp->error("need upper and lower bound to slice tuple"); 4463 return setError(); 4464 } 4465 } 4466 else if (t1b->ty == Tvector) 4467 { 4468 // Convert e1 to corresponding static array 4469 TypeVector *tv1 = (TypeVector *)t1b; 4470 t1b = tv1->basetype; 4471 t1b = t1b->castMod(tv1->mod); 4472 exp->e1->type = t1b; 4473 } 4474 else 4475 { 4476 exp->error("%s cannot be sliced with []", 4477 t1b->ty == Tvoid ? exp->e1->toChars() : t1b->toChars()); 4478 return setError(); 4479 } 4480 4481 /* Run semantic on lwr and upr. 4482 */ 4483 Scope *scx = sc; 4484 if (t1b->ty == Tsarray || t1b->ty == Tarray || t1b->ty == Ttuple) 4485 { 4486 // Create scope for 'length' variable 4487 ScopeDsymbol *sym = new ArrayScopeSymbol(sc, exp); 4488 sym->loc = exp->loc; 4489 sym->parent = sc->scopesym; 4490 sc = sc->push(sym); 4491 } 4492 if (exp->lwr) 4493 { 4494 if (t1b->ty == Ttuple) sc = sc->startCTFE(); 4495 exp->lwr = semantic(exp->lwr, sc); 4496 exp->lwr = resolveProperties(sc, exp->lwr); 4497 if (t1b->ty == Ttuple) sc = sc->endCTFE(); 4498 exp->lwr = exp->lwr->implicitCastTo(sc, Type::tsize_t); 4499 } 4500 if (exp->upr) 4501 { 4502 if (t1b->ty == Ttuple) sc = sc->startCTFE(); 4503 exp->upr = semantic(exp->upr, sc); 4504 exp->upr = resolveProperties(sc, exp->upr); 4505 if (t1b->ty == Ttuple) sc = sc->endCTFE(); 4506 exp->upr = exp->upr->implicitCastTo(sc, Type::tsize_t); 4507 } 4508 if (sc != scx) 4509 sc = sc->pop(); 4510 if ((exp->lwr && exp->lwr->type == Type::terror) || 4511 (exp->upr && exp->upr->type == Type::terror)) 4512 { 4513 return setError(); 4514 } 4515 4516 if (t1b->ty == Ttuple) 4517 { 4518 exp->lwr = exp->lwr->ctfeInterpret(); 4519 exp->upr = exp->upr->ctfeInterpret(); 4520 uinteger_t i1 = exp->lwr->toUInteger(); 4521 uinteger_t i2 = exp->upr->toUInteger(); 4522 4523 TupleExp *te; 4524 TypeTuple *tup; 4525 size_t length; 4526 if (exp->e1->op == TOKtuple) // slicing an expression tuple 4527 { 4528 te = (TupleExp *)exp->e1; 4529 tup = NULL; 4530 length = te->exps->dim; 4531 } 4532 else if (exp->e1->op == TOKtype) // slicing a type tuple 4533 { 4534 te = NULL; 4535 tup = (TypeTuple *)t1b; 4536 length = Parameter::dim(tup->arguments); 4537 } 4538 else 4539 assert(0); 4540 4541 if (i2 < i1 || length < i2) 4542 { 4543 exp->error("string slice [%llu .. %llu] is out of bounds", i1, i2); 4544 return setError(); 4545 } 4546 4547 size_t j1 = (size_t) i1; 4548 size_t j2 = (size_t) i2; 4549 Expression *e; 4550 if (exp->e1->op == TOKtuple) 4551 { 4552 Expressions *exps = new Expressions; 4553 exps->setDim(j2 - j1); 4554 for (size_t i = 0; i < j2 - j1; i++) 4555 { 4556 (*exps)[i] = (*te->exps)[j1 + i]; 4557 } 4558 e = new TupleExp(exp->loc, te->e0, exps); 4559 } 4560 else 4561 { 4562 Parameters *args = new Parameters; 4563 args->reserve(j2 - j1); 4564 for (size_t i = j1; i < j2; i++) 4565 { 4566 Parameter *arg = Parameter::getNth(tup->arguments, i); 4567 args->push(arg); 4568 } 4569 e = new TypeExp(exp->e1->loc, new TypeTuple(args)); 4570 } 4571 e = semantic(e, sc); 4572 result = e; 4573 return; 4574 } 4575 4576 exp->type = t1b->nextOf()->arrayOf(); 4577 // Allow typedef[] -> typedef[] 4578 if (exp->type->equals(t1b)) 4579 exp->type = exp->e1->type; 4580 4581 if (exp->lwr && exp->upr) 4582 { 4583 exp->lwr = exp->lwr->optimize(WANTvalue); 4584 exp->upr = exp->upr->optimize(WANTvalue); 4585 4586 IntRange lwrRange = getIntRange(exp->lwr); 4587 IntRange uprRange = getIntRange(exp->upr); 4588 4589 if (t1b->ty == Tsarray || t1b->ty == Tarray) 4590 { 4591 Expression *el = new ArrayLengthExp(exp->loc, exp->e1); 4592 el = semantic(el, sc); 4593 el = el->optimize(WANTvalue); 4594 if (el->op == TOKint64) 4595 { 4596 dinteger_t length = el->toInteger(); 4597 IntRange bounds(SignExtendedNumber(0), SignExtendedNumber(length)); 4598 exp->upperIsInBounds = bounds.contains(uprRange); 4599 } 4600 } 4601 else if (t1b->ty == Tpointer) 4602 { 4603 exp->upperIsInBounds = true; 4604 } 4605 else 4606 assert(0); 4607 4608 exp->lowerIsLessThanUpper = (lwrRange.imax <= uprRange.imin); 4609 4610 //printf("upperIsInBounds = %d lowerIsLessThanUpper = %d\n", upperIsInBounds, lowerIsLessThanUpper); 4611 } 4612 4613 result = exp; 4614 } 4615 4616 void visit(ArrayLengthExp *e) 4617 { 4618 if (e->type) 4619 { 4620 result = e; 4621 return; 4622 } 4623 4624 if (Expression *ex = unaSemantic(e, sc)) 4625 { 4626 result = ex; 4627 return; 4628 } 4629 e->e1 = resolveProperties(sc, e->e1); 4630 4631 e->type = Type::tsize_t; 4632 result = e; 4633 } 4634 4635 void visit(IntervalExp *e) 4636 { 4637 if (e->type) 4638 { 4639 result = e; 4640 return; 4641 } 4642 4643 Expression *le = e->lwr; 4644 le = semantic(le, sc); 4645 le = resolveProperties(sc, le); 4646 4647 Expression *ue = e->upr; 4648 ue = semantic(ue, sc); 4649 ue = resolveProperties(sc, ue); 4650 4651 if (le->op == TOKerror) 4652 { 4653 result = le; 4654 return; 4655 } 4656 if (ue->op == TOKerror) 4657 { 4658 result = ue; 4659 return; 4660 } 4661 4662 e->lwr = le; 4663 e->upr = ue; 4664 4665 e->type = Type::tvoid; 4666 result = e; 4667 } 4668 4669 void visit(DelegatePtrExp *e) 4670 { 4671 if (!e->type) 4672 { 4673 unaSemantic(e, sc); 4674 e->e1 = resolveProperties(sc, e->e1); 4675 4676 if (e->e1->op == TOKerror) 4677 { 4678 result = e->e1; 4679 return; 4680 } 4681 e->type = Type::tvoidptr; 4682 } 4683 result = e; 4684 } 4685 4686 void visit(DelegateFuncptrExp *e) 4687 { 4688 if (!e->type) 4689 { 4690 unaSemantic(e, sc); 4691 e->e1 = resolveProperties(sc, e->e1); 4692 4693 if (e->e1->op == TOKerror) 4694 { 4695 result = e->e1; 4696 return; 4697 } 4698 e->type = e->e1->type->nextOf()->pointerTo(); 4699 } 4700 result = e; 4701 } 4702 4703 void visit(ArrayExp *exp) 4704 { 4705 assert(!exp->type); 4706 4707 Expression *e = exp->op_overload(sc); 4708 if (e) 4709 { 4710 result = e; 4711 return; 4712 } 4713 4714 if (isAggregate(exp->e1->type)) 4715 exp->error("no [] operator overload for type %s", exp->e1->type->toChars()); 4716 else 4717 exp->error("only one index allowed to index %s", exp->e1->type->toChars()); 4718 return setError(); 4719 } 4720 4721 void visit(DotExp *exp) 4722 { 4723 exp->e1 = semantic(exp->e1, sc); 4724 exp->e2 = semantic(exp->e2, sc); 4725 4726 if (exp->e1->op == TOKtype) 4727 { 4728 result = exp->e2; 4729 return; 4730 } 4731 if (exp->e2->op == TOKtype) 4732 { 4733 result = exp->e2; 4734 return; 4735 } 4736 if (exp->e2->op == TOKtemplate) 4737 { 4738 TemplateDeclaration *td = ((TemplateExp *)exp->e2)->td; 4739 Expression *e = new DotTemplateExp(exp->loc, exp->e1, td); 4740 result = semantic(e, sc); 4741 return; 4742 } 4743 if (!exp->type) 4744 exp->type = exp->e2->type; 4745 result = exp; 4746 } 4747 4748 void visit(CommaExp *e) 4749 { 4750 if (e->type) 4751 { 4752 result = e; 4753 return; 4754 } 4755 4756 // Allow `((a,b),(x,y))` 4757 if (e->allowCommaExp) 4758 { 4759 if (e->e1 && e->e1->op == TOKcomma) 4760 ((CommaExp *)e->e1)->allowCommaExp = true; 4761 if (e->e2 && e->e2->op == TOKcomma) 4762 ((CommaExp *)e->e2)->allowCommaExp = true; 4763 } 4764 4765 if (Expression *ex = binSemanticProp(e, sc)) 4766 { 4767 result = ex; 4768 return; 4769 } 4770 e->e1 = e->e1->addDtorHook(sc); 4771 4772 if (checkNonAssignmentArrayOp(e->e1)) 4773 return setError(); 4774 4775 e->type = e->e2->type; 4776 if (e->type != Type::tvoid && !e->allowCommaExp && !e->isGenerated) 4777 e->deprecation("Using the result of a comma expression is deprecated"); 4778 result = e; 4779 } 4780 4781 void visit(IndexExp *exp) 4782 { 4783 if (exp->type) 4784 { 4785 result = exp; 4786 return; 4787 } 4788 4789 // operator overloading should be handled in ArrayExp already. 4790 4791 if (!exp->e1->type) 4792 exp->e1 = semantic(exp->e1, sc); 4793 assert(exp->e1->type); // semantic() should already be run on it 4794 if (exp->e1->op == TOKtype && exp->e1->type->ty != Ttuple) 4795 { 4796 exp->e2 = semantic(exp->e2, sc); 4797 exp->e2 = resolveProperties(sc, exp->e2); 4798 Type *nt; 4799 if (exp->e2->op == TOKtype) 4800 nt = new TypeAArray(exp->e1->type, exp->e2->type); 4801 else 4802 nt = new TypeSArray(exp->e1->type, exp->e2); 4803 Expression *e = new TypeExp(exp->loc, nt); 4804 result = semantic(e, sc); 4805 return; 4806 } 4807 if (exp->e1->op == TOKerror) 4808 { 4809 result = exp->e1; 4810 return; 4811 } 4812 if (exp->e1->type->ty == Terror) 4813 return setError(); 4814 4815 // Note that unlike C we do not implement the int[ptr] 4816 4817 Type *t1b = exp->e1->type->toBasetype(); 4818 4819 if (t1b->ty == Tvector) 4820 { 4821 // Convert e1 to corresponding static array 4822 TypeVector *tv1 = (TypeVector *)t1b; 4823 t1b = tv1->basetype; 4824 t1b = t1b->castMod(tv1->mod); 4825 exp->e1->type = t1b; 4826 } 4827 4828 /* Run semantic on e2 4829 */ 4830 Scope *scx = sc; 4831 if (t1b->ty == Tsarray || t1b->ty == Tarray || t1b->ty == Ttuple) 4832 { 4833 // Create scope for 'length' variable 4834 ScopeDsymbol *sym = new ArrayScopeSymbol(sc, exp); 4835 sym->loc = exp->loc; 4836 sym->parent = sc->scopesym; 4837 sc = sc->push(sym); 4838 } 4839 if (t1b->ty == Ttuple) sc = sc->startCTFE(); 4840 exp->e2 = semantic(exp->e2, sc); 4841 exp->e2 = resolveProperties(sc, exp->e2); 4842 if (t1b->ty == Ttuple) sc = sc->endCTFE(); 4843 if (exp->e2->op == TOKtuple) 4844 { 4845 TupleExp *te = (TupleExp *)exp->e2; 4846 if (te->exps && te->exps->dim == 1) 4847 exp->e2 = Expression::combine(te->e0, (*te->exps)[0]); // bug 4444 fix 4848 } 4849 if (sc != scx) 4850 sc = sc->pop(); 4851 if (exp->e2->type == Type::terror) 4852 return setError(); 4853 4854 if (checkNonAssignmentArrayOp(exp->e1)) 4855 return setError(); 4856 4857 switch (t1b->ty) 4858 { 4859 case Tpointer: 4860 if (((TypePointer *)t1b)->next->ty == Tfunction) 4861 { 4862 exp->error("cannot index function pointer %s", exp->e1->toChars()); 4863 return setError(); 4864 } 4865 exp->e2 = exp->e2->implicitCastTo(sc, Type::tsize_t); 4866 if (exp->e2->type == Type::terror) 4867 return setError(); 4868 exp->e2 = exp->e2->optimize(WANTvalue); 4869 if (exp->e2->op == TOKint64 && exp->e2->toInteger() == 0) 4870 ; 4871 else if (sc->func && sc->func->setUnsafe()) 4872 { 4873 exp->error("safe function '%s' cannot index pointer '%s'", 4874 sc->func->toPrettyChars(), exp->e1->toChars()); 4875 return setError(); 4876 } 4877 exp->type = ((TypeNext *)t1b)->next; 4878 break; 4879 4880 case Tarray: 4881 exp->e2 = exp->e2->implicitCastTo(sc, Type::tsize_t); 4882 if (exp->e2->type == Type::terror) 4883 return setError(); 4884 exp->type = ((TypeNext *)t1b)->next; 4885 break; 4886 4887 case Tsarray: 4888 { 4889 exp->e2 = exp->e2->implicitCastTo(sc, Type::tsize_t); 4890 if (exp->e2->type == Type::terror) 4891 return setError(); 4892 exp->type = t1b->nextOf(); 4893 break; 4894 } 4895 4896 case Taarray: 4897 { 4898 TypeAArray *taa = (TypeAArray *)t1b; 4899 /* We can skip the implicit conversion if they differ only by 4900 * constness (Bugzilla 2684, see also bug 2954b) 4901 */ 4902 if (!arrayTypeCompatibleWithoutCasting(exp->e2->type, taa->index)) 4903 { 4904 exp->e2 = exp->e2->implicitCastTo(sc, taa->index); // type checking 4905 if (exp->e2->type == Type::terror) 4906 return setError(); 4907 } 4908 4909 semanticTypeInfo(sc, taa); 4910 4911 exp->type = taa->next; 4912 break; 4913 } 4914 4915 case Ttuple: 4916 { 4917 exp->e2 = exp->e2->implicitCastTo(sc, Type::tsize_t); 4918 if (exp->e2->type == Type::terror) 4919 return setError(); 4920 exp->e2 = exp->e2->ctfeInterpret(); 4921 uinteger_t index = exp->e2->toUInteger(); 4922 4923 TupleExp *te; 4924 TypeTuple *tup; 4925 size_t length; 4926 if (exp->e1->op == TOKtuple) 4927 { 4928 te = (TupleExp *)exp->e1; 4929 tup = NULL; 4930 length = te->exps->dim; 4931 } 4932 else if (exp->e1->op == TOKtype) 4933 { 4934 te = NULL; 4935 tup = (TypeTuple *)t1b; 4936 length = Parameter::dim(tup->arguments); 4937 } 4938 else 4939 assert(0); 4940 4941 if (length <= index) 4942 { 4943 exp->error("array index [%llu] is outside array bounds [0 .. %llu]", 4944 index, (ulonglong)length); 4945 return setError(); 4946 } 4947 4948 Expression *e; 4949 if (exp->e1->op == TOKtuple) 4950 { 4951 e = (*te->exps)[(size_t)index]; 4952 e = Expression::combine(te->e0, e); 4953 } 4954 else 4955 e = new TypeExp(exp->e1->loc, Parameter::getNth(tup->arguments, (size_t)index)->type); 4956 result = e; 4957 return; 4958 } 4959 4960 default: 4961 exp->error("%s must be an array or pointer type, not %s", 4962 exp->e1->toChars(), exp->e1->type->toChars()); 4963 return setError(); 4964 } 4965 4966 if (t1b->ty == Tsarray || t1b->ty == Tarray) 4967 { 4968 Expression *el = new ArrayLengthExp(exp->loc, exp->e1); 4969 el = semantic(el, sc); 4970 el = el->optimize(WANTvalue); 4971 if (el->op == TOKint64) 4972 { 4973 exp->e2 = exp->e2->optimize(WANTvalue); 4974 dinteger_t length = el->toInteger(); 4975 if (length) 4976 { 4977 IntRange bounds(SignExtendedNumber(0), SignExtendedNumber(length - 1)); 4978 exp->indexIsInBounds = bounds.contains(getIntRange(exp->e2)); 4979 } 4980 } 4981 } 4982 4983 result = exp; 4984 } 4985 4986 void visit(PostExp *exp) 4987 { 4988 if (exp->type) 4989 { 4990 result = exp; 4991 return; 4992 } 4993 4994 if (Expression *ex = binSemantic(exp, sc)) 4995 { 4996 result = ex; 4997 return; 4998 } 4999 Expression *e1x = resolveProperties(sc, exp->e1); 5000 if (e1x->op == TOKerror) 5001 { 5002 result = e1x; 5003 return; 5004 } 5005 exp->e1 = e1x; 5006 5007 Expression *e = exp->op_overload(sc); 5008 if (e) 5009 { 5010 result = e; 5011 return; 5012 } 5013 5014 if (exp->e1->checkReadModifyWrite(exp->op)) 5015 return setError(); 5016 if (exp->e1->op == TOKslice) 5017 { 5018 const char *s = exp->op == TOKplusplus ? "increment" : "decrement"; 5019 exp->error("cannot post-%s array slice '%s', use pre-%s instead", s, exp->e1->toChars(), s); 5020 return setError(); 5021 } 5022 5023 exp->e1 = exp->e1->optimize(WANTvalue); 5024 5025 Type *t1 = exp->e1->type->toBasetype(); 5026 if (t1->ty == Tclass || t1->ty == Tstruct || exp->e1->op == TOKarraylength) 5027 { 5028 /* Check for operator overloading, 5029 * but rewrite in terms of ++e instead of e++ 5030 */ 5031 5032 /* If e1 is not trivial, take a reference to it 5033 */ 5034 Expression *de = NULL; 5035 if (exp->e1->op != TOKvar && exp->e1->op != TOKarraylength) 5036 { 5037 // ref v = e1; 5038 VarDeclaration *v = copyToTemp(STCref, "__postref", exp->e1); 5039 de = new DeclarationExp(exp->loc, v); 5040 exp->e1 = new VarExp(exp->e1->loc, v); 5041 } 5042 5043 /* Rewrite as: 5044 * auto tmp = e1; ++e1; tmp 5045 */ 5046 VarDeclaration *tmp = copyToTemp(0, "__pitmp", exp->e1); 5047 Expression *ea = new DeclarationExp(exp->loc, tmp); 5048 5049 Expression *eb = exp->e1->syntaxCopy(); 5050 eb = new PreExp(exp->op == TOKplusplus ? TOKpreplusplus : TOKpreminusminus, exp->loc, eb); 5051 5052 Expression *ec = new VarExp(exp->loc, tmp); 5053 5054 // Combine de,ea,eb,ec 5055 if (de) 5056 ea = new CommaExp(exp->loc, de, ea); 5057 e = new CommaExp(exp->loc, ea, eb); 5058 e = new CommaExp(exp->loc, e, ec); 5059 e = semantic(e, sc); 5060 result = e; 5061 return; 5062 } 5063 5064 exp->e1 = exp->e1->modifiableLvalue(sc, exp->e1); 5065 5066 e = exp; 5067 if (exp->e1->checkScalar()) 5068 return setError(); 5069 if (exp->e1->checkNoBool()) 5070 return setError(); 5071 5072 if (exp->e1->type->ty == Tpointer) 5073 e = scaleFactor(exp, sc); 5074 else 5075 exp->e2 = exp->e2->castTo(sc, exp->e1->type); 5076 e->type = exp->e1->type; 5077 result = e; 5078 } 5079 5080 void visit(PreExp *exp) 5081 { 5082 Expression *e = exp->op_overload(sc); 5083 // printf("PreExp::semantic('%s')\n", exp->toChars()); 5084 5085 if (e) 5086 { 5087 result = e; 5088 return; 5089 } 5090 5091 // Rewrite as e1+=1 or e1-=1 5092 if (exp->op == TOKpreplusplus) 5093 e = new AddAssignExp(exp->loc, exp->e1, new IntegerExp(exp->loc, 1, Type::tint32)); 5094 else 5095 e = new MinAssignExp(exp->loc, exp->e1, new IntegerExp(exp->loc, 1, Type::tint32)); 5096 result = semantic(e, sc); 5097 } 5098 5099 void visit(AssignExp *exp) 5100 { 5101 //printf("e1->op = %d, '%s'\n", exp->e1->op, Token::toChars(exp->e1->op)); 5102 //printf("e2->op = %d, '%s'\n", exp->e2->op, Token::toChars(exp->e2->op)); 5103 if (exp->type) 5104 { 5105 result = exp; 5106 return; 5107 } 5108 5109 Expression *e1old = exp->e1; 5110 5111 if (exp->e2->op == TOKcomma) 5112 { 5113 /* Rewrite to get rid of the comma from rvalue 5114 */ 5115 if (!((CommaExp *)exp->e2)->isGenerated) 5116 exp->deprecation("Using the result of a comma expression is deprecated"); 5117 Expression *e0; 5118 exp->e2 = Expression::extractLast(exp->e2, &e0); 5119 Expression *e = Expression::combine(e0, exp); 5120 result = semantic(e, sc); 5121 return; 5122 } 5123 5124 /* Look for operator overloading of a[arguments] = e2. 5125 * Do it before e1->semantic() otherwise the ArrayExp will have been 5126 * converted to unary operator overloading already. 5127 */ 5128 if (exp->e1->op == TOKarray) 5129 { 5130 Expression *res; 5131 5132 ArrayExp *ae = (ArrayExp *)exp->e1; 5133 ae->e1 = semantic(ae->e1, sc); 5134 ae->e1 = resolveProperties(sc, ae->e1); 5135 Expression *ae1old = ae->e1; 5136 5137 const bool maybeSlice = 5138 (ae->arguments->dim == 0 || 5139 (ae->arguments->dim == 1 && (*ae->arguments)[0]->op == TOKinterval)); 5140 IntervalExp *ie = NULL; 5141 if (maybeSlice && ae->arguments->dim) 5142 { 5143 assert((*ae->arguments)[0]->op == TOKinterval); 5144 ie = (IntervalExp *)(*ae->arguments)[0]; 5145 } 5146 5147 while (true) 5148 { 5149 if (ae->e1->op == TOKerror) 5150 { 5151 result = ae->e1; 5152 return; 5153 } 5154 Expression *e0 = NULL; 5155 Expression *ae1save = ae->e1; 5156 ae->lengthVar = NULL; 5157 5158 Type *t1b = ae->e1->type->toBasetype(); 5159 AggregateDeclaration *ad = isAggregate(t1b); 5160 if (!ad) 5161 break; 5162 if (search_function(ad, Id::indexass)) 5163 { 5164 // Deal with $ 5165 res = resolveOpDollar(sc, ae, &e0); 5166 if (!res) // a[i..j] = e2 might be: a.opSliceAssign(e2, i, j) 5167 goto Lfallback; 5168 if (res->op == TOKerror) 5169 { 5170 result = res; 5171 return; 5172 } 5173 5174 res = semantic(exp->e2, sc); 5175 if (res->op == TOKerror) 5176 { 5177 result = res; 5178 return; 5179 } 5180 exp->e2 = res; 5181 5182 /* Rewrite (a[arguments] = e2) as: 5183 * a.opIndexAssign(e2, arguments) 5184 */ 5185 Expressions *a = (Expressions *)ae->arguments->copy(); 5186 a->insert(0, exp->e2); 5187 res = new DotIdExp(exp->loc, ae->e1, Id::indexass); 5188 res = new CallExp(exp->loc, res, a); 5189 if (maybeSlice) // a[] = e2 might be: a.opSliceAssign(e2) 5190 res = trySemantic(res, sc); 5191 else 5192 res = semantic(res, sc); 5193 if (res) 5194 { 5195 res = Expression::combine(e0, res); 5196 result = res; 5197 return; 5198 } 5199 } 5200 Lfallback: 5201 if (maybeSlice && search_function(ad, Id::sliceass)) 5202 { 5203 // Deal with $ 5204 res = resolveOpDollar(sc, ae, ie, &e0); 5205 if (res->op == TOKerror) 5206 { 5207 result = res; 5208 return; 5209 } 5210 5211 res = semantic(exp->e2, sc); 5212 if (res->op == TOKerror) 5213 { 5214 result = res; 5215 return; 5216 } 5217 exp->e2 = res; 5218 5219 /* Rewrite (a[i..j] = e2) as: 5220 * a.opSliceAssign(e2, i, j) 5221 */ 5222 Expressions *a = new Expressions(); 5223 a->push(exp->e2); 5224 if (ie) 5225 { 5226 a->push(ie->lwr); 5227 a->push(ie->upr); 5228 } 5229 res = new DotIdExp(exp->loc, ae->e1, Id::sliceass); 5230 res = new CallExp(exp->loc, res, a); 5231 res = semantic(res, sc); 5232 res = Expression::combine(e0, res); 5233 result = res; 5234 return; 5235 } 5236 5237 // No operator overloading member function found yet, but 5238 // there might be an alias this to try. 5239 if (ad->aliasthis && t1b != ae->att1) 5240 { 5241 if (!ae->att1 && t1b->checkAliasThisRec()) 5242 ae->att1 = t1b; 5243 5244 /* Rewrite (a[arguments] op e2) as: 5245 * a.aliasthis[arguments] op e2 5246 */ 5247 ae->e1 = resolveAliasThis(sc, ae1save, true); 5248 if (ae->e1) 5249 continue; 5250 } 5251 break; 5252 } 5253 ae->e1 = ae1old; // recovery 5254 ae->lengthVar = NULL; 5255 } 5256 5257 /* Run exp->e1 semantic. 5258 */ 5259 { 5260 Expression *e1x = exp->e1; 5261 5262 /* With UFCS, e.f = value 5263 * Could mean: 5264 * .f(e, value) 5265 * or: 5266 * .f(e) = value 5267 */ 5268 if (e1x->op == TOKdotti) 5269 { 5270 DotTemplateInstanceExp *dti = (DotTemplateInstanceExp *)e1x; 5271 Expression *e = semanticY(dti, sc, 1); 5272 if (!e) 5273 { 5274 result = resolveUFCSProperties(sc, e1x, exp->e2); 5275 return; 5276 } 5277 e1x = e; 5278 } 5279 else if (e1x->op == TOKdotid) 5280 { 5281 DotIdExp *die = (DotIdExp *)e1x; 5282 Expression *e = semanticY(die, sc, 1); 5283 if (e && isDotOpDispatch(e)) 5284 { 5285 unsigned errors = global.startGagging(); 5286 e = resolvePropertiesX(sc, e, exp->e2); 5287 if (global.endGagging(errors)) 5288 e = NULL; /* fall down to UFCS */ 5289 else 5290 { 5291 result = e; 5292 return; 5293 } 5294 } 5295 if (!e) 5296 { 5297 result = resolveUFCSProperties(sc, e1x, exp->e2); 5298 return; 5299 } 5300 e1x = e; 5301 } 5302 else 5303 { 5304 if (e1x->op == TOKslice) 5305 ((SliceExp *)e1x)->arrayop = true; 5306 5307 e1x = semantic(e1x, sc); 5308 } 5309 5310 /* We have f = value. 5311 * Could mean: 5312 * f(value) 5313 * or: 5314 * f() = value 5315 */ 5316 if (Expression *e = resolvePropertiesX(sc, e1x, exp->e2)) 5317 { 5318 result = e; 5319 return; 5320 } 5321 if (e1x->checkRightThis(sc)) 5322 return setError(); 5323 exp->e1 = e1x; 5324 assert(exp->e1->type); 5325 } 5326 Type *t1 = exp->e1->type->toBasetype(); 5327 5328 /* Run exp->e2 semantic. 5329 * Different from other binary expressions, the analysis of e2 5330 * depends on the result of e1 in assignments. 5331 */ 5332 { 5333 Expression *e2x = inferType(exp->e2, t1->baseElemOf()); 5334 5335 e2x = semantic(e2x, sc); 5336 e2x = resolveProperties(sc, e2x); 5337 5338 if (e2x->op == TOKtype) 5339 e2x = resolveAliasThis(sc, e2x); //https://issues.dlang.org/show_bug.cgi?id=17684 5340 if (e2x->op == TOKerror) 5341 { 5342 result = e2x; 5343 return; 5344 } 5345 if (e2x->checkValue()) 5346 return setError(); 5347 exp->e2 = e2x; 5348 } 5349 5350 /* Rewrite tuple assignment as a tuple of assignments. 5351 */ 5352 { 5353 Expression *e2x = exp->e2; 5354 5355 Ltupleassign: 5356 if (exp->e1->op == TOKtuple && e2x->op == TOKtuple) 5357 { 5358 TupleExp *tup1 = (TupleExp *)exp->e1; 5359 TupleExp *tup2 = (TupleExp *)e2x; 5360 size_t dim = tup1->exps->dim; 5361 Expression *e = NULL; 5362 if (dim != tup2->exps->dim) 5363 { 5364 exp->error("mismatched tuple lengths, %d and %d", (int)dim, (int)tup2->exps->dim); 5365 return setError(); 5366 } 5367 if (dim == 0) 5368 { 5369 e = new IntegerExp(exp->loc, 0, Type::tint32); 5370 e = new CastExp(exp->loc, e, Type::tvoid); // avoid "has no effect" error 5371 e = Expression::combine(Expression::combine(tup1->e0, tup2->e0), e); 5372 } 5373 else 5374 { 5375 Expressions *exps = new Expressions; 5376 exps->setDim(dim); 5377 for (size_t i = 0; i < dim; i++) 5378 { 5379 Expression *ex1 = (*tup1->exps)[i]; 5380 Expression *ex2 = (*tup2->exps)[i]; 5381 (*exps)[i] = new AssignExp(exp->loc, ex1, ex2); 5382 } 5383 e = new TupleExp(exp->loc, Expression::combine(tup1->e0, tup2->e0), exps); 5384 } 5385 result = semantic(e, sc); 5386 return; 5387 } 5388 5389 /* Look for form: e1 = e2->aliasthis. 5390 */ 5391 if (exp->e1->op == TOKtuple) 5392 { 5393 TupleDeclaration *td = isAliasThisTuple(e2x); 5394 if (!td) 5395 goto Lnomatch; 5396 5397 assert(exp->e1->type->ty == Ttuple); 5398 TypeTuple *tt = (TypeTuple *)exp->e1->type; 5399 5400 Expression *e0 = NULL; 5401 Expression *ev = extractSideEffect(sc, "__tup", &e0, e2x); 5402 5403 Expressions *iexps = new Expressions(); 5404 iexps->push(ev); 5405 5406 for (size_t u = 0; u < iexps->dim ; u++) 5407 { 5408 Lexpand: 5409 Expression *e = (*iexps)[u]; 5410 5411 Parameter *arg = Parameter::getNth(tt->arguments, u); 5412 //printf("[%d] iexps->dim = %d, ", u, iexps->dim); 5413 //printf("e = (%s %s, %s), ", Token::tochars[e->op], e->toChars(), e->type->toChars()); 5414 //printf("arg = (%s, %s)\n", arg->toChars(), arg->type->toChars()); 5415 5416 if (!arg || !e->type->implicitConvTo(arg->type)) 5417 { 5418 // expand initializer to tuple 5419 if (expandAliasThisTuples(iexps, u) != -1) 5420 { 5421 if (iexps->dim <= u) 5422 break; 5423 goto Lexpand; 5424 } 5425 goto Lnomatch; 5426 } 5427 } 5428 e2x = new TupleExp(e2x->loc, e0, iexps); 5429 e2x = semantic(e2x, sc); 5430 if (e2x->op == TOKerror) 5431 { 5432 result = e2x; 5433 return; 5434 } 5435 // Do not need to overwrite exp->e2 5436 goto Ltupleassign; 5437 } 5438 Lnomatch: 5439 ; 5440 } 5441 5442 /* Inside constructor, if this is the first assignment of object field, 5443 * rewrite this to initializing the field. 5444 */ 5445 if (exp->op == TOKassign && exp->e1->checkModifiable(sc) == 2) 5446 { 5447 //printf("[%s] change to init - %s\n", exp->loc.toChars(), toChars()); 5448 exp->op = TOKconstruct; 5449 5450 // Bugzilla 13515: set Index::modifiable flag for complex AA element initialization 5451 if (exp->e1->op == TOKindex) 5452 { 5453 Expression *e1x = ((IndexExp *)exp->e1)->markSettingAAElem(); 5454 if (e1x->op == TOKerror) 5455 { 5456 result = e1x; 5457 return; 5458 } 5459 } 5460 } 5461 else if (exp->op == TOKconstruct && exp->e1->op == TOKvar && 5462 ((VarExp *)exp->e1)->var->storage_class & (STCout | STCref)) 5463 { 5464 exp->memset |= referenceInit; 5465 } 5466 5467 /* If it is an assignment from a 'foreign' type, 5468 * check for operator overloading. 5469 */ 5470 if (exp->memset & referenceInit) 5471 { 5472 // If this is an initialization of a reference, 5473 // do nothing 5474 } 5475 else if (t1->ty == Tstruct) 5476 { 5477 Expression *e1x = exp->e1; 5478 Expression *e2x = exp->e2; 5479 StructDeclaration *sd = ((TypeStruct *)t1)->sym; 5480 5481 if (exp->op == TOKconstruct) 5482 { 5483 Type *t2 = e2x->type->toBasetype(); 5484 if (t2->ty == Tstruct && sd == ((TypeStruct *)t2)->sym) 5485 { 5486 sd->size(exp->loc); 5487 if (sd->sizeok != SIZEOKdone) 5488 return setError(); 5489 if (!sd->ctor) 5490 sd->ctor = sd->searchCtor(); 5491 5492 // Bugzilla 15661: Look for the form from last of comma chain. 5493 Expression *e2y = e2x; 5494 while (e2y->op == TOKcomma) 5495 e2y = ((CommaExp *)e2y)->e2; 5496 5497 CallExp *ce = (e2y->op == TOKcall) ? (CallExp *)e2y : NULL; 5498 DotVarExp *dve = (ce && ce->e1->op == TOKdotvar) 5499 ? (DotVarExp *)ce->e1 : NULL; 5500 if (sd->ctor && ce && dve && dve->var->isCtorDeclaration() && 5501 e2y->type->implicitConvTo(t1)) 5502 { 5503 /* Look for form of constructor call which is: 5504 * __ctmp.ctor(arguments...) 5505 */ 5506 5507 /* Before calling the constructor, initialize 5508 * variable with a bit copy of the default 5509 * initializer 5510 */ 5511 AssignExp *ae = exp; 5512 if (sd->zeroInit == 1 && !sd->isNested()) 5513 { 5514 // Bugzilla 14606: Always use BlitExp for the special expression: (struct = 0) 5515 ae = new BlitExp(ae->loc, ae->e1, new IntegerExp(exp->loc, 0, Type::tint32)); 5516 } 5517 else 5518 { 5519 // Keep ae->op == TOKconstruct 5520 ae->e2 = sd->isNested() ? t1->defaultInitLiteral(exp->loc) : t1->defaultInit(exp->loc); 5521 } 5522 ae->type = e1x->type; 5523 5524 /* Replace __ctmp being constructed with e1. 5525 * We need to copy constructor call expression, 5526 * because it may be used in other place. 5527 */ 5528 DotVarExp *dvx = (DotVarExp *)dve->copy(); 5529 dvx->e1 = e1x; 5530 CallExp *cx = (CallExp *)ce->copy(); 5531 cx->e1 = dvx; 5532 5533 Expression *e0; 5534 Expression::extractLast(e2x, &e0); 5535 5536 Expression *e = Expression::combine(ae, cx); 5537 e = Expression::combine(e0, e); 5538 e = semantic(e, sc); 5539 result = e; 5540 return; 5541 } 5542 if (sd->postblit) 5543 { 5544 /* We have a copy constructor for this 5545 */ 5546 if (e2x->op == TOKquestion) 5547 { 5548 /* Rewrite as: 5549 * a ? e1 = b : e1 = c; 5550 */ 5551 CondExp *econd = (CondExp *)e2x; 5552 Expression *ea1 = new ConstructExp(econd->e1->loc, e1x, econd->e1); 5553 Expression *ea2 = new ConstructExp(econd->e1->loc, e1x, econd->e2); 5554 Expression *e = new CondExp(exp->loc, econd->econd, ea1, ea2); 5555 result = semantic(e, sc); 5556 return; 5557 } 5558 5559 if (e2x->isLvalue()) 5560 { 5561 if (!e2x->type->implicitConvTo(e1x->type)) 5562 { 5563 exp->error("conversion error from %s to %s", e2x->type->toChars(), e1x->type->toChars()); 5564 return setError(); 5565 } 5566 5567 /* Rewrite as: 5568 * (e1 = e2).postblit(); 5569 * 5570 * Blit assignment e1 = e2 returns a reference to the original e1, 5571 * then call the postblit on it. 5572 */ 5573 Expression *e = e1x->copy(); 5574 e->type = e->type->mutableOf(); 5575 e = new BlitExp(exp->loc, e, e2x); 5576 e = new DotVarExp(exp->loc, e, sd->postblit, false); 5577 e = new CallExp(exp->loc, e); 5578 result = semantic(e, sc); 5579 return; 5580 } 5581 else 5582 { 5583 /* The struct value returned from the function is transferred 5584 * so should not call the destructor on it. 5585 */ 5586 e2x = valueNoDtor(e2x); 5587 } 5588 } 5589 } 5590 else if (!e2x->implicitConvTo(t1)) 5591 { 5592 sd->size(exp->loc); 5593 if (sd->sizeok != SIZEOKdone) 5594 return setError(); 5595 if (!sd->ctor) 5596 sd->ctor = sd->searchCtor(); 5597 5598 if (sd->ctor) 5599 { 5600 /* Look for implicit constructor call 5601 * Rewrite as: 5602 * e1 = init, e1.ctor(e2) 5603 */ 5604 Expression *einit; 5605 einit = new BlitExp(exp->loc, e1x, e1x->type->defaultInit(exp->loc)); 5606 einit->type = e1x->type; 5607 5608 Expression *e; 5609 e = new DotIdExp(exp->loc, e1x, Id::ctor); 5610 e = new CallExp(exp->loc, e, e2x); 5611 e = new CommaExp(exp->loc, einit, e); 5612 e = semantic(e, sc); 5613 result = e; 5614 return; 5615 } 5616 if (search_function(sd, Id::call)) 5617 { 5618 /* Look for static opCall 5619 * (See bugzilla 2702 for more discussion) 5620 * Rewrite as: 5621 * e1 = typeof(e1).opCall(arguments) 5622 */ 5623 e2x = typeDotIdExp(e2x->loc, e1x->type, Id::call); 5624 e2x = new CallExp(exp->loc, e2x, exp->e2); 5625 5626 e2x = semantic(e2x, sc); 5627 e2x = resolveProperties(sc, e2x); 5628 if (e2x->op == TOKerror) 5629 { 5630 result = e2x; 5631 return; 5632 } 5633 if (e2x->checkValue()) 5634 return setError(); 5635 } 5636 } 5637 else // Bugzilla 11355 5638 { 5639 AggregateDeclaration *ad2 = isAggregate(e2x->type); 5640 if (ad2 && ad2->aliasthis && !(exp->att2 && e2x->type == exp->att2)) 5641 { 5642 if (!exp->att2 && exp->e2->type->checkAliasThisRec()) 5643 exp->att2 = exp->e2->type; 5644 5645 /* Rewrite (e1 op e2) as: 5646 * (e1 op e2.aliasthis) 5647 */ 5648 exp->e2 = new DotIdExp(exp->e2->loc, exp->e2, ad2->aliasthis->ident); 5649 result = semantic(exp, sc); 5650 return; 5651 } 5652 } 5653 } 5654 else if (exp->op == TOKassign) 5655 { 5656 if (e1x->op == TOKindex && 5657 ((IndexExp *)e1x)->e1->type->toBasetype()->ty == Taarray) 5658 { 5659 /* 5660 * Rewrite: 5661 * aa[key] = e2; 5662 * as: 5663 * ref __aatmp = aa; 5664 * ref __aakey = key; 5665 * ref __aaval = e2; 5666 * (__aakey in __aatmp 5667 * ? __aatmp[__aakey].opAssign(__aaval) 5668 * : ConstructExp(__aatmp[__aakey], __aaval)); 5669 */ 5670 IndexExp *ie = (IndexExp *)e1x; 5671 Type *t2 = e2x->type->toBasetype(); 5672 5673 Expression *e0 = NULL; 5674 Expression *ea = extractSideEffect(sc, "__aatmp", &e0, ie->e1); 5675 Expression *ek = extractSideEffect(sc, "__aakey", &e0, ie->e2); 5676 Expression *ev = extractSideEffect(sc, "__aaval", &e0, e2x); 5677 5678 AssignExp *ae = (AssignExp *)exp->copy(); 5679 ae->e1 = new IndexExp(exp->loc, ea, ek); 5680 ae->e1 = semantic(ae->e1, sc); 5681 ae->e1 = ae->e1->optimize(WANTvalue); 5682 ae->e2 = ev; 5683 Expression *e = ae->op_overload(sc); 5684 if (e) 5685 { 5686 Expression *ey = NULL; 5687 if (t2->ty == Tstruct && sd == t2->toDsymbol(sc)) 5688 { 5689 ey = ev; 5690 } 5691 else if (!ev->implicitConvTo(ie->type) && sd->ctor) 5692 { 5693 // Look for implicit constructor call 5694 // Rewrite as S().ctor(e2) 5695 ey = new StructLiteralExp(exp->loc, sd, NULL); 5696 ey = new DotIdExp(exp->loc, ey, Id::ctor); 5697 ey = new CallExp(exp->loc, ey, ev); 5698 ey = trySemantic(ey, sc); 5699 } 5700 if (ey) 5701 { 5702 Expression *ex; 5703 ex = new IndexExp(exp->loc, ea, ek); 5704 ex = semantic(ex, sc); 5705 ex = ex->optimize(WANTvalue); 5706 ex = ex->modifiableLvalue(sc, ex); // allocate new slot 5707 ey = new ConstructExp(exp->loc, ex, ey); 5708 ey = semantic(ey, sc); 5709 if (ey->op == TOKerror) 5710 { 5711 result = ey; 5712 return; 5713 } 5714 ex = e; 5715 5716 // Bugzilla 14144: The whole expression should have the common type 5717 // of opAssign() return and assigned AA entry. 5718 // Even if there's no common type, expression should be typed as void. 5719 Type *t = NULL; 5720 if (!typeMerge(sc, TOKquestion, &t, &ex, &ey)) 5721 { 5722 ex = new CastExp(ex->loc, ex, Type::tvoid); 5723 ey = new CastExp(ey->loc, ey, Type::tvoid); 5724 } 5725 e = new CondExp(exp->loc, new InExp(exp->loc, ek, ea), ex, ey); 5726 } 5727 e = Expression::combine(e0, e); 5728 e = semantic(e, sc); 5729 result = e; 5730 return; 5731 } 5732 } 5733 else 5734 { 5735 Expression *e = exp->op_overload(sc); 5736 if (e) 5737 { 5738 result = e; 5739 return; 5740 } 5741 } 5742 } 5743 else 5744 assert(exp->op == TOKblit); 5745 5746 exp->e1 = e1x; 5747 exp->e2 = e2x; 5748 } 5749 else if (t1->ty == Tclass) 5750 { 5751 // Disallow assignment operator overloads for same type 5752 if (exp->op == TOKassign && !exp->e2->implicitConvTo(exp->e1->type)) 5753 { 5754 Expression *e = exp->op_overload(sc); 5755 if (e) 5756 { 5757 result = e; 5758 return; 5759 } 5760 } 5761 } 5762 else if (t1->ty == Tsarray) 5763 { 5764 // SliceExp cannot have static array type without context inference. 5765 assert(exp->e1->op != TOKslice); 5766 5767 Expression *e1x = exp->e1; 5768 Expression *e2x = exp->e2; 5769 5770 if (e2x->implicitConvTo(e1x->type)) 5771 { 5772 if (exp->op != TOKblit && 5773 ((e2x->op == TOKslice && ((UnaExp *)e2x)->e1->isLvalue()) || 5774 (e2x->op == TOKcast && ((UnaExp *)e2x)->e1->isLvalue()) || 5775 (e2x->op != TOKslice && e2x->isLvalue()))) 5776 { 5777 if (e1x->checkPostblit(sc, t1)) 5778 return setError(); 5779 } 5780 5781 // e2 matches to t1 because of the implicit length match, so 5782 if (isUnaArrayOp(e2x->op) || isBinArrayOp(e2x->op)) 5783 { 5784 // convert e1 to e1[] 5785 // e.g. e1[] = a[] + b[]; 5786 SliceExp *sle = new SliceExp(e1x->loc, e1x, NULL, NULL); 5787 sle->arrayop = true; 5788 e1x = semantic(sle, sc); 5789 } 5790 else 5791 { 5792 // convert e2 to t1 later 5793 // e.g. e1 = [1, 2, 3]; 5794 } 5795 } 5796 else 5797 { 5798 if (e2x->implicitConvTo(t1->nextOf()->arrayOf()) > MATCHnomatch) 5799 { 5800 uinteger_t dim1 = ((TypeSArray *)t1)->dim->toInteger(); 5801 uinteger_t dim2 = dim1; 5802 if (e2x->op == TOKarrayliteral) 5803 { 5804 ArrayLiteralExp *ale = (ArrayLiteralExp *)e2x; 5805 dim2 = ale->elements ? ale->elements->dim : 0; 5806 } 5807 else if (e2x->op == TOKslice) 5808 { 5809 Type *tx = toStaticArrayType((SliceExp *)e2x); 5810 if (tx) 5811 dim2 = ((TypeSArray *)tx)->dim->toInteger(); 5812 } 5813 if (dim1 != dim2) 5814 { 5815 exp->error("mismatched array lengths, %d and %d", (int)dim1, (int)dim2); 5816 return setError(); 5817 } 5818 } 5819 5820 // May be block or element-wise assignment, so 5821 // convert e1 to e1[] 5822 if (exp->op != TOKassign) 5823 { 5824 // If multidimensional static array, treat as one large array 5825 dinteger_t dim = ((TypeSArray *)t1)->dim->toInteger(); 5826 Type *t = t1; 5827 while (1) 5828 { 5829 t = t->nextOf()->toBasetype(); 5830 if (t->ty != Tsarray) 5831 break; 5832 dim *= ((TypeSArray *)t)->dim->toInteger(); 5833 e1x->type = t->nextOf()->sarrayOf(dim); 5834 } 5835 } 5836 SliceExp *sle = new SliceExp(e1x->loc, e1x, NULL, NULL); 5837 sle->arrayop = true; 5838 e1x = semantic(sle, sc); 5839 } 5840 if (e1x->op == TOKerror) 5841 { 5842 result = e1x; 5843 return; 5844 } 5845 if (e2x->op == TOKerror) 5846 { 5847 result = e2x; 5848 return; 5849 } 5850 5851 exp->e1 = e1x; 5852 exp->e2 = e2x; 5853 t1 = e1x->type->toBasetype(); 5854 } 5855 5856 /* Check the mutability of e1. 5857 */ 5858 if (exp->e1->op == TOKarraylength) 5859 { 5860 // e1 is not an lvalue, but we let code generator handle it 5861 ArrayLengthExp *ale = (ArrayLengthExp *)exp->e1; 5862 5863 Expression *ale1x = ale->e1; 5864 ale1x = ale1x->modifiableLvalue(sc, exp->e1); 5865 if (ale1x->op == TOKerror) 5866 { 5867 result = ale1x; 5868 return; 5869 } 5870 ale->e1 = ale1x; 5871 5872 Type *tn = ale->e1->type->toBasetype()->nextOf(); 5873 checkDefCtor(ale->loc, tn); 5874 semanticTypeInfo(sc, tn); 5875 } 5876 else if (exp->e1->op == TOKslice) 5877 { 5878 Type *tn = exp->e1->type->nextOf(); 5879 if (exp->op == TOKassign && !tn->isMutable()) 5880 { 5881 exp->error("slice %s is not mutable", exp->e1->toChars()); 5882 return setError(); 5883 } 5884 5885 // For conditional operator, both branches need conversion. 5886 SliceExp *se = (SliceExp *)exp->e1; 5887 while (se->e1->op == TOKslice) 5888 se = (SliceExp *)se->e1; 5889 if (se->e1->op == TOKquestion && 5890 se->e1->type->toBasetype()->ty == Tsarray) 5891 { 5892 se->e1 = se->e1->modifiableLvalue(sc, exp->e1); 5893 if (se->e1->op == TOKerror) 5894 { 5895 result = se->e1; 5896 return; 5897 } 5898 } 5899 } 5900 else 5901 { 5902 Expression *e1x = exp->e1; 5903 5904 // Try to do a decent error message with the expression 5905 // before it got constant folded 5906 if (e1x->op != TOKvar) 5907 e1x = e1x->optimize(WANTvalue); 5908 5909 if (exp->op == TOKassign) 5910 e1x = e1x->modifiableLvalue(sc, e1old); 5911 5912 if (e1x->op == TOKerror) 5913 { 5914 result = e1x; 5915 return; 5916 } 5917 exp->e1 = e1x; 5918 } 5919 5920 /* Tweak e2 based on the type of e1. 5921 */ 5922 Expression *e2x = exp->e2; 5923 Type *t2 = e2x->type->toBasetype(); 5924 5925 // If it is a array, get the element type. Note that it may be 5926 // multi-dimensional. 5927 Type *telem = t1; 5928 while (telem->ty == Tarray) 5929 telem = telem->nextOf(); 5930 5931 if (exp->e1->op == TOKslice && 5932 t1->nextOf() && (telem->ty != Tvoid || e2x->op == TOKnull) && 5933 e2x->implicitConvTo(t1->nextOf()) 5934 ) 5935 { 5936 // Check for block assignment. If it is of type void[], void[][], etc, 5937 // '= null' is the only allowable block assignment (Bug 7493) 5938 // memset 5939 exp->memset |= blockAssign; // make it easy for back end to tell what this is 5940 e2x = e2x->implicitCastTo(sc, t1->nextOf()); 5941 if (exp->op != TOKblit && e2x->isLvalue() && 5942 exp->e1->checkPostblit(sc, t1->nextOf())) 5943 return setError(); 5944 } 5945 else if (exp->e1->op == TOKslice && 5946 (t2->ty == Tarray || t2->ty == Tsarray) && 5947 t2->nextOf()->implicitConvTo(t1->nextOf())) 5948 { 5949 // Check element-wise assignment. 5950 5951 /* If assigned elements number is known at compile time, 5952 * check the mismatch. 5953 */ 5954 SliceExp *se1 = (SliceExp *)exp->e1; 5955 TypeSArray *tsa1 = (TypeSArray *)toStaticArrayType(se1); 5956 TypeSArray *tsa2 = NULL; 5957 if (e2x->op == TOKarrayliteral) 5958 tsa2 = (TypeSArray *)t2->nextOf()->sarrayOf(((ArrayLiteralExp *)e2x)->elements->dim); 5959 else if (e2x->op == TOKslice) 5960 tsa2 = (TypeSArray *)toStaticArrayType((SliceExp *)e2x); 5961 else if (t2->ty == Tsarray) 5962 tsa2 = (TypeSArray *)t2; 5963 if (tsa1 && tsa2) 5964 { 5965 uinteger_t dim1 = tsa1->dim->toInteger(); 5966 uinteger_t dim2 = tsa2->dim->toInteger(); 5967 if (dim1 != dim2) 5968 { 5969 exp->error("mismatched array lengths, %d and %d", (int)dim1, (int)dim2); 5970 return setError(); 5971 } 5972 } 5973 5974 if (exp->op != TOKblit && 5975 ((e2x->op == TOKslice && ((UnaExp *)e2x)->e1->isLvalue()) || 5976 (e2x->op == TOKcast && ((UnaExp *)e2x)->e1->isLvalue()) || 5977 (e2x->op != TOKslice && e2x->isLvalue()))) 5978 { 5979 if (exp->e1->checkPostblit(sc, t1->nextOf())) 5980 return setError(); 5981 } 5982 5983 if (0 && global.params.warnings != DIAGNOSTICoff && !global.gag && exp->op == TOKassign && 5984 e2x->op != TOKslice && e2x->op != TOKassign && 5985 e2x->op != TOKarrayliteral && e2x->op != TOKstring && 5986 !(e2x->op == TOKadd || e2x->op == TOKmin || 5987 e2x->op == TOKmul || e2x->op == TOKdiv || 5988 e2x->op == TOKmod || e2x->op == TOKxor || 5989 e2x->op == TOKand || e2x->op == TOKor || 5990 e2x->op == TOKpow || 5991 e2x->op == TOKtilde || e2x->op == TOKneg)) 5992 { 5993 const char* e1str = exp->e1->toChars(); 5994 const char* e2str = e2x->toChars(); 5995 exp->warning("explicit element-wise assignment %s = (%s)[] is better than %s = %s", 5996 e1str, e2str, e1str, e2str); 5997 } 5998 5999 Type *t2n = t2->nextOf(); 6000 Type *t1n = t1->nextOf(); 6001 int offset; 6002 if (t2n->equivalent(t1n) || 6003 (t1n->isBaseOf(t2n, &offset) && offset == 0)) 6004 { 6005 /* Allow copy of distinct qualifier elements. 6006 * eg. 6007 * char[] dst; const(char)[] src; 6008 * dst[] = src; 6009 * 6010 * class C {} class D : C {} 6011 * C[2] ca; D[] da; 6012 * ca[] = da; 6013 */ 6014 if (isArrayOpValid(e2x)) 6015 { 6016 // Don't add CastExp to keep AST for array operations 6017 e2x = e2x->copy(); 6018 e2x->type = exp->e1->type->constOf(); 6019 } 6020 else 6021 e2x = e2x->castTo(sc, exp->e1->type->constOf()); 6022 } 6023 else 6024 { 6025 /* Bugzilla 15778: A string literal has an array type of immutable 6026 * elements by default, and normally it cannot be convertible to 6027 * array type of mutable elements. But for element-wise assignment, 6028 * elements need to be const at best. So we should give a chance 6029 * to change code unit size for polysemous string literal. 6030 */ 6031 if (e2x->op == TOKstring) 6032 e2x = e2x->implicitCastTo(sc, exp->e1->type->constOf()); 6033 else 6034 e2x = e2x->implicitCastTo(sc, exp->e1->type); 6035 } 6036 if (t1n->toBasetype()->ty == Tvoid && t2n->toBasetype()->ty == Tvoid) 6037 { 6038 if (!sc->intypeof && sc->func && sc->func->setUnsafe()) 6039 { 6040 exp->error("cannot copy void[] to void[] in @safe code"); 6041 return setError(); 6042 } 6043 } 6044 } 6045 else 6046 { 6047 if (0 && global.params.warnings != DIAGNOSTICoff && !global.gag && exp->op == TOKassign && 6048 t1->ty == Tarray && t2->ty == Tsarray && 6049 e2x->op != TOKslice && 6050 t2->implicitConvTo(t1)) 6051 { // Disallow ar[] = sa (Converted to ar[] = sa[]) 6052 // Disallow da = sa (Converted to da = sa[]) 6053 const char* e1str = exp->e1->toChars(); 6054 const char* e2str = e2x->toChars(); 6055 const char* atypestr = exp->e1->op == TOKslice ? "element-wise" : "slice"; 6056 exp->warning("explicit %s assignment %s = (%s)[] is better than %s = %s", 6057 atypestr, e1str, e2str, e1str, e2str); 6058 } 6059 if (exp->op == TOKblit) 6060 e2x = e2x->castTo(sc, exp->e1->type); 6061 else 6062 e2x = e2x->implicitCastTo(sc, exp->e1->type); 6063 } 6064 if (e2x->op == TOKerror) 6065 { 6066 result = e2x; 6067 return; 6068 } 6069 exp->e2 = e2x; 6070 t2 = exp->e2->type->toBasetype(); 6071 6072 /* Look for array operations 6073 */ 6074 if ((t2->ty == Tarray || t2->ty == Tsarray) && isArrayOpValid(exp->e2)) 6075 { 6076 // Look for valid array operations 6077 if (!(exp->memset & blockAssign) && exp->e1->op == TOKslice && 6078 (isUnaArrayOp(exp->e2->op) || isBinArrayOp(exp->e2->op))) 6079 { 6080 exp->type = exp->e1->type; 6081 if (exp->op == TOKconstruct) // Bugzilla 10282: tweak mutability of e1 element 6082 exp->e1->type = exp->e1->type->nextOf()->mutableOf()->arrayOf(); 6083 result = arrayOp(exp, sc); 6084 return; 6085 } 6086 6087 // Drop invalid array operations in e2 6088 // d = a[] + b[], d = (a[] + b[])[0..2], etc 6089 if (checkNonAssignmentArrayOp(exp->e2, !(exp->memset & blockAssign) && exp->op == TOKassign)) 6090 return setError(); 6091 6092 // Remains valid array assignments 6093 // d = d[], d = [1,2,3], etc 6094 } 6095 6096 /* Don't allow assignment to classes that were allocated on the stack with: 6097 * scope Class c = new Class(); 6098 */ 6099 6100 if (exp->e1->op == TOKvar && exp->op == TOKassign) 6101 { 6102 VarExp *ve = (VarExp *)exp->e1; 6103 VarDeclaration *vd = ve->var->isVarDeclaration(); 6104 if (vd && (vd->onstack || vd->mynew)) 6105 { 6106 assert(t1->ty == Tclass); 6107 exp->error("cannot rebind scope variables"); 6108 } 6109 } 6110 if (exp->e1->op == TOKvar && ((VarExp *)exp->e1)->var->ident == Id::ctfe) 6111 { 6112 exp->error("cannot modify compiler-generated variable __ctfe"); 6113 } 6114 6115 exp->type = exp->e1->type; 6116 assert(exp->type); 6117 Expression *res = exp->op == TOKassign ? exp->reorderSettingAAElem(sc) : exp; 6118 checkAssignEscape(sc, res, false); 6119 result = res; 6120 } 6121 6122 void visit(CatAssignExp *exp) 6123 { 6124 if (exp->type) 6125 { 6126 result = exp; 6127 return; 6128 } 6129 6130 //printf("CatAssignExp::semantic() %s\n", toChars()); 6131 Expression *e = exp->op_overload(sc); 6132 if (e) 6133 { 6134 result = e; 6135 return; 6136 } 6137 6138 if (exp->e1->op == TOKslice) 6139 { 6140 SliceExp *se = (SliceExp *)exp->e1; 6141 if (se->e1->type->toBasetype()->ty == Tsarray) 6142 { 6143 exp->error("cannot append to static array %s", se->e1->type->toChars()); 6144 return setError(); 6145 } 6146 } 6147 6148 exp->e1 = exp->e1->modifiableLvalue(sc, exp->e1); 6149 if (exp->e1->op == TOKerror) 6150 { 6151 result = exp->e1; 6152 return; 6153 } 6154 if (exp->e2->op == TOKerror) 6155 { 6156 result = exp->e2; 6157 return; 6158 } 6159 6160 if (checkNonAssignmentArrayOp(exp->e2)) 6161 return setError(); 6162 6163 Type *tb1 = exp->e1->type->toBasetype(); 6164 Type *tb1next = tb1->nextOf(); 6165 Type *tb2 = exp->e2->type->toBasetype(); 6166 6167 if ((tb1->ty == Tarray) && 6168 (tb2->ty == Tarray || tb2->ty == Tsarray) && 6169 (exp->e2->implicitConvTo(exp->e1->type) 6170 || (tb2->nextOf()->implicitConvTo(tb1next) && 6171 (tb2->nextOf()->size(Loc()) == tb1next->size(Loc()))) 6172 ) 6173 ) 6174 { 6175 // Append array 6176 if (exp->e1->checkPostblit(sc, tb1next)) 6177 return setError(); 6178 exp->e2 = exp->e2->castTo(sc, exp->e1->type); 6179 } 6180 else if ((tb1->ty == Tarray) && 6181 exp->e2->implicitConvTo(tb1next) 6182 ) 6183 { 6184 // Append element 6185 if (exp->e2->checkPostblit(sc, tb2)) 6186 return setError(); 6187 exp->e2 = exp->e2->castTo(sc, tb1next); 6188 exp->e2 = doCopyOrMove(sc, exp->e2); 6189 } 6190 else if (tb1->ty == Tarray && 6191 (tb1next->ty == Tchar || tb1next->ty == Twchar) && 6192 exp->e2->type->ty != tb1next->ty && 6193 exp->e2->implicitConvTo(Type::tdchar) 6194 ) 6195 { // Append dchar to char[] or wchar[] 6196 exp->e2 = exp->e2->castTo(sc, Type::tdchar); 6197 6198 /* Do not allow appending wchar to char[] because if wchar happens 6199 * to be a surrogate pair, nothing good can result. 6200 */ 6201 } 6202 else 6203 { 6204 exp->error("cannot append type %s to type %s", tb2->toChars(), tb1->toChars()); 6205 return setError(); 6206 } 6207 if (exp->e2->checkValue()) 6208 return setError(); 6209 6210 exp->type = exp->e1->type; 6211 result = exp->reorderSettingAAElem(sc); 6212 } 6213 6214 void visit(PowAssignExp *exp) 6215 { 6216 if (exp->type) 6217 { 6218 result = exp; 6219 return; 6220 } 6221 6222 Expression *e = exp->op_overload(sc); 6223 if (e) 6224 { 6225 result = e; 6226 return; 6227 } 6228 6229 if (exp->e1->checkReadModifyWrite(exp->op, exp->e2)) 6230 return setError(); 6231 6232 assert(exp->e1->type && exp->e2->type); 6233 if (exp->e1->op == TOKslice || exp->e1->type->ty == Tarray || exp->e1->type->ty == Tsarray) 6234 { 6235 // T[] ^^= ... 6236 if (exp->e2->implicitConvTo(exp->e1->type->nextOf())) 6237 { 6238 // T[] ^^= T 6239 exp->e2 = exp->e2->castTo(sc, exp->e1->type->nextOf()); 6240 } 6241 else if (Expression *ex = typeCombine(exp, sc)) 6242 { 6243 result = ex; 6244 return; 6245 } 6246 6247 // Check element types are arithmetic 6248 Type *tb1 = exp->e1->type->nextOf()->toBasetype(); 6249 Type *tb2 = exp->e2->type->toBasetype(); 6250 if (tb2->ty == Tarray || tb2->ty == Tsarray) 6251 tb2 = tb2->nextOf()->toBasetype(); 6252 6253 if ( (tb1->isintegral() || tb1->isfloating()) && 6254 (tb2->isintegral() || tb2->isfloating())) 6255 { 6256 exp->type = exp->e1->type; 6257 result = arrayOp(exp, sc); 6258 return; 6259 } 6260 } 6261 else 6262 { 6263 exp->e1 = exp->e1->modifiableLvalue(sc, exp->e1); 6264 } 6265 6266 if ((exp->e1->type->isintegral() || exp->e1->type->isfloating()) && 6267 (exp->e2->type->isintegral() || exp->e2->type->isfloating())) 6268 { 6269 Expression *e0 = NULL; 6270 e = exp->reorderSettingAAElem(sc); 6271 e = Expression::extractLast(e, &e0); 6272 assert(e == exp); 6273 6274 if (exp->e1->op == TOKvar) 6275 { 6276 // Rewrite: e1 = e1 ^^ e2 6277 e = new PowExp(exp->loc, exp->e1->syntaxCopy(), exp->e2); 6278 e = new AssignExp(exp->loc, exp->e1, e); 6279 } 6280 else 6281 { 6282 // Rewrite: ref tmp = e1; tmp = tmp ^^ e2 6283 VarDeclaration *v = copyToTemp(STCref, "__powtmp", exp->e1); 6284 Expression *de = new DeclarationExp(exp->e1->loc, v); 6285 VarExp *ve = new VarExp(exp->e1->loc, v); 6286 e = new PowExp(exp->loc, ve, exp->e2); 6287 e = new AssignExp(exp->loc, new VarExp(exp->e1->loc, v), e); 6288 e = new CommaExp(exp->loc, de, e); 6289 } 6290 e = Expression::combine(e0, e); 6291 e = semantic(e, sc); 6292 result = e; 6293 return; 6294 } 6295 result = exp->incompatibleTypes(); 6296 } 6297 6298 void visit(AddExp *exp) 6299 { 6300 if (exp->type) 6301 { 6302 result = exp; 6303 return; 6304 } 6305 6306 if (Expression *ex = binSemanticProp(exp, sc)) 6307 { 6308 result = ex; 6309 return; 6310 } 6311 Expression *e = exp->op_overload(sc); 6312 if (e) 6313 { 6314 result = e; 6315 return; 6316 } 6317 6318 Type *tb1 = exp->e1->type->toBasetype(); 6319 Type *tb2 = exp->e2->type->toBasetype(); 6320 6321 bool err = false; 6322 if (tb1->ty == Tdelegate || 6323 (tb1->ty == Tpointer && tb1->nextOf()->ty == Tfunction)) 6324 { 6325 err |= exp->e1->checkArithmetic(); 6326 } 6327 if (tb2->ty == Tdelegate || 6328 (tb2->ty == Tpointer && tb2->nextOf()->ty == Tfunction)) 6329 { 6330 err |= exp->e2->checkArithmetic(); 6331 } 6332 if (err) 6333 return setError(); 6334 6335 if ((tb1->ty == Tpointer && exp->e2->type->isintegral()) || 6336 (tb2->ty == Tpointer && exp->e1->type->isintegral())) 6337 { 6338 result = scaleFactor(exp, sc); 6339 return; 6340 } 6341 6342 if (tb1->ty == Tpointer && tb2->ty == Tpointer) 6343 { 6344 result = exp->incompatibleTypes(); 6345 return; 6346 } 6347 6348 if (Expression *ex = typeCombine(exp, sc)) 6349 { 6350 result = ex; 6351 return; 6352 } 6353 6354 Type *tb = exp->type->toBasetype(); 6355 if (tb->ty == Tarray || tb->ty == Tsarray) 6356 { 6357 if (!isArrayOpValid(exp)) 6358 { 6359 exp->error("invalid array operation %s (possible missing [])", exp->toChars()); 6360 return setError(); 6361 } 6362 result = exp; 6363 return; 6364 } 6365 6366 tb1 = exp->e1->type->toBasetype(); 6367 if (!Target::isVectorOpSupported(tb1, exp->op, tb2)) 6368 { 6369 result = exp->incompatibleTypes(); 6370 return; 6371 } 6372 if ((tb1->isreal() && exp->e2->type->isimaginary()) || 6373 (tb1->isimaginary() && exp->e2->type->isreal())) 6374 { 6375 switch (exp->type->toBasetype()->ty) 6376 { 6377 case Tfloat32: 6378 case Timaginary32: 6379 exp->type = Type::tcomplex32; 6380 break; 6381 6382 case Tfloat64: 6383 case Timaginary64: 6384 exp->type = Type::tcomplex64; 6385 break; 6386 6387 case Tfloat80: 6388 case Timaginary80: 6389 exp->type = Type::tcomplex80; 6390 break; 6391 6392 default: 6393 assert(0); 6394 } 6395 } 6396 result = exp; 6397 } 6398 6399 void visit(MinExp *exp) 6400 { 6401 if (exp->type) 6402 { 6403 result = exp; 6404 return; 6405 } 6406 6407 if (Expression *ex = binSemanticProp(exp, sc)) 6408 { 6409 result = ex; 6410 return; 6411 } 6412 Expression *e = exp->op_overload(sc); 6413 if (e) 6414 { 6415 result = e; 6416 return; 6417 } 6418 6419 Type *t1 = exp->e1->type->toBasetype(); 6420 Type *t2 = exp->e2->type->toBasetype(); 6421 6422 bool err = false; 6423 if (t1->ty == Tdelegate || 6424 (t1->ty == Tpointer && t1->nextOf()->ty == Tfunction)) 6425 { 6426 err |= exp->e1->checkArithmetic(); 6427 } 6428 if (t2->ty == Tdelegate || 6429 (t2->ty == Tpointer && t2->nextOf()->ty == Tfunction)) 6430 { 6431 err |= exp->e2->checkArithmetic(); 6432 } 6433 if (err) 6434 return setError(); 6435 6436 if (t1->ty == Tpointer) 6437 { 6438 if (t2->ty == Tpointer) 6439 { 6440 // Need to divide the result by the stride 6441 // Replace (ptr - ptr) with (ptr - ptr) / stride 6442 d_int64 stride; 6443 6444 // make sure pointer types are compatible 6445 if (Expression *ex = typeCombine(exp, sc)) 6446 { 6447 result = ex; 6448 return; 6449 } 6450 6451 exp->type = Type::tptrdiff_t; 6452 stride = t2->nextOf()->size(); 6453 if (stride == 0) 6454 { 6455 e = new IntegerExp(exp->loc, 0, Type::tptrdiff_t); 6456 } 6457 else 6458 { 6459 e = new DivExp(exp->loc, exp, new IntegerExp(Loc(), stride, Type::tptrdiff_t)); 6460 e->type = Type::tptrdiff_t; 6461 } 6462 } 6463 else if (t2->isintegral()) 6464 e = scaleFactor(exp, sc); 6465 else 6466 { 6467 exp->error("can't subtract %s from pointer", t2->toChars()); 6468 e = new ErrorExp(); 6469 } 6470 result = e; 6471 return; 6472 } 6473 if (t2->ty == Tpointer) 6474 { 6475 exp->type = exp->e2->type; 6476 exp->error("can't subtract pointer from %s", exp->e1->type->toChars()); 6477 return setError(); 6478 } 6479 6480 if (Expression *ex = typeCombine(exp, sc)) 6481 { 6482 result = ex; 6483 return; 6484 } 6485 6486 Type *tb = exp->type->toBasetype(); 6487 if (tb->ty == Tarray || tb->ty == Tsarray) 6488 { 6489 if (!isArrayOpValid(exp)) 6490 { 6491 exp->error("invalid array operation %s (possible missing [])", exp->toChars()); 6492 return setError(); 6493 } 6494 result = exp; 6495 return; 6496 } 6497 6498 t1 = exp->e1->type->toBasetype(); 6499 t2 = exp->e2->type->toBasetype(); 6500 if (!Target::isVectorOpSupported(t1, exp->op, t2)) 6501 { 6502 result = exp->incompatibleTypes(); 6503 return; 6504 } 6505 if ((t1->isreal() && t2->isimaginary()) || 6506 (t1->isimaginary() && t2->isreal())) 6507 { 6508 switch (exp->type->ty) 6509 { 6510 case Tfloat32: 6511 case Timaginary32: 6512 exp->type = Type::tcomplex32; 6513 break; 6514 6515 case Tfloat64: 6516 case Timaginary64: 6517 exp->type = Type::tcomplex64; 6518 break; 6519 6520 case Tfloat80: 6521 case Timaginary80: 6522 exp->type = Type::tcomplex80; 6523 break; 6524 6525 default: 6526 assert(0); 6527 } 6528 } 6529 result = exp; 6530 } 6531 6532 void visit(CatExp *exp) 6533 { 6534 //printf("CatExp::semantic() %s\n", exp->toChars()); 6535 if (exp->type) 6536 { 6537 result = exp; 6538 return; 6539 } 6540 6541 if (Expression *ex = binSemanticProp(exp, sc)) 6542 { 6543 result = ex; 6544 return; 6545 } 6546 Expression *e = exp->op_overload(sc); 6547 if (e) 6548 { 6549 result = e; 6550 return; 6551 } 6552 6553 Type *tb1 = exp->e1->type->toBasetype(); 6554 Type *tb2 = exp->e2->type->toBasetype(); 6555 6556 bool f1 = checkNonAssignmentArrayOp(exp->e1); 6557 bool f2 = checkNonAssignmentArrayOp(exp->e2); 6558 if (f1 || f2) 6559 return setError(); 6560 6561 /* BUG: Should handle things like: 6562 * char c; 6563 * c ~ ' ' 6564 * ' ' ~ c; 6565 */ 6566 Type *tb1next = tb1->nextOf(); 6567 Type *tb2next = tb2->nextOf(); 6568 6569 // Check for: array ~ array 6570 if (tb1next && tb2next && 6571 (tb1next->implicitConvTo(tb2next) >= MATCHconst || 6572 tb2next->implicitConvTo(tb1next) >= MATCHconst || 6573 (exp->e1->op == TOKarrayliteral && exp->e1->implicitConvTo(tb2)) || 6574 (exp->e2->op == TOKarrayliteral && exp->e2->implicitConvTo(tb1)) 6575 ) 6576 ) 6577 { 6578 /* Bugzilla 9248: Here to avoid the case of: 6579 * void*[] a = [cast(void*)1]; 6580 * void*[] b = [cast(void*)2]; 6581 * a ~ b; 6582 * becoming: 6583 * a ~ [cast(void*)b]; 6584 */ 6585 6586 /* Bugzilla 14682: Also to avoid the case of: 6587 * int[][] a; 6588 * a ~ []; 6589 * becoming: 6590 * a ~ cast(int[])[]; 6591 */ 6592 goto Lpeer; 6593 } 6594 6595 // Check for: array ~ element 6596 if ((tb1->ty == Tsarray || tb1->ty == Tarray) && tb2->ty != Tvoid) 6597 { 6598 if (exp->e1->op == TOKarrayliteral) 6599 { 6600 exp->e2 = exp->e2->isLvalue() ? callCpCtor(sc, exp->e2) : valueNoDtor(exp->e2); 6601 // Bugzilla 14686: Postblit call appears in AST, and this is 6602 // finally translated to an ArrayLiteralExp in below otpimize(). 6603 } 6604 else if (exp->e1->op == TOKstring) 6605 { 6606 // No postblit call exists on character (integer) value. 6607 } 6608 else 6609 { 6610 if (exp->e2->checkPostblit(sc, tb2)) 6611 return setError(); 6612 // Postblit call will be done in runtime helper function 6613 } 6614 6615 if (exp->e1->op == TOKarrayliteral && exp->e1->implicitConvTo(tb2->arrayOf())) 6616 { 6617 exp->e1 = exp->e1->implicitCastTo(sc, tb2->arrayOf()); 6618 exp->type = tb2->arrayOf(); 6619 goto L2elem; 6620 } 6621 if (exp->e2->implicitConvTo(tb1next) >= MATCHconvert) 6622 { 6623 exp->e2 = exp->e2->implicitCastTo(sc, tb1next); 6624 exp->type = tb1next->arrayOf(); 6625 L2elem: 6626 if (tb2->ty == Tarray || tb2->ty == Tsarray) 6627 { 6628 // Make e2 into [e2] 6629 exp->e2 = new ArrayLiteralExp(exp->e2->loc, exp->type, exp->e2); 6630 } 6631 result = exp->optimize(WANTvalue); 6632 return; 6633 } 6634 } 6635 // Check for: element ~ array 6636 if ((tb2->ty == Tsarray || tb2->ty == Tarray) && tb1->ty != Tvoid) 6637 { 6638 if (exp->e2->op == TOKarrayliteral) 6639 { 6640 exp->e1 = exp->e1->isLvalue() ? callCpCtor(sc, exp->e1) : valueNoDtor(exp->e1); 6641 } 6642 else if (exp->e2->op == TOKstring) 6643 { 6644 } 6645 else 6646 { 6647 if (exp->e1->checkPostblit(sc, tb1)) 6648 return setError(); 6649 } 6650 6651 if (exp->e2->op == TOKarrayliteral && exp->e2->implicitConvTo(tb1->arrayOf())) 6652 { 6653 exp->e2 = exp->e2->implicitCastTo(sc, tb1->arrayOf()); 6654 exp->type = tb1->arrayOf(); 6655 goto L1elem; 6656 } 6657 if (exp->e1->implicitConvTo(tb2next) >= MATCHconvert) 6658 { 6659 exp->e1 = exp->e1->implicitCastTo(sc, tb2next); 6660 exp->type = tb2next->arrayOf(); 6661 L1elem: 6662 if (tb1->ty == Tarray || tb1->ty == Tsarray) 6663 { 6664 // Make e1 into [e1] 6665 exp->e1 = new ArrayLiteralExp(exp->e1->loc, exp->type, exp->e1); 6666 } 6667 result = exp->optimize(WANTvalue); 6668 return; 6669 } 6670 } 6671 6672 Lpeer: 6673 if ((tb1->ty == Tsarray || tb1->ty == Tarray) && 6674 (tb2->ty == Tsarray || tb2->ty == Tarray) && 6675 (tb1next->mod || tb2next->mod) && 6676 (tb1next->mod != tb2next->mod) 6677 ) 6678 { 6679 Type *t1 = tb1next->mutableOf()->constOf()->arrayOf(); 6680 Type *t2 = tb2next->mutableOf()->constOf()->arrayOf(); 6681 if (exp->e1->op == TOKstring && !((StringExp *)exp->e1)->committed) 6682 exp->e1->type = t1; 6683 else 6684 exp->e1 = exp->e1->castTo(sc, t1); 6685 if (exp->e2->op == TOKstring && !((StringExp *)exp->e2)->committed) 6686 exp->e2->type = t2; 6687 else 6688 exp->e2 = exp->e2->castTo(sc, t2); 6689 } 6690 6691 if (Expression *ex = typeCombine(exp, sc)) 6692 { 6693 result = ex; 6694 return; 6695 } 6696 exp->type = exp->type->toHeadMutable(); 6697 6698 Type *tb = exp->type->toBasetype(); 6699 if (tb->ty == Tsarray) 6700 exp->type = tb->nextOf()->arrayOf(); 6701 if (exp->type->ty == Tarray && tb1next && tb2next && 6702 tb1next->mod != tb2next->mod) 6703 { 6704 exp->type = exp->type->nextOf()->toHeadMutable()->arrayOf(); 6705 } 6706 if (Type *tbn = tb->nextOf()) 6707 { 6708 if (exp->checkPostblit(sc, tbn)) 6709 return setError(); 6710 } 6711 Type *t1 = exp->e1->type->toBasetype(); 6712 Type *t2 = exp->e2->type->toBasetype(); 6713 if ((t1->ty == Tarray || t1->ty == Tsarray) && 6714 (t2->ty == Tarray || t2->ty == Tsarray)) 6715 { 6716 // Normalize to ArrayLiteralExp or StringExp as far as possible 6717 e = exp->optimize(WANTvalue); 6718 } 6719 else 6720 { 6721 //printf("(%s) ~ (%s)\n", exp->e1->toChars(), exp->e2->toChars()); 6722 result = exp->incompatibleTypes(); 6723 return; 6724 } 6725 result = e; 6726 } 6727 6728 void visit(MulExp *exp) 6729 { 6730 if (exp->type) 6731 { 6732 result = exp; 6733 return; 6734 } 6735 6736 if (Expression *ex = binSemanticProp(exp, sc)) 6737 { 6738 result = ex; 6739 return; 6740 } 6741 Expression *e = exp->op_overload(sc); 6742 if (e) 6743 { 6744 result = e; 6745 return; 6746 } 6747 6748 if (Expression *ex = typeCombine(exp, sc)) 6749 { 6750 result = ex; 6751 return; 6752 } 6753 6754 Type *tb = exp->type->toBasetype(); 6755 if (tb->ty == Tarray || tb->ty == Tsarray) 6756 { 6757 if (!isArrayOpValid(exp)) 6758 { 6759 exp->error("invalid array operation %s (possible missing [])", exp->toChars()); 6760 return setError(); 6761 } 6762 result = exp; 6763 return; 6764 } 6765 6766 if (exp->checkArithmeticBin()) 6767 return setError(); 6768 6769 if (exp->type->isfloating()) 6770 { 6771 Type *t1 = exp->e1->type; 6772 Type *t2 = exp->e2->type; 6773 6774 if (t1->isreal()) 6775 { 6776 exp->type = t2; 6777 } 6778 else if (t2->isreal()) 6779 { 6780 exp->type = t1; 6781 } 6782 else if (t1->isimaginary()) 6783 { 6784 if (t2->isimaginary()) 6785 { 6786 6787 switch (t1->toBasetype()->ty) 6788 { 6789 case Timaginary32: 6790 exp->type = Type::tfloat32; 6791 break; 6792 6793 case Timaginary64: 6794 exp->type = Type::tfloat64; 6795 break; 6796 6797 case Timaginary80: 6798 exp->type = Type::tfloat80; 6799 break; 6800 6801 default: 6802 assert(0); 6803 } 6804 6805 // iy * iv = -yv 6806 exp->e1->type = exp->type; 6807 exp->e2->type = exp->type; 6808 e = new NegExp(exp->loc, exp); 6809 e = semantic(e, sc); 6810 result = e; 6811 return; 6812 } 6813 else 6814 exp->type = t2; // t2 is complex 6815 } 6816 else if (t2->isimaginary()) 6817 { 6818 exp->type = t1; // t1 is complex 6819 } 6820 } 6821 else if (!Target::isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype())) 6822 { 6823 result = exp->incompatibleTypes(); 6824 return; 6825 } 6826 result = exp; 6827 } 6828 6829 void visit(DivExp *exp) 6830 { 6831 if (exp->type) 6832 { 6833 result = exp; 6834 return; 6835 } 6836 6837 if (Expression *ex = binSemanticProp(exp, sc)) 6838 { 6839 result = ex; 6840 } 6841 Expression *e = exp->op_overload(sc); 6842 if (e) 6843 { 6844 result = e; 6845 return; 6846 } 6847 6848 if (Expression *ex = typeCombine(exp, sc)) 6849 { 6850 result = ex; 6851 return; 6852 } 6853 6854 Type *tb = exp->type->toBasetype(); 6855 if (tb->ty == Tarray || tb->ty == Tsarray) 6856 { 6857 if (!isArrayOpValid(exp)) 6858 { 6859 exp->error("invalid array operation %s (possible missing [])", exp->toChars()); 6860 return setError(); 6861 } 6862 result = exp; 6863 return; 6864 } 6865 6866 if (exp->checkArithmeticBin()) 6867 return setError(); 6868 6869 if (exp->type->isfloating()) 6870 { 6871 Type *t1 = exp->e1->type; 6872 Type *t2 = exp->e2->type; 6873 6874 if (t1->isreal()) 6875 { 6876 exp->type = t2; 6877 if (t2->isimaginary()) 6878 { 6879 // x/iv = i(-x/v) 6880 exp->e2->type = t1; 6881 e = new NegExp(exp->loc, exp); 6882 e = semantic(e, sc); 6883 result = e; 6884 return; 6885 } 6886 } 6887 else if (t2->isreal()) 6888 { 6889 exp->type = t1; 6890 } 6891 else if (t1->isimaginary()) 6892 { 6893 if (t2->isimaginary()) 6894 { 6895 switch (t1->toBasetype()->ty) 6896 { 6897 case Timaginary32: 6898 exp->type = Type::tfloat32; 6899 break; 6900 6901 case Timaginary64: 6902 exp->type = Type::tfloat64; 6903 break; 6904 6905 case Timaginary80: 6906 exp->type = Type::tfloat80; 6907 break; 6908 6909 default: 6910 assert(0); 6911 } 6912 } 6913 else 6914 exp->type = t2; // t2 is complex 6915 } 6916 else if (t2->isimaginary()) 6917 { 6918 exp->type = t1; // t1 is complex 6919 } 6920 } 6921 else if (!Target::isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype())) 6922 { 6923 result = exp->incompatibleTypes(); 6924 return; 6925 } 6926 result = exp; 6927 } 6928 6929 void visit(ModExp *exp) 6930 { 6931 if (exp->type) 6932 { 6933 result = exp; 6934 return; 6935 } 6936 6937 if (Expression *ex = binSemanticProp(exp, sc)) 6938 { 6939 result = ex; 6940 return; 6941 } 6942 Expression *e = exp->op_overload(sc); 6943 if (e) 6944 { 6945 result = e; 6946 return; 6947 } 6948 6949 if (Expression *ex = typeCombine(exp, sc)) 6950 { 6951 result = ex; 6952 return; 6953 } 6954 6955 Type *tb = exp->type->toBasetype(); 6956 if (tb->ty == Tarray || tb->ty == Tsarray) 6957 { 6958 if (!isArrayOpValid(exp)) 6959 { 6960 exp->error("invalid array operation %s (possible missing [])", exp->toChars()); 6961 return setError(); 6962 } 6963 result = exp; 6964 return; 6965 } 6966 if (!Target::isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype())) 6967 { 6968 result = exp->incompatibleTypes(); 6969 return; 6970 } 6971 6972 if (exp->checkArithmeticBin()) 6973 return setError(); 6974 6975 if (exp->type->isfloating()) 6976 { 6977 exp->type = exp->e1->type; 6978 if (exp->e2->type->iscomplex()) 6979 { 6980 exp->error("cannot perform modulo complex arithmetic"); 6981 return setError(); 6982 } 6983 } 6984 result = exp; 6985 } 6986 6987 Module *loadStdMath() 6988 { 6989 static Import *impStdMath = NULL; 6990 if (!impStdMath) 6991 { 6992 Identifiers *a = new Identifiers(); 6993 a->push(Id::std); 6994 Import *s = new Import(Loc(), a, Id::math, NULL, false); 6995 s->load(NULL); 6996 if (s->mod) 6997 { 6998 s->mod->importAll(NULL); 6999 s->mod->semantic(NULL); 7000 } 7001 impStdMath = s; 7002 } 7003 return impStdMath->mod; 7004 } 7005 7006 void visit(PowExp *exp) 7007 { 7008 if (exp->type) 7009 { 7010 result = exp; 7011 return; 7012 } 7013 7014 //printf("PowExp::semantic() %s\n", exp->toChars()); 7015 if (Expression *ex = binSemanticProp(exp, sc)) 7016 { 7017 result = ex; 7018 return; 7019 } 7020 Expression *e = exp->op_overload(sc); 7021 if (e) 7022 { 7023 result = e; 7024 return; 7025 } 7026 7027 if (Expression *ex = typeCombine(exp, sc)) 7028 { 7029 result = ex; 7030 return; 7031 } 7032 7033 Type *tb = exp->type->toBasetype(); 7034 if (tb->ty == Tarray || tb->ty == Tsarray) 7035 { 7036 if (!isArrayOpValid(exp)) 7037 { 7038 exp->error("invalid array operation %s (possible missing [])", exp->toChars()); 7039 return setError(); 7040 } 7041 result = exp; 7042 return; 7043 } 7044 7045 if (exp->checkArithmeticBin()) 7046 return setError(); 7047 7048 if (!Target::isVectorOpSupported(exp->e1->type->toBasetype(), exp->op, exp->e2->type->toBasetype())) 7049 { 7050 result = exp->incompatibleTypes(); 7051 return; 7052 } 7053 7054 // For built-in numeric types, there are several cases. 7055 // TODO: backend support, especially for e1 ^^ 2. 7056 7057 // First, attempt to fold the expression. 7058 e = exp->optimize(WANTvalue); 7059 if (e->op != TOKpow) 7060 { 7061 e = semantic(e, sc); 7062 result = e; 7063 return; 7064 } 7065 7066 // Determine if we're raising to an integer power. 7067 sinteger_t intpow = 0; 7068 if (exp->e2->op == TOKint64 && ((sinteger_t)exp->e2->toInteger() == 2 || (sinteger_t)exp->e2->toInteger() == 3)) 7069 intpow = exp->e2->toInteger(); 7070 else if (exp->e2->op == TOKfloat64 && (exp->e2->toReal() == ldouble((sinteger_t)exp->e2->toReal()))) 7071 intpow = (sinteger_t)(exp->e2->toReal()); 7072 7073 // Deal with x^^2, x^^3 immediately, since they are of practical importance. 7074 if (intpow == 2 || intpow == 3) 7075 { 7076 // Replace x^^2 with (tmp = x, tmp*tmp) 7077 // Replace x^^3 with (tmp = x, tmp*tmp*tmp) 7078 VarDeclaration *tmp = copyToTemp(0, "__powtmp", exp->e1); 7079 Expression *de = new DeclarationExp(exp->loc, tmp); 7080 Expression *ve = new VarExp(exp->loc, tmp); 7081 7082 /* Note that we're reusing ve. This should be ok. 7083 */ 7084 Expression *me = new MulExp(exp->loc, ve, ve); 7085 if (intpow == 3) 7086 me = new MulExp(exp->loc, me, ve); 7087 e = new CommaExp(exp->loc, de, me); 7088 e = semantic(e, sc); 7089 result = e; 7090 return; 7091 } 7092 7093 Module *mmath = loadStdMath(); 7094 if (!mmath) 7095 { 7096 //exp->error("requires std.math for ^^ operators"); 7097 //fatal(); 7098 7099 // Leave handling of PowExp to the backend, or throw 7100 // an error gracefully if no backend support exists. 7101 if (Expression *ex = typeCombine(exp, sc)) 7102 { 7103 result = ex; 7104 return; 7105 } 7106 result = exp; 7107 return; 7108 } 7109 e = new ScopeExp(exp->loc, mmath); 7110 7111 if (exp->e2->op == TOKfloat64 && exp->e2->toReal() == CTFloat::half) 7112 { 7113 // Replace e1 ^^ 0.5 with .std.math.sqrt(x) 7114 e = new CallExp(exp->loc, new DotIdExp(exp->loc, e, Id::_sqrt), exp->e1); 7115 } 7116 else 7117 { 7118 // Replace e1 ^^ e2 with .std.math.pow(e1, e2) 7119 e = new CallExp(exp->loc, new DotIdExp(exp->loc, e, Id::_pow), exp->e1, exp->e2); 7120 } 7121 e = semantic(e, sc); 7122 result = e; 7123 } 7124 7125 void visit(ShlExp *exp) 7126 { 7127 //printf("ShlExp::semantic(), type = %p\n", exp->type); 7128 if (exp->type) 7129 { 7130 result = exp; 7131 return; 7132 } 7133 7134 if (Expression *ex = binSemanticProp(exp, sc)) 7135 { 7136 result = ex; 7137 return; 7138 } 7139 Expression *e = exp->op_overload(sc); 7140 if (e) 7141 { 7142 result = e; 7143 return; 7144 } 7145 7146 if (exp->checkIntegralBin()) 7147 return setError(); 7148 if (!Target::isVectorOpSupported(exp->e1->type->toBasetype(), exp->op, exp->e2->type->toBasetype())) 7149 { 7150 result = exp->incompatibleTypes(); 7151 return; 7152 } 7153 exp->e1 = integralPromotions(exp->e1, sc); 7154 if (exp->e2->type->toBasetype()->ty != Tvector) 7155 exp->e2 = exp->e2->castTo(sc, Type::tshiftcnt); 7156 7157 exp->type = exp->e1->type; 7158 result = exp; 7159 } 7160 7161 void visit(ShrExp *exp) 7162 { 7163 if (exp->type) 7164 { 7165 result = exp; 7166 return; 7167 } 7168 7169 if (Expression *ex = binSemanticProp(exp, sc)) 7170 { 7171 result = ex; 7172 return; 7173 } 7174 Expression *e = exp->op_overload(sc); 7175 if (e) 7176 { 7177 result = e; 7178 return; 7179 } 7180 7181 if (exp->checkIntegralBin()) 7182 return setError(); 7183 if (!Target::isVectorOpSupported(exp->e1->type->toBasetype(), exp->op, exp->e2->type->toBasetype())) 7184 { 7185 result = exp->incompatibleTypes(); 7186 return; 7187 } 7188 exp->e1 = integralPromotions(exp->e1, sc); 7189 if (exp->e2->type->toBasetype()->ty != Tvector) 7190 exp->e2 = exp->e2->castTo(sc, Type::tshiftcnt); 7191 7192 exp->type = exp->e1->type; 7193 result = exp; 7194 } 7195 7196 void visit(UshrExp *exp) 7197 { 7198 if (exp->type) 7199 { 7200 result = exp; 7201 return; 7202 } 7203 7204 if (Expression *ex = binSemanticProp(exp, sc)) 7205 { 7206 result = ex; 7207 return; 7208 } 7209 Expression *e = exp->op_overload(sc); 7210 if (e) 7211 { 7212 result = e; 7213 return; 7214 } 7215 7216 if (exp->checkIntegralBin()) 7217 return setError(); 7218 if (!Target::isVectorOpSupported(exp->e1->type->toBasetype(), exp->op, exp->e2->type->toBasetype())) 7219 { 7220 result = exp->incompatibleTypes(); 7221 return; 7222 } 7223 exp->e1 = integralPromotions(exp->e1, sc); 7224 if (exp->e2->type->toBasetype()->ty != Tvector) 7225 exp->e2 = exp->e2->castTo(sc, Type::tshiftcnt); 7226 7227 exp->type = exp->e1->type; 7228 result = exp; 7229 } 7230 7231 void visit(AndExp *exp) 7232 { 7233 if (exp->type) 7234 { 7235 result = exp; 7236 return; 7237 } 7238 7239 if (Expression *ex = binSemanticProp(exp, sc)) 7240 { 7241 result = ex; 7242 return; 7243 } 7244 Expression *e = exp->op_overload(sc); 7245 if (e) 7246 { 7247 result = e; 7248 return; 7249 } 7250 7251 if (exp->e1->type->toBasetype()->ty == Tbool && 7252 exp->e2->type->toBasetype()->ty == Tbool) 7253 { 7254 exp->type = exp->e1->type; 7255 result = exp; 7256 return; 7257 } 7258 7259 if (Expression *ex = typeCombine(exp, sc)) 7260 { 7261 result = ex; 7262 return; 7263 } 7264 7265 Type *tb = exp->type->toBasetype(); 7266 if (tb->ty == Tarray || tb->ty == Tsarray) 7267 { 7268 if (!isArrayOpValid(exp)) 7269 { 7270 exp->error("invalid array operation %s (possible missing [])", exp->toChars()); 7271 return setError(); 7272 } 7273 result = exp; 7274 return; 7275 } 7276 7277 if (!Target::isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype())) 7278 { 7279 result = exp->incompatibleTypes(); 7280 return; 7281 } 7282 if (exp->checkIntegralBin()) 7283 return setError(); 7284 7285 result = exp; 7286 } 7287 7288 void visit(OrExp *exp) 7289 { 7290 if (exp->type) 7291 { 7292 result = exp; 7293 return; 7294 } 7295 7296 if (Expression *ex = binSemanticProp(exp, sc)) 7297 { 7298 result = ex; 7299 return; 7300 } 7301 Expression *e = exp->op_overload(sc); 7302 if (e) 7303 { 7304 result = e; 7305 return; 7306 } 7307 7308 if (exp->e1->type->toBasetype()->ty == Tbool && 7309 exp->e2->type->toBasetype()->ty == Tbool) 7310 { 7311 exp->type = exp->e1->type; 7312 result = exp; 7313 return; 7314 } 7315 7316 if (Expression *ex = typeCombine(exp, sc)) 7317 { 7318 result = ex; 7319 return; 7320 } 7321 7322 Type *tb = exp->type->toBasetype(); 7323 if (tb->ty == Tarray || tb->ty == Tsarray) 7324 { 7325 if (!isArrayOpValid(exp)) 7326 { 7327 exp->error("invalid array operation %s (possible missing [])", exp->toChars()); 7328 return setError(); 7329 } 7330 result = exp; 7331 return; 7332 } 7333 7334 if (!Target::isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype())) 7335 { 7336 result = exp->incompatibleTypes(); 7337 return; 7338 } 7339 if (exp->checkIntegralBin()) 7340 return setError(); 7341 7342 result = exp; 7343 } 7344 7345 void visit(XorExp *exp) 7346 { 7347 if (exp->type) 7348 { 7349 result = exp; 7350 return; 7351 } 7352 7353 if (Expression *ex = binSemanticProp(exp, sc)) 7354 { 7355 result = ex; 7356 return; 7357 } 7358 Expression *e = exp->op_overload(sc); 7359 if (e) 7360 { 7361 result = e; 7362 return; 7363 } 7364 7365 if (exp->e1->type->toBasetype()->ty == Tbool && 7366 exp->e2->type->toBasetype()->ty == Tbool) 7367 { 7368 exp->type = exp->e1->type; 7369 result = exp; 7370 return; 7371 } 7372 7373 if (Expression *ex = typeCombine(exp, sc)) 7374 { 7375 result = ex; 7376 return; 7377 } 7378 7379 Type *tb = exp->type->toBasetype(); 7380 if (tb->ty == Tarray || tb->ty == Tsarray) 7381 { 7382 if (!isArrayOpValid(exp)) 7383 { 7384 exp->error("invalid array operation %s (possible missing [])", exp->toChars()); 7385 return setError(); 7386 } 7387 result = exp; 7388 return; 7389 } 7390 7391 if (!Target::isVectorOpSupported(tb, exp->op, exp->e2->type->toBasetype())) 7392 { 7393 result = exp->incompatibleTypes(); 7394 return; 7395 } 7396 if (exp->checkIntegralBin()) 7397 return setError(); 7398 7399 result = exp; 7400 } 7401 7402 void visit(OrOrExp *exp) 7403 { 7404 if (exp->type) 7405 { 7406 result = exp; 7407 return; 7408 } 7409 7410 setNoderefOperands(exp); 7411 7412 // same as for AndAnd 7413 Expression *e1x = semantic(exp->e1, sc); 7414 7415 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684 7416 if (e1x->op == TOKtype) 7417 e1x = resolveAliasThis(sc, e1x); 7418 7419 e1x = resolveProperties(sc, e1x); 7420 e1x = e1x->toBoolean(sc); 7421 unsigned cs1 = sc->callSuper; 7422 7423 if (sc->flags & SCOPEcondition) 7424 { 7425 /* If in static if, don't evaluate e2 if we don't have to. 7426 */ 7427 e1x = e1x->optimize(WANTvalue); 7428 if (e1x->isBool(true)) 7429 { 7430 result = new IntegerExp(exp->loc, 1, Type::tbool); 7431 return; 7432 } 7433 } 7434 7435 Expression *e2x = semantic(exp->e2, sc); 7436 sc->mergeCallSuper(exp->loc, cs1); 7437 7438 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684 7439 if (e2x->op == TOKtype) 7440 e2x = resolveAliasThis(sc, e2x); 7441 7442 e2x = resolveProperties(sc, e2x); 7443 7444 bool f1 = checkNonAssignmentArrayOp(e1x); 7445 bool f2 = checkNonAssignmentArrayOp(e2x); 7446 if (f1 || f2) 7447 return setError(); 7448 7449 // Unless the right operand is 'void', the expression is converted to 'bool'. 7450 if (e2x->type->ty != Tvoid) 7451 e2x = e2x->toBoolean(sc); 7452 7453 if (e2x->op == TOKtype || e2x->op == TOKscope) 7454 { 7455 exp->error("%s is not an expression", exp->e2->toChars()); 7456 return setError(); 7457 } 7458 if (e1x->op == TOKerror) 7459 { 7460 result = e1x; 7461 return; 7462 } 7463 if (e2x->op == TOKerror) 7464 { 7465 result = e2x; 7466 return; 7467 } 7468 7469 // The result type is 'bool', unless the right operand has type 'void'. 7470 if (e2x->type->ty == Tvoid) 7471 exp->type = Type::tvoid; 7472 else 7473 exp->type = Type::tbool; 7474 7475 exp->e1 = e1x; 7476 exp->e2 = e2x; 7477 result = exp; 7478 } 7479 7480 void visit(AndAndExp *exp) 7481 { 7482 if (exp->type) 7483 { 7484 result = exp; 7485 return; 7486 } 7487 7488 setNoderefOperands(exp); 7489 7490 // same as for OrOr 7491 Expression *e1x = semantic(exp->e1, sc); 7492 7493 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684 7494 if (e1x->op == TOKtype) 7495 e1x = resolveAliasThis(sc, e1x); 7496 7497 e1x = resolveProperties(sc, e1x); 7498 e1x = e1x->toBoolean(sc); 7499 unsigned cs1 = sc->callSuper; 7500 7501 if (sc->flags & SCOPEcondition) 7502 { 7503 /* If in static if, don't evaluate e2 if we don't have to. 7504 */ 7505 e1x = e1x->optimize(WANTvalue); 7506 if (e1x->isBool(false)) 7507 { 7508 result = new IntegerExp(exp->loc, 0, Type::tbool); 7509 return; 7510 } 7511 } 7512 7513 Expression *e2x = semantic(exp->e2, sc); 7514 sc->mergeCallSuper(exp->loc, cs1); 7515 7516 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684 7517 if (e2x->op == TOKtype) 7518 e2x = resolveAliasThis(sc, e2x); 7519 7520 e2x = resolveProperties(sc, e2x); 7521 7522 bool f1 = checkNonAssignmentArrayOp(e1x); 7523 bool f2 = checkNonAssignmentArrayOp(e2x); 7524 if (f1 || f2) 7525 return setError(); 7526 7527 // Unless the right operand is 'void', the expression is converted to 'bool'. 7528 if (e2x->type->ty != Tvoid) 7529 e2x = e2x->toBoolean(sc); 7530 7531 if (e2x->op == TOKtype || e2x->op == TOKscope) 7532 { 7533 exp->error("%s is not an expression", exp->e2->toChars()); 7534 return setError(); 7535 } 7536 if (e1x->op == TOKerror) 7537 { 7538 result = e1x; 7539 return; 7540 } 7541 if (e2x->op == TOKerror) 7542 { 7543 result = e2x; 7544 return; 7545 } 7546 7547 // The result type is 'bool', unless the right operand has type 'void'. 7548 if (e2x->type->ty == Tvoid) 7549 exp->type = Type::tvoid; 7550 else 7551 exp->type = Type::tbool; 7552 7553 exp->e1 = e1x; 7554 exp->e2 = e2x; 7555 result = exp; 7556 } 7557 7558 void visit(InExp *exp) 7559 { 7560 if (exp->type) 7561 { 7562 result = exp; 7563 return; 7564 } 7565 7566 if (Expression *ex = binSemanticProp(exp, sc)) 7567 { 7568 result = ex; 7569 return; 7570 } 7571 Expression *e = exp->op_overload(sc); 7572 if (e) 7573 { 7574 result = e; 7575 return; 7576 } 7577 7578 Type *t2b = exp->e2->type->toBasetype(); 7579 switch (t2b->ty) 7580 { 7581 case Taarray: 7582 { 7583 TypeAArray *ta = (TypeAArray *)t2b; 7584 7585 // Special handling for array keys 7586 if (!arrayTypeCompatible(exp->e1->loc, exp->e1->type, ta->index)) 7587 { 7588 // Convert key to type of key 7589 exp->e1 = exp->e1->implicitCastTo(sc, ta->index); 7590 } 7591 7592 semanticTypeInfo(sc, ta->index); 7593 7594 // Return type is pointer to value 7595 exp->type = ta->nextOf()->pointerTo(); 7596 break; 7597 } 7598 7599 default: 7600 result = exp->incompatibleTypes(); 7601 return; 7602 7603 case Terror: 7604 return setError(); 7605 } 7606 result = exp; 7607 } 7608 7609 void visit(RemoveExp *e) 7610 { 7611 if (Expression *ex = binSemantic(e, sc)) 7612 { 7613 result = ex; 7614 return; 7615 } 7616 result = e; 7617 } 7618 7619 void visit(CmpExp *exp) 7620 { 7621 if (exp->type) 7622 { 7623 result = exp; 7624 return; 7625 } 7626 7627 setNoderefOperands(exp); 7628 7629 if (Expression *ex = binSemanticProp(exp, sc)) 7630 { 7631 result = ex; 7632 return; 7633 } 7634 Type *t1 = exp->e1->type->toBasetype(); 7635 Type *t2 = exp->e2->type->toBasetype(); 7636 if ((t1->ty == Tclass && exp->e2->op == TOKnull) || 7637 (t2->ty == Tclass && exp->e1->op == TOKnull)) 7638 { 7639 exp->error("do not use null when comparing class types"); 7640 return setError(); 7641 } 7642 7643 Expression *e = exp->op_overload(sc); 7644 if (e) 7645 { 7646 if (!e->type->isscalar() && e->type->equals(exp->e1->type)) 7647 { 7648 exp->error("recursive opCmp expansion"); 7649 return setError(); 7650 } 7651 if (e->op == TOKcall) 7652 { 7653 e = new CmpExp(exp->op, exp->loc, e, new IntegerExp(exp->loc, 0, Type::tint32)); 7654 e = semantic(e, sc); 7655 } 7656 result = e; 7657 return; 7658 } 7659 7660 if (Expression *ex = typeCombine(exp, sc)) 7661 { 7662 result = ex; 7663 return; 7664 } 7665 7666 bool f1 = checkNonAssignmentArrayOp(exp->e1); 7667 bool f2 = checkNonAssignmentArrayOp(exp->e2); 7668 if (f1 || f2) 7669 return setError(); 7670 7671 exp->type = Type::tbool; 7672 7673 // Special handling for array comparisons 7674 t1 = exp->e1->type->toBasetype(); 7675 t2 = exp->e2->type->toBasetype(); 7676 if ((t1->ty == Tarray || t1->ty == Tsarray || t1->ty == Tpointer) && 7677 (t2->ty == Tarray || t2->ty == Tsarray || t2->ty == Tpointer)) 7678 { 7679 Type *t1next = t1->nextOf(); 7680 Type *t2next = t2->nextOf(); 7681 if (t1next->implicitConvTo(t2next) < MATCHconst && 7682 t2next->implicitConvTo(t1next) < MATCHconst && 7683 (t1next->ty != Tvoid && t2next->ty != Tvoid)) 7684 { 7685 exp->error("array comparison type mismatch, %s vs %s", t1next->toChars(), t2next->toChars()); 7686 return setError(); 7687 } 7688 if ((t1->ty == Tarray || t1->ty == Tsarray) && 7689 (t2->ty == Tarray || t2->ty == Tsarray)) 7690 { 7691 semanticTypeInfo(sc, t1->nextOf()); 7692 } 7693 } 7694 else if (t1->ty == Tstruct || t2->ty == Tstruct || 7695 (t1->ty == Tclass && t2->ty == Tclass)) 7696 { 7697 if (t2->ty == Tstruct) 7698 exp->error("need member function opCmp() for %s %s to compare", t2->toDsymbol(sc)->kind(), t2->toChars()); 7699 else 7700 exp->error("need member function opCmp() for %s %s to compare", t1->toDsymbol(sc)->kind(), t1->toChars()); 7701 return setError(); 7702 } 7703 else if (t1->iscomplex() || t2->iscomplex()) 7704 { 7705 exp->error("compare not defined for complex operands"); 7706 return setError(); 7707 } 7708 else if (t1->ty == Taarray || t2->ty == Taarray) 7709 { 7710 exp->error("%s is not defined for associative arrays", Token::toChars(exp->op)); 7711 return setError(); 7712 } 7713 else if (!Target::isVectorOpSupported(t1, exp->op, t2)) 7714 { 7715 result = exp->incompatibleTypes(); 7716 return; 7717 } 7718 else 7719 { 7720 bool r1 = exp->e1->checkValue(); 7721 bool r2 = exp->e2->checkValue(); 7722 if (r1 || r2) 7723 return setError(); 7724 } 7725 7726 TOK altop; 7727 switch (exp->op) 7728 { 7729 // Refer rel_integral[] table 7730 case TOKunord: altop = TOKerror; break; 7731 case TOKlg: altop = TOKnotequal; break; 7732 case TOKleg: altop = TOKerror; break; 7733 case TOKule: altop = TOKle; break; 7734 case TOKul: altop = TOKlt; break; 7735 case TOKuge: altop = TOKge; break; 7736 case TOKug: altop = TOKgt; break; 7737 case TOKue: altop = TOKequal; break; 7738 default: altop = TOKreserved; break; 7739 } 7740 if (altop == TOKerror && 7741 (t1->ty == Tarray || t1->ty == Tsarray || 7742 t2->ty == Tarray || t2->ty == Tsarray)) 7743 { 7744 exp->error("'%s' is not defined for array comparisons", Token::toChars(exp->op)); 7745 return setError(); 7746 } 7747 if (altop != TOKreserved) 7748 { 7749 if (!t1->isfloating()) 7750 { 7751 if (altop == TOKerror) 7752 { 7753 const char *s = exp->op == TOKunord ? "false" : "true"; 7754 exp->error("floating point operator '%s' always returns %s for non-floating comparisons", 7755 Token::toChars(exp->op), s); 7756 } 7757 else 7758 { 7759 exp->error("use '%s' for non-floating comparisons rather than floating point operator '%s'", 7760 Token::toChars(altop), Token::toChars(exp->op)); 7761 } 7762 } 7763 else 7764 { 7765 exp->error("use std.math.isNaN to deal with NaN operands rather than floating point operator '%s'", 7766 Token::toChars(exp->op)); 7767 } 7768 return setError(); 7769 } 7770 7771 //printf("CmpExp: %s, type = %s\n", e->toChars(), e->type->toChars()); 7772 result = exp; 7773 } 7774 7775 void visit(EqualExp *exp) 7776 { 7777 //printf("EqualExp::semantic('%s')\n", toChars()); 7778 if (exp->type) 7779 { 7780 result = exp; 7781 return; 7782 } 7783 7784 setNoderefOperands(exp); 7785 7786 if (Expression *e = binSemanticProp(exp, sc)) 7787 { 7788 result = e; 7789 return; 7790 } 7791 if (exp->e1->op == TOKtype || exp->e2->op == TOKtype) 7792 { 7793 result = exp->incompatibleTypes(); 7794 return; 7795 } 7796 7797 { 7798 Type *t1 = exp->e1->type; 7799 Type *t2 = exp->e2->type; 7800 if (t1->ty == Tenum && t2->ty == Tenum && !t1->equivalent(t2)) 7801 exp->deprecation("Comparison between different enumeration types `%s` and `%s`; If this behavior is intended consider using `std.conv.asOriginalType`", 7802 t1->toChars(), t2->toChars()); 7803 } 7804 7805 /* Before checking for operator overloading, check to see if we're 7806 * comparing the addresses of two statics. If so, we can just see 7807 * if they are the same symbol. 7808 */ 7809 if (exp->e1->op == TOKaddress && exp->e2->op == TOKaddress) 7810 { 7811 AddrExp *ae1 = (AddrExp *)exp->e1; 7812 AddrExp *ae2 = (AddrExp *)exp->e2; 7813 if (ae1->e1->op == TOKvar && ae2->e1->op == TOKvar) 7814 { 7815 VarExp *ve1 = (VarExp *)ae1->e1; 7816 VarExp *ve2 = (VarExp *)ae2->e1; 7817 7818 if (ve1->var == ve2->var) 7819 { 7820 // They are the same, result is 'true' for ==, 'false' for != 7821 result = new IntegerExp(exp->loc, (exp->op == TOKequal), Type::tbool); 7822 return; 7823 } 7824 } 7825 } 7826 7827 if (Expression *e = exp->op_overload(sc)) 7828 { 7829 result = e; 7830 return; 7831 } 7832 7833 if (Expression *e = typeCombine(exp, sc)) 7834 { 7835 result = e; 7836 return; 7837 } 7838 7839 bool f1 = checkNonAssignmentArrayOp(exp->e1); 7840 bool f2 = checkNonAssignmentArrayOp(exp->e2); 7841 if (f1 || f2) 7842 return setError(); 7843 7844 exp->type = Type::tbool; 7845 7846 // Special handling for array comparisons 7847 if (!arrayTypeCompatible(exp->loc, exp->e1->type, exp->e2->type)) 7848 { 7849 if (exp->e1->type != exp->e2->type && exp->e1->type->isfloating() && exp->e2->type->isfloating()) 7850 { 7851 // Cast both to complex 7852 exp->e1 = exp->e1->castTo(sc, Type::tcomplex80); 7853 exp->e2 = exp->e2->castTo(sc, Type::tcomplex80); 7854 } 7855 } 7856 if (exp->e1->type->toBasetype()->ty == Taarray) 7857 semanticTypeInfo(sc, exp->e1->type->toBasetype()); 7858 7859 Type *t1 = exp->e1->type->toBasetype(); 7860 Type *t2 = exp->e2->type->toBasetype(); 7861 7862 if (!Target::isVectorOpSupported(t1, exp->op, t2)) 7863 { 7864 result = exp->incompatibleTypes(); 7865 return; 7866 } 7867 7868 result = exp; 7869 } 7870 7871 void visit(IdentityExp *exp) 7872 { 7873 if (exp->type) 7874 { 7875 result = exp; 7876 return; 7877 } 7878 7879 setNoderefOperands(exp); 7880 7881 if (Expression *ex = binSemanticProp(exp, sc)) 7882 { 7883 result = ex; 7884 return; 7885 } 7886 7887 if (Expression *ex = typeCombine(exp, sc)) 7888 { 7889 result = ex; 7890 return; 7891 } 7892 7893 bool f1 = checkNonAssignmentArrayOp(exp->e1); 7894 bool f2 = checkNonAssignmentArrayOp(exp->e2); 7895 if (f1 || f2) 7896 return setError(); 7897 7898 exp->type = Type::tbool; 7899 7900 if (exp->e1->type != exp->e2->type && exp->e1->type->isfloating() && exp->e2->type->isfloating()) 7901 { 7902 // Cast both to complex 7903 exp->e1 = exp->e1->castTo(sc, Type::tcomplex80); 7904 exp->e2 = exp->e2->castTo(sc, Type::tcomplex80); 7905 } 7906 7907 Type *tb1 = exp->e1->type->toBasetype(); 7908 Type *tb2 = exp->e2->type->toBasetype(); 7909 if (!Target::isVectorOpSupported(tb1, exp->op, tb2)) 7910 { 7911 result = exp->incompatibleTypes(); 7912 return; 7913 } 7914 7915 result = exp; 7916 } 7917 7918 void visit(CondExp *exp) 7919 { 7920 if (exp->type) 7921 { 7922 result = exp; 7923 return; 7924 } 7925 7926 if (exp->econd->op == TOKdotid) 7927 ((DotIdExp *)exp->econd)->noderef = true; 7928 7929 Expression *ec = semantic(exp->econd, sc); 7930 ec = resolveProperties(sc, ec); 7931 ec = ec->toBoolean(sc); 7932 7933 unsigned cs0 = sc->callSuper; 7934 unsigned *fi0 = sc->saveFieldInit(); 7935 Expression *e1x = semantic(exp->e1, sc); 7936 e1x = resolveProperties(sc, e1x); 7937 7938 unsigned cs1 = sc->callSuper; 7939 unsigned *fi1 = sc->fieldinit; 7940 sc->callSuper = cs0; 7941 sc->fieldinit = fi0; 7942 Expression *e2x = semantic(exp->e2, sc); 7943 e2x = resolveProperties(sc, e2x); 7944 7945 sc->mergeCallSuper(exp->loc, cs1); 7946 sc->mergeFieldInit(exp->loc, fi1); 7947 7948 if (ec->op == TOKerror) 7949 { 7950 result = ec; 7951 return; 7952 } 7953 if (ec->type == Type::terror) 7954 return setError(); 7955 exp->econd = ec; 7956 7957 if (e1x->op == TOKerror) 7958 { 7959 result = e1x; 7960 return; 7961 } 7962 if (e1x->type == Type::terror) 7963 return setError(); 7964 exp->e1 = e1x; 7965 7966 if (e2x->op == TOKerror) 7967 { 7968 result = e2x; 7969 return; 7970 } 7971 if (e2x->type == Type::terror) 7972 return setError(); 7973 exp->e2 = e2x; 7974 7975 bool f0 = checkNonAssignmentArrayOp(exp->econd); 7976 bool f1 = checkNonAssignmentArrayOp(exp->e1); 7977 bool f2 = checkNonAssignmentArrayOp(exp->e2); 7978 if (f0 || f1 || f2) 7979 return setError(); 7980 7981 Type *t1 = exp->e1->type; 7982 Type *t2 = exp->e2->type; 7983 // If either operand is void the result is void, we have to cast both 7984 // the expression to void so that we explicitly discard the expression 7985 // value if any (bugzilla 16598) 7986 if (t1->ty == Tvoid || t2->ty == Tvoid) 7987 { 7988 exp->type = Type::tvoid; 7989 exp->e1 = exp->e1->castTo(sc, exp->type); 7990 exp->e2 = exp->e2->castTo(sc, exp->type); 7991 } 7992 else if (t1 == t2) 7993 exp->type = t1; 7994 else 7995 { 7996 if (Expression *ex = typeCombine(exp, sc)) 7997 { 7998 result = ex; 7999 return; 8000 } 8001 switch (exp->e1->type->toBasetype()->ty) 8002 { 8003 case Tcomplex32: 8004 case Tcomplex64: 8005 case Tcomplex80: 8006 exp->e2 = exp->e2->castTo(sc, exp->e1->type); 8007 break; 8008 } 8009 switch (exp->e2->type->toBasetype()->ty) 8010 { 8011 case Tcomplex32: 8012 case Tcomplex64: 8013 case Tcomplex80: 8014 exp->e1 = exp->e1->castTo(sc, exp->e2->type); 8015 break; 8016 } 8017 if (exp->type->toBasetype()->ty == Tarray) 8018 { 8019 exp->e1 = exp->e1->castTo(sc, exp->type); 8020 exp->e2 = exp->e2->castTo(sc, exp->type); 8021 } 8022 } 8023 exp->type = exp->type->merge2(); 8024 8025 /* Bugzilla 14696: If either e1 or e2 contain temporaries which need dtor, 8026 * make them conditional. 8027 * Rewrite: 8028 * cond ? (__tmp1 = ..., __tmp1) : (__tmp2 = ..., __tmp2) 8029 * to: 8030 * (auto __cond = cond) ? (... __tmp1) : (... __tmp2) 8031 * and replace edtors of __tmp1 and __tmp2 with: 8032 * __tmp1->edtor --> __cond && __tmp1.dtor() 8033 * __tmp2->edtor --> __cond || __tmp2.dtor() 8034 */ 8035 exp->hookDtors(sc); 8036 8037 result = exp; 8038 } 8039 8040 void visit(FileInitExp *e) 8041 { 8042 //printf("FileInitExp::semantic()\n"); 8043 e->type = Type::tstring; 8044 result = e; 8045 } 8046 8047 void visit(LineInitExp *e) 8048 { 8049 e->type = Type::tint32; 8050 result = e; 8051 } 8052 8053 void visit(ModuleInitExp *e) 8054 { 8055 //printf("ModuleInitExp::semantic()\n"); 8056 e->type = Type::tstring; 8057 result = e; 8058 } 8059 8060 void visit(FuncInitExp *e) 8061 { 8062 //printf("FuncInitExp::semantic()\n"); 8063 e->type = Type::tstring; 8064 if (sc->func) 8065 { 8066 result = e->resolveLoc(Loc(), sc); 8067 return; 8068 } 8069 result = e; 8070 } 8071 8072 void visit(PrettyFuncInitExp *e) 8073 { 8074 //printf("PrettyFuncInitExp::semantic()\n"); 8075 e->type = Type::tstring; 8076 if (sc->func) 8077 { 8078 result = e->resolveLoc(Loc(), sc); 8079 return; 8080 } 8081 result = e; 8082 } 8083 }; 8084 8085 /********************************** 8086 * Try to run semantic routines. 8087 * If they fail, return NULL. 8088 */ 8089 Expression *trySemantic(Expression *exp, Scope* sc) 8090 { 8091 //printf("+trySemantic(%s)\n", toChars()); 8092 unsigned errors = global.startGagging(); 8093 Expression *e = semantic(exp, sc); 8094 if (global.endGagging(errors)) 8095 { 8096 e = NULL; 8097 } 8098 //printf("-trySemantic(%s)\n", toChars()); 8099 return e; 8100 } 8101 8102 /************************** 8103 * Helper function for easy error propagation. 8104 * If error occurs, returns ErrorExp. Otherwise returns NULL. 8105 */ 8106 Expression *unaSemantic(UnaExp *e, Scope *sc) 8107 { 8108 Expression *e1x = semantic(e->e1, sc); 8109 if (e1x->op == TOKerror) 8110 return e1x; 8111 e->e1 = e1x; 8112 return NULL; 8113 } 8114 8115 /************************** 8116 * Helper function for easy error propagation. 8117 * If error occurs, returns ErrorExp. Otherwise returns NULL. 8118 */ 8119 Expression *binSemantic(BinExp *e, Scope *sc) 8120 { 8121 Expression *e1x = semantic(e->e1, sc); 8122 Expression *e2x = semantic(e->e2, sc); 8123 8124 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684 8125 if (e1x->op == TOKtype) 8126 e1x = resolveAliasThis(sc, e1x); 8127 if (e2x->op == TOKtype) 8128 e2x = resolveAliasThis(sc, e2x); 8129 8130 if (e1x->op == TOKerror) 8131 return e1x; 8132 if (e2x->op == TOKerror) 8133 return e2x; 8134 e->e1 = e1x; 8135 e->e2 = e2x; 8136 return NULL; 8137 } 8138 8139 Expression *binSemanticProp(BinExp *e, Scope *sc) 8140 { 8141 if (Expression *ex = binSemantic(e, sc)) 8142 return ex; 8143 Expression *e1x = resolveProperties(sc, e->e1); 8144 Expression *e2x = resolveProperties(sc, e->e2); 8145 if (e1x->op == TOKerror) 8146 return e1x; 8147 if (e2x->op == TOKerror) 8148 return e2x; 8149 e->e1 = e1x; 8150 e->e2 = e2x; 8151 return NULL; 8152 } 8153 8154 // entrypoint for semantic ExpressionSemanticVisitor 8155 Expression *semantic(Expression *e, Scope *sc) 8156 { 8157 ExpressionSemanticVisitor v = ExpressionSemanticVisitor(sc); 8158 e->accept(&v); 8159 return v.result; 8160 } 8161 8162 Expression *semanticX(DotIdExp *exp, Scope *sc) 8163 { 8164 //printf("DotIdExp::semanticX(this = %p, '%s')\n", this, toChars()); 8165 if (Expression *ex = unaSemantic(exp, sc)) 8166 return ex; 8167 8168 if (exp->ident == Id::_mangleof) 8169 { 8170 // symbol.mangleof 8171 Dsymbol *ds; 8172 switch (exp->e1->op) 8173 { 8174 case TOKscope: 8175 ds = ((ScopeExp *)exp->e1)->sds; 8176 goto L1; 8177 case TOKvar: 8178 ds = ((VarExp *)exp->e1)->var; 8179 goto L1; 8180 case TOKdotvar: 8181 ds = ((DotVarExp *)exp->e1)->var; 8182 goto L1; 8183 case TOKoverloadset: 8184 ds = ((OverExp *)exp->e1)->vars; 8185 goto L1; 8186 case TOKtemplate: 8187 { 8188 TemplateExp *te = (TemplateExp *)exp->e1; 8189 ds = te->fd ? (Dsymbol *)te->fd : te->td; 8190 } 8191 L1: 8192 { 8193 assert(ds); 8194 if (FuncDeclaration *f = ds->isFuncDeclaration()) 8195 { 8196 if (f->checkForwardRef(exp->loc)) 8197 return new ErrorExp(); 8198 } 8199 OutBuffer buf; 8200 mangleToBuffer(ds, &buf); 8201 const char *s = buf.extractString(); 8202 Expression *e = new StringExp(exp->loc, const_cast<char*>(s), strlen(s)); 8203 e = semantic(e, sc); 8204 return e; 8205 } 8206 default: 8207 break; 8208 } 8209 } 8210 8211 if (exp->e1->op == TOKvar && exp->e1->type->toBasetype()->ty == Tsarray && exp->ident == Id::length) 8212 { 8213 // bypass checkPurity 8214 return exp->e1->type->dotExp(sc, exp->e1, exp->ident, exp->noderef ? 2 : 0); 8215 } 8216 8217 if (exp->e1->op == TOKdot) 8218 { 8219 } 8220 else 8221 { 8222 exp->e1 = resolvePropertiesX(sc, exp->e1); 8223 } 8224 if (exp->e1->op == TOKtuple && exp->ident == Id::offsetof) 8225 { 8226 /* 'distribute' the .offsetof to each of the tuple elements. 8227 */ 8228 TupleExp *te = (TupleExp *)exp->e1; 8229 Expressions *exps = new Expressions(); 8230 exps->setDim(te->exps->dim); 8231 for (size_t i = 0; i < exps->dim; i++) 8232 { 8233 Expression *e = (*te->exps)[i]; 8234 e = semantic(e, sc); 8235 e = new DotIdExp(e->loc, e, Id::offsetof); 8236 (*exps)[i] = e; 8237 } 8238 // Don't evaluate te->e0 in runtime 8239 Expression *e = new TupleExp(exp->loc, NULL, exps); 8240 e = semantic(e, sc); 8241 return e; 8242 } 8243 if (exp->e1->op == TOKtuple && exp->ident == Id::length) 8244 { 8245 TupleExp *te = (TupleExp *)exp->e1; 8246 // Don't evaluate te->e0 in runtime 8247 Expression *e = new IntegerExp(exp->loc, te->exps->dim, Type::tsize_t); 8248 return e; 8249 } 8250 8251 // Bugzilla 14416: Template has no built-in properties except for 'stringof'. 8252 if ((exp->e1->op == TOKdottd || exp->e1->op == TOKtemplate) && exp->ident != Id::stringof) 8253 { 8254 exp->error("template %s does not have property '%s'", exp->e1->toChars(), exp->ident->toChars()); 8255 return new ErrorExp(); 8256 } 8257 8258 if (!exp->e1->type) 8259 { 8260 exp->error("expression %s does not have property '%s'", exp->e1->toChars(), exp->ident->toChars()); 8261 return new ErrorExp(); 8262 } 8263 8264 return exp; 8265 } 8266 8267 // Resolve e1.ident without seeing UFCS. 8268 // If flag == 1, stop "not a property" error and return NULL. 8269 Expression *semanticY(DotIdExp *exp, Scope *sc, int flag) 8270 { 8271 //printf("DotIdExp::semanticY(this = %p, '%s')\n", this, toChars()); 8272 8273 //{ static int z; fflush(stdout); if (++z == 10) *(char*)0=0; } 8274 8275 /* Special case: rewrite this.id and super.id 8276 * to be classtype.id and baseclasstype.id 8277 * if we have no this pointer. 8278 */ 8279 if ((exp->e1->op == TOKthis || exp->e1->op == TOKsuper) && !hasThis(sc)) 8280 { 8281 if (AggregateDeclaration *ad = sc->getStructClassScope()) 8282 { 8283 if (exp->e1->op == TOKthis) 8284 { 8285 exp->e1 = new TypeExp(exp->e1->loc, ad->type); 8286 } 8287 else 8288 { 8289 ClassDeclaration *cd = ad->isClassDeclaration(); 8290 if (cd && cd->baseClass) 8291 exp->e1 = new TypeExp(exp->e1->loc, cd->baseClass->type); 8292 } 8293 } 8294 } 8295 8296 Expression *e = semanticX(exp, sc); 8297 if (e != exp) 8298 return e; 8299 8300 Expression *eleft; 8301 Expression *eright; 8302 if (exp->e1->op == TOKdot) 8303 { 8304 DotExp *de = (DotExp *)exp->e1; 8305 eleft = de->e1; 8306 eright = de->e2; 8307 } 8308 else 8309 { 8310 eleft = NULL; 8311 eright = exp->e1; 8312 } 8313 8314 Type *t1b = exp->e1->type->toBasetype(); 8315 8316 if (eright->op == TOKscope) // also used for template alias's 8317 { 8318 ScopeExp *ie = (ScopeExp *)eright; 8319 int flags = SearchLocalsOnly; 8320 8321 /* Disable access to another module's private imports. 8322 * The check for 'is sds our current module' is because 8323 * the current module should have access to its own imports. 8324 */ 8325 if (ie->sds->isModule() && ie->sds != sc->_module) 8326 flags |= IgnorePrivateImports; 8327 if (sc->flags & SCOPEignoresymbolvisibility) 8328 flags |= IgnoreSymbolVisibility; 8329 Dsymbol *s = ie->sds->search(exp->loc, exp->ident, flags); 8330 /* Check for visibility before resolving aliases because public 8331 * aliases to private symbols are public. 8332 */ 8333 if (s && !(sc->flags & SCOPEignoresymbolvisibility) && !symbolIsVisible(sc->_module, s)) 8334 { 8335 if (s->isDeclaration()) 8336 ::error(exp->loc, "%s is not visible from module %s", s->toPrettyChars(), sc->_module->toChars()); 8337 else 8338 ::deprecation(exp->loc, "%s is not visible from module %s", s->toPrettyChars(), sc->_module->toChars()); 8339 // s = NULL 8340 } 8341 if (s) 8342 { 8343 if (Package *p = s->isPackage()) 8344 checkAccess(exp->loc, sc, p); 8345 8346 // if 's' is a tuple variable, the tuple is returned. 8347 s = s->toAlias(); 8348 8349 exp->checkDeprecated(sc, s); 8350 8351 EnumMember *em = s->isEnumMember(); 8352 if (em) 8353 { 8354 return em->getVarExp(exp->loc, sc); 8355 } 8356 8357 VarDeclaration *v = s->isVarDeclaration(); 8358 if (v) 8359 { 8360 //printf("DotIdExp:: Identifier '%s' is a variable, type '%s'\n", toChars(), v->type->toChars()); 8361 if (!v->type || 8362 (!v->type->deco && v->inuse)) 8363 { 8364 if (v->inuse) 8365 exp->error("circular reference to %s '%s'", v->kind(), v->toPrettyChars()); 8366 else 8367 exp->error("forward reference to %s '%s'", v->kind(), v->toPrettyChars()); 8368 return new ErrorExp(); 8369 } 8370 if (v->type->ty == Terror) 8371 return new ErrorExp(); 8372 8373 if ((v->storage_class & STCmanifest) && v->_init && !exp->wantsym) 8374 { 8375 /* Normally, the replacement of a symbol with its initializer is supposed to be in semantic2(). 8376 * Introduced by https://github.com/dlang/dmd/pull/5588 which should probably 8377 * be reverted. `wantsym` is the hack to work around the problem. 8378 */ 8379 if (v->inuse) 8380 { 8381 ::error(exp->loc, "circular initialization of %s '%s'", v->kind(), v->toPrettyChars()); 8382 return new ErrorExp(); 8383 } 8384 e = v->expandInitializer(exp->loc); 8385 v->inuse++; 8386 e = semantic(e, sc); 8387 v->inuse--; 8388 return e; 8389 } 8390 8391 if (v->needThis()) 8392 { 8393 if (!eleft) 8394 eleft = new ThisExp(exp->loc); 8395 e = new DotVarExp(exp->loc, eleft, v); 8396 e = semantic(e, sc); 8397 } 8398 else 8399 { 8400 e = new VarExp(exp->loc, v); 8401 if (eleft) 8402 { e = new CommaExp(exp->loc, eleft, e); 8403 e->type = v->type; 8404 } 8405 } 8406 e = e->deref(); 8407 return semantic(e, sc); 8408 } 8409 8410 FuncDeclaration *f = s->isFuncDeclaration(); 8411 if (f) 8412 { 8413 //printf("it's a function\n"); 8414 if (!f->functionSemantic()) 8415 return new ErrorExp(); 8416 if (f->needThis()) 8417 { 8418 if (!eleft) 8419 eleft = new ThisExp(exp->loc); 8420 e = new DotVarExp(exp->loc, eleft, f, true); 8421 e = semantic(e, sc); 8422 } 8423 else 8424 { 8425 e = new VarExp(exp->loc, f, true); 8426 if (eleft) 8427 { e = new CommaExp(exp->loc, eleft, e); 8428 e->type = f->type; 8429 } 8430 } 8431 return e; 8432 } 8433 if (TemplateDeclaration *td = s->isTemplateDeclaration()) 8434 { 8435 if (eleft) 8436 e = new DotTemplateExp(exp->loc, eleft, td); 8437 else 8438 e = new TemplateExp(exp->loc, td); 8439 e = semantic(e, sc); 8440 return e; 8441 } 8442 if (OverDeclaration *od = s->isOverDeclaration()) 8443 { 8444 e = new VarExp(exp->loc, od, true); 8445 if (eleft) 8446 { 8447 e = new CommaExp(exp->loc, eleft, e); 8448 e->type = Type::tvoid; // ambiguous type? 8449 } 8450 return e; 8451 } 8452 OverloadSet *o = s->isOverloadSet(); 8453 if (o) 8454 { //printf("'%s' is an overload set\n", o->toChars()); 8455 return new OverExp(exp->loc, o); 8456 } 8457 8458 if (Type *t = s->getType()) 8459 { 8460 return semantic(new TypeExp(exp->loc, t), sc); 8461 } 8462 8463 TupleDeclaration *tup = s->isTupleDeclaration(); 8464 if (tup) 8465 { 8466 if (eleft) 8467 { 8468 e = new DotVarExp(exp->loc, eleft, tup); 8469 e = semantic(e, sc); 8470 return e; 8471 } 8472 e = new TupleExp(exp->loc, tup); 8473 e = semantic(e, sc); 8474 return e; 8475 } 8476 8477 ScopeDsymbol *sds = s->isScopeDsymbol(); 8478 if (sds) 8479 { 8480 //printf("it's a ScopeDsymbol %s\n", exp->ident->toChars()); 8481 e = new ScopeExp(exp->loc, sds); 8482 e = semantic(e, sc); 8483 if (eleft) 8484 e = new DotExp(exp->loc, eleft, e); 8485 return e; 8486 } 8487 8488 Import *imp = s->isImport(); 8489 if (imp) 8490 { 8491 ie = new ScopeExp(exp->loc, imp->pkg); 8492 return semantic(ie, sc); 8493 } 8494 8495 // BUG: handle other cases like in IdentifierExp::semantic() 8496 assert(0); 8497 } 8498 else if (exp->ident == Id::stringof) 8499 { 8500 const char *p = ie->toChars(); 8501 e = new StringExp(exp->loc, const_cast<char *>(p), strlen(p)); 8502 e = semantic(e, sc); 8503 return e; 8504 } 8505 if (ie->sds->isPackage() || 8506 ie->sds->isImport() || 8507 ie->sds->isModule()) 8508 { 8509 flag = 0; 8510 } 8511 if (flag) 8512 return NULL; 8513 s = ie->sds->search_correct(exp->ident); 8514 if (s) 8515 exp->error("undefined identifier '%s' in %s '%s', did you mean %s '%s'?", 8516 exp->ident->toChars(), ie->sds->kind(), ie->sds->toPrettyChars(), s->kind(), s->toChars()); 8517 else 8518 exp->error("undefined identifier '%s' in %s '%s'", 8519 exp->ident->toChars(), ie->sds->kind(), ie->sds->toPrettyChars()); 8520 return new ErrorExp(); 8521 } 8522 else if (t1b->ty == Tpointer && exp->e1->type->ty != Tenum && 8523 exp->ident != Id::_init && exp->ident != Id::__sizeof && 8524 exp->ident != Id::__xalignof && exp->ident != Id::offsetof && 8525 exp->ident != Id::_mangleof && exp->ident != Id::stringof) 8526 { 8527 Type *t1bn = t1b->nextOf(); 8528 if (flag) 8529 { 8530 AggregateDeclaration *ad = isAggregate(t1bn); 8531 if (ad && !ad->members) // Bugzilla 11312 8532 return NULL; 8533 } 8534 8535 /* Rewrite: 8536 * p.ident 8537 * as: 8538 * (*p).ident 8539 */ 8540 if (flag && t1bn->ty == Tvoid) 8541 return NULL; 8542 e = new PtrExp(exp->loc, exp->e1); 8543 e = semantic(e, sc); 8544 return e->type->dotExp(sc, e, exp->ident, flag | (exp->noderef ? 2 : 0)); 8545 } 8546 else 8547 { 8548 if (exp->e1->op == TOKtype || exp->e1->op == TOKtemplate) 8549 flag = 0; 8550 e = exp->e1->type->dotExp(sc, exp->e1, exp->ident, flag | (exp->noderef ? 2 : 0)); 8551 if (e) 8552 e = semantic(e, sc); 8553 return e; 8554 } 8555 } 8556 8557 // Resolve e1.ident!tiargs without seeing UFCS. 8558 // If flag == 1, stop "not a property" error and return NULL. 8559 Expression *semanticY(DotTemplateInstanceExp *exp, Scope *sc, int flag) 8560 { 8561 DotIdExp *die = new DotIdExp(exp->loc, exp->e1, exp->ti->name); 8562 8563 Expression *e = semanticX(die, sc); 8564 if (e == die) 8565 { 8566 exp->e1 = die->e1; // take back 8567 8568 Type *t1b = exp->e1->type->toBasetype(); 8569 if (t1b->ty == Tarray || t1b->ty == Tsarray || t1b->ty == Taarray || 8570 t1b->ty == Tnull || (t1b->isTypeBasic() && t1b->ty != Tvoid)) 8571 { 8572 /* No built-in type has templatized properties, so do shortcut. 8573 * It is necessary in: 1024.max!"a < b" 8574 */ 8575 if (flag) 8576 return NULL; 8577 } 8578 e = semanticY(die, sc, flag); 8579 if (flag && e && isDotOpDispatch(e)) 8580 { 8581 /* opDispatch!tiargs would be a function template that needs IFTI, 8582 * so it's not a template 8583 */ 8584 e = NULL; /* fall down to UFCS */ 8585 } 8586 if (flag && !e) 8587 return NULL; 8588 } 8589 assert(e); 8590 8591 if (e->op == TOKerror) 8592 return e; 8593 if (e->op == TOKdotvar) 8594 { 8595 DotVarExp *dve = (DotVarExp *)e; 8596 if (FuncDeclaration *fd = dve->var->isFuncDeclaration()) 8597 { 8598 TemplateDeclaration *td = fd->findTemplateDeclRoot(); 8599 if (td) 8600 { 8601 e = new DotTemplateExp(dve->loc, dve->e1, td); 8602 e = semantic(e, sc); 8603 } 8604 } 8605 else if (dve->var->isOverDeclaration()) 8606 { 8607 exp->e1 = dve->e1; // pull semantic() result 8608 if (!exp->findTempDecl(sc)) 8609 goto Lerr; 8610 if (exp->ti->needsTypeInference(sc)) 8611 return exp; 8612 exp->ti->semantic(sc); 8613 if (!exp->ti->inst || exp->ti->errors) // if template failed to expand 8614 return new ErrorExp(); 8615 Dsymbol *s = exp->ti->toAlias(); 8616 Declaration *v = s->isDeclaration(); 8617 if (v) 8618 { 8619 if (v->type && !v->type->deco) 8620 v->type = v->type->semantic(v->loc, sc); 8621 e = new DotVarExp(exp->loc, exp->e1, v); 8622 e = semantic(e, sc); 8623 return e; 8624 } 8625 e = new ScopeExp(exp->loc, exp->ti); 8626 e = new DotExp(exp->loc, exp->e1, e); 8627 e = semantic(e, sc); 8628 return e; 8629 } 8630 } 8631 else if (e->op == TOKvar) 8632 { 8633 VarExp *ve = (VarExp *)e; 8634 if (FuncDeclaration *fd = ve->var->isFuncDeclaration()) 8635 { 8636 TemplateDeclaration *td = fd->findTemplateDeclRoot(); 8637 if (td) 8638 { 8639 e = new TemplateExp(ve->loc, td); 8640 e = semantic(e, sc); 8641 } 8642 } 8643 else if (OverDeclaration *od = ve->var->isOverDeclaration()) 8644 { 8645 exp->ti->tempdecl = od; 8646 e = new ScopeExp(exp->loc, exp->ti); 8647 e = semantic(e, sc); 8648 return e; 8649 } 8650 } 8651 if (e->op == TOKdottd) 8652 { 8653 DotTemplateExp *dte = (DotTemplateExp *)e; 8654 exp->e1 = dte->e1; // pull semantic() result 8655 8656 exp->ti->tempdecl = dte->td; 8657 if (!exp->ti->semanticTiargs(sc)) 8658 return new ErrorExp(); 8659 if (exp->ti->needsTypeInference(sc)) 8660 return exp; 8661 exp->ti->semantic(sc); 8662 if (!exp->ti->inst || exp->ti->errors) // if template failed to expand 8663 return new ErrorExp(); 8664 Dsymbol *s = exp->ti->toAlias(); 8665 Declaration *v = s->isDeclaration(); 8666 if (v && (v->isFuncDeclaration() || v->isVarDeclaration())) 8667 { 8668 e = new DotVarExp(exp->loc, exp->e1, v); 8669 e = semantic(e, sc); 8670 return e; 8671 } 8672 e = new ScopeExp(exp->loc, exp->ti); 8673 e = new DotExp(exp->loc, exp->e1, e); 8674 e = semantic(e, sc); 8675 return e; 8676 } 8677 else if (e->op == TOKtemplate) 8678 { 8679 exp->ti->tempdecl = ((TemplateExp *)e)->td; 8680 e = new ScopeExp(exp->loc, exp->ti); 8681 e = semantic(e, sc); 8682 return e; 8683 } 8684 else if (e->op == TOKdot) 8685 { 8686 DotExp *de = (DotExp *)e; 8687 8688 if (de->e2->op == TOKoverloadset) 8689 { 8690 if (!exp->findTempDecl(sc) || 8691 !exp->ti->semanticTiargs(sc)) 8692 { 8693 return new ErrorExp(); 8694 } 8695 if (exp->ti->needsTypeInference(sc)) 8696 return exp; 8697 exp->ti->semantic(sc); 8698 if (!exp->ti->inst || exp->ti->errors) // if template failed to expand 8699 return new ErrorExp(); 8700 Dsymbol *s = exp->ti->toAlias(); 8701 Declaration *v = s->isDeclaration(); 8702 if (v) 8703 { 8704 if (v->type && !v->type->deco) 8705 v->type = v->type->semantic(v->loc, sc); 8706 e = new DotVarExp(exp->loc, exp->e1, v); 8707 e = semantic(e, sc); 8708 return e; 8709 } 8710 e = new ScopeExp(exp->loc, exp->ti); 8711 e = new DotExp(exp->loc, exp->e1, e); 8712 e = semantic(e, sc); 8713 return e; 8714 } 8715 } 8716 else if (e->op == TOKoverloadset) 8717 { 8718 OverExp *oe = (OverExp *)e; 8719 exp->ti->tempdecl = oe->vars; 8720 e = new ScopeExp(exp->loc, exp->ti); 8721 e = semantic(e, sc); 8722 return e; 8723 } 8724 Lerr: 8725 e->error("%s isn't a template", e->toChars()); 8726 return new ErrorExp(); 8727 } 8728