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