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