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 * https://github.com/D-Programming-Language/dmd/blob/master/src/expression.c
9 */
10
11 #include "root/dsystem.h"
12 #include "root/rmem.h"
13 #include "root/root.h"
14
15 #include "errors.h"
16 #include "mtype.h"
17 #include "init.h"
18 #include "expression.h"
19 #include "template.h"
20 #include "utf.h"
21 #include "enum.h"
22 #include "scope.h"
23 #include "statement.h"
24 #include "declaration.h"
25 #include "aggregate.h"
26 #include "import.h"
27 #include "id.h"
28 #include "dsymbol.h"
29 #include "module.h"
30 #include "attrib.h"
31 #include "hdrgen.h"
32 #include "parse.h"
33 #include "doc.h"
34 #include "root/aav.h"
35 #include "nspace.h"
36 #include "ctfe.h"
37 #include "target.h"
38
39 bool walkPostorder(Expression *e, StoppableVisitor *v);
40 bool checkParamArgumentEscape(Scope *sc, FuncDeclaration *fdc, Identifier *par, Expression *arg, bool gag);
41 bool checkAccess(AggregateDeclaration *ad, Loc loc, Scope *sc, Dsymbol *smember);
42 VarDeclaration *copyToTemp(StorageClass stc, const char *name, Expression *e);
43 Expression *extractSideEffect(Scope *sc, const char *name, Expression **e0, Expression *e, bool alwaysCopy = false);
44 char *MODtoChars(MOD mod);
45 bool MODimplicitConv(MOD modfrom, MOD modto);
46 void MODMatchToBuffer(OutBuffer *buf, unsigned char lhsMod, unsigned char rhsMod);
47 Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads);
48 bool checkUnsafeAccess(Scope *sc, Expression *e, bool readonly, bool printmsg);
49 void toAutoQualChars(const char **result, Type *t1, Type *t2);
50
51 /*****************************************
52 * Determine if 'this' is available.
53 * If it is, return the FuncDeclaration that has it.
54 */
55
hasThis(Scope * sc)56 FuncDeclaration *hasThis(Scope *sc)
57 {
58 //printf("hasThis()\n");
59 Dsymbol *p = sc->parent;
60 while (p && p->isTemplateMixin())
61 p = p->parent;
62 FuncDeclaration *fdthis = p ? p->isFuncDeclaration() : NULL;
63 //printf("fdthis = %p, '%s'\n", fdthis, fdthis ? fdthis->toChars() : "");
64
65 // Go upwards until we find the enclosing member function
66 FuncDeclaration *fd = fdthis;
67 while (1)
68 {
69 if (!fd)
70 {
71 goto Lno;
72 }
73 if (!fd->isNested())
74 break;
75
76 Dsymbol *parent = fd->parent;
77 while (1)
78 {
79 if (!parent)
80 goto Lno;
81 TemplateInstance *ti = parent->isTemplateInstance();
82 if (ti)
83 parent = ti->parent;
84 else
85 break;
86 }
87 fd = parent->isFuncDeclaration();
88 }
89
90 if (!fd->isThis())
91 { //printf("test '%s'\n", fd->toChars());
92 goto Lno;
93 }
94
95 assert(fd->vthis);
96 return fd;
97
98 Lno:
99 return NULL; // don't have 'this' available
100 }
101
isNeedThisScope(Scope * sc,Declaration * d)102 bool isNeedThisScope(Scope *sc, Declaration *d)
103 {
104 if (sc->intypeof == 1)
105 return false;
106
107 AggregateDeclaration *ad = d->isThis();
108 if (!ad)
109 return false;
110 //printf("d = %s, ad = %s\n", d->toChars(), ad->toChars());
111
112 for (Dsymbol *s = sc->parent; s; s = s->toParent2())
113 {
114 //printf("\ts = %s %s, toParent2() = %p\n", s->kind(), s->toChars(), s->toParent2());
115 if (AggregateDeclaration *ad2 = s->isAggregateDeclaration())
116 {
117 if (ad2 == ad)
118 return false;
119 else if (ad2->isNested())
120 continue;
121 else
122 return true;
123 }
124 if (FuncDeclaration *f = s->isFuncDeclaration())
125 {
126 if (f->isMember2())
127 break;
128 }
129 }
130 return true;
131 }
132
133 /******************************
134 * check e is exp.opDispatch!(tiargs) or not
135 * It's used to switch to UFCS the semantic analysis path
136 */
137
isDotOpDispatch(Expression * e)138 bool isDotOpDispatch(Expression *e)
139 {
140 return e->op == TOKdotti &&
141 ((DotTemplateInstanceExp *)e)->ti->name == Id::opDispatch;
142 }
143
144 /****************************************
145 * Expand tuples.
146 * Input:
147 * exps aray of Expressions
148 * Output:
149 * exps rewritten in place
150 */
151
expandTuples(Expressions * exps)152 void expandTuples(Expressions *exps)
153 {
154 //printf("expandTuples()\n");
155 if (exps)
156 {
157 for (size_t i = 0; i < exps->length; i++)
158 {
159 Expression *arg = (*exps)[i];
160 if (!arg)
161 continue;
162
163 // Look for tuple with 0 members
164 if (arg->op == TOKtype)
165 {
166 TypeExp *e = (TypeExp *)arg;
167 if (e->type->toBasetype()->ty == Ttuple)
168 {
169 TypeTuple *tt = (TypeTuple *)e->type->toBasetype();
170
171 if (!tt->arguments || tt->arguments->length == 0)
172 {
173 exps->remove(i);
174 if (i == exps->length)
175 return;
176 i--;
177 continue;
178 }
179 }
180 }
181
182 // Inline expand all the tuples
183 while (arg->op == TOKtuple)
184 {
185 TupleExp *te = (TupleExp *)arg;
186 exps->remove(i); // remove arg
187 exps->insert(i, te->exps); // replace with tuple contents
188 if (i == exps->length)
189 return; // empty tuple, no more arguments
190 (*exps)[i] = Expression::combine(te->e0, (*exps)[i]);
191 arg = (*exps)[i];
192 }
193 }
194 }
195 }
196
197 /****************************************
198 * Expand alias this tuples.
199 */
200
isAliasThisTuple(Expression * e)201 TupleDeclaration *isAliasThisTuple(Expression *e)
202 {
203 if (!e->type)
204 return NULL;
205
206 Type *t = e->type->toBasetype();
207 Lagain:
208 if (Dsymbol *s = t->toDsymbol(NULL))
209 {
210 AggregateDeclaration *ad = s->isAggregateDeclaration();
211 if (ad)
212 {
213 s = ad->aliasthis;
214 if (s && s->isVarDeclaration())
215 {
216 TupleDeclaration *td = s->isVarDeclaration()->toAlias()->isTupleDeclaration();
217 if (td && td->isexp)
218 return td;
219 }
220 if (Type *att = t->aliasthisOf())
221 {
222 t = att;
223 goto Lagain;
224 }
225 }
226 }
227 return NULL;
228 }
229
expandAliasThisTuples(Expressions * exps,size_t starti)230 int expandAliasThisTuples(Expressions *exps, size_t starti)
231 {
232 if (!exps || exps->length == 0)
233 return -1;
234
235 for (size_t u = starti; u < exps->length; u++)
236 {
237 Expression *exp = (*exps)[u];
238 TupleDeclaration *td = isAliasThisTuple(exp);
239 if (td)
240 {
241 exps->remove(u);
242 for (size_t i = 0; i<td->objects->length; ++i)
243 {
244 Expression *e = isExpression((*td->objects)[i]);
245 assert(e);
246 assert(e->op == TOKdsymbol);
247 DsymbolExp *se = (DsymbolExp *)e;
248 Declaration *d = se->s->isDeclaration();
249 assert(d);
250 e = new DotVarExp(exp->loc, exp, d);
251 assert(d->type);
252 e->type = d->type;
253 exps->insert(u + i, e);
254 }
255 return (int)u;
256 }
257 }
258
259 return -1;
260 }
261
262 /****************************************
263 * Get TemplateDeclaration enclosing FuncDeclaration.
264 */
265
getFuncTemplateDecl(Dsymbol * s)266 TemplateDeclaration *getFuncTemplateDecl(Dsymbol *s)
267 {
268 FuncDeclaration *f = s->isFuncDeclaration();
269 if (f && f->parent)
270 {
271 TemplateInstance *ti = f->parent->isTemplateInstance();
272 if (ti && !ti->isTemplateMixin() &&
273 ti->tempdecl && ((TemplateDeclaration *)ti->tempdecl)->onemember &&
274 ti->tempdecl->ident == f->ident)
275 {
276 return (TemplateDeclaration *)ti->tempdecl;
277 }
278 }
279 return NULL;
280 }
281
282 /************************************************
283 * If we want the value of this expression, but do not want to call
284 * the destructor on it.
285 */
286
valueNoDtor(Expression * e)287 Expression *valueNoDtor(Expression *e)
288 {
289 if (e->op == TOKcall)
290 {
291 /* The struct value returned from the function is transferred
292 * so do not call the destructor on it.
293 * Recognize:
294 * ((S _ctmp = S.init), _ctmp).this(...)
295 * and make sure the destructor is not called on _ctmp
296 * BUG: if e is a CommaExp, we should go down the right side.
297 */
298 CallExp *ce = (CallExp *)e;
299 if (ce->e1->op == TOKdotvar)
300 {
301 DotVarExp *dve = (DotVarExp *)ce->e1;
302 if (dve->var->isCtorDeclaration())
303 {
304 // It's a constructor call
305 if (dve->e1->op == TOKcomma)
306 {
307 CommaExp *comma = (CommaExp *)dve->e1;
308 if (comma->e2->op == TOKvar)
309 {
310 VarExp *ve = (VarExp *)comma->e2;
311 VarDeclaration *ctmp = ve->var->isVarDeclaration();
312 if (ctmp)
313 {
314 ctmp->storage_class |= STCnodtor;
315 assert(!ce->isLvalue());
316 }
317 }
318 }
319 }
320 }
321 }
322 else if (e->op == TOKvar)
323 {
324 VarDeclaration *vtmp = ((VarExp *)e)->var->isVarDeclaration();
325 if (vtmp && vtmp->storage_class & STCrvalue)
326 {
327 vtmp->storage_class |= STCnodtor;
328 }
329 }
330 return e;
331 }
332
333 /*********************************************
334 * If e is an instance of a struct, and that struct has a copy constructor,
335 * rewrite e as:
336 * (tmp = e),tmp
337 * Input:
338 * sc just used to specify the scope of created temporary variable
339 */
callCpCtor(Scope * sc,Expression * e)340 Expression *callCpCtor(Scope *sc, Expression *e)
341 {
342 Type *tv = e->type->baseElemOf();
343 if (tv->ty == Tstruct)
344 {
345 StructDeclaration *sd = ((TypeStruct *)tv)->sym;
346 if (sd->postblit)
347 {
348 /* Create a variable tmp, and replace the argument e with:
349 * (tmp = e),tmp
350 * and let AssignExp() handle the construction.
351 * This is not the most efficent, ideally tmp would be constructed
352 * directly onto the stack.
353 */
354 VarDeclaration *tmp = copyToTemp(STCrvalue, "__copytmp", e);
355 tmp->storage_class |= STCnodtor;
356 dsymbolSemantic(tmp, sc);
357 Expression *de = new DeclarationExp(e->loc, tmp);
358 Expression *ve = new VarExp(e->loc, tmp);
359 de->type = Type::tvoid;
360 ve->type = e->type;
361 e = Expression::combine(de, ve);
362 }
363 }
364 return e;
365 }
366
367 /************************************************
368 * Handle the postblit call on lvalue, or the move of rvalue.
369 */
doCopyOrMove(Scope * sc,Expression * e)370 Expression *doCopyOrMove(Scope *sc, Expression *e)
371 {
372 if (e->op == TOKquestion)
373 {
374 CondExp *ce = (CondExp *)e;
375 ce->e1 = doCopyOrMove(sc, ce->e1);
376 ce->e2 = doCopyOrMove(sc, ce->e2);
377 }
378 else
379 {
380 e = e->isLvalue() ? callCpCtor(sc, e) : valueNoDtor(e);
381 }
382 return e;
383 }
384
385 /******************************** Expression **************************/
386
Expression(Loc loc,TOK op,int size)387 Expression::Expression(Loc loc, TOK op, int size)
388 {
389 //printf("Expression::Expression(op = %d) this = %p\n", op, this);
390 this->loc = loc;
391 this->op = op;
392 this->size = (unsigned char)size;
393 this->parens = 0;
394 type = NULL;
395 }
396
_init()397 void Expression::_init()
398 {
399 CTFEExp::cantexp = new CTFEExp(TOKcantexp);
400 CTFEExp::voidexp = new CTFEExp(TOKvoidexp);
401 CTFEExp::breakexp = new CTFEExp(TOKbreak);
402 CTFEExp::continueexp = new CTFEExp(TOKcontinue);
403 CTFEExp::gotoexp = new CTFEExp(TOKgoto);
404 }
405
syntaxCopy()406 Expression *Expression::syntaxCopy()
407 {
408 //printf("Expression::syntaxCopy()\n");
409 //print();
410 return copy();
411 }
412
413 /*********************************
414 * Does *not* do a deep copy.
415 */
416
copy()417 Expression *Expression::copy()
418 {
419 Expression *e;
420 if (!size)
421 {
422 assert(0);
423 }
424 void *pe = mem.xmalloc(size);
425 //printf("Expression::copy(op = %d) e = %p\n", op, pe);
426 e = (Expression *)memcpy(pe, (void *)this, size);
427 return e;
428 }
429
print()430 void Expression::print()
431 {
432 fprintf(stderr, "%s\n", toChars());
433 fflush(stderr);
434 }
435
toChars()436 const char *Expression::toChars()
437 {
438 OutBuffer buf;
439 HdrGenState hgs;
440 toCBuffer(this, &buf, &hgs);
441 return buf.extractChars();
442 }
443
error(const char * format,...)444 void Expression::error(const char *format, ...) const
445 {
446 if (type != Type::terror)
447 {
448 va_list ap;
449 va_start(ap, format);
450 ::verror(loc, format, ap);
451 va_end( ap );
452 }
453 }
454
warning(const char * format,...)455 void Expression::warning(const char *format, ...) const
456 {
457 if (type != Type::terror)
458 {
459 va_list ap;
460 va_start(ap, format);
461 ::vwarning(loc, format, ap);
462 va_end( ap );
463 }
464 }
465
deprecation(const char * format,...)466 void Expression::deprecation(const char *format, ...) const
467 {
468 if (type != Type::terror)
469 {
470 va_list ap;
471 va_start(ap, format);
472 ::vdeprecation(loc, format, ap);
473 va_end( ap );
474 }
475 }
476
477 /**********************************
478 * Combine e1 and e2 by CommaExp if both are not NULL.
479 */
combine(Expression * e1,Expression * e2)480 Expression *Expression::combine(Expression *e1, Expression *e2)
481 {
482 if (e1)
483 {
484 if (e2)
485 {
486 e1 = new CommaExp(e1->loc, e1, e2);
487 e1->type = e2->type;
488 }
489 }
490 else
491 e1 = e2;
492 return e1;
493 }
494
495 /**********************************
496 * If 'e' is a tree of commas, returns the leftmost expression
497 * by stripping off it from the tree. The remained part of the tree
498 * is returned via *pe0.
499 * Otherwise 'e' is directly returned and *pe0 is set to NULL.
500 */
extractLast(Expression * e,Expression ** pe0)501 Expression *Expression::extractLast(Expression *e, Expression **pe0)
502 {
503 if (e->op != TOKcomma)
504 {
505 *pe0 = NULL;
506 return e;
507 }
508
509 CommaExp *ce = (CommaExp *)e;
510 if (ce->e2->op != TOKcomma)
511 {
512 *pe0 = ce->e1;
513 return ce->e2;
514 }
515 else
516 {
517 *pe0 = e;
518
519 Expression **pce = &ce->e2;
520 while (((CommaExp *)(*pce))->e2->op == TOKcomma)
521 {
522 pce = &((CommaExp *)(*pce))->e2;
523 }
524 assert((*pce)->op == TOKcomma);
525 ce = (CommaExp *)(*pce);
526 *pce = ce->e1;
527
528 return ce->e2;
529 }
530 }
531
toInteger()532 dinteger_t Expression::toInteger()
533 {
534 //printf("Expression %s\n", Token::toChars(op));
535 error("integer constant expression expected instead of %s", toChars());
536 return 0;
537 }
538
toUInteger()539 uinteger_t Expression::toUInteger()
540 {
541 //printf("Expression %s\n", Token::toChars(op));
542 return (uinteger_t)toInteger();
543 }
544
toReal()545 real_t Expression::toReal()
546 {
547 error("floating point constant expression expected instead of %s", toChars());
548 return CTFloat::zero;
549 }
550
toImaginary()551 real_t Expression::toImaginary()
552 {
553 error("floating point constant expression expected instead of %s", toChars());
554 return CTFloat::zero;
555 }
556
toComplex()557 complex_t Expression::toComplex()
558 {
559 error("floating point constant expression expected instead of %s", toChars());
560 return complex_t(CTFloat::zero);
561 }
562
toStringExp()563 StringExp *Expression::toStringExp()
564 {
565 return NULL;
566 }
567
toTupleExp()568 TupleExp *Expression::toTupleExp()
569 {
570 return NULL;
571 }
572
573 /***************************************
574 * Return !=0 if expression is an lvalue.
575 */
576
isLvalue()577 bool Expression::isLvalue()
578 {
579 return false;
580 }
581
582 /*******************************
583 * Give error if we're not an lvalue.
584 * If we can, convert expression to be an lvalue.
585 */
586
toLvalue(Scope *,Expression * e)587 Expression *Expression::toLvalue(Scope *, Expression *e)
588 {
589 if (!e)
590 e = this;
591 else if (!loc.filename)
592 loc = e->loc;
593
594 if (e->op == TOKtype)
595 error("%s `%s` is a type, not an lvalue", e->type->kind(), e->type->toChars());
596 else
597 error("%s is not an lvalue", e->toChars());
598
599 return new ErrorExp();
600 }
601
602 /***************************************
603 * Parameters:
604 * sc: scope
605 * flag: 1: do not issue error message for invalid modification
606 * Returns:
607 * 0: is not modifiable
608 * 1: is modifiable in default == being related to type->isMutable()
609 * 2: is modifiable, because this is a part of initializing.
610 */
611
checkModifiable(Scope *,int)612 int Expression::checkModifiable(Scope *, int)
613 {
614 return type ? 1 : 0; // default modifiable
615 }
616
modifiableLvalue(Scope * sc,Expression * e)617 Expression *Expression::modifiableLvalue(Scope *sc, Expression *e)
618 {
619 //printf("Expression::modifiableLvalue() %s, type = %s\n", toChars(), type->toChars());
620
621 // See if this expression is a modifiable lvalue (i.e. not const)
622 if (checkModifiable(sc) == 1)
623 {
624 assert(type);
625 if (!type->isMutable())
626 {
627 error("cannot modify %s expression %s", MODtoChars(type->mod), toChars());
628 return new ErrorExp();
629 }
630 else if (!type->isAssignable())
631 {
632 error("cannot modify struct %s %s with immutable members", toChars(), type->toChars());
633 return new ErrorExp();
634 }
635 }
636 return toLvalue(sc, e);
637 }
638
639 /****************************************
640 * Check that the expression has a valid type.
641 * If not, generates an error "... has no type".
642 * Returns:
643 * true if the expression is not valid.
644 * Note:
645 * When this function returns true, `checkValue()` should also return true.
646 */
checkType()647 bool Expression::checkType()
648 {
649 return false;
650 }
651
652 /****************************************
653 * Check that the expression has a valid value.
654 * If not, generates an error "... has no value".
655 * Returns:
656 * true if the expression is not valid or has void type.
657 */
checkValue()658 bool Expression::checkValue()
659 {
660 if (type && type->toBasetype()->ty == Tvoid)
661 {
662 error("expression %s is void and has no value", toChars());
663 //print(); halt();
664 if (!global.gag)
665 type = Type::terror;
666 return true;
667 }
668 return false;
669 }
670
checkScalar()671 bool Expression::checkScalar()
672 {
673 if (op == TOKerror)
674 return true;
675 if (type->toBasetype()->ty == Terror)
676 return true;
677 if (!type->isscalar())
678 {
679 error("`%s` is not a scalar, it is a %s", toChars(), type->toChars());
680 return true;
681 }
682 return checkValue();
683 }
684
checkNoBool()685 bool Expression::checkNoBool()
686 {
687 if (op == TOKerror)
688 return true;
689 if (type->toBasetype()->ty == Terror)
690 return true;
691 if (type->toBasetype()->ty == Tbool)
692 {
693 error("operation not allowed on bool `%s`", toChars());
694 return true;
695 }
696 return false;
697 }
698
checkIntegral()699 bool Expression::checkIntegral()
700 {
701 if (op == TOKerror)
702 return true;
703 if (type->toBasetype()->ty == Terror)
704 return true;
705 if (!type->isintegral())
706 {
707 error("`%s` is not of integral type, it is a %s", toChars(), type->toChars());
708 return true;
709 }
710 return checkValue();
711 }
712
checkArithmetic()713 bool Expression::checkArithmetic()
714 {
715 if (op == TOKerror)
716 return true;
717 if (type->toBasetype()->ty == Terror)
718 return true;
719 if (!type->isintegral() && !type->isfloating())
720 {
721 error("`%s` is not of arithmetic type, it is a %s", toChars(), type->toChars());
722 return true;
723 }
724 return checkValue();
725 }
726
checkDeprecated(Scope * sc,Dsymbol * s)727 bool Expression::checkDeprecated(Scope *sc, Dsymbol *s)
728 {
729 return s->checkDeprecated(loc, sc);
730 }
731
checkDisabled(Scope * sc,Dsymbol * s)732 bool Expression::checkDisabled(Scope *sc, Dsymbol *s)
733 {
734 if (Declaration *d = s->isDeclaration())
735 {
736 return d->checkDisabled(loc, sc);
737 }
738 return false;
739 }
740
741 /*********************************************
742 * Calling function f.
743 * Check the purity, i.e. if we're in a pure function
744 * we can only call other pure functions.
745 * Returns true if error occurs.
746 */
checkPurity(Scope * sc,FuncDeclaration * f)747 bool Expression::checkPurity(Scope *sc, FuncDeclaration *f)
748 {
749 if (!sc->func)
750 return false;
751 if (sc->func == f)
752 return false;
753 if (sc->intypeof == 1)
754 return false;
755 if (sc->flags & (SCOPEctfe | SCOPEdebug))
756 return false;
757
758 /* Given:
759 * void f() {
760 * pure void g() {
761 * /+pure+/ void h() {
762 * /+pure+/ void i() { }
763 * }
764 * }
765 * }
766 * g() can call h() but not f()
767 * i() can call h() and g() but not f()
768 */
769
770 // Find the closest pure parent of the calling function
771 FuncDeclaration *outerfunc = sc->func;
772 FuncDeclaration *calledparent = f;
773
774 if (outerfunc->isInstantiated())
775 {
776 // The attributes of outerfunc should be inferred from the call of f.
777 }
778 else if (f->isInstantiated())
779 {
780 // The attributes of f are inferred from its body.
781 }
782 else if (f->isFuncLiteralDeclaration())
783 {
784 // The attributes of f are always inferred in its declared place.
785 }
786 else
787 {
788 /* Today, static local functions are impure by default, but they cannot
789 * violate purity of enclosing functions.
790 *
791 * auto foo() pure { // non instantiated funciton
792 * static auto bar() { // static, without pure attribute
793 * impureFunc(); // impure call
794 * // Although impureFunc is called inside bar, f(= impureFunc)
795 * // is not callable inside pure outerfunc(= foo <- bar).
796 * }
797 *
798 * bar();
799 * // Although bar is called inside foo, f(= bar) is callable
800 * // bacause calledparent(= foo) is same with outerfunc(= foo).
801 * }
802 */
803
804 while (outerfunc->toParent2() &&
805 outerfunc->isPureBypassingInference() == PUREimpure &&
806 outerfunc->toParent2()->isFuncDeclaration())
807 {
808 outerfunc = outerfunc->toParent2()->isFuncDeclaration();
809 if (outerfunc->type->ty == Terror)
810 return true;
811 }
812 while (calledparent->toParent2() &&
813 calledparent->isPureBypassingInference() == PUREimpure &&
814 calledparent->toParent2()->isFuncDeclaration())
815 {
816 calledparent = calledparent->toParent2()->isFuncDeclaration();
817 if (calledparent->type->ty == Terror)
818 return true;
819 }
820 }
821
822 // If the caller has a pure parent, then either the called func must be pure,
823 // OR, they must have the same pure parent.
824 if (!f->isPure() && calledparent != outerfunc)
825 {
826 FuncDeclaration *ff = outerfunc;
827 if (sc->flags & SCOPEcompile ? ff->isPureBypassingInference() >= PUREweak : ff->setImpure())
828 {
829 error("pure %s `%s` cannot call impure %s `%s`",
830 ff->kind(), ff->toPrettyChars(), f->kind(), f->toPrettyChars());
831 return true;
832 }
833 }
834 return false;
835 }
836
837 /*******************************************
838 * Accessing variable v.
839 * Check for purity and safety violations.
840 * Returns true if error occurs.
841 */
checkPurity(Scope * sc,VarDeclaration * v)842 bool Expression::checkPurity(Scope *sc, VarDeclaration *v)
843 {
844 //printf("v = %s %s\n", v->type->toChars(), v->toChars());
845
846 /* Look for purity and safety violations when accessing variable v
847 * from current function.
848 */
849 if (!sc->func)
850 return false;
851 if (sc->intypeof == 1)
852 return false; // allow violations inside typeof(expression)
853 if (sc->flags & (SCOPEctfe | SCOPEdebug))
854 return false; // allow violations inside compile-time evaluated expressions and debug conditionals
855 if (v->ident == Id::ctfe)
856 return false; // magic variable never violates pure and safe
857 if (v->isImmutable())
858 return false; // always safe and pure to access immutables...
859 if (v->isConst() && !v->isRef() && (v->isDataseg() || v->isParameter()) &&
860 v->type->implicitConvTo(v->type->immutableOf()))
861 return false; // or const global/parameter values which have no mutable indirections
862 if (v->storage_class & STCmanifest)
863 return false; // ...or manifest constants
864
865 bool err = false;
866 if (v->isDataseg())
867 {
868 // Bugzilla 7533: Accessing implicit generated __gate is pure.
869 if (v->ident == Id::gate)
870 return false;
871
872 /* Accessing global mutable state.
873 * Therefore, this function and all its immediately enclosing
874 * functions must be pure.
875 */
876 /* Today, static local functions are impure by default, but they cannot
877 * violate purity of enclosing functions.
878 *
879 * auto foo() pure { // non instantiated funciton
880 * static auto bar() { // static, without pure attribute
881 * globalData++; // impure access
882 * // Although globalData is accessed inside bar,
883 * // it is not accessible inside pure foo.
884 * }
885 * }
886 */
887 for (Dsymbol *s = sc->func; s; s = s->toParent2())
888 {
889 FuncDeclaration *ff = s->isFuncDeclaration();
890 if (!ff)
891 break;
892 if (sc->flags & SCOPEcompile ? ff->isPureBypassingInference() >= PUREweak : ff->setImpure())
893 {
894 error("pure %s `%s` cannot access mutable static data `%s`",
895 ff->kind(), ff->toPrettyChars(), v->toChars());
896 err = true;
897 break;
898 }
899 /* If the enclosing is an instantiated function or a lambda, its
900 * attribute inference result is preferred.
901 */
902 if (ff->isInstantiated())
903 break;
904 if (ff->isFuncLiteralDeclaration())
905 break;
906 }
907 }
908 else
909 {
910 /* Given:
911 * void f() {
912 * int fx;
913 * pure void g() {
914 * int gx;
915 * /+pure+/ void h() {
916 * int hx;
917 * /+pure+/ void i() { }
918 * }
919 * }
920 * }
921 * i() can modify hx and gx but not fx
922 */
923
924 Dsymbol *vparent = v->toParent2();
925 for (Dsymbol *s = sc->func; !err && s; s = s->toParent2())
926 {
927 if (s == vparent)
928 break;
929
930 if (AggregateDeclaration *ad = s->isAggregateDeclaration())
931 {
932 if (ad->isNested())
933 continue;
934 break;
935 }
936 FuncDeclaration *ff = s->isFuncDeclaration();
937 if (!ff)
938 break;
939 if (ff->isNested() || ff->isThis())
940 {
941 if (ff->type->isImmutable() ||
942 (ff->type->isShared() && !MODimplicitConv(ff->type->mod, v->type->mod)))
943 {
944 OutBuffer ffbuf;
945 OutBuffer vbuf;
946 MODMatchToBuffer(&ffbuf, ff->type->mod, v->type->mod);
947 MODMatchToBuffer(&vbuf, v->type->mod, ff->type->mod);
948 error("%s%s `%s` cannot access %sdata `%s`",
949 ffbuf.peekChars(), ff->kind(), ff->toPrettyChars(), vbuf.peekChars(), v->toChars());
950 err = true;
951 break;
952 }
953 continue;
954 }
955 break;
956 }
957 }
958
959 /* Do not allow safe functions to access __gshared data
960 */
961 if (v->storage_class & STCgshared)
962 {
963 if (sc->func->setUnsafe())
964 {
965 error("safe %s `%s` cannot access __gshared data `%s`",
966 sc->func->kind(), sc->func->toChars(), v->toChars());
967 err = true;
968 }
969 }
970
971 return err;
972 }
973
974 /*********************************************
975 * Calling function f.
976 * Check the safety, i.e. if we're in a @safe function
977 * we can only call @safe or @trusted functions.
978 * Returns true if error occurs.
979 */
checkSafety(Scope * sc,FuncDeclaration * f)980 bool Expression::checkSafety(Scope *sc, FuncDeclaration *f)
981 {
982 if (!sc->func)
983 return false;
984 if (sc->func == f)
985 return false;
986 if (sc->intypeof == 1)
987 return false;
988 if (sc->flags & SCOPEctfe)
989 return false;
990
991 if (!f->isSafe() && !f->isTrusted())
992 {
993 if (sc->flags & SCOPEcompile ? sc->func->isSafeBypassingInference() : sc->func->setUnsafe())
994 {
995 if (loc.linnum == 0) // e.g. implicitly generated dtor
996 loc = sc->func->loc;
997
998 error("@safe %s `%s` cannot call @system %s `%s`",
999 sc->func->kind(), sc->func->toPrettyChars(), f->kind(), f->toPrettyChars());
1000 return true;
1001 }
1002 }
1003 return false;
1004 }
1005
1006 /*********************************************
1007 * Calling function f.
1008 * Check the @nogc-ness, i.e. if we're in a @nogc function
1009 * we can only call other @nogc functions.
1010 * Returns true if error occurs.
1011 */
checkNogc(Scope * sc,FuncDeclaration * f)1012 bool Expression::checkNogc(Scope *sc, FuncDeclaration *f)
1013 {
1014 if (!sc->func)
1015 return false;
1016 if (sc->func == f)
1017 return false;
1018 if (sc->intypeof == 1)
1019 return false;
1020 if (sc->flags & SCOPEctfe)
1021 return false;
1022
1023 if (!f->isNogc())
1024 {
1025 if (sc->flags & SCOPEcompile ? sc->func->isNogcBypassingInference() : sc->func->setGC())
1026 {
1027 if (loc.linnum == 0) // e.g. implicitly generated dtor
1028 loc = sc->func->loc;
1029
1030 error("@nogc %s `%s` cannot call non-@nogc %s `%s`",
1031 sc->func->kind(), sc->func->toPrettyChars(), f->kind(), f->toPrettyChars());
1032 return true;
1033 }
1034 }
1035 return false;
1036 }
1037
1038 /********************************************
1039 * Check that the postblit is callable if t is an array of structs.
1040 * Returns true if error happens.
1041 */
checkPostblit(Scope * sc,Type * t)1042 bool Expression::checkPostblit(Scope *sc, Type *t)
1043 {
1044 t = t->baseElemOf();
1045 if (t->ty == Tstruct)
1046 {
1047 if (global.params.useTypeInfo && Type::dtypeinfo)
1048 {
1049 // Bugzilla 11395: Require TypeInfo generation for array concatenation
1050 semanticTypeInfo(sc, t);
1051 }
1052
1053 StructDeclaration *sd = ((TypeStruct *)t)->sym;
1054 if (sd->postblit)
1055 {
1056 if (sd->postblit->checkDisabled(loc, sc))
1057 return true;
1058 //checkDeprecated(sc, sd->postblit); // necessary?
1059 checkPurity(sc, sd->postblit);
1060 checkSafety(sc, sd->postblit);
1061 checkNogc(sc, sd->postblit);
1062 //checkAccess(sd, loc, sc, sd->postblit); // necessary?
1063 return false;
1064 }
1065 }
1066 return false;
1067 }
1068
checkRightThis(Scope * sc)1069 bool Expression::checkRightThis(Scope *sc)
1070 {
1071 if (op == TOKerror)
1072 return true;
1073 if (op == TOKvar && type->ty != Terror)
1074 {
1075 VarExp *ve = (VarExp *)this;
1076 if (isNeedThisScope(sc, ve->var))
1077 {
1078 //printf("checkRightThis sc->intypeof = %d, ad = %p, func = %p, fdthis = %p\n",
1079 // sc->intypeof, sc->getStructClassScope(), func, fdthis);
1080 error("need `this` for `%s` of type `%s`", ve->var->toChars(), ve->var->type->toChars());
1081 return true;
1082 }
1083 }
1084 return false;
1085 }
1086
1087 /*******************************
1088 * Check whether the expression allows RMW operations, error with rmw operator diagnostic if not.
1089 * ex is the RHS expression, or NULL if ++/-- is used (for diagnostics)
1090 * Returns true if error occurs.
1091 */
checkReadModifyWrite(TOK rmwOp,Expression * ex)1092 bool Expression::checkReadModifyWrite(TOK rmwOp, Expression *ex)
1093 {
1094 //printf("Expression::checkReadModifyWrite() %s %s", toChars(), ex ? ex->toChars() : "");
1095 if (!type || !type->isShared())
1096 return false;
1097
1098 // atomicOp uses opAssign (+=/-=) rather than opOp (++/--) for the CT string literal.
1099 switch (rmwOp)
1100 {
1101 case TOKplusplus:
1102 case TOKpreplusplus:
1103 rmwOp = TOKaddass;
1104 break;
1105
1106 case TOKminusminus:
1107 case TOKpreminusminus:
1108 rmwOp = TOKminass;
1109 break;
1110
1111 default:
1112 break;
1113 }
1114
1115 deprecation("read-modify-write operations are not allowed for shared variables. "
1116 "Use core.atomic.atomicOp!\"%s\"(%s, %s) instead.",
1117 Token::tochars[rmwOp], toChars(), ex ? ex->toChars() : "1");
1118 return false;
1119
1120 // note: enable when deprecation becomes an error.
1121 // return true;
1122 }
1123
1124 /*****************************
1125 * If expression can be tested for true or false,
1126 * returns the modified expression.
1127 * Otherwise returns ErrorExp.
1128 */
toBoolean(Scope * sc)1129 Expression *Expression::toBoolean(Scope *sc)
1130 {
1131 // Default is 'yes' - do nothing
1132 Expression *e = this;
1133 Type *t = type;
1134 Type *tb = type->toBasetype();
1135 Type *att = NULL;
1136 Lagain:
1137 // Structs can be converted to bool using opCast(bool)()
1138 if (tb->ty == Tstruct)
1139 {
1140 AggregateDeclaration *ad = ((TypeStruct *)tb)->sym;
1141 /* Don't really need to check for opCast first, but by doing so we
1142 * get better error messages if it isn't there.
1143 */
1144 Dsymbol *fd = search_function(ad, Id::_cast);
1145 if (fd)
1146 {
1147 e = new CastExp(loc, e, Type::tbool);
1148 e = expressionSemantic(e, sc);
1149 return e;
1150 }
1151
1152 // Forward to aliasthis.
1153 if (ad->aliasthis && tb != att)
1154 {
1155 if (!att && tb->checkAliasThisRec())
1156 att = tb;
1157 e = resolveAliasThis(sc, e);
1158 t = e->type;
1159 tb = e->type->toBasetype();
1160 goto Lagain;
1161 }
1162 }
1163
1164 if (!t->isBoolean())
1165 {
1166 if (tb != Type::terror)
1167 error("expression %s of type %s does not have a boolean value", toChars(), t->toChars());
1168 return new ErrorExp();
1169 }
1170 return e;
1171 }
1172
1173 /******************************
1174 * Take address of expression.
1175 */
1176
addressOf()1177 Expression *Expression::addressOf()
1178 {
1179 //printf("Expression::addressOf()\n");
1180 Expression *e = new AddrExp(loc, this);
1181 e->type = type->pointerTo();
1182 return e;
1183 }
1184
1185 /******************************
1186 * If this is a reference, dereference it.
1187 */
1188
deref()1189 Expression *Expression::deref()
1190 {
1191 //printf("Expression::deref()\n");
1192 // type could be null if forward referencing an 'auto' variable
1193 if (type && type->ty == Treference)
1194 {
1195 Expression *e = new PtrExp(loc, this);
1196 e->type = ((TypeReference *)type)->next;
1197 return e;
1198 }
1199 return this;
1200 }
1201
1202 /********************************
1203 * Does this expression statically evaluate to a boolean 'result' (true or false)?
1204 */
isBool(bool)1205 bool Expression::isBool(bool)
1206 {
1207 return false;
1208 }
1209
isIntegerExp()1210 IntegerExp *Expression::isIntegerExp()
1211 {
1212 return op == TOKint64 ? (IntegerExp *)this : NULL;
1213 }
1214
isErrorExp()1215 ErrorExp *Expression::isErrorExp()
1216 {
1217 return op == TOKerror ? (ErrorExp *)this : NULL;
1218 }
1219
isVoidInitExp()1220 VoidInitExp *Expression::isVoidInitExp()
1221 {
1222 return op == TOKvoid ? (VoidInitExp *)this : NULL;
1223 }
1224
isRealExp()1225 RealExp *Expression::isRealExp()
1226 {
1227 return op == TOKfloat64 ? (RealExp *)this : NULL;
1228 }
1229
isComplexExp()1230 ComplexExp *Expression::isComplexExp()
1231 {
1232 return op == TOKcomplex80 ? (ComplexExp *)this : NULL;
1233 }
1234
isIdentifierExp()1235 IdentifierExp *Expression::isIdentifierExp()
1236 {
1237 return op == TOKidentifier ? (IdentifierExp *)this : NULL;
1238 }
1239
isDollarExp()1240 DollarExp *Expression::isDollarExp()
1241 {
1242 return op == TOKdollar ? (DollarExp *)this : NULL;
1243 }
1244
isDsymbolExp()1245 DsymbolExp *Expression::isDsymbolExp()
1246 {
1247 return op == TOKdsymbol ? (DsymbolExp *)this : NULL;
1248 }
1249
isThisExp()1250 ThisExp *Expression::isThisExp()
1251 {
1252 return op == TOKthis ? (ThisExp *)this : NULL;
1253 }
1254
isSuperExp()1255 SuperExp *Expression::isSuperExp()
1256 {
1257 return op == TOKsuper ? (SuperExp *)this : NULL;
1258 }
1259
isNullExp()1260 NullExp *Expression::isNullExp()
1261 {
1262 return op == TOKnull ? (NullExp *)this : NULL;
1263 }
1264
isStringExp()1265 StringExp *Expression::isStringExp()
1266 {
1267 return op == TOKstring ? (StringExp *)this : NULL;
1268 }
1269
isTupleExp()1270 TupleExp *Expression::isTupleExp()
1271 {
1272 return op == TOKtuple ? (TupleExp *)this : NULL;
1273 }
1274
isArrayLiteralExp()1275 ArrayLiteralExp *Expression::isArrayLiteralExp()
1276 {
1277 return op == TOKarrayliteral ? (ArrayLiteralExp *)this : NULL;
1278 }
1279
isAssocArrayLiteralExp()1280 AssocArrayLiteralExp *Expression::isAssocArrayLiteralExp()
1281 {
1282 return op == TOKassocarrayliteral ? (AssocArrayLiteralExp *)this : NULL;
1283 }
1284
isStructLiteralExp()1285 StructLiteralExp *Expression::isStructLiteralExp()
1286 {
1287 return op == TOKstructliteral ? (StructLiteralExp *)this : NULL;
1288 }
1289
isTypeExp()1290 TypeExp *Expression::isTypeExp()
1291 {
1292 return op == TOKtype ? (TypeExp *)this : NULL;
1293 }
1294
isScopeExp()1295 ScopeExp *Expression::isScopeExp()
1296 {
1297 return op == TOKscope ? (ScopeExp *)this : NULL;
1298 }
1299
isTemplateExp()1300 TemplateExp *Expression::isTemplateExp()
1301 {
1302 return op == TOKtemplate ? (TemplateExp *)this : NULL;
1303 }
1304
isNewExp()1305 NewExp *Expression::isNewExp()
1306 {
1307 return op == TOKnew ? (NewExp *)this : NULL;
1308 }
1309
isNewAnonClassExp()1310 NewAnonClassExp *Expression::isNewAnonClassExp()
1311 {
1312 return op == TOKnewanonclass ? (NewAnonClassExp *)this : NULL;
1313 }
1314
isSymOffExp()1315 SymOffExp *Expression::isSymOffExp()
1316 {
1317 return op == TOKsymoff ? (SymOffExp *)this : NULL;
1318 }
1319
isVarExp()1320 VarExp *Expression::isVarExp()
1321 {
1322 return op == TOKvar ? (VarExp *)this : NULL;
1323 }
1324
isOverExp()1325 OverExp *Expression::isOverExp()
1326 {
1327 return op == TOKoverloadset ? (OverExp *)this : NULL;
1328 }
1329
isFuncExp()1330 FuncExp *Expression::isFuncExp()
1331 {
1332 return op == TOKfunction ? (FuncExp *)this : NULL;
1333 }
1334
isDeclarationExp()1335 DeclarationExp *Expression::isDeclarationExp()
1336 {
1337 return op == TOKdeclaration ? (DeclarationExp *)this : NULL;
1338 }
1339
isTypeidExp()1340 TypeidExp *Expression::isTypeidExp()
1341 {
1342 return op == TOKtypeid ? (TypeidExp *)this : NULL;
1343 }
1344
isTraitsExp()1345 TraitsExp *Expression::isTraitsExp()
1346 {
1347 return op == TOKtraits ? (TraitsExp *)this : NULL;
1348 }
1349
isHaltExp()1350 HaltExp *Expression::isHaltExp()
1351 {
1352 return op == TOKhalt ? (HaltExp *)this : NULL;
1353 }
1354
isExp()1355 IsExp *Expression::isExp()
1356 {
1357 return op == TOKis ? (IsExp *)this : NULL;
1358 }
1359
isCompileExp()1360 CompileExp *Expression::isCompileExp()
1361 {
1362 return op == TOKmixin ? (CompileExp *)this : NULL;
1363 }
1364
isImportExp()1365 ImportExp *Expression::isImportExp()
1366 {
1367 return op == TOKimport ? (ImportExp *)this : NULL;
1368 }
1369
isAssertExp()1370 AssertExp *Expression::isAssertExp()
1371 {
1372 return op == TOKassert ? (AssertExp *)this : NULL;
1373 }
1374
isDotIdExp()1375 DotIdExp *Expression::isDotIdExp()
1376 {
1377 return op == TOKdotid ? (DotIdExp *)this : NULL;
1378 }
1379
isDotTemplateExp()1380 DotTemplateExp *Expression::isDotTemplateExp()
1381 {
1382 return op == TOKdotti ? (DotTemplateExp *)this : NULL;
1383 }
1384
isDotVarExp()1385 DotVarExp *Expression::isDotVarExp()
1386 {
1387 return op == TOKdotvar ? (DotVarExp *)this : NULL;
1388 }
1389
isDotTemplateInstanceExp()1390 DotTemplateInstanceExp *Expression::isDotTemplateInstanceExp()
1391 {
1392 return op == TOKdotti ? (DotTemplateInstanceExp *)this : NULL;
1393 }
1394
isDelegateExp()1395 DelegateExp *Expression::isDelegateExp()
1396 {
1397 return op == TOKdelegate ? (DelegateExp *)this : NULL;
1398 }
1399
isDotTypeExp()1400 DotTypeExp *Expression::isDotTypeExp()
1401 {
1402 return op == TOKdottype ? (DotTypeExp *)this : NULL;
1403 }
1404
isCallExp()1405 CallExp *Expression::isCallExp()
1406 {
1407 return op == TOKcall ? (CallExp *)this : NULL;
1408 }
1409
isAddrExp()1410 AddrExp *Expression::isAddrExp()
1411 {
1412 return op == TOKaddress ? (AddrExp *)this : NULL;
1413 }
1414
isPtrExp()1415 PtrExp *Expression::isPtrExp()
1416 {
1417 return op == TOKstar ? (PtrExp *)this : NULL;
1418 }
1419
isNegExp()1420 NegExp *Expression::isNegExp()
1421 {
1422 return op == TOKneg ? (NegExp *)this : NULL;
1423 }
1424
isUAddExp()1425 UAddExp *Expression::isUAddExp()
1426 {
1427 return op == TOKuadd ? (UAddExp *)this : NULL;
1428 }
1429
isComExp()1430 ComExp *Expression::isComExp()
1431 {
1432 return op == TOKtilde ? (ComExp *)this : NULL;
1433 }
1434
isNotExp()1435 NotExp *Expression::isNotExp()
1436 {
1437 return op == TOKnot ? (NotExp *)this : NULL;
1438 }
1439
isDeleteExp()1440 DeleteExp *Expression::isDeleteExp()
1441 {
1442 return op == TOKdelete ? (DeleteExp *)this : NULL;
1443 }
1444
isCastExp()1445 CastExp *Expression::isCastExp()
1446 {
1447 return op == TOKcast ? (CastExp *)this : NULL;
1448 }
1449
isVectorExp()1450 VectorExp *Expression::isVectorExp()
1451 {
1452 return op == TOKvector ? (VectorExp *)this : NULL;
1453 }
1454
isVectorArrayExp()1455 VectorArrayExp *Expression::isVectorArrayExp()
1456 {
1457 return op == TOKvectorarray ? (VectorArrayExp *)this : NULL;
1458 }
1459
isSliceExp()1460 SliceExp *Expression::isSliceExp()
1461 {
1462 return op == TOKslice ? (SliceExp *)this : NULL;
1463 }
1464
isArrayLengthExp()1465 ArrayLengthExp *Expression::isArrayLengthExp()
1466 {
1467 return op == TOKarraylength ? (ArrayLengthExp *)this : NULL;
1468 }
1469
isArrayExp()1470 ArrayExp *Expression::isArrayExp()
1471 {
1472 return op == TOKarray ? (ArrayExp *)this : NULL;
1473 }
1474
isDotExp()1475 DotExp *Expression::isDotExp()
1476 {
1477 return op == TOKdot ? (DotExp *)this : NULL;
1478 }
1479
isCommaExp()1480 CommaExp *Expression::isCommaExp()
1481 {
1482 return op == TOKcomma ? (CommaExp *)this : NULL;
1483 }
1484
isIntervalExp()1485 IntervalExp *Expression::isIntervalExp()
1486 {
1487 return op == TOKinterval ? (IntervalExp *)this : NULL;
1488 }
1489
isDelegatePtrExp()1490 DelegatePtrExp *Expression::isDelegatePtrExp()
1491 {
1492 return op == TOKdelegateptr ? (DelegatePtrExp *)this : NULL;
1493 }
1494
isDelegateFuncptrExp()1495 DelegateFuncptrExp *Expression::isDelegateFuncptrExp()
1496 {
1497 return op == TOKdelegatefuncptr ? (DelegateFuncptrExp *)this : NULL;
1498 }
1499
isIndexExp()1500 IndexExp *Expression::isIndexExp()
1501 {
1502 return op == TOKindex ? (IndexExp *)this : NULL;
1503 }
1504
isPostExp()1505 PostExp *Expression::isPostExp()
1506 {
1507 return (op == TOKplusplus || op == TOKminusminus) ? (PostExp *)this : NULL;
1508 }
1509
isPreExp()1510 PreExp *Expression::isPreExp()
1511 {
1512 return (op == TOKpreplusplus || op == TOKpreminusminus) ? (PreExp *)this : NULL;
1513 }
1514
isAssignExp()1515 AssignExp *Expression::isAssignExp()
1516 {
1517 return op == TOKassign ? (AssignExp *)this : NULL;
1518 }
1519
isConstructExp()1520 ConstructExp *Expression::isConstructExp()
1521 {
1522 return op == TOKconstruct ? (ConstructExp *)this : NULL;
1523 }
1524
isBlitExp()1525 BlitExp *Expression::isBlitExp()
1526 {
1527 return op == TOKblit ? (BlitExp *)this : NULL;
1528 }
1529
isAddAssignExp()1530 AddAssignExp *Expression::isAddAssignExp()
1531 {
1532 return op == TOKaddass ? (AddAssignExp *)this : NULL;
1533 }
1534
isMinAssignExp()1535 MinAssignExp *Expression::isMinAssignExp()
1536 {
1537 return op == TOKminass ? (MinAssignExp *)this : NULL;
1538 }
1539
isMulAssignExp()1540 MulAssignExp *Expression::isMulAssignExp()
1541 {
1542 return op == TOKmulass ? (MulAssignExp *)this : NULL;
1543 }
1544
1545
isDivAssignExp()1546 DivAssignExp *Expression::isDivAssignExp()
1547 {
1548 return op == TOKdivass ? (DivAssignExp *)this : NULL;
1549 }
1550
isModAssignExp()1551 ModAssignExp *Expression::isModAssignExp()
1552 {
1553 return op == TOKmodass ? (ModAssignExp *)this : NULL;
1554 }
1555
isAndAssignExp()1556 AndAssignExp *Expression::isAndAssignExp()
1557 {
1558 return op == TOKandass ? (AndAssignExp *)this : NULL;
1559 }
1560
isOrAssignExp()1561 OrAssignExp *Expression::isOrAssignExp()
1562 {
1563 return op == TOKorass ? (OrAssignExp *)this : NULL;
1564 }
1565
isXorAssignExp()1566 XorAssignExp *Expression::isXorAssignExp()
1567 {
1568 return op == TOKxorass ? (XorAssignExp *)this : NULL;
1569 }
1570
isPowAssignExp()1571 PowAssignExp *Expression::isPowAssignExp()
1572 {
1573 return op == TOKpowass ? (PowAssignExp *)this : NULL;
1574 }
1575
1576
isShlAssignExp()1577 ShlAssignExp *Expression::isShlAssignExp()
1578 {
1579 return op == TOKshlass ? (ShlAssignExp *)this : NULL;
1580 }
1581
isShrAssignExp()1582 ShrAssignExp *Expression::isShrAssignExp()
1583 {
1584 return op == TOKshrass ? (ShrAssignExp *)this : NULL;
1585 }
1586
isUshrAssignExp()1587 UshrAssignExp *Expression::isUshrAssignExp()
1588 {
1589 return op == TOKushrass ? (UshrAssignExp *)this : NULL;
1590 }
1591
isCatAssignExp()1592 CatAssignExp *Expression::isCatAssignExp()
1593 {
1594 return op == TOKcatass ? (CatAssignExp *)this : NULL;
1595 }
1596
isAddExp()1597 AddExp *Expression::isAddExp()
1598 {
1599 return op == TOKadd ? (AddExp *)this : NULL;
1600 }
1601
isMinExp()1602 MinExp *Expression::isMinExp()
1603 {
1604 return op == TOKmin ? (MinExp *)this : NULL;
1605 }
1606
isCatExp()1607 CatExp *Expression::isCatExp()
1608 {
1609 return op == TOKcat ? (CatExp *)this : NULL;
1610 }
1611
isMulExp()1612 MulExp *Expression::isMulExp()
1613 {
1614 return op == TOKmul ? (MulExp *)this : NULL;
1615 }
1616
isDivExp()1617 DivExp *Expression::isDivExp()
1618 {
1619 return op == TOKdiv ? (DivExp *)this : NULL;
1620 }
1621
isModExp()1622 ModExp *Expression::isModExp()
1623 {
1624 return op == TOKmod ? (ModExp *)this : NULL;
1625 }
1626
isPowExp()1627 PowExp *Expression::isPowExp()
1628 {
1629 return op == TOKpow ? (PowExp *)this : NULL;
1630 }
1631
isShlExp()1632 ShlExp *Expression::isShlExp()
1633 {
1634 return op == TOKshl ? (ShlExp *)this : NULL;
1635 }
1636
isShrExp()1637 ShrExp *Expression::isShrExp()
1638 {
1639 return op == TOKshr ? (ShrExp *)this : NULL;
1640 }
1641
isUshrExp()1642 UshrExp *Expression::isUshrExp()
1643 {
1644 return op == TOKushr ? (UshrExp *)this : NULL;
1645 }
1646
isAndExp()1647 AndExp *Expression::isAndExp()
1648 {
1649 return op == TOKand ? (AndExp *)this : NULL;
1650 }
1651
isOrExp()1652 OrExp *Expression::isOrExp()
1653 {
1654 return op == TOKor ? (OrExp *)this : NULL;
1655 }
1656
isXorExp()1657 XorExp *Expression::isXorExp()
1658 {
1659 return op == TOKxor ? (XorExp *)this : NULL;
1660 }
1661
isLogicalExp()1662 LogicalExp *Expression::isLogicalExp()
1663 {
1664 return (op == TOKandand || op == TOKoror) ? (LogicalExp *)this : NULL;
1665 }
1666
isInExp()1667 InExp *Expression::isInExp()
1668 {
1669 return op == TOKin ? (InExp *)this : NULL;
1670 }
1671
isRemoveExp()1672 RemoveExp *Expression::isRemoveExp()
1673 {
1674 return op == TOKremove ? (RemoveExp *)this : NULL;
1675 }
1676
isEqualExp()1677 EqualExp *Expression::isEqualExp()
1678 {
1679 return (op == TOKequal || op == TOKnotequal) ? (EqualExp *)this : NULL;
1680 }
1681
isIdentityExp()1682 IdentityExp *Expression::isIdentityExp()
1683 {
1684 return (op == TOKidentity || op == TOKnotidentity) ? (IdentityExp *)this : NULL;
1685 }
1686
isCondExp()1687 CondExp *Expression::isCondExp()
1688 {
1689 return op == TOKquestion ? (CondExp *)this : NULL;
1690 }
1691
isDefaultInitExp()1692 DefaultInitExp *Expression::isDefaultInitExp()
1693 {
1694 return op == TOKdefault ? (DefaultInitExp *)this : NULL;
1695 }
1696
isFileInitExp()1697 FileInitExp *Expression::isFileInitExp()
1698 {
1699 return (op == TOKfile || op == TOKfilefullpath) ? (FileInitExp *)this : NULL;
1700 }
1701
isLineInitExp()1702 LineInitExp *Expression::isLineInitExp()
1703 {
1704 return op == TOKline ? (LineInitExp *)this : NULL;
1705 }
1706
isModuleInitExp()1707 ModuleInitExp *Expression::isModuleInitExp()
1708 {
1709 return op == TOKmodulestring ? (ModuleInitExp *)this : NULL;
1710 }
1711
isFuncInitExp()1712 FuncInitExp *Expression::isFuncInitExp()
1713 {
1714 return op == TOKfuncstring ? (FuncInitExp *)this : NULL;
1715 }
1716
isPrettyFuncInitExp()1717 PrettyFuncInitExp *Expression::isPrettyFuncInitExp()
1718 {
1719 return op == TOKprettyfunc ? (PrettyFuncInitExp *)this : NULL;
1720 }
1721
isClassReferenceExp()1722 ClassReferenceExp *Expression::isClassReferenceExp()
1723 {
1724 return op == TOKclassreference ? (ClassReferenceExp *)this : NULL;
1725 }
1726
1727
1728 /****************************************
1729 * Resolve __FILE__, __LINE__, __MODULE__, __FUNCTION__, __PRETTY_FUNCTION__, __FILE__FULL_PATH__ to loc.
1730 */
1731
resolveLoc(Loc,Scope *)1732 Expression *Expression::resolveLoc(Loc, Scope *)
1733 {
1734 return this;
1735 }
1736
arraySyntaxCopy(Expressions * exps)1737 Expressions *Expression::arraySyntaxCopy(Expressions *exps)
1738 {
1739 Expressions *a = NULL;
1740 if (exps)
1741 {
1742 a = new Expressions();
1743 a->setDim(exps->length);
1744 for (size_t i = 0; i < a->length; i++)
1745 {
1746 Expression *e = (*exps)[i];
1747 (*a)[i] = e ? e->syntaxCopy() : NULL;
1748 }
1749 }
1750 return a;
1751 }
1752
1753 /************************************************
1754 * Destructors are attached to VarDeclarations.
1755 * Hence, if expression returns a temp that needs a destructor,
1756 * make sure and create a VarDeclaration for that temp.
1757 */
1758
addDtorHook(Scope *)1759 Expression *Expression::addDtorHook(Scope *)
1760 {
1761 return this;
1762 }
1763
1764 /******************************** IntegerExp **************************/
1765
IntegerExp(Loc loc,dinteger_t value,Type * type)1766 IntegerExp::IntegerExp(Loc loc, dinteger_t value, Type *type)
1767 : Expression(loc, TOKint64, sizeof(IntegerExp))
1768 {
1769 //printf("IntegerExp(value = %lld, type = '%s')\n", value, type ? type->toChars() : "");
1770 assert(type);
1771 if (!type->isscalar())
1772 {
1773 //printf("%s, loc = %d\n", toChars(), loc.linnum);
1774 if (type->ty != Terror)
1775 error("integral constant must be scalar type, not %s", type->toChars());
1776 type = Type::terror;
1777 }
1778 this->type = type;
1779 setInteger(value);
1780 }
1781
IntegerExp(dinteger_t value)1782 IntegerExp::IntegerExp(dinteger_t value)
1783 : Expression(Loc(), TOKint64, sizeof(IntegerExp))
1784 {
1785 this->type = Type::tint32;
1786 this->value = (d_int32) value;
1787 }
1788
create(Loc loc,dinteger_t value,Type * type)1789 IntegerExp *IntegerExp::create(Loc loc, dinteger_t value, Type *type)
1790 {
1791 return new IntegerExp(loc, value, type);
1792 }
1793
equals(RootObject * o)1794 bool IntegerExp::equals(RootObject *o)
1795 {
1796 if (this == o)
1797 return true;
1798 if (((Expression *)o)->op == TOKint64)
1799 {
1800 IntegerExp *ne = (IntegerExp *)o;
1801 if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) &&
1802 value == ne->value)
1803 {
1804 return true;
1805 }
1806 }
1807 return false;
1808 }
1809
setInteger(dinteger_t value)1810 void IntegerExp::setInteger(dinteger_t value)
1811 {
1812 this->value = value;
1813 normalize();
1814 }
1815
normalize()1816 void IntegerExp::normalize()
1817 {
1818 /* 'Normalize' the value of the integer to be in range of the type
1819 */
1820 switch (type->toBasetype()->ty)
1821 {
1822 case Tbool: value = (value != 0); break;
1823 case Tint8: value = (d_int8) value; break;
1824 case Tchar:
1825 case Tuns8: value = (d_uns8) value; break;
1826 case Tint16: value = (d_int16) value; break;
1827 case Twchar:
1828 case Tuns16: value = (d_uns16) value; break;
1829 case Tint32: value = (d_int32) value; break;
1830 case Tdchar:
1831 case Tuns32: value = (d_uns32) value; break;
1832 case Tint64: value = (d_int64) value; break;
1833 case Tuns64: value = (d_uns64) value; break;
1834 case Tpointer:
1835 if (target.ptrsize == 8)
1836 value = (d_uns64) value;
1837 else if (target.ptrsize == 4)
1838 value = (d_uns32) value;
1839 else if (target.ptrsize == 2)
1840 value = (d_uns16) value;
1841 else
1842 assert(0);
1843 break;
1844 default:
1845 break;
1846 }
1847 }
1848
toInteger()1849 dinteger_t IntegerExp::toInteger()
1850 {
1851 normalize(); // necessary until we fix all the paints of 'type'
1852 return value;
1853 }
1854
toReal()1855 real_t IntegerExp::toReal()
1856 {
1857 normalize(); // necessary until we fix all the paints of 'type'
1858 Type *t = type->toBasetype();
1859 if (t->ty == Tuns64)
1860 return ldouble((d_uns64)value);
1861 else
1862 return ldouble((d_int64)value);
1863 }
1864
toImaginary()1865 real_t IntegerExp::toImaginary()
1866 {
1867 return CTFloat::zero;
1868 }
1869
toComplex()1870 complex_t IntegerExp::toComplex()
1871 {
1872 return (complex_t)toReal();
1873 }
1874
isBool(bool result)1875 bool IntegerExp::isBool(bool result)
1876 {
1877 bool r = toInteger() != 0;
1878 return result ? r : !r;
1879 }
1880
toLvalue(Scope *,Expression * e)1881 Expression *IntegerExp::toLvalue(Scope *, Expression *e)
1882 {
1883 if (!e)
1884 e = this;
1885 else if (!loc.filename)
1886 loc = e->loc;
1887 e->error("constant %s is not an lvalue", e->toChars());
1888 return new ErrorExp();
1889 }
1890
1891 /******************************** ErrorExp **************************/
1892
1893 /* Use this expression for error recovery.
1894 * It should behave as a 'sink' to prevent further cascaded error messages.
1895 */
1896
ErrorExp()1897 ErrorExp::ErrorExp()
1898 : Expression(Loc(), TOKerror, sizeof(ErrorExp))
1899 {
1900 type = Type::terror;
1901 }
1902
toLvalue(Scope *,Expression *)1903 Expression *ErrorExp::toLvalue(Scope *, Expression *)
1904 {
1905 return this;
1906 }
1907
1908 /******************************** RealExp **************************/
1909
RealExp(Loc loc,real_t value,Type * type)1910 RealExp::RealExp(Loc loc, real_t value, Type *type)
1911 : Expression(loc, TOKfloat64, sizeof(RealExp))
1912 {
1913 //printf("RealExp::RealExp(%Lg)\n", value);
1914 this->value = value;
1915 this->type = type;
1916 }
1917
create(Loc loc,real_t value,Type * type)1918 RealExp *RealExp::create(Loc loc, real_t value, Type *type)
1919 {
1920 return new RealExp(loc, value,type);
1921 }
1922
toInteger()1923 dinteger_t RealExp::toInteger()
1924 {
1925 return (sinteger_t) toReal();
1926 }
1927
toUInteger()1928 uinteger_t RealExp::toUInteger()
1929 {
1930 return (uinteger_t) toReal();
1931 }
1932
toReal()1933 real_t RealExp::toReal()
1934 {
1935 return type->isreal() ? value : CTFloat::zero;
1936 }
1937
toImaginary()1938 real_t RealExp::toImaginary()
1939 {
1940 return type->isreal() ? CTFloat::zero : value;
1941 }
1942
toComplex()1943 complex_t RealExp::toComplex()
1944 {
1945 return complex_t(toReal(), toImaginary());
1946 }
1947
1948 /********************************
1949 * Test to see if two reals are the same.
1950 * Regard NaN's as equivalent.
1951 * Regard +0 and -0 as different.
1952 */
1953
RealEquals(real_t x1,real_t x2)1954 int RealEquals(real_t x1, real_t x2)
1955 {
1956 return (CTFloat::isNaN(x1) && CTFloat::isNaN(x2)) ||
1957 CTFloat::isIdentical(x1, x2);
1958 }
1959
equals(RootObject * o)1960 bool RealExp::equals(RootObject *o)
1961 {
1962 if (this == o)
1963 return true;
1964 if (((Expression *)o)->op == TOKfloat64)
1965 {
1966 RealExp *ne = (RealExp *)o;
1967 if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) &&
1968 RealEquals(value, ne->value))
1969 {
1970 return true;
1971 }
1972 }
1973 return false;
1974 }
1975
isBool(bool result)1976 bool RealExp::isBool(bool result)
1977 {
1978 return result ? (bool)value : !(bool)value;
1979 }
1980
1981 /******************************** ComplexExp **************************/
1982
ComplexExp(Loc loc,complex_t value,Type * type)1983 ComplexExp::ComplexExp(Loc loc, complex_t value, Type *type)
1984 : Expression(loc, TOKcomplex80, sizeof(ComplexExp)), value(value)
1985 {
1986 this->type = type;
1987 //printf("ComplexExp::ComplexExp(%s)\n", toChars());
1988 }
1989
create(Loc loc,complex_t value,Type * type)1990 ComplexExp *ComplexExp::create(Loc loc, complex_t value, Type *type)
1991 {
1992 return new ComplexExp(loc, value, type);
1993 }
1994
toInteger()1995 dinteger_t ComplexExp::toInteger()
1996 {
1997 return (sinteger_t) toReal();
1998 }
1999
toUInteger()2000 uinteger_t ComplexExp::toUInteger()
2001 {
2002 return (uinteger_t) toReal();
2003 }
2004
toReal()2005 real_t ComplexExp::toReal()
2006 {
2007 return creall(value);
2008 }
2009
toImaginary()2010 real_t ComplexExp::toImaginary()
2011 {
2012 return cimagl(value);
2013 }
2014
toComplex()2015 complex_t ComplexExp::toComplex()
2016 {
2017 return value;
2018 }
2019
equals(RootObject * o)2020 bool ComplexExp::equals(RootObject *o)
2021 {
2022 if (this == o)
2023 return true;
2024 if (((Expression *)o)->op == TOKcomplex80)
2025 {
2026 ComplexExp *ne = (ComplexExp *)o;
2027 if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) &&
2028 RealEquals(creall(value), creall(ne->value)) &&
2029 RealEquals(cimagl(value), cimagl(ne->value)))
2030 {
2031 return true;
2032 }
2033 }
2034 return false;
2035 }
2036
isBool(bool result)2037 bool ComplexExp::isBool(bool result)
2038 {
2039 if (result)
2040 return (bool)(value);
2041 else
2042 return !value;
2043 }
2044
2045 /******************************** IdentifierExp **************************/
2046
IdentifierExp(Loc loc,Identifier * ident)2047 IdentifierExp::IdentifierExp(Loc loc, Identifier *ident)
2048 : Expression(loc, TOKidentifier, sizeof(IdentifierExp))
2049 {
2050 this->ident = ident;
2051 }
2052
create(Loc loc,Identifier * ident)2053 IdentifierExp *IdentifierExp::create(Loc loc, Identifier *ident)
2054 {
2055 return new IdentifierExp(loc, ident);
2056 }
2057
isLvalue()2058 bool IdentifierExp::isLvalue()
2059 {
2060 return true;
2061 }
2062
toLvalue(Scope *,Expression *)2063 Expression *IdentifierExp::toLvalue(Scope *, Expression *)
2064 {
2065 return this;
2066 }
2067
2068 /******************************** DollarExp **************************/
2069
DollarExp(Loc loc)2070 DollarExp::DollarExp(Loc loc)
2071 : IdentifierExp(loc, Id::dollar)
2072 {
2073 }
2074
2075 /******************************** DsymbolExp **************************/
2076
DsymbolExp(Loc loc,Dsymbol * s,bool hasOverloads)2077 DsymbolExp::DsymbolExp(Loc loc, Dsymbol *s, bool hasOverloads)
2078 : Expression(loc, TOKdsymbol, sizeof(DsymbolExp))
2079 {
2080 this->s = s;
2081 this->hasOverloads = hasOverloads;
2082 }
2083
2084 /****************************************
2085 * Resolve a symbol `s` and wraps it in an expression object.
2086 * Params:
2087 * hasOverloads = works if the aliased symbol is a function.
2088 * true: it's overloaded and will be resolved later.
2089 * false: it's exact function symbol.
2090 */
resolve(Loc loc,Scope * sc,Dsymbol * s,bool hasOverloads)2091 Expression *resolve(Loc loc, Scope *sc, Dsymbol *s, bool hasOverloads)
2092 {
2093 Lagain:
2094 Expression *e;
2095
2096 //printf("DsymbolExp:: %p '%s' is a symbol\n", this, toChars());
2097 //printf("s = '%s', s->kind = '%s'\n", s->toChars(), s->kind());
2098 Dsymbol *olds = s;
2099 Declaration *d = s->isDeclaration();
2100 if (d && (d->storage_class & STCtemplateparameter))
2101 {
2102 s = s->toAlias();
2103 }
2104 else
2105 {
2106 if (!s->isFuncDeclaration()) // functions are checked after overloading
2107 {
2108 s->checkDeprecated(loc, sc);
2109 if (d)
2110 d->checkDisabled(loc, sc);
2111 }
2112
2113 // Bugzilla 12023: if 's' is a tuple variable, the tuple is returned.
2114 s = s->toAlias();
2115
2116 //printf("s = '%s', s->kind = '%s', s->needThis() = %p\n", s->toChars(), s->kind(), s->needThis());
2117 if (s != olds && !s->isFuncDeclaration())
2118 {
2119 s->checkDeprecated(loc, sc);
2120 if (d)
2121 d->checkDisabled(loc, sc);
2122 }
2123 }
2124
2125 if (EnumMember *em = s->isEnumMember())
2126 {
2127 return em->getVarExp(loc, sc);
2128 }
2129 if (VarDeclaration *v = s->isVarDeclaration())
2130 {
2131 //printf("Identifier '%s' is a variable, type '%s'\n", toChars(), v->type->toChars());
2132 if (!v->type || // during variable type inference
2133 (!v->type->deco && v->inuse)) // during variable type semantic
2134 {
2135 if (v->inuse) // variable type depends on the variable itself
2136 ::error(loc, "circular reference to %s `%s`", v->kind(), v->toPrettyChars());
2137 else // variable type cannot be determined
2138 ::error(loc, "forward reference to %s `%s`", v->kind(), v->toPrettyChars());
2139 return new ErrorExp();
2140 }
2141 if (v->type->ty == Terror)
2142 return new ErrorExp();
2143
2144 if ((v->storage_class & STCmanifest) && v->_init)
2145 {
2146 if (v->inuse)
2147 {
2148 ::error(loc, "circular initialization of %s `%s`", v->kind(), v->toPrettyChars());
2149 return new ErrorExp();
2150 }
2151
2152 e = v->expandInitializer(loc);
2153 v->inuse++;
2154 e = expressionSemantic(e, sc);
2155 v->inuse--;
2156 return e;
2157 }
2158
2159 // Change the ancestor lambdas to delegate before hasThis(sc) call.
2160 if (v->checkNestedReference(sc, loc))
2161 return new ErrorExp();
2162
2163 if (v->needThis() && hasThis(sc))
2164 e = new DotVarExp(loc, new ThisExp(loc), v);
2165 else
2166 e = new VarExp(loc, v);
2167 e = expressionSemantic(e, sc);
2168 return e;
2169 }
2170 if (FuncLiteralDeclaration *fld = s->isFuncLiteralDeclaration())
2171 {
2172 //printf("'%s' is a function literal\n", fld->toChars());
2173 e = new FuncExp(loc, fld);
2174 return expressionSemantic(e, sc);
2175 }
2176 if (FuncDeclaration *f = s->isFuncDeclaration())
2177 {
2178 f = f->toAliasFunc();
2179 if (!f->functionSemantic())
2180 return new ErrorExp();
2181
2182 if (!hasOverloads && f->checkForwardRef(loc))
2183 return new ErrorExp();
2184
2185 FuncDeclaration *fd = s->isFuncDeclaration();
2186 fd->type = f->type;
2187 return new VarExp(loc, fd, hasOverloads);
2188 }
2189 if (OverDeclaration *od = s->isOverDeclaration())
2190 {
2191 e = new VarExp(loc, od, true);
2192 e->type = Type::tvoid;
2193 return e;
2194 }
2195 if (OverloadSet *o = s->isOverloadSet())
2196 {
2197 //printf("'%s' is an overload set\n", o->toChars());
2198 return new OverExp(loc, o);
2199 }
2200
2201 if (Import *imp = s->isImport())
2202 {
2203 if (!imp->pkg)
2204 {
2205 ::error(loc, "forward reference of import %s", imp->toChars());
2206 return new ErrorExp();
2207 }
2208 ScopeExp *ie = new ScopeExp(loc, imp->pkg);
2209 return expressionSemantic(ie, sc);
2210 }
2211 if (Package *pkg = s->isPackage())
2212 {
2213 ScopeExp *ie = new ScopeExp(loc, pkg);
2214 return expressionSemantic(ie, sc);
2215 }
2216 if (Module *mod = s->isModule())
2217 {
2218 ScopeExp *ie = new ScopeExp(loc, mod);
2219 return expressionSemantic(ie, sc);
2220 }
2221
2222 if (Nspace *ns = s->isNspace())
2223 {
2224 ScopeExp *ie = new ScopeExp(loc, ns);
2225 return expressionSemantic(ie, sc);
2226 }
2227
2228 if (Type *t = s->getType())
2229 {
2230 return expressionSemantic(new TypeExp(loc, t), sc);
2231 }
2232
2233 if (TupleDeclaration *tup = s->isTupleDeclaration())
2234 {
2235 if (tup->needThis() && hasThis(sc))
2236 e = new DotVarExp(loc, new ThisExp(loc), tup);
2237 else
2238 e = new TupleExp(loc, tup);
2239 e = expressionSemantic(e, sc);
2240 return e;
2241 }
2242
2243 if (TemplateInstance *ti = s->isTemplateInstance())
2244 {
2245 dsymbolSemantic(ti, sc);
2246 if (!ti->inst || ti->errors)
2247 return new ErrorExp();
2248 s = ti->toAlias();
2249 if (!s->isTemplateInstance())
2250 goto Lagain;
2251 e = new ScopeExp(loc, ti);
2252 e = expressionSemantic(e, sc);
2253 return e;
2254 }
2255 if (TemplateDeclaration *td = s->isTemplateDeclaration())
2256 {
2257 Dsymbol *p = td->toParent2();
2258 FuncDeclaration *fdthis = hasThis(sc);
2259 AggregateDeclaration *ad = p ? p->isAggregateDeclaration() : NULL;
2260 if (fdthis && ad && isAggregate(fdthis->vthis->type) == ad &&
2261 (td->_scope->stc & STCstatic) == 0)
2262 {
2263 e = new DotTemplateExp(loc, new ThisExp(loc), td);
2264 }
2265 else
2266 e = new TemplateExp(loc, td);
2267 e = expressionSemantic(e, sc);
2268 return e;
2269 }
2270
2271 ::error(loc, "%s `%s` is not a variable", s->kind(), s->toChars());
2272 return new ErrorExp();
2273 }
2274
isLvalue()2275 bool DsymbolExp::isLvalue()
2276 {
2277 return true;
2278 }
2279
toLvalue(Scope *,Expression *)2280 Expression *DsymbolExp::toLvalue(Scope *, Expression *)
2281 {
2282 return this;
2283 }
2284
2285 /******************************** ThisExp **************************/
2286
ThisExp(Loc loc)2287 ThisExp::ThisExp(Loc loc)
2288 : Expression(loc, TOKthis, sizeof(ThisExp))
2289 {
2290 //printf("ThisExp::ThisExp() loc = %d\n", loc.linnum);
2291 var = NULL;
2292 }
2293
isBool(bool result)2294 bool ThisExp::isBool(bool result)
2295 {
2296 return result ? true : false;
2297 }
2298
isLvalue()2299 bool ThisExp::isLvalue()
2300 {
2301 // Class `this` should be an rvalue; struct `this` should be an lvalue.
2302 return type->toBasetype()->ty != Tclass;
2303 }
2304
toLvalue(Scope * sc,Expression * e)2305 Expression *ThisExp::toLvalue(Scope *sc, Expression *e)
2306 {
2307 if (type->toBasetype()->ty == Tclass)
2308 {
2309 // Class `this` is an rvalue; struct `this` is an lvalue.
2310 return Expression::toLvalue(sc, e);
2311 }
2312 return this;
2313 }
2314
2315 /******************************** SuperExp **************************/
2316
SuperExp(Loc loc)2317 SuperExp::SuperExp(Loc loc)
2318 : ThisExp(loc)
2319 {
2320 op = TOKsuper;
2321 }
2322
2323 /******************************** NullExp **************************/
2324
NullExp(Loc loc,Type * type)2325 NullExp::NullExp(Loc loc, Type *type)
2326 : Expression(loc, TOKnull, sizeof(NullExp))
2327 {
2328 committed = 0;
2329 this->type = type;
2330 }
2331
equals(RootObject * o)2332 bool NullExp::equals(RootObject *o)
2333 {
2334 if (o && o->dyncast() == DYNCAST_EXPRESSION)
2335 {
2336 Expression *e = (Expression *)o;
2337 if (e->op == TOKnull &&
2338 type->equals(e->type))
2339 {
2340 return true;
2341 }
2342 }
2343 return false;
2344 }
2345
isBool(bool result)2346 bool NullExp::isBool(bool result)
2347 {
2348 return result ? false : true;
2349 }
2350
toStringExp()2351 StringExp *NullExp::toStringExp()
2352 {
2353 if (implicitConvTo(Type::tstring))
2354 {
2355 StringExp *se = new StringExp(loc, (char*)mem.xcalloc(1, 1), 0);
2356 se->type = Type::tstring;
2357 return se;
2358 }
2359 return NULL;
2360 }
2361
2362 /******************************** StringExp **************************/
2363
StringExp(Loc loc,char * string)2364 StringExp::StringExp(Loc loc, char *string)
2365 : Expression(loc, TOKstring, sizeof(StringExp))
2366 {
2367 this->string = string;
2368 this->len = strlen(string);
2369 this->sz = 1;
2370 this->committed = 0;
2371 this->postfix = 0;
2372 this->ownedByCtfe = OWNEDcode;
2373 }
2374
StringExp(Loc loc,void * string,size_t len)2375 StringExp::StringExp(Loc loc, void *string, size_t len)
2376 : Expression(loc, TOKstring, sizeof(StringExp))
2377 {
2378 this->string = string;
2379 this->len = len;
2380 this->sz = 1;
2381 this->committed = 0;
2382 this->postfix = 0;
2383 this->ownedByCtfe = OWNEDcode;
2384 }
2385
StringExp(Loc loc,void * string,size_t len,utf8_t postfix)2386 StringExp::StringExp(Loc loc, void *string, size_t len, utf8_t postfix)
2387 : Expression(loc, TOKstring, sizeof(StringExp))
2388 {
2389 this->string = string;
2390 this->len = len;
2391 this->sz = 1;
2392 this->committed = 0;
2393 this->postfix = postfix;
2394 this->ownedByCtfe = OWNEDcode;
2395 }
2396
create(Loc loc,char * s)2397 StringExp *StringExp::create(Loc loc, char *s)
2398 {
2399 return new StringExp(loc, s);
2400 }
2401
create(Loc loc,void * string,size_t len)2402 StringExp *StringExp::create(Loc loc, void *string, size_t len)
2403 {
2404 return new StringExp(loc, string, len);
2405 }
2406
equals(RootObject * o)2407 bool StringExp::equals(RootObject *o)
2408 {
2409 //printf("StringExp::equals('%s') %s\n", o->toChars(), toChars());
2410 if (o && o->dyncast() == DYNCAST_EXPRESSION)
2411 {
2412 Expression *e = (Expression *)o;
2413 if (e->op == TOKstring)
2414 {
2415 return compare(o) == 0;
2416 }
2417 }
2418 return false;
2419 }
2420
2421 /**********************************
2422 * Return the number of code units the string would be if it were re-encoded
2423 * as tynto.
2424 * Params:
2425 * tynto = code unit type of the target encoding
2426 * Returns:
2427 * number of code units
2428 */
2429
numberOfCodeUnits(int tynto)2430 size_t StringExp::numberOfCodeUnits(int tynto) const
2431 {
2432 int encSize;
2433 switch (tynto)
2434 {
2435 case 0: return len;
2436 case Tchar: encSize = 1; break;
2437 case Twchar: encSize = 2; break;
2438 case Tdchar: encSize = 4; break;
2439 default:
2440 assert(0);
2441 }
2442 if (sz == encSize)
2443 return len;
2444
2445 size_t result = 0;
2446 dchar_t c;
2447
2448 switch (sz)
2449 {
2450 case 1:
2451 for (size_t u = 0; u < len;)
2452 {
2453 if (const char *p = utf_decodeChar((utf8_t *)string, len, &u, &c))
2454 {
2455 error("%s", p);
2456 return 0;
2457 }
2458 result += utf_codeLength(encSize, c);
2459 }
2460 break;
2461
2462 case 2:
2463 for (size_t u = 0; u < len;)
2464 {
2465 if (const char *p = utf_decodeWchar((utf16_t *)string, len, &u, &c))
2466 {
2467 error("%s", p);
2468 return 0;
2469 }
2470 result += utf_codeLength(encSize, c);
2471 }
2472 break;
2473
2474 case 4:
2475 for (size_t u = 0; u < len;)
2476 {
2477 c = *((utf32_t *)((char *)string + u));
2478 u += 4;
2479 result += utf_codeLength(encSize, c);
2480 }
2481 break;
2482
2483 default:
2484 assert(0);
2485 }
2486 return result;
2487 }
2488
2489 /**********************************************
2490 * Write the contents of the string to dest.
2491 * Use numberOfCodeUnits() to determine size of result.
2492 * Params:
2493 * dest = destination
2494 * tyto = encoding type of the result
2495 * zero = add terminating 0
2496 */
writeTo(void * dest,bool zero,int tyto)2497 void StringExp::writeTo(void *dest, bool zero, int tyto) const
2498 {
2499 int encSize;
2500 switch (tyto)
2501 {
2502 case 0: encSize = sz; break;
2503 case Tchar: encSize = 1; break;
2504 case Twchar: encSize = 2; break;
2505 case Tdchar: encSize = 4; break;
2506 default:
2507 assert(0);
2508 }
2509 if (sz == encSize)
2510 {
2511 memcpy(dest, string, len * sz);
2512 if (zero)
2513 memset((char *)dest + len * sz, 0, sz);
2514 }
2515 else
2516 assert(0);
2517 }
2518
2519 /**************************************************
2520 * If the string data is UTF-8 and can be accessed directly,
2521 * return a pointer to it.
2522 * Do not assume a terminating 0.
2523 * Returns:
2524 * pointer to string data if possible, null if not
2525 */
toPtr()2526 char *StringExp::toPtr()
2527 {
2528 return (sz == 1) ? (char*)string : NULL;
2529 }
2530
toStringExp()2531 StringExp *StringExp::toStringExp()
2532 {
2533 return this;
2534 }
2535
2536 /****************************************
2537 * Convert string to char[].
2538 */
2539
toUTF8(Scope * sc)2540 StringExp *StringExp::toUTF8(Scope *sc)
2541 {
2542 if (sz != 1)
2543 { // Convert to UTF-8 string
2544 committed = 0;
2545 Expression *e = castTo(sc, Type::tchar->arrayOf());
2546 e = e->optimize(WANTvalue);
2547 assert(e->op == TOKstring);
2548 StringExp *se = (StringExp *)e;
2549 assert(se->sz == 1);
2550 return se;
2551 }
2552 return this;
2553 }
2554
compare(RootObject * obj)2555 int StringExp::compare(RootObject *obj)
2556 {
2557 //printf("StringExp::compare()\n");
2558 // Used to sort case statement expressions so we can do an efficient lookup
2559 StringExp *se2 = (StringExp *)(obj);
2560
2561 // This is a kludge so isExpression() in template.c will return 5
2562 // for StringExp's.
2563 if (!se2)
2564 return 5;
2565
2566 assert(se2->op == TOKstring);
2567
2568 size_t len1 = len;
2569 size_t len2 = se2->len;
2570
2571 //printf("sz = %d, len1 = %d, len2 = %d\n", sz, (int)len1, (int)len2);
2572 if (len1 == len2)
2573 {
2574 switch (sz)
2575 {
2576 case 1:
2577 return memcmp((char *)string, (char *)se2->string, len1);
2578
2579 case 2:
2580 {
2581 d_uns16 *s1 = (d_uns16 *)string;
2582 d_uns16 *s2 = (d_uns16 *)se2->string;
2583
2584 for (size_t u = 0; u < len; u++)
2585 {
2586 if (s1[u] != s2[u])
2587 return s1[u] - s2[u];
2588 }
2589 }
2590 break;
2591
2592 case 4:
2593 {
2594 d_uns32 *s1 = (d_uns32 *)string;
2595 d_uns32 *s2 = (d_uns32 *)se2->string;
2596
2597 for (size_t u = 0; u < len; u++)
2598 {
2599 if (s1[u] != s2[u])
2600 return s1[u] - s2[u];
2601 }
2602 }
2603 break;
2604
2605 default:
2606 assert(0);
2607 }
2608 }
2609 return (int)(len1 - len2);
2610 }
2611
isBool(bool result)2612 bool StringExp::isBool(bool result)
2613 {
2614 return result ? true : false;
2615 }
2616
2617
isLvalue()2618 bool StringExp::isLvalue()
2619 {
2620 /* string literal is rvalue in default, but
2621 * conversion to reference of static array is only allowed.
2622 */
2623 return (type && type->toBasetype()->ty == Tsarray);
2624 }
2625
toLvalue(Scope * sc,Expression * e)2626 Expression *StringExp::toLvalue(Scope *sc, Expression *e)
2627 {
2628 //printf("StringExp::toLvalue(%s) type = %s\n", toChars(), type ? type->toChars() : NULL);
2629 return (type && type->toBasetype()->ty == Tsarray)
2630 ? this : Expression::toLvalue(sc, e);
2631 }
2632
modifiableLvalue(Scope *,Expression *)2633 Expression *StringExp::modifiableLvalue(Scope *, Expression *)
2634 {
2635 error("cannot modify string literal %s", toChars());
2636 return new ErrorExp();
2637 }
2638
charAt(uinteger_t i)2639 unsigned StringExp::charAt(uinteger_t i) const
2640 { unsigned value;
2641
2642 switch (sz)
2643 {
2644 case 1:
2645 value = ((utf8_t *)string)[(size_t)i];
2646 break;
2647
2648 case 2:
2649 value = ((unsigned short *)string)[(size_t)i];
2650 break;
2651
2652 case 4:
2653 value = ((unsigned int *)string)[(size_t)i];
2654 break;
2655
2656 default:
2657 assert(0);
2658 break;
2659 }
2660 return value;
2661 }
2662
2663 /************************ ArrayLiteralExp ************************************/
2664
2665 // [ e1, e2, e3, ... ]
2666
ArrayLiteralExp(Loc loc,Type * type,Expressions * elements)2667 ArrayLiteralExp::ArrayLiteralExp(Loc loc, Type *type, Expressions *elements)
2668 : Expression(loc, TOKarrayliteral, sizeof(ArrayLiteralExp))
2669 {
2670 this->basis = NULL;
2671 this->type = type;
2672 this->elements = elements;
2673 this->ownedByCtfe = OWNEDcode;
2674 }
2675
ArrayLiteralExp(Loc loc,Type * type,Expression * e)2676 ArrayLiteralExp::ArrayLiteralExp(Loc loc, Type *type, Expression *e)
2677 : Expression(loc, TOKarrayliteral, sizeof(ArrayLiteralExp))
2678 {
2679 this->basis = NULL;
2680 this->type = type;
2681 elements = new Expressions;
2682 elements->push(e);
2683 this->ownedByCtfe = OWNEDcode;
2684 }
2685
ArrayLiteralExp(Loc loc,Type * type,Expression * basis,Expressions * elements)2686 ArrayLiteralExp::ArrayLiteralExp(Loc loc, Type *type, Expression *basis, Expressions *elements)
2687 : Expression(loc, TOKarrayliteral, sizeof(ArrayLiteralExp))
2688 {
2689 this->basis = basis;
2690 this->type = type;
2691 this->elements = elements;
2692 this->ownedByCtfe = OWNEDcode;
2693 }
2694
create(Loc loc,Expressions * elements)2695 ArrayLiteralExp *ArrayLiteralExp::create(Loc loc, Expressions *elements)
2696 {
2697 return new ArrayLiteralExp(loc, NULL, elements);
2698 }
2699
equals(RootObject * o)2700 bool ArrayLiteralExp::equals(RootObject *o)
2701 {
2702 if (this == o)
2703 return true;
2704 if (o && o->dyncast() == DYNCAST_EXPRESSION &&
2705 ((Expression *)o)->op == TOKarrayliteral)
2706 {
2707 ArrayLiteralExp *ae = (ArrayLiteralExp *)o;
2708 if (elements->length != ae->elements->length)
2709 return false;
2710 if (elements->length == 0 &&
2711 !type->equals(ae->type))
2712 {
2713 return false;
2714 }
2715 for (size_t i = 0; i < elements->length; i++)
2716 {
2717 Expression *e1 = (*elements)[i];
2718 Expression *e2 = (*ae->elements)[i];
2719 if (!e1)
2720 e1 = basis;
2721 if (!e2)
2722 e2 = basis;
2723 if (e1 != e2 &&
2724 (!e1 || !e2 || !e1->equals(e2)))
2725 return false;
2726 }
2727 return true;
2728 }
2729 return false;
2730 }
2731
syntaxCopy()2732 Expression *ArrayLiteralExp::syntaxCopy()
2733 {
2734 return new ArrayLiteralExp(loc,
2735 NULL,
2736 basis ? basis->syntaxCopy() : NULL,
2737 arraySyntaxCopy(elements));
2738 }
2739
getElement(size_t i)2740 Expression *ArrayLiteralExp::getElement(size_t i)
2741 {
2742 Expression *el = (*elements)[i];
2743 if (!el)
2744 el = basis;
2745 return el;
2746 }
2747
appendArrayLiteral(Expressions * elems,ArrayLiteralExp * ale)2748 static void appendArrayLiteral(Expressions *elems, ArrayLiteralExp *ale)
2749 {
2750 if (!ale->elements)
2751 return;
2752 size_t d = elems->length;
2753 elems->append(ale->elements);
2754 for (size_t i = d; i < elems->length; i++)
2755 {
2756 Expression *el = (*elems)[i];
2757 if (!el)
2758 (*elems)[i] = ale->basis;
2759 }
2760 }
2761
2762 /* Copy element `Expressions` in the parameters when they're `ArrayLiteralExp`s.
2763 * Params:
2764 * e1 = If it's ArrayLiteralExp, its `elements` will be copied.
2765 * Otherwise, `e1` itself will be pushed into the new `Expressions`.
2766 * e2 = If it's not `null`, it will be pushed/appended to the new
2767 * `Expressions` by the same way with `e1`.
2768 * Returns:
2769 * Newly allocated `Expressions`. Note that it points to the original
2770 * `Expression` values in e1 and e2.
2771 */
copyElements(Expression * e1,Expression * e2)2772 Expressions* ArrayLiteralExp::copyElements(Expression *e1, Expression *e2)
2773 {
2774 Expressions *elems = new Expressions();
2775
2776 if (e1->op == TOKarrayliteral)
2777 appendArrayLiteral(elems, (ArrayLiteralExp *)e1);
2778 else
2779 elems->push(e1);
2780
2781 if (e2)
2782 {
2783 if (e2->op == TOKarrayliteral)
2784 appendArrayLiteral(elems, (ArrayLiteralExp *)e2);
2785 else
2786 elems->push(e2);
2787 }
2788
2789 return elems;
2790 }
2791
isBool(bool result)2792 bool ArrayLiteralExp::isBool(bool result)
2793 {
2794 size_t dim = elements ? elements->length : 0;
2795 return result ? (dim != 0) : (dim == 0);
2796 }
2797
toStringExp()2798 StringExp *ArrayLiteralExp::toStringExp()
2799 {
2800 TY telem = type->nextOf()->toBasetype()->ty;
2801
2802 if (telem == Tchar || telem == Twchar || telem == Tdchar ||
2803 (telem == Tvoid && (!elements || elements->length == 0)))
2804 {
2805 unsigned char sz = 1;
2806 if (telem == Twchar) sz = 2;
2807 else if (telem == Tdchar) sz = 4;
2808
2809 OutBuffer buf;
2810 if (elements)
2811 {
2812 for (size_t i = 0; i < elements->length; ++i)
2813 {
2814 Expression *ch = getElement(i);
2815 if (ch->op != TOKint64)
2816 return NULL;
2817 if (sz == 1)
2818 buf.writeByte((unsigned)ch->toInteger());
2819 else if (sz == 2)
2820 buf.writeword((unsigned)ch->toInteger());
2821 else
2822 buf.write4((unsigned)ch->toInteger());
2823 }
2824 }
2825 char prefix;
2826 if (sz == 1) { prefix = 'c'; buf.writeByte(0); }
2827 else if (sz == 2) { prefix = 'w'; buf.writeword(0); }
2828 else { prefix = 'd'; buf.write4(0); }
2829
2830 const size_t len = buf.length() / sz - 1;
2831 StringExp *se = new StringExp(loc, buf.extractData(), len, prefix);
2832 se->sz = sz;
2833 se->type = type;
2834 return se;
2835 }
2836 return NULL;
2837 }
2838
2839 /************************ AssocArrayLiteralExp ************************************/
2840
2841 // [ key0 : value0, key1 : value1, ... ]
2842
AssocArrayLiteralExp(Loc loc,Expressions * keys,Expressions * values)2843 AssocArrayLiteralExp::AssocArrayLiteralExp(Loc loc,
2844 Expressions *keys, Expressions *values)
2845 : Expression(loc, TOKassocarrayliteral, sizeof(AssocArrayLiteralExp))
2846 {
2847 assert(keys->length == values->length);
2848 this->keys = keys;
2849 this->values = values;
2850 this->ownedByCtfe = OWNEDcode;
2851 }
2852
equals(RootObject * o)2853 bool AssocArrayLiteralExp::equals(RootObject *o)
2854 {
2855 if (this == o)
2856 return true;
2857 if (o && o->dyncast() == DYNCAST_EXPRESSION &&
2858 ((Expression *)o)->op == TOKassocarrayliteral)
2859 {
2860 AssocArrayLiteralExp *ae = (AssocArrayLiteralExp *)o;
2861 if (keys->length != ae->keys->length)
2862 return false;
2863 size_t count = 0;
2864 for (size_t i = 0; i < keys->length; i++)
2865 {
2866 for (size_t j = 0; j < ae->keys->length; j++)
2867 {
2868 if ((*keys)[i]->equals((*ae->keys)[j]))
2869 {
2870 if (!(*values)[i]->equals((*ae->values)[j]))
2871 return false;
2872 ++count;
2873 }
2874 }
2875 }
2876 return count == keys->length;
2877 }
2878 return false;
2879 }
2880
syntaxCopy()2881 Expression *AssocArrayLiteralExp::syntaxCopy()
2882 {
2883 return new AssocArrayLiteralExp(loc,
2884 arraySyntaxCopy(keys), arraySyntaxCopy(values));
2885 }
2886
isBool(bool result)2887 bool AssocArrayLiteralExp::isBool(bool result)
2888 {
2889 size_t dim = keys->length;
2890 return result ? (dim != 0) : (dim == 0);
2891 }
2892
2893 /************************ StructLiteralExp ************************************/
2894
2895 // sd( e1, e2, e3, ... )
2896
StructLiteralExp(Loc loc,StructDeclaration * sd,Expressions * elements,Type * stype)2897 StructLiteralExp::StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions *elements, Type *stype)
2898 : Expression(loc, TOKstructliteral, sizeof(StructLiteralExp))
2899 {
2900 this->sd = sd;
2901 if (!elements)
2902 elements = new Expressions();
2903 this->elements = elements;
2904 this->stype = stype;
2905 this->useStaticInit = false;
2906 this->sym = NULL;
2907 this->ownedByCtfe = OWNEDcode;
2908 this->origin = this;
2909 this->stageflags = 0;
2910 this->inlinecopy = NULL;
2911 //printf("StructLiteralExp::StructLiteralExp(%s)\n", toChars());
2912 }
2913
create(Loc loc,StructDeclaration * sd,void * elements,Type * stype)2914 StructLiteralExp *StructLiteralExp::create(Loc loc, StructDeclaration *sd, void *elements, Type *stype)
2915 {
2916 return new StructLiteralExp(loc, sd, (Expressions *)elements, stype);
2917 }
2918
equals(RootObject * o)2919 bool StructLiteralExp::equals(RootObject *o)
2920 {
2921 if (this == o)
2922 return true;
2923 if (o && o->dyncast() == DYNCAST_EXPRESSION &&
2924 ((Expression *)o)->op == TOKstructliteral)
2925 {
2926 StructLiteralExp *se = (StructLiteralExp *)o;
2927 if (!type->equals(se->type))
2928 return false;
2929 if (elements->length != se->elements->length)
2930 return false;
2931 for (size_t i = 0; i < elements->length; i++)
2932 {
2933 Expression *e1 = (*elements)[i];
2934 Expression *e2 = (*se->elements)[i];
2935 if (e1 != e2 &&
2936 (!e1 || !e2 || !e1->equals(e2)))
2937 return false;
2938 }
2939 return true;
2940 }
2941 return false;
2942 }
2943
syntaxCopy()2944 Expression *StructLiteralExp::syntaxCopy()
2945 {
2946 StructLiteralExp *exp = new StructLiteralExp(loc, sd, arraySyntaxCopy(elements), type ? type : stype);
2947 exp->origin = this;
2948 return exp;
2949 }
2950
addDtorHook(Scope * sc)2951 Expression *StructLiteralExp::addDtorHook(Scope *sc)
2952 {
2953 /* If struct requires a destructor, rewrite as:
2954 * (S tmp = S()),tmp
2955 * so that the destructor can be hung on tmp.
2956 */
2957 if (sd->dtor && sc->func)
2958 {
2959 /* Make an identifier for the temporary of the form:
2960 * __sl%s%d, where %s is the struct name
2961 */
2962 const size_t len = 10;
2963 char buf[len + 1];
2964 buf[len] = 0;
2965 strcpy(buf, "__sl");
2966 strncat(buf, sd->ident->toChars(), len - 4 - 1);
2967 assert(buf[len] == 0);
2968
2969 VarDeclaration *tmp = copyToTemp(0, buf, this);
2970 Expression *ae = new DeclarationExp(loc, tmp);
2971 Expression *e = new CommaExp(loc, ae, new VarExp(loc, tmp));
2972 e = expressionSemantic(e, sc);
2973 return e;
2974 }
2975 return this;
2976 }
2977
2978 /**************************************
2979 * Gets expression at offset of type.
2980 * Returns NULL if not found.
2981 */
2982
getField(Type * type,unsigned offset)2983 Expression *StructLiteralExp::getField(Type *type, unsigned offset)
2984 {
2985 //printf("StructLiteralExp::getField(this = %s, type = %s, offset = %u)\n",
2986 // /*toChars()*/"", type->toChars(), offset);
2987 Expression *e = NULL;
2988 int i = getFieldIndex(type, offset);
2989
2990 if (i != -1)
2991 {
2992 //printf("\ti = %d\n", i);
2993 if (i == (int)sd->fields.length - 1 && sd->isNested())
2994 return NULL;
2995
2996 assert(i < (int)elements->length);
2997 e = (*elements)[i];
2998 if (e)
2999 {
3000 //printf("e = %s, e->type = %s\n", e->toChars(), e->type->toChars());
3001
3002 /* If type is a static array, and e is an initializer for that array,
3003 * then the field initializer should be an array literal of e.
3004 */
3005 if (e->type->castMod(0) != type->castMod(0) && type->ty == Tsarray)
3006 { TypeSArray *tsa = (TypeSArray *)type;
3007 size_t length = (size_t)tsa->dim->toInteger();
3008 Expressions *z = new Expressions;
3009 z->setDim(length);
3010 for (size_t q = 0; q < length; ++q)
3011 (*z)[q] = e->copy();
3012 e = new ArrayLiteralExp(loc, type, z);
3013 }
3014 else
3015 {
3016 e = e->copy();
3017 e->type = type;
3018 }
3019 if (useStaticInit && e->op == TOKstructliteral &&
3020 e->type->needsNested())
3021 {
3022 StructLiteralExp *se = (StructLiteralExp *)e;
3023 se->useStaticInit = true;
3024 }
3025 }
3026 }
3027 return e;
3028 }
3029
3030 /************************************
3031 * Get index of field.
3032 * Returns -1 if not found.
3033 */
3034
getFieldIndex(Type * type,unsigned offset)3035 int StructLiteralExp::getFieldIndex(Type *type, unsigned offset)
3036 {
3037 /* Find which field offset is by looking at the field offsets
3038 */
3039 if (elements->length)
3040 {
3041 for (size_t i = 0; i < sd->fields.length; i++)
3042 {
3043 VarDeclaration *v = sd->fields[i];
3044
3045 if (offset == v->offset &&
3046 type->size() == v->type->size())
3047 {
3048 /* context field might not be filled. */
3049 if (i == sd->fields.length - 1 && sd->isNested())
3050 return (int)i;
3051 Expression *e = (*elements)[i];
3052 if (e)
3053 {
3054 return (int)i;
3055 }
3056 break;
3057 }
3058 }
3059 }
3060 return -1;
3061 }
3062
3063 /************************ TypeDotIdExp ************************************/
3064
3065 /* Things like:
3066 * int.size
3067 * foo.size
3068 * (foo).size
3069 * cast(foo).size
3070 */
3071
typeDotIdExp(Loc loc,Type * type,Identifier * ident)3072 DotIdExp *typeDotIdExp(Loc loc, Type *type, Identifier *ident)
3073 {
3074 return new DotIdExp(loc, new TypeExp(loc, type), ident);
3075 }
3076
3077
3078 /************************************************************/
3079
3080 // Mainly just a placeholder
3081
TypeExp(Loc loc,Type * type)3082 TypeExp::TypeExp(Loc loc, Type *type)
3083 : Expression(loc, TOKtype, sizeof(TypeExp))
3084 {
3085 //printf("TypeExp::TypeExp(%s)\n", type->toChars());
3086 this->type = type;
3087 }
3088
syntaxCopy()3089 Expression *TypeExp::syntaxCopy()
3090 {
3091 return new TypeExp(loc, type->syntaxCopy());
3092 }
3093
checkType()3094 bool TypeExp::checkType()
3095 {
3096 error("type %s is not an expression", toChars());
3097 return true;
3098 }
3099
checkValue()3100 bool TypeExp::checkValue()
3101 {
3102 error("type %s has no value", toChars());
3103 return true;
3104 }
3105
3106 /************************************************************/
3107
3108 /***********************************************************
3109 * Mainly just a placeholder of
3110 * Package, Module, Nspace, and TemplateInstance (including TemplateMixin)
3111 *
3112 * A template instance that requires IFTI:
3113 * foo!tiargs(fargs) // foo!tiargs
3114 * is left until CallExp::semantic() or resolveProperties()
3115 */
ScopeExp(Loc loc,ScopeDsymbol * sds)3116 ScopeExp::ScopeExp(Loc loc, ScopeDsymbol *sds)
3117 : Expression(loc, TOKscope, sizeof(ScopeExp))
3118 {
3119 //printf("ScopeExp::ScopeExp(sds = '%s')\n", sds->toChars());
3120 //static int count; if (++count == 38) *(char*)0=0;
3121 this->sds = sds;
3122 assert(!sds->isTemplateDeclaration()); // instead, you should use TemplateExp
3123 }
3124
syntaxCopy()3125 Expression *ScopeExp::syntaxCopy()
3126 {
3127 return new ScopeExp(loc, (ScopeDsymbol *)sds->syntaxCopy(NULL));
3128 }
3129
checkType()3130 bool ScopeExp::checkType()
3131 {
3132 if (sds->isPackage())
3133 {
3134 error("%s %s has no type", sds->kind(), sds->toChars());
3135 return true;
3136 }
3137 if (TemplateInstance *ti = sds->isTemplateInstance())
3138 {
3139 //assert(ti->needsTypeInference(sc));
3140 if (ti->tempdecl &&
3141 ti->semantictiargsdone &&
3142 ti->semanticRun == PASSinit)
3143 {
3144 error("partial %s %s has no type", sds->kind(), toChars());
3145 return true;
3146 }
3147 }
3148 return false;
3149 }
3150
checkValue()3151 bool ScopeExp::checkValue()
3152 {
3153 error("%s %s has no value", sds->kind(), sds->toChars());
3154 return true;
3155 }
3156
3157 /********************** TemplateExp **************************************/
3158
3159 // Mainly just a placeholder
3160
TemplateExp(Loc loc,TemplateDeclaration * td,FuncDeclaration * fd)3161 TemplateExp::TemplateExp(Loc loc, TemplateDeclaration *td, FuncDeclaration *fd)
3162 : Expression(loc, TOKtemplate, sizeof(TemplateExp))
3163 {
3164 //printf("TemplateExp(): %s\n", td->toChars());
3165 this->td = td;
3166 this->fd = fd;
3167 }
3168
checkType()3169 bool TemplateExp::checkType()
3170 {
3171 error("%s %s has no type", td->kind(), toChars());
3172 return true;
3173 }
3174
checkValue()3175 bool TemplateExp::checkValue()
3176 {
3177 error("%s %s has no value", td->kind(), toChars());
3178 return true;
3179 }
3180
isLvalue()3181 bool TemplateExp::isLvalue()
3182 {
3183 return fd != NULL;
3184 }
3185
toLvalue(Scope * sc,Expression * e)3186 Expression *TemplateExp::toLvalue(Scope *sc, Expression *e)
3187 {
3188 if (!fd)
3189 return Expression::toLvalue(sc, e);
3190
3191 assert(sc);
3192 return resolve(loc, sc, fd, true);
3193 }
3194
3195 /********************** NewExp **************************************/
3196
3197 /* thisexp.new(newargs) newtype(arguments) */
3198
NewExp(Loc loc,Expression * thisexp,Expressions * newargs,Type * newtype,Expressions * arguments)3199 NewExp::NewExp(Loc loc, Expression *thisexp, Expressions *newargs,
3200 Type *newtype, Expressions *arguments)
3201 : Expression(loc, TOKnew, sizeof(NewExp))
3202 {
3203 this->thisexp = thisexp;
3204 this->newargs = newargs;
3205 this->newtype = newtype;
3206 this->arguments = arguments;
3207 argprefix = NULL;
3208 member = NULL;
3209 allocator = NULL;
3210 onstack = 0;
3211 }
3212
create(Loc loc,Expression * thisexp,Expressions * newargs,Type * newtype,Expressions * arguments)3213 NewExp *NewExp::create(Loc loc, Expression *thisexp, Expressions *newargs,
3214 Type *newtype, Expressions *arguments)
3215 {
3216 return new NewExp(loc, thisexp, newargs, newtype, arguments);
3217 }
3218
syntaxCopy()3219 Expression *NewExp::syntaxCopy()
3220 {
3221 return new NewExp(loc,
3222 thisexp ? thisexp->syntaxCopy() : NULL,
3223 arraySyntaxCopy(newargs),
3224 newtype->syntaxCopy(), arraySyntaxCopy(arguments));
3225 }
3226
3227 /********************** NewAnonClassExp **************************************/
3228
NewAnonClassExp(Loc loc,Expression * thisexp,Expressions * newargs,ClassDeclaration * cd,Expressions * arguments)3229 NewAnonClassExp::NewAnonClassExp(Loc loc, Expression *thisexp,
3230 Expressions *newargs, ClassDeclaration *cd, Expressions *arguments)
3231 : Expression(loc, TOKnewanonclass, sizeof(NewAnonClassExp))
3232 {
3233 this->thisexp = thisexp;
3234 this->newargs = newargs;
3235 this->cd = cd;
3236 this->arguments = arguments;
3237 }
3238
syntaxCopy()3239 Expression *NewAnonClassExp::syntaxCopy()
3240 {
3241 return new NewAnonClassExp(loc,
3242 thisexp ? thisexp->syntaxCopy() : NULL,
3243 arraySyntaxCopy(newargs),
3244 (ClassDeclaration *)cd->syntaxCopy(NULL),
3245 arraySyntaxCopy(arguments));
3246 }
3247
3248 /********************** SymbolExp **************************************/
3249
SymbolExp(Loc loc,TOK op,int size,Declaration * var,bool hasOverloads)3250 SymbolExp::SymbolExp(Loc loc, TOK op, int size, Declaration *var, bool hasOverloads)
3251 : Expression(loc, op, size)
3252 {
3253 assert(var);
3254 this->var = var;
3255 this->hasOverloads = hasOverloads;
3256 }
3257
3258 /********************** SymOffExp **************************************/
3259
SymOffExp(Loc loc,Declaration * var,dinteger_t offset,bool hasOverloads)3260 SymOffExp::SymOffExp(Loc loc, Declaration *var, dinteger_t offset, bool hasOverloads)
3261 : SymbolExp(loc, TOKsymoff, sizeof(SymOffExp), var,
3262 var->isVarDeclaration() ? false : hasOverloads)
3263 {
3264 if (VarDeclaration *v = var->isVarDeclaration())
3265 {
3266 // FIXME: This error report will never be handled anyone.
3267 // It should be done before the SymOffExp construction.
3268 if (v->needThis())
3269 ::error(loc, "need `this` for address of %s", v->toChars());
3270 }
3271 this->offset = offset;
3272 }
3273
isBool(bool result)3274 bool SymOffExp::isBool(bool result)
3275 {
3276 return result ? true : false;
3277 }
3278
3279 /******************************** VarExp **************************/
3280
VarExp(Loc loc,Declaration * var,bool hasOverloads)3281 VarExp::VarExp(Loc loc, Declaration *var, bool hasOverloads)
3282 : SymbolExp(loc, TOKvar, sizeof(VarExp), var,
3283 var->isVarDeclaration() ? false : hasOverloads)
3284 {
3285 //printf("VarExp(this = %p, '%s', loc = %s)\n", this, var->toChars(), loc.toChars());
3286 //if (strcmp(var->ident->toChars(), "func") == 0) halt();
3287 this->type = var->type;
3288 }
3289
create(Loc loc,Declaration * var,bool hasOverloads)3290 VarExp *VarExp::create(Loc loc, Declaration *var, bool hasOverloads)
3291 {
3292 return new VarExp(loc, var, hasOverloads);
3293 }
3294
equals(RootObject * o)3295 bool VarExp::equals(RootObject *o)
3296 {
3297 if (this == o)
3298 return true;
3299 if (((Expression *)o)->op == TOKvar)
3300 {
3301 VarExp *ne = (VarExp *)o;
3302 if (type->toHeadMutable()->equals(ne->type->toHeadMutable()) &&
3303 var == ne->var)
3304 {
3305 return true;
3306 }
3307 }
3308 return false;
3309 }
3310
isLvalue()3311 bool VarExp::isLvalue()
3312 {
3313 if (var->storage_class & (STClazy | STCrvalue | STCmanifest))
3314 return false;
3315 return true;
3316 }
3317
toLvalue(Scope *,Expression *)3318 Expression *VarExp::toLvalue(Scope *, Expression *)
3319 {
3320 if (var->storage_class & STCmanifest)
3321 {
3322 error("manifest constant `%s` is not lvalue", var->toChars());
3323 return new ErrorExp();
3324 }
3325 if (var->storage_class & STClazy)
3326 {
3327 error("lazy variables cannot be lvalues");
3328 return new ErrorExp();
3329 }
3330 if (var->ident == Id::ctfe)
3331 {
3332 error("compiler-generated variable __ctfe is not an lvalue");
3333 return new ErrorExp();
3334 }
3335 if (var->ident == Id::dollar) // Bugzilla 13574
3336 {
3337 error("`$` is not an lvalue");
3338 return new ErrorExp();
3339 }
3340 return this;
3341 }
3342
checkModifiable(Scope * sc,int flag)3343 int VarExp::checkModifiable(Scope *sc, int flag)
3344 {
3345 //printf("VarExp::checkModifiable %s", toChars());
3346 assert(type);
3347 return var->checkModify(loc, sc, type, NULL, flag);
3348 }
3349
modifiableLvalue(Scope * sc,Expression * e)3350 Expression *VarExp::modifiableLvalue(Scope *sc, Expression *e)
3351 {
3352 //printf("VarExp::modifiableLvalue('%s')\n", var->toChars());
3353 if (var->storage_class & STCmanifest)
3354 {
3355 error("cannot modify manifest constant `%s`", toChars());
3356 return new ErrorExp();
3357 }
3358 // See if this expression is a modifiable lvalue (i.e. not const)
3359 return Expression::modifiableLvalue(sc, e);
3360 }
3361
3362
3363 /******************************** OverExp **************************/
3364
OverExp(Loc loc,OverloadSet * s)3365 OverExp::OverExp(Loc loc, OverloadSet *s)
3366 : Expression(loc, TOKoverloadset, sizeof(OverExp))
3367 {
3368 //printf("OverExp(this = %p, '%s')\n", this, var->toChars());
3369 vars = s;
3370 type = Type::tvoid;
3371 }
3372
isLvalue()3373 bool OverExp::isLvalue()
3374 {
3375 return true;
3376 }
3377
toLvalue(Scope *,Expression *)3378 Expression *OverExp::toLvalue(Scope *, Expression *)
3379 {
3380 return this;
3381 }
3382
3383 /******************************** TupleExp **************************/
3384
TupleExp(Loc loc,Expression * e0,Expressions * exps)3385 TupleExp::TupleExp(Loc loc, Expression *e0, Expressions *exps)
3386 : Expression(loc, TOKtuple, sizeof(TupleExp))
3387 {
3388 //printf("TupleExp(this = %p)\n", this);
3389 this->e0 = e0;
3390 this->exps = exps;
3391 }
3392
TupleExp(Loc loc,Expressions * exps)3393 TupleExp::TupleExp(Loc loc, Expressions *exps)
3394 : Expression(loc, TOKtuple, sizeof(TupleExp))
3395 {
3396 //printf("TupleExp(this = %p)\n", this);
3397 this->e0 = NULL;
3398 this->exps = exps;
3399 }
3400
TupleExp(Loc loc,TupleDeclaration * tup)3401 TupleExp::TupleExp(Loc loc, TupleDeclaration *tup)
3402 : Expression(loc, TOKtuple, sizeof(TupleExp))
3403 {
3404 this->e0 = NULL;
3405 this->exps = new Expressions();
3406
3407 this->exps->reserve(tup->objects->length);
3408 for (size_t i = 0; i < tup->objects->length; i++)
3409 { RootObject *o = (*tup->objects)[i];
3410 if (Dsymbol *s = getDsymbol(o))
3411 {
3412 /* If tuple element represents a symbol, translate to DsymbolExp
3413 * to supply implicit 'this' if needed later.
3414 */
3415 Expression *e = new DsymbolExp(loc, s);
3416 this->exps->push(e);
3417 }
3418 else if (o->dyncast() == DYNCAST_EXPRESSION)
3419 {
3420 Expression *e = ((Expression *)o)->copy();
3421 e->loc = loc; // Bugzilla 15669
3422 this->exps->push(e);
3423 }
3424 else if (o->dyncast() == DYNCAST_TYPE)
3425 {
3426 Type *t = (Type *)o;
3427 Expression *e = new TypeExp(loc, t);
3428 this->exps->push(e);
3429 }
3430 else
3431 {
3432 error("%s is not an expression", o->toChars());
3433 }
3434 }
3435 }
3436
equals(RootObject * o)3437 bool TupleExp::equals(RootObject *o)
3438 {
3439 if (this == o)
3440 return true;
3441 if (((Expression *)o)->op == TOKtuple)
3442 {
3443 TupleExp *te = (TupleExp *)o;
3444 if (exps->length != te->exps->length)
3445 return false;
3446 if ((e0 && !e0->equals(te->e0)) || (!e0 && te->e0))
3447 return false;
3448 for (size_t i = 0; i < exps->length; i++)
3449 {
3450 Expression *e1 = (*exps)[i];
3451 Expression *e2 = (*te->exps)[i];
3452 if (!e1->equals(e2))
3453 return false;
3454 }
3455 return true;
3456 }
3457 return false;
3458 }
3459
syntaxCopy()3460 Expression *TupleExp::syntaxCopy()
3461 {
3462 return new TupleExp(loc, e0 ? e0->syntaxCopy() : NULL, arraySyntaxCopy(exps));
3463 }
3464
toTupleExp()3465 TupleExp *TupleExp::toTupleExp()
3466 {
3467 return this;
3468 }
3469
3470 /******************************** FuncExp *********************************/
3471
FuncExp(Loc loc,Dsymbol * s)3472 FuncExp::FuncExp(Loc loc, Dsymbol *s)
3473 : Expression(loc, TOKfunction, sizeof(FuncExp))
3474 {
3475 this->td = s->isTemplateDeclaration();
3476 this->fd = s->isFuncLiteralDeclaration();
3477 if (td)
3478 {
3479 assert(td->literal);
3480 assert(td->members && td->members->length == 1);
3481 fd = (*td->members)[0]->isFuncLiteralDeclaration();
3482 }
3483 tok = fd->tok; // save original kind of function/delegate/(infer)
3484 assert(fd->fbody);
3485 }
3486
equals(RootObject * o)3487 bool FuncExp::equals(RootObject *o)
3488 {
3489 if (this == o)
3490 return true;
3491 if (o->dyncast() != DYNCAST_EXPRESSION)
3492 return false;
3493 if (((Expression *)o)->op == TOKfunction)
3494 {
3495 FuncExp *fe = (FuncExp *)o;
3496 return fd == fe->fd;
3497 }
3498 return false;
3499 }
3500
genIdent(Scope * sc)3501 void FuncExp::genIdent(Scope *sc)
3502 {
3503 if (fd->ident == Id::empty)
3504 {
3505 const char *s;
3506 if (fd->fes) s = "__foreachbody";
3507 else if (fd->tok == TOKreserved) s = "__lambda";
3508 else if (fd->tok == TOKdelegate) s = "__dgliteral";
3509 else s = "__funcliteral";
3510
3511 DsymbolTable *symtab;
3512 if (FuncDeclaration *func = sc->parent->isFuncDeclaration())
3513 {
3514 if (func->localsymtab == NULL)
3515 {
3516 // Inside template constraint, symtab is not set yet.
3517 // Initialize it lazily.
3518 func->localsymtab = new DsymbolTable();
3519 }
3520 symtab = func->localsymtab;
3521 }
3522 else
3523 {
3524 ScopeDsymbol *sds = sc->parent->isScopeDsymbol();
3525 if (!sds->symtab)
3526 {
3527 // Inside template constraint, symtab may not be set yet.
3528 // Initialize it lazily.
3529 assert(sds->isTemplateInstance());
3530 sds->symtab = new DsymbolTable();
3531 }
3532 symtab = sds->symtab;
3533 }
3534 assert(symtab);
3535 int num = (int)dmd_aaLen(symtab->tab) + 1;
3536 Identifier *id = Identifier::generateId(s, num);
3537 fd->ident = id;
3538 if (td) td->ident = id;
3539 symtab->insert(td ? (Dsymbol *)td : (Dsymbol *)fd);
3540 }
3541 }
3542
syntaxCopy()3543 Expression *FuncExp::syntaxCopy()
3544 {
3545 if (td)
3546 return new FuncExp(loc, td->syntaxCopy(NULL));
3547 else if (fd->semanticRun == PASSinit)
3548 return new FuncExp(loc, fd->syntaxCopy(NULL));
3549 else // Bugzilla 13481: Prevent multiple semantic analysis of lambda body.
3550 return new FuncExp(loc, fd);
3551 }
3552
matchType(Type * to,Scope * sc,FuncExp ** presult,int flag)3553 MATCH FuncExp::matchType(Type *to, Scope *sc, FuncExp **presult, int flag)
3554 {
3555 //printf("FuncExp::matchType('%s'), to=%s\n", type ? type->toChars() : "null", to->toChars());
3556 if (presult)
3557 *presult = NULL;
3558
3559 TypeFunction *tof = NULL;
3560 if (to->ty == Tdelegate)
3561 {
3562 if (tok == TOKfunction)
3563 {
3564 if (!flag)
3565 error("cannot match function literal to delegate type `%s`", to->toChars());
3566 return MATCHnomatch;
3567 }
3568 tof = (TypeFunction *)to->nextOf();
3569 }
3570 else if (to->ty == Tpointer && to->nextOf()->ty == Tfunction)
3571 {
3572 if (tok == TOKdelegate)
3573 {
3574 if (!flag)
3575 error("cannot match delegate literal to function pointer type `%s`", to->toChars());
3576 return MATCHnomatch;
3577 }
3578 tof = (TypeFunction *)to->nextOf();
3579 }
3580
3581 if (td)
3582 {
3583 if (!tof)
3584 {
3585 L1:
3586 if (!flag)
3587 error("cannot infer parameter types from %s", to->toChars());
3588 return MATCHnomatch;
3589 }
3590
3591 // Parameter types inference from 'tof'
3592 assert(td->_scope);
3593 TypeFunction *tf = (TypeFunction *)fd->type;
3594 //printf("\ttof = %s\n", tof->toChars());
3595 //printf("\ttf = %s\n", tf->toChars());
3596 size_t dim = tf->parameterList.length();
3597
3598 if (tof->parameterList.length() != dim ||
3599 tof->parameterList.varargs != tf->parameterList.varargs)
3600 goto L1;
3601
3602 Objects *tiargs = new Objects();
3603 tiargs->reserve(td->parameters->length);
3604
3605 for (size_t i = 0; i < td->parameters->length; i++)
3606 {
3607 TemplateParameter *tp = (*td->parameters)[i];
3608 size_t u = 0;
3609 for (; u < dim; u++)
3610 {
3611 Parameter *p = tf->parameterList[u];
3612 if (p->type->ty == Tident &&
3613 ((TypeIdentifier *)p->type)->ident == tp->ident)
3614 {
3615 break;
3616 }
3617 }
3618 assert(u < dim);
3619 Parameter *pto = tof->parameterList[u];
3620 Type *t = pto->type;
3621 if (t->ty == Terror)
3622 goto L1;
3623 tiargs->push(t);
3624 }
3625
3626 // Set target of return type inference
3627 if (!tf->next && tof->next)
3628 fd->treq = to;
3629
3630 TemplateInstance *ti = new TemplateInstance(loc, td, tiargs);
3631 Expression *ex = new ScopeExp(loc, ti);
3632 ex = expressionSemantic(ex, td->_scope);
3633
3634 // Reset inference target for the later re-semantic
3635 fd->treq = NULL;
3636
3637 if (ex->op == TOKerror)
3638 return MATCHnomatch;
3639 if (ex->op != TOKfunction)
3640 goto L1;
3641 return ((FuncExp *)ex)->matchType(to, sc, presult, flag);
3642 }
3643
3644 if (!tof || !tof->next)
3645 return MATCHnomatch;
3646
3647 assert(type && type != Type::tvoid);
3648 TypeFunction *tfx = (TypeFunction *)fd->type;
3649 bool convertMatch = (type->ty != to->ty);
3650
3651 if (fd->inferRetType && tfx->next->implicitConvTo(tof->next) == MATCHconvert)
3652 {
3653 /* If return type is inferred and covariant return,
3654 * tweak return statements to required return type.
3655 *
3656 * interface I {}
3657 * class C : Object, I{}
3658 *
3659 * I delegate() dg = delegate() { return new class C(); }
3660 */
3661 convertMatch = true;
3662
3663 TypeFunction *tfy = new TypeFunction(tfx->parameterList, tof->next, tfx->linkage, STCundefined);
3664 tfy->mod = tfx->mod;
3665 tfy->isnothrow = tfx->isnothrow;
3666 tfy->isnogc = tfx->isnogc;
3667 tfy->purity = tfx->purity;
3668 tfy->isproperty = tfx->isproperty;
3669 tfy->isref = tfx->isref;
3670 tfy->iswild = tfx->iswild;
3671 tfy->deco = tfy->merge()->deco;
3672
3673 tfx = tfy;
3674 }
3675
3676 Type *tx;
3677 if (tok == TOKdelegate ||
3678 (tok == TOKreserved && (type->ty == Tdelegate ||
3679 (type->ty == Tpointer && to->ty == Tdelegate))))
3680 {
3681 // Allow conversion from implicit function pointer to delegate
3682 tx = new TypeDelegate(tfx);
3683 tx->deco = tx->merge()->deco;
3684 }
3685 else
3686 {
3687 assert(tok == TOKfunction ||
3688 (tok == TOKreserved && type->ty == Tpointer));
3689 tx = tfx->pointerTo();
3690 }
3691 //printf("\ttx = %s, to = %s\n", tx->toChars(), to->toChars());
3692
3693 MATCH m = tx->implicitConvTo(to);
3694 if (m > MATCHnomatch)
3695 {
3696 // MATCHexact: exact type match
3697 // MATCHconst: covairiant type match (eg. attributes difference)
3698 // MATCHconvert: context conversion
3699 m = convertMatch ? MATCHconvert : tx->equals(to) ? MATCHexact : MATCHconst;
3700
3701 if (presult)
3702 {
3703 (*presult) = (FuncExp *)copy();
3704 (*presult)->type = to;
3705
3706 // Bugzilla 12508: Tweak function body for covariant returns.
3707 (*presult)->fd->modifyReturns(sc, tof->next);
3708 }
3709 }
3710 else if (!flag)
3711 {
3712 const char *ts[2];
3713 toAutoQualChars(ts, tx, to);
3714 error("cannot implicitly convert expression (%s) of type %s to %s",
3715 toChars(), ts[0], ts[1]);
3716 }
3717 return m;
3718 }
3719
toChars()3720 const char *FuncExp::toChars()
3721 {
3722 return fd->toChars();
3723 }
3724
checkType()3725 bool FuncExp::checkType()
3726 {
3727 if (td)
3728 {
3729 error("template lambda has no type");
3730 return true;
3731 }
3732 return false;
3733 }
3734
checkValue()3735 bool FuncExp::checkValue()
3736 {
3737 if (td)
3738 {
3739 error("template lambda has no value");
3740 return true;
3741 }
3742 return false;
3743 }
3744
3745 /******************************** DeclarationExp **************************/
3746
DeclarationExp(Loc loc,Dsymbol * declaration)3747 DeclarationExp::DeclarationExp(Loc loc, Dsymbol *declaration)
3748 : Expression(loc, TOKdeclaration, sizeof(DeclarationExp))
3749 {
3750 this->declaration = declaration;
3751 }
3752
syntaxCopy()3753 Expression *DeclarationExp::syntaxCopy()
3754 {
3755 return new DeclarationExp(loc, declaration->syntaxCopy(NULL));
3756 }
3757
hasCode()3758 bool DeclarationExp::hasCode()
3759 {
3760 if (VarDeclaration *vd = declaration->isVarDeclaration())
3761 {
3762 return !(vd->storage_class & (STCmanifest | STCstatic));
3763 }
3764 return false;
3765 }
3766
3767 /************************ TypeidExp ************************************/
3768
3769 /*
3770 * typeid(int)
3771 */
3772
TypeidExp(Loc loc,RootObject * o)3773 TypeidExp::TypeidExp(Loc loc, RootObject *o)
3774 : Expression(loc, TOKtypeid, sizeof(TypeidExp))
3775 {
3776 this->obj = o;
3777 }
3778
syntaxCopy()3779 Expression *TypeidExp::syntaxCopy()
3780 {
3781 return new TypeidExp(loc, objectSyntaxCopy(obj));
3782 }
3783
3784 /************************ TraitsExp ************************************/
3785 /*
3786 * __traits(identifier, args...)
3787 */
3788
TraitsExp(Loc loc,Identifier * ident,Objects * args)3789 TraitsExp::TraitsExp(Loc loc, Identifier *ident, Objects *args)
3790 : Expression(loc, TOKtraits, sizeof(TraitsExp))
3791 {
3792 this->ident = ident;
3793 this->args = args;
3794 }
3795
syntaxCopy()3796 Expression *TraitsExp::syntaxCopy()
3797 {
3798 return new TraitsExp(loc, ident, TemplateInstance::arraySyntaxCopy(args));
3799 }
3800
3801 /************************************************************/
3802
HaltExp(Loc loc)3803 HaltExp::HaltExp(Loc loc)
3804 : Expression(loc, TOKhalt, sizeof(HaltExp))
3805 {
3806 }
3807
3808 /************************************************************/
3809
IsExp(Loc loc,Type * targ,Identifier * id,TOK tok,Type * tspec,TOK tok2,TemplateParameters * parameters)3810 IsExp::IsExp(Loc loc, Type *targ, Identifier *id, TOK tok,
3811 Type *tspec, TOK tok2, TemplateParameters *parameters)
3812 : Expression(loc, TOKis, sizeof(IsExp))
3813 {
3814 this->targ = targ;
3815 this->id = id;
3816 this->tok = tok;
3817 this->tspec = tspec;
3818 this->tok2 = tok2;
3819 this->parameters = parameters;
3820 }
3821
syntaxCopy()3822 Expression *IsExp::syntaxCopy()
3823 {
3824 // This section is identical to that in TemplateDeclaration::syntaxCopy()
3825 TemplateParameters *p = NULL;
3826 if (parameters)
3827 {
3828 p = new TemplateParameters();
3829 p->setDim(parameters->length);
3830 for (size_t i = 0; i < p->length; i++)
3831 (*p)[i] = (*parameters)[i]->syntaxCopy();
3832 }
3833 return new IsExp(loc,
3834 targ->syntaxCopy(),
3835 id,
3836 tok,
3837 tspec ? tspec->syntaxCopy() : NULL,
3838 tok2,
3839 p);
3840 }
3841
3842 void unSpeculative(Scope *sc, RootObject *o);
3843
3844 /************************************************************/
3845
UnaExp(Loc loc,TOK op,int size,Expression * e1)3846 UnaExp::UnaExp(Loc loc, TOK op, int size, Expression *e1)
3847 : Expression(loc, op, size)
3848 {
3849 this->e1 = e1;
3850 this->att1 = NULL;
3851 }
3852
syntaxCopy()3853 Expression *UnaExp::syntaxCopy()
3854 {
3855 UnaExp *e = (UnaExp *)copy();
3856 e->type = NULL;
3857 e->e1 = e->e1->syntaxCopy();
3858 return e;
3859 }
3860
3861 /********************************
3862 * The type for a unary expression is incompatible.
3863 * Print error message.
3864 * Returns:
3865 * ErrorExp
3866 */
incompatibleTypes()3867 Expression *UnaExp::incompatibleTypes()
3868 {
3869 if (e1->type->toBasetype() == Type::terror)
3870 return e1;
3871
3872 if (e1->op == TOKtype)
3873 {
3874 error("incompatible type for (%s(%s)): cannot use `%s` with types",
3875 Token::toChars(op), e1->toChars(), Token::toChars(op));
3876 }
3877 else
3878 {
3879 error("incompatible type for (%s(%s)): `%s`",
3880 Token::toChars(op), e1->toChars(), e1->type->toChars());
3881 }
3882 return new ErrorExp();
3883 }
3884
resolveLoc(Loc loc,Scope * sc)3885 Expression *UnaExp::resolveLoc(Loc loc, Scope *sc)
3886 {
3887 e1 = e1->resolveLoc(loc, sc);
3888 return this;
3889 }
3890
3891 /************************************************************/
3892
BinExp(Loc loc,TOK op,int size,Expression * e1,Expression * e2)3893 BinExp::BinExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2)
3894 : Expression(loc, op, size)
3895 {
3896 this->e1 = e1;
3897 this->e2 = e2;
3898
3899 this->att1 = NULL;
3900 this->att2 = NULL;
3901 }
3902
syntaxCopy()3903 Expression *BinExp::syntaxCopy()
3904 {
3905 BinExp *e = (BinExp *)copy();
3906 e->type = NULL;
3907 e->e1 = e->e1->syntaxCopy();
3908 e->e2 = e->e2->syntaxCopy();
3909 return e;
3910 }
3911
checkOpAssignTypes(Scope * sc)3912 Expression *BinExp::checkOpAssignTypes(Scope *sc)
3913 {
3914 // At that point t1 and t2 are the merged types. type is the original type of the lhs.
3915 Type *t1 = e1->type;
3916 Type *t2 = e2->type;
3917
3918 // T opAssign floating yields a floating. Prevent truncating conversions (float to int).
3919 // See issue 3841.
3920 // Should we also prevent double to float (type->isfloating() && type->size() < t2 ->size()) ?
3921 if (op == TOKaddass || op == TOKminass ||
3922 op == TOKmulass || op == TOKdivass || op == TOKmodass ||
3923 op == TOKpowass)
3924 {
3925 if ((type->isintegral() && t2->isfloating()))
3926 {
3927 warning("%s %s %s is performing truncating conversion",
3928 type->toChars(), Token::toChars(op), t2->toChars());
3929 }
3930 }
3931
3932 // generate an error if this is a nonsensical *=,/=, or %=, eg real *= imaginary
3933 if (op == TOKmulass || op == TOKdivass || op == TOKmodass)
3934 {
3935 // Any multiplication by an imaginary or complex number yields a complex result.
3936 // r *= c, i*=c, r*=i, i*=i are all forbidden operations.
3937 const char *opstr = Token::toChars(op);
3938 if (t1->isreal() && t2->iscomplex())
3939 {
3940 error("%s %s %s is undefined. Did you mean %s %s %s.re ?",
3941 t1->toChars(), opstr, t2->toChars(),
3942 t1->toChars(), opstr, t2->toChars());
3943 return new ErrorExp();
3944 }
3945 else if (t1->isimaginary() && t2->iscomplex())
3946 {
3947 error("%s %s %s is undefined. Did you mean %s %s %s.im ?",
3948 t1->toChars(), opstr, t2->toChars(),
3949 t1->toChars(), opstr, t2->toChars());
3950 return new ErrorExp();
3951 }
3952 else if ((t1->isreal() || t1->isimaginary()) &&
3953 t2->isimaginary())
3954 {
3955 error("%s %s %s is an undefined operation", t1->toChars(), opstr, t2->toChars());
3956 return new ErrorExp();
3957 }
3958 }
3959
3960 // generate an error if this is a nonsensical += or -=, eg real += imaginary
3961 if (op == TOKaddass || op == TOKminass)
3962 {
3963 // Addition or subtraction of a real and an imaginary is a complex result.
3964 // Thus, r+=i, r+=c, i+=r, i+=c are all forbidden operations.
3965 if ((t1->isreal() && (t2->isimaginary() || t2->iscomplex())) ||
3966 (t1->isimaginary() && (t2->isreal() || t2->iscomplex())))
3967 {
3968 error("%s %s %s is undefined (result is complex)",
3969 t1->toChars(), Token::toChars(op), t2->toChars());
3970 return new ErrorExp();
3971 }
3972 if (type->isreal() || type->isimaginary())
3973 {
3974 assert(global.errors || t2->isfloating());
3975 e2 = e2->castTo(sc, t1);
3976 }
3977 }
3978
3979 if (op == TOKmulass)
3980 {
3981 if (t2->isfloating())
3982 {
3983 if (t1->isreal())
3984 {
3985 if (t2->isimaginary() || t2->iscomplex())
3986 {
3987 e2 = e2->castTo(sc, t1);
3988 }
3989 }
3990 else if (t1->isimaginary())
3991 {
3992 if (t2->isimaginary() || t2->iscomplex())
3993 {
3994 switch (t1->ty)
3995 {
3996 case Timaginary32: t2 = Type::tfloat32; break;
3997 case Timaginary64: t2 = Type::tfloat64; break;
3998 case Timaginary80: t2 = Type::tfloat80; break;
3999 default:
4000 assert(0);
4001 }
4002 e2 = e2->castTo(sc, t2);
4003 }
4004 }
4005 }
4006 }
4007 else if (op == TOKdivass)
4008 {
4009 if (t2->isimaginary())
4010 {
4011 if (t1->isreal())
4012 {
4013 // x/iv = i(-x/v)
4014 // Therefore, the result is 0
4015 e2 = new CommaExp(loc, e2, new RealExp(loc, CTFloat::zero, t1));
4016 e2->type = t1;
4017 Expression *e = new AssignExp(loc, e1, e2);
4018 e->type = t1;
4019 return e;
4020 }
4021 else if (t1->isimaginary())
4022 {
4023 Type *t3;
4024 switch (t1->ty)
4025 {
4026 case Timaginary32: t3 = Type::tfloat32; break;
4027 case Timaginary64: t3 = Type::tfloat64; break;
4028 case Timaginary80: t3 = Type::tfloat80; break;
4029 default:
4030 assert(0);
4031 }
4032 e2 = e2->castTo(sc, t3);
4033 Expression *e = new AssignExp(loc, e1, e2);
4034 e->type = t1;
4035 return e;
4036 }
4037 }
4038 }
4039 else if (op == TOKmodass)
4040 {
4041 if (t2->iscomplex())
4042 {
4043 error("cannot perform modulo complex arithmetic");
4044 return new ErrorExp();
4045 }
4046 }
4047 return this;
4048 }
4049
4050 /********************************
4051 * The types for a binary expression are incompatible.
4052 * Print error message.
4053 * Returns:
4054 * ErrorExp
4055 */
incompatibleTypes()4056 Expression *BinExp::incompatibleTypes()
4057 {
4058 if (e1->type->toBasetype() == Type::terror)
4059 return e1;
4060 if (e2->type->toBasetype() == Type::terror)
4061 return e2;
4062
4063 // CondExp uses 'a ? b : c' but we're comparing 'b : c'
4064 TOK thisOp = (op == TOKquestion) ? TOKcolon : op;
4065 if (e1->op == TOKtype || e2->op == TOKtype)
4066 {
4067 error("incompatible types for ((%s) %s (%s)): cannot use `%s` with types",
4068 e1->toChars(), Token::toChars(thisOp), e2->toChars(), Token::toChars(op));
4069 }
4070 else if (e1->type->equals(e2->type))
4071 {
4072 error("incompatible types for ((%s) %s (%s)): both operands are of type `%s`",
4073 e1->toChars(), Token::toChars(thisOp), e2->toChars(), e1->type->toChars());
4074 }
4075 else
4076 {
4077 const char *ts[2];
4078 toAutoQualChars(ts, e1->type, e2->type);
4079 error("incompatible types for ((%s) %s (%s)): `%s` and `%s`",
4080 e1->toChars(), Token::toChars(thisOp), e2->toChars(), ts[0], ts[1]);
4081 }
4082 return new ErrorExp();
4083 }
4084
checkIntegralBin()4085 bool BinExp::checkIntegralBin()
4086 {
4087 bool r1 = e1->checkIntegral();
4088 bool r2 = e2->checkIntegral();
4089 return (r1 || r2);
4090 }
4091
checkArithmeticBin()4092 bool BinExp::checkArithmeticBin()
4093 {
4094 bool r1 = e1->checkArithmetic();
4095 bool r2 = e2->checkArithmetic();
4096 return (r1 || r2);
4097 }
4098
4099 /********************** BinAssignExp **************************************/
4100
BinAssignExp(Loc loc,TOK op,int size,Expression * e1,Expression * e2)4101 BinAssignExp::BinAssignExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2)
4102 : BinExp(loc, op, size, e1, e2)
4103 {
4104 }
4105
isLvalue()4106 bool BinAssignExp::isLvalue()
4107 {
4108 return true;
4109 }
4110
toLvalue(Scope *,Expression *)4111 Expression *BinAssignExp::toLvalue(Scope *, Expression *)
4112 {
4113 // Lvalue-ness will be handled in glue layer.
4114 return this;
4115 }
4116
modifiableLvalue(Scope * sc,Expression *)4117 Expression *BinAssignExp::modifiableLvalue(Scope *sc, Expression *)
4118 {
4119 // should check e1->checkModifiable() ?
4120 return toLvalue(sc, this);
4121 }
4122
4123 /************************************************************/
4124
CompileExp(Loc loc,Expressions * exps)4125 CompileExp::CompileExp(Loc loc, Expressions *exps)
4126 : Expression(loc, TOKmixin, sizeof(CompileExp))
4127 {
4128 this->exps = exps;
4129 }
4130
syntaxCopy()4131 Expression *CompileExp::syntaxCopy()
4132 {
4133 return new CompileExp(loc, arraySyntaxCopy(exps));
4134 }
4135
equals(RootObject * o)4136 bool CompileExp::equals(RootObject *o)
4137 {
4138 if (this == o)
4139 return true;
4140 if (o && o->dyncast() == DYNCAST_EXPRESSION && ((Expression *)o)->op == TOKmixin)
4141 {
4142 CompileExp *ce = (CompileExp *)o;
4143 if (exps->length != ce->exps->length)
4144 return false;
4145 for (size_t i = 0; i < exps->length; i++)
4146 {
4147 Expression *e1 = (*exps)[i];
4148 Expression *e2 = (*ce->exps)[i];
4149 if (e1 != e2 && (!e1 || !e2 || !e1->equals(e2)))
4150 return false;
4151 }
4152 return true;
4153 }
4154 return false;
4155 }
4156
4157 /************************************************************/
4158
ImportExp(Loc loc,Expression * e)4159 ImportExp::ImportExp(Loc loc, Expression *e)
4160 : UnaExp(loc, TOKimport, sizeof(ImportExp), e)
4161 {
4162 }
4163
4164 /************************************************************/
4165
AssertExp(Loc loc,Expression * e,Expression * msg)4166 AssertExp::AssertExp(Loc loc, Expression *e, Expression *msg)
4167 : UnaExp(loc, TOKassert, sizeof(AssertExp), e)
4168 {
4169 this->msg = msg;
4170 }
4171
syntaxCopy()4172 Expression *AssertExp::syntaxCopy()
4173 {
4174 return new AssertExp(loc, e1->syntaxCopy(), msg ? msg->syntaxCopy() : NULL);
4175 }
4176
4177 /************************************************************/
4178
DotIdExp(Loc loc,Expression * e,Identifier * ident)4179 DotIdExp::DotIdExp(Loc loc, Expression *e, Identifier *ident)
4180 : UnaExp(loc, TOKdotid, sizeof(DotIdExp), e)
4181 {
4182 this->ident = ident;
4183 this->wantsym = false;
4184 this->noderef = false;
4185 }
4186
create(Loc loc,Expression * e,Identifier * ident)4187 DotIdExp *DotIdExp::create(Loc loc, Expression *e, Identifier *ident)
4188 {
4189 return new DotIdExp(loc, e, ident);
4190 }
4191
4192 /********************** DotTemplateExp ***********************************/
4193
4194 // Mainly just a placeholder
4195
DotTemplateExp(Loc loc,Expression * e,TemplateDeclaration * td)4196 DotTemplateExp::DotTemplateExp(Loc loc, Expression *e, TemplateDeclaration *td)
4197 : UnaExp(loc, TOKdottd, sizeof(DotTemplateExp), e)
4198
4199 {
4200 this->td = td;
4201 }
4202
4203 /************************************************************/
4204
DotVarExp(Loc loc,Expression * e,Declaration * var,bool hasOverloads)4205 DotVarExp::DotVarExp(Loc loc, Expression *e, Declaration *var, bool hasOverloads)
4206 : UnaExp(loc, TOKdotvar, sizeof(DotVarExp), e)
4207 {
4208 //printf("DotVarExp()\n");
4209 this->var = var;
4210 this->hasOverloads = var->isVarDeclaration() ? false : hasOverloads;
4211 }
4212
isLvalue()4213 bool DotVarExp::isLvalue()
4214 {
4215 return true;
4216 }
4217
toLvalue(Scope *,Expression *)4218 Expression *DotVarExp::toLvalue(Scope *, Expression *)
4219 {
4220 //printf("DotVarExp::toLvalue(%s)\n", toChars());
4221 return this;
4222 }
4223
4224 /***********************************************
4225 * Mark variable v as modified if it is inside a constructor that var
4226 * is a field in.
4227 */
modifyFieldVar(Loc loc,Scope * sc,VarDeclaration * var,Expression * e1)4228 int modifyFieldVar(Loc loc, Scope *sc, VarDeclaration *var, Expression *e1)
4229 {
4230 //printf("modifyFieldVar(var = %s)\n", var->toChars());
4231 Dsymbol *s = sc->func;
4232 while (1)
4233 {
4234 FuncDeclaration *fd = NULL;
4235 if (s)
4236 fd = s->isFuncDeclaration();
4237 if (fd &&
4238 ((fd->isCtorDeclaration() && var->isField()) ||
4239 (fd->isStaticCtorDeclaration() && !var->isField())) &&
4240 fd->toParent2() == var->toParent2() &&
4241 (!e1 || e1->op == TOKthis)
4242 )
4243 {
4244 bool result = true;
4245
4246 var->ctorinit = true;
4247 //printf("setting ctorinit\n");
4248
4249 if (var->isField() && sc->fieldinit && !sc->intypeof)
4250 {
4251 assert(e1);
4252 bool mustInit = ((var->storage_class & STCnodefaultctor) != 0 ||
4253 var->type->needsNested());
4254
4255 size_t dim = sc->fieldinit_dim;
4256 AggregateDeclaration *ad = fd->isMember2();
4257 assert(ad);
4258 size_t i;
4259 for (i = 0; i < dim; i++) // same as findFieldIndexByName in ctfeexp.c ?
4260 {
4261 if (ad->fields[i] == var)
4262 break;
4263 }
4264 assert(i < dim);
4265 unsigned fi = sc->fieldinit[i];
4266
4267 if (fi & CSXthis_ctor)
4268 {
4269 if (var->type->isMutable() && e1->type->isMutable())
4270 result = false;
4271 else
4272 {
4273 const char *modStr = !var->type->isMutable() ? MODtoChars(var->type->mod) : MODtoChars(e1->type->mod);
4274 ::error(loc, "%s field `%s` initialized multiple times", modStr, var->toChars());
4275 }
4276 }
4277 else if (sc->noctor || (fi & CSXlabel))
4278 {
4279 if (!mustInit && var->type->isMutable() && e1->type->isMutable())
4280 result = false;
4281 else
4282 {
4283 const char *modStr = !var->type->isMutable() ? MODtoChars(var->type->mod) : MODtoChars(e1->type->mod);
4284 ::error(loc, "%s field `%s` initialization is not allowed in loops or after labels", modStr, var->toChars());
4285 }
4286 }
4287 sc->fieldinit[i] |= CSXthis_ctor;
4288 if (var->overlapped) // Bugzilla 15258
4289 {
4290 for (size_t j = 0; j < ad->fields.length; j++)
4291 {
4292 VarDeclaration *v = ad->fields[j];
4293 if (v == var || !var->isOverlappedWith(v))
4294 continue;
4295 v->ctorinit = true;
4296 sc->fieldinit[j] = CSXthis_ctor;
4297 }
4298 }
4299 }
4300 else if (fd != sc->func)
4301 {
4302 if (var->type->isMutable())
4303 result = false;
4304 else if (sc->func->fes)
4305 {
4306 const char *p = var->isField() ? "field" : var->kind();
4307 ::error(loc, "%s %s `%s` initialization is not allowed in foreach loop",
4308 MODtoChars(var->type->mod), p, var->toChars());
4309 }
4310 else
4311 {
4312 const char *p = var->isField() ? "field" : var->kind();
4313 ::error(loc, "%s %s `%s` initialization is not allowed in nested function `%s`",
4314 MODtoChars(var->type->mod), p, var->toChars(), sc->func->toChars());
4315 }
4316 }
4317 return result;
4318 }
4319 else
4320 {
4321 if (s)
4322 {
4323 s = s->toParent2();
4324 continue;
4325 }
4326 }
4327 break;
4328 }
4329 return false;
4330 }
4331
checkModifiable(Scope * sc,int flag)4332 int DotVarExp::checkModifiable(Scope *sc, int flag)
4333 {
4334 //printf("DotVarExp::checkModifiable %s %s\n", toChars(), type->toChars());
4335 if (checkUnsafeAccess(sc, this, false, !flag))
4336 return 2;
4337
4338 if (e1->op == TOKthis)
4339 return var->checkModify(loc, sc, type, e1, flag);
4340
4341 //printf("\te1 = %s\n", e1->toChars());
4342 return e1->checkModifiable(sc, flag);
4343 }
4344
modifiableLvalue(Scope * sc,Expression * e)4345 Expression *DotVarExp::modifiableLvalue(Scope *sc, Expression *e)
4346 {
4347 return Expression::modifiableLvalue(sc, e);
4348 }
4349
4350 /************************************************************/
4351
4352 /* Things like:
4353 * foo.bar!(args)
4354 */
4355
DotTemplateInstanceExp(Loc loc,Expression * e,Identifier * name,Objects * tiargs)4356 DotTemplateInstanceExp::DotTemplateInstanceExp(Loc loc, Expression *e, Identifier *name, Objects *tiargs)
4357 : UnaExp(loc, TOKdotti, sizeof(DotTemplateInstanceExp), e)
4358 {
4359 //printf("DotTemplateInstanceExp()\n");
4360 this->ti = new TemplateInstance(loc, name);
4361 this->ti->tiargs = tiargs;
4362 }
4363
DotTemplateInstanceExp(Loc loc,Expression * e,TemplateInstance * ti)4364 DotTemplateInstanceExp::DotTemplateInstanceExp(Loc loc, Expression *e, TemplateInstance *ti)
4365 : UnaExp(loc, TOKdotti, sizeof(DotTemplateInstanceExp), e)
4366 {
4367 this->ti = ti;
4368 }
4369
syntaxCopy()4370 Expression *DotTemplateInstanceExp::syntaxCopy()
4371 {
4372 return new DotTemplateInstanceExp(loc,
4373 e1->syntaxCopy(),
4374 ti->name,
4375 TemplateInstance::arraySyntaxCopy(ti->tiargs));
4376 }
4377
findTempDecl(Scope * sc)4378 bool DotTemplateInstanceExp::findTempDecl(Scope *sc)
4379 {
4380 if (ti->tempdecl)
4381 return true;
4382
4383 Expression *e = new DotIdExp(loc, e1, ti->name);
4384 e = expressionSemantic(e, sc);
4385 if (e->op == TOKdot)
4386 e = ((DotExp *)e)->e2;
4387
4388 Dsymbol *s = NULL;
4389 switch (e->op)
4390 {
4391 case TOKoverloadset: s = ((OverExp *)e)->vars; break;
4392 case TOKdottd: s = ((DotTemplateExp *)e)->td; break;
4393 case TOKscope: s = ((ScopeExp *)e)->sds; break;
4394 case TOKdotvar: s = ((DotVarExp *)e)->var; break;
4395 case TOKvar: s = ((VarExp *)e)->var; break;
4396 default: return false;
4397 }
4398 return ti->updateTempDecl(sc, s);
4399 }
4400
4401 /************************************************************/
4402
DelegateExp(Loc loc,Expression * e,FuncDeclaration * f,bool hasOverloads)4403 DelegateExp::DelegateExp(Loc loc, Expression *e, FuncDeclaration *f, bool hasOverloads)
4404 : UnaExp(loc, TOKdelegate, sizeof(DelegateExp), e)
4405 {
4406 this->func = f;
4407 this->hasOverloads = hasOverloads;
4408 }
4409
4410 /************************************************************/
4411
DotTypeExp(Loc loc,Expression * e,Dsymbol * s)4412 DotTypeExp::DotTypeExp(Loc loc, Expression *e, Dsymbol *s)
4413 : UnaExp(loc, TOKdottype, sizeof(DotTypeExp), e)
4414 {
4415 this->sym = s;
4416 this->type = NULL;
4417 }
4418
4419 /************************************************************/
4420
CallExp(Loc loc,Expression * e,Expressions * exps)4421 CallExp::CallExp(Loc loc, Expression *e, Expressions *exps)
4422 : UnaExp(loc, TOKcall, sizeof(CallExp), e)
4423 {
4424 this->arguments = exps;
4425 this->f = NULL;
4426 this->directcall = false;
4427 }
4428
CallExp(Loc loc,Expression * e)4429 CallExp::CallExp(Loc loc, Expression *e)
4430 : UnaExp(loc, TOKcall, sizeof(CallExp), e)
4431 {
4432 this->arguments = NULL;
4433 this->f = NULL;
4434 this->directcall = false;
4435 }
4436
CallExp(Loc loc,Expression * e,Expression * earg1)4437 CallExp::CallExp(Loc loc, Expression *e, Expression *earg1)
4438 : UnaExp(loc, TOKcall, sizeof(CallExp), e)
4439 {
4440 Expressions *arguments = new Expressions();
4441 if (earg1)
4442 {
4443 arguments->setDim(1);
4444 (*arguments)[0] = earg1;
4445 }
4446 this->arguments = arguments;
4447 this->f = NULL;
4448 this->directcall = false;
4449 }
4450
CallExp(Loc loc,Expression * e,Expression * earg1,Expression * earg2)4451 CallExp::CallExp(Loc loc, Expression *e, Expression *earg1, Expression *earg2)
4452 : UnaExp(loc, TOKcall, sizeof(CallExp), e)
4453 {
4454 Expressions *arguments = new Expressions();
4455 arguments->setDim(2);
4456 (*arguments)[0] = earg1;
4457 (*arguments)[1] = earg2;
4458
4459 this->arguments = arguments;
4460 this->f = NULL;
4461 this->directcall = false;
4462 }
4463
create(Loc loc,Expression * e,Expressions * exps)4464 CallExp *CallExp::create(Loc loc, Expression *e, Expressions *exps)
4465 {
4466 return new CallExp(loc, e, exps);
4467 }
4468
create(Loc loc,Expression * e)4469 CallExp *CallExp::create(Loc loc, Expression *e)
4470 {
4471 return new CallExp(loc, e);
4472 }
4473
create(Loc loc,Expression * e,Expression * earg1)4474 CallExp *CallExp::create(Loc loc, Expression *e, Expression *earg1)
4475 {
4476 return new CallExp(loc, e, earg1);
4477 }
4478
syntaxCopy()4479 Expression *CallExp::syntaxCopy()
4480 {
4481 return new CallExp(loc, e1->syntaxCopy(), arraySyntaxCopy(arguments));
4482 }
4483
isLvalue()4484 bool CallExp::isLvalue()
4485 {
4486 Type *tb = e1->type->toBasetype();
4487 if (tb->ty == Tdelegate || tb->ty == Tpointer)
4488 tb = tb->nextOf();
4489 if (tb->ty == Tfunction && ((TypeFunction *)tb)->isref)
4490 {
4491 if (e1->op == TOKdotvar)
4492 if (((DotVarExp *)e1)->var->isCtorDeclaration())
4493 return false;
4494 return true; // function returns a reference
4495 }
4496 return false;
4497 }
4498
toLvalue(Scope * sc,Expression * e)4499 Expression *CallExp::toLvalue(Scope *sc, Expression *e)
4500 {
4501 if (isLvalue())
4502 return this;
4503 return Expression::toLvalue(sc, e);
4504 }
4505
addDtorHook(Scope * sc)4506 Expression *CallExp::addDtorHook(Scope *sc)
4507 {
4508 /* Only need to add dtor hook if it's a type that needs destruction.
4509 * Use same logic as VarDeclaration::callScopeDtor()
4510 */
4511
4512 if (e1->type && e1->type->ty == Tfunction)
4513 {
4514 TypeFunction *tf = (TypeFunction *)e1->type;
4515 if (tf->isref)
4516 return this;
4517 }
4518
4519 Type *tv = type->baseElemOf();
4520 if (tv->ty == Tstruct)
4521 {
4522 TypeStruct *ts = (TypeStruct *)tv;
4523 StructDeclaration *sd = ts->sym;
4524 if (sd->dtor)
4525 {
4526 /* Type needs destruction, so declare a tmp
4527 * which the back end will recognize and call dtor on
4528 */
4529 VarDeclaration *tmp = copyToTemp(0, "__tmpfordtor", this);
4530 DeclarationExp *de = new DeclarationExp(loc, tmp);
4531 VarExp *ve = new VarExp(loc, tmp);
4532 Expression *e = new CommaExp(loc, de, ve);
4533 e = expressionSemantic(e, sc);
4534 return e;
4535 }
4536 }
4537 return this;
4538 }
4539
4540 FuncDeclaration *isFuncAddress(Expression *e, bool *hasOverloads = NULL)
4541 {
4542 if (e->op == TOKaddress)
4543 {
4544 Expression *ae1 = ((AddrExp *)e)->e1;
4545 if (ae1->op == TOKvar)
4546 {
4547 VarExp *ve = (VarExp *)ae1;
4548 if (hasOverloads)
4549 *hasOverloads = ve->hasOverloads;
4550 return ve->var->isFuncDeclaration();
4551 }
4552 if (ae1->op == TOKdotvar)
4553 {
4554 DotVarExp *dve = (DotVarExp *)ae1;
4555 if (hasOverloads)
4556 *hasOverloads = dve->hasOverloads;
4557 return dve->var->isFuncDeclaration();
4558 }
4559 }
4560 else
4561 {
4562 if (e->op == TOKsymoff)
4563 {
4564 SymOffExp *soe = (SymOffExp *)e;
4565 if (hasOverloads)
4566 *hasOverloads = soe->hasOverloads;
4567 return soe->var->isFuncDeclaration();
4568 }
4569 if (e->op == TOKdelegate)
4570 {
4571 DelegateExp *dge = (DelegateExp *)e;
4572 if (hasOverloads)
4573 *hasOverloads = dge->hasOverloads;
4574 return dge->func->isFuncDeclaration();
4575 }
4576 }
4577 return NULL;
4578 }
4579
4580 /************************************************************/
4581
AddrExp(Loc loc,Expression * e)4582 AddrExp::AddrExp(Loc loc, Expression *e)
4583 : UnaExp(loc, TOKaddress, sizeof(AddrExp), e)
4584 {
4585 }
4586
AddrExp(Loc loc,Expression * e,Type * t)4587 AddrExp::AddrExp(Loc loc, Expression *e, Type *t)
4588 : UnaExp(loc, TOKaddress, sizeof(AddrExp), e)
4589 {
4590 type = t;
4591 }
4592
4593 /************************************************************/
4594
PtrExp(Loc loc,Expression * e)4595 PtrExp::PtrExp(Loc loc, Expression *e)
4596 : UnaExp(loc, TOKstar, sizeof(PtrExp), e)
4597 {
4598 // if (e->type)
4599 // type = ((TypePointer *)e->type)->next;
4600 }
4601
PtrExp(Loc loc,Expression * e,Type * t)4602 PtrExp::PtrExp(Loc loc, Expression *e, Type *t)
4603 : UnaExp(loc, TOKstar, sizeof(PtrExp), e)
4604 {
4605 type = t;
4606 }
4607
isLvalue()4608 bool PtrExp::isLvalue()
4609 {
4610 return true;
4611 }
4612
toLvalue(Scope *,Expression *)4613 Expression *PtrExp::toLvalue(Scope *, Expression *)
4614 {
4615 return this;
4616 }
4617
checkModifiable(Scope * sc,int flag)4618 int PtrExp::checkModifiable(Scope *sc, int flag)
4619 {
4620 if (e1->op == TOKsymoff)
4621 { SymOffExp *se = (SymOffExp *)e1;
4622 return se->var->checkModify(loc, sc, type, NULL, flag);
4623 }
4624 else if (e1->op == TOKaddress)
4625 {
4626 AddrExp *ae = (AddrExp *)e1;
4627 return ae->e1->checkModifiable(sc, flag);
4628 }
4629 return 1;
4630 }
4631
modifiableLvalue(Scope * sc,Expression * e)4632 Expression *PtrExp::modifiableLvalue(Scope *sc, Expression *e)
4633 {
4634 //printf("PtrExp::modifiableLvalue() %s, type %s\n", toChars(), type->toChars());
4635 return Expression::modifiableLvalue(sc, e);
4636 }
4637
4638 /************************************************************/
4639
NegExp(Loc loc,Expression * e)4640 NegExp::NegExp(Loc loc, Expression *e)
4641 : UnaExp(loc, TOKneg, sizeof(NegExp), e)
4642 {
4643 }
4644
4645 /************************************************************/
4646
UAddExp(Loc loc,Expression * e)4647 UAddExp::UAddExp(Loc loc, Expression *e)
4648 : UnaExp(loc, TOKuadd, sizeof(UAddExp), e)
4649 {
4650 }
4651
4652 /************************************************************/
4653
ComExp(Loc loc,Expression * e)4654 ComExp::ComExp(Loc loc, Expression *e)
4655 : UnaExp(loc, TOKtilde, sizeof(ComExp), e)
4656 {
4657 }
4658
4659 /************************************************************/
4660
NotExp(Loc loc,Expression * e)4661 NotExp::NotExp(Loc loc, Expression *e)
4662 : UnaExp(loc, TOKnot, sizeof(NotExp), e)
4663 {
4664 }
4665
4666 /************************************************************/
4667
DeleteExp(Loc loc,Expression * e,bool isRAII)4668 DeleteExp::DeleteExp(Loc loc, Expression *e, bool isRAII)
4669 : UnaExp(loc, TOKdelete, sizeof(DeleteExp), e)
4670 {
4671 this->isRAII = isRAII;
4672 }
4673
toBoolean(Scope *)4674 Expression *DeleteExp::toBoolean(Scope *)
4675 {
4676 error("delete does not give a boolean result");
4677 return new ErrorExp();
4678 }
4679
4680 /************************************************************/
4681
CastExp(Loc loc,Expression * e,Type * t)4682 CastExp::CastExp(Loc loc, Expression *e, Type *t)
4683 : UnaExp(loc, TOKcast, sizeof(CastExp), e)
4684 {
4685 this->to = t;
4686 this->mod = (unsigned char)~0;
4687 }
4688
4689 /* For cast(const) and cast(immutable)
4690 */
CastExp(Loc loc,Expression * e,unsigned char mod)4691 CastExp::CastExp(Loc loc, Expression *e, unsigned char mod)
4692 : UnaExp(loc, TOKcast, sizeof(CastExp), e)
4693 {
4694 this->to = NULL;
4695 this->mod = mod;
4696 }
4697
syntaxCopy()4698 Expression *CastExp::syntaxCopy()
4699 {
4700 return to ? new CastExp(loc, e1->syntaxCopy(), to->syntaxCopy())
4701 : new CastExp(loc, e1->syntaxCopy(), mod);
4702 }
4703
4704 /************************************************************/
4705
VectorExp(Loc loc,Expression * e,Type * t)4706 VectorExp::VectorExp(Loc loc, Expression *e, Type *t)
4707 : UnaExp(loc, TOKvector, sizeof(VectorExp), e)
4708 {
4709 assert(t->ty == Tvector);
4710 to = (TypeVector *)t;
4711 dim = ~0;
4712 ownedByCtfe = OWNEDcode;
4713 }
4714
create(Loc loc,Expression * e,Type * t)4715 VectorExp *VectorExp::create(Loc loc, Expression *e, Type *t)
4716 {
4717 return new VectorExp(loc, e, t);
4718 }
4719
syntaxCopy()4720 Expression *VectorExp::syntaxCopy()
4721 {
4722 return new VectorExp(loc, e1->syntaxCopy(), to->syntaxCopy());
4723 }
4724
4725 /************************************************************/
4726
VectorArrayExp(Loc loc,Expression * e1)4727 VectorArrayExp::VectorArrayExp(Loc loc, Expression *e1)
4728 : UnaExp(loc, TOKvectorarray, sizeof(VectorArrayExp), e1)
4729 {
4730 }
4731
isLvalue()4732 bool VectorArrayExp::isLvalue()
4733 {
4734 return e1->isLvalue();
4735 }
4736
toLvalue(Scope * sc,Expression * e)4737 Expression *VectorArrayExp::toLvalue(Scope *sc, Expression *e)
4738 {
4739 e1 = e1->toLvalue(sc, e);
4740 return this;
4741 }
4742
4743 /************************************************************/
4744
SliceExp(Loc loc,Expression * e1,IntervalExp * ie)4745 SliceExp::SliceExp(Loc loc, Expression *e1, IntervalExp *ie)
4746 : UnaExp(loc, TOKslice, sizeof(SliceExp), e1)
4747 {
4748 this->upr = ie ? ie->upr : NULL;
4749 this->lwr = ie ? ie->lwr : NULL;
4750 lengthVar = NULL;
4751 upperIsInBounds = false;
4752 lowerIsLessThanUpper = false;
4753 arrayop = false;
4754 }
4755
SliceExp(Loc loc,Expression * e1,Expression * lwr,Expression * upr)4756 SliceExp::SliceExp(Loc loc, Expression *e1, Expression *lwr, Expression *upr)
4757 : UnaExp(loc, TOKslice, sizeof(SliceExp), e1)
4758 {
4759 this->upr = upr;
4760 this->lwr = lwr;
4761 lengthVar = NULL;
4762 upperIsInBounds = false;
4763 lowerIsLessThanUpper = false;
4764 arrayop = false;
4765 }
4766
syntaxCopy()4767 Expression *SliceExp::syntaxCopy()
4768 {
4769 SliceExp *se = new SliceExp(loc, e1->syntaxCopy(),
4770 lwr ? lwr->syntaxCopy() : NULL,
4771 upr ? upr->syntaxCopy() : NULL);
4772 se->lengthVar = this->lengthVar; // bug7871
4773 return se;
4774 }
4775
checkModifiable(Scope * sc,int flag)4776 int SliceExp::checkModifiable(Scope *sc, int flag)
4777 {
4778 //printf("SliceExp::checkModifiable %s\n", toChars());
4779 if (e1->type->ty == Tsarray ||
4780 (e1->op == TOKindex && e1->type->ty != Tarray) ||
4781 e1->op == TOKslice)
4782 {
4783 return e1->checkModifiable(sc, flag);
4784 }
4785 return 1;
4786 }
4787
isLvalue()4788 bool SliceExp::isLvalue()
4789 {
4790 /* slice expression is rvalue in default, but
4791 * conversion to reference of static array is only allowed.
4792 */
4793 return (type && type->toBasetype()->ty == Tsarray);
4794 }
4795
toLvalue(Scope * sc,Expression * e)4796 Expression *SliceExp::toLvalue(Scope *sc, Expression *e)
4797 {
4798 //printf("SliceExp::toLvalue(%s) type = %s\n", toChars(), type ? type->toChars() : NULL);
4799 return (type && type->toBasetype()->ty == Tsarray)
4800 ? this : Expression::toLvalue(sc, e);
4801 }
4802
modifiableLvalue(Scope *,Expression *)4803 Expression *SliceExp::modifiableLvalue(Scope *, Expression *)
4804 {
4805 error("slice expression %s is not a modifiable lvalue", toChars());
4806 return this;
4807 }
4808
isBool(bool result)4809 bool SliceExp::isBool(bool result)
4810 {
4811 return e1->isBool(result);
4812 }
4813
4814 /********************** ArrayLength **************************************/
4815
ArrayLengthExp(Loc loc,Expression * e1)4816 ArrayLengthExp::ArrayLengthExp(Loc loc, Expression *e1)
4817 : UnaExp(loc, TOKarraylength, sizeof(ArrayLengthExp), e1)
4818 {
4819 }
4820
4821 /*********************** IntervalExp ********************************/
4822
4823 // Mainly just a placeholder
4824
IntervalExp(Loc loc,Expression * lwr,Expression * upr)4825 IntervalExp::IntervalExp(Loc loc, Expression *lwr, Expression *upr)
4826 : Expression(loc, TOKinterval, sizeof(IntervalExp))
4827 {
4828 this->lwr = lwr;
4829 this->upr = upr;
4830 }
4831
syntaxCopy()4832 Expression *IntervalExp::syntaxCopy()
4833 {
4834 return new IntervalExp(loc, lwr->syntaxCopy(), upr->syntaxCopy());
4835 }
4836
4837 /********************** DelegatePtrExp **************************************/
4838
DelegatePtrExp(Loc loc,Expression * e1)4839 DelegatePtrExp::DelegatePtrExp(Loc loc, Expression *e1)
4840 : UnaExp(loc, TOKdelegateptr, sizeof(DelegatePtrExp), e1)
4841 {
4842 }
4843
isLvalue()4844 bool DelegatePtrExp::isLvalue()
4845 {
4846 return e1->isLvalue();
4847 }
4848
toLvalue(Scope * sc,Expression * e)4849 Expression *DelegatePtrExp::toLvalue(Scope *sc, Expression *e)
4850 {
4851 e1 = e1->toLvalue(sc, e);
4852 return this;
4853 }
4854
modifiableLvalue(Scope * sc,Expression * e)4855 Expression *DelegatePtrExp::modifiableLvalue(Scope *sc, Expression *e)
4856 {
4857 if (sc->func->setUnsafe())
4858 {
4859 error("cannot modify delegate pointer in @safe code %s", toChars());
4860 return new ErrorExp();
4861 }
4862 return Expression::modifiableLvalue(sc, e);
4863 }
4864
4865 /********************** DelegateFuncptrExp **************************************/
4866
DelegateFuncptrExp(Loc loc,Expression * e1)4867 DelegateFuncptrExp::DelegateFuncptrExp(Loc loc, Expression *e1)
4868 : UnaExp(loc, TOKdelegatefuncptr, sizeof(DelegateFuncptrExp), e1)
4869 {
4870 }
4871
isLvalue()4872 bool DelegateFuncptrExp::isLvalue()
4873 {
4874 return e1->isLvalue();
4875 }
4876
toLvalue(Scope * sc,Expression * e)4877 Expression *DelegateFuncptrExp::toLvalue(Scope *sc, Expression *e)
4878 {
4879 e1 = e1->toLvalue(sc, e);
4880 return this;
4881 }
4882
modifiableLvalue(Scope * sc,Expression * e)4883 Expression *DelegateFuncptrExp::modifiableLvalue(Scope *sc, Expression *e)
4884 {
4885 if (sc->func->setUnsafe())
4886 {
4887 error("cannot modify delegate function pointer in @safe code %s", toChars());
4888 return new ErrorExp();
4889 }
4890 return Expression::modifiableLvalue(sc, e);
4891 }
4892
4893 /*********************** ArrayExp *************************************/
4894
4895 // e1 [ i1, i2, i3, ... ]
4896
ArrayExp(Loc loc,Expression * e1,Expression * index)4897 ArrayExp::ArrayExp(Loc loc, Expression *e1, Expression *index)
4898 : UnaExp(loc, TOKarray, sizeof(ArrayExp), e1)
4899 {
4900 arguments = new Expressions();
4901 if (index)
4902 arguments->push(index);
4903 lengthVar = NULL;
4904 currentDimension = 0;
4905 }
4906
ArrayExp(Loc loc,Expression * e1,Expressions * args)4907 ArrayExp::ArrayExp(Loc loc, Expression *e1, Expressions *args)
4908 : UnaExp(loc, TOKarray, sizeof(ArrayExp), e1)
4909 {
4910 arguments = args;
4911 lengthVar = NULL;
4912 currentDimension = 0;
4913 }
4914
syntaxCopy()4915 Expression *ArrayExp::syntaxCopy()
4916 {
4917 ArrayExp *ae = new ArrayExp(loc, e1->syntaxCopy(), arraySyntaxCopy(arguments));
4918 ae->lengthVar = this->lengthVar; // bug7871
4919 return ae;
4920 }
4921
isLvalue()4922 bool ArrayExp::isLvalue()
4923 {
4924 if (type && type->toBasetype()->ty == Tvoid)
4925 return false;
4926 return true;
4927 }
4928
toLvalue(Scope *,Expression *)4929 Expression *ArrayExp::toLvalue(Scope *, Expression *)
4930 {
4931 if (type && type->toBasetype()->ty == Tvoid)
4932 error("voids have no value");
4933 return this;
4934 }
4935
4936 /************************* DotExp ***********************************/
4937
DotExp(Loc loc,Expression * e1,Expression * e2)4938 DotExp::DotExp(Loc loc, Expression *e1, Expression *e2)
4939 : BinExp(loc, TOKdot, sizeof(DotExp), e1, e2)
4940 {
4941 }
4942
4943 /************************* CommaExp ***********************************/
4944
CommaExp(Loc loc,Expression * e1,Expression * e2,bool generated)4945 CommaExp::CommaExp(Loc loc, Expression *e1, Expression *e2, bool generated)
4946 : BinExp(loc, TOKcomma, sizeof(CommaExp), e1, e2)
4947 {
4948 isGenerated = generated;
4949 allowCommaExp = generated;
4950 }
4951
isLvalue()4952 bool CommaExp::isLvalue()
4953 {
4954 return e2->isLvalue();
4955 }
4956
toLvalue(Scope * sc,Expression *)4957 Expression *CommaExp::toLvalue(Scope *sc, Expression *)
4958 {
4959 e2 = e2->toLvalue(sc, NULL);
4960 return this;
4961 }
4962
checkModifiable(Scope * sc,int flag)4963 int CommaExp::checkModifiable(Scope *sc, int flag)
4964 {
4965 return e2->checkModifiable(sc, flag);
4966 }
4967
modifiableLvalue(Scope * sc,Expression * e)4968 Expression *CommaExp::modifiableLvalue(Scope *sc, Expression *e)
4969 {
4970 e2 = e2->modifiableLvalue(sc, e);
4971 return this;
4972 }
4973
isBool(bool result)4974 bool CommaExp::isBool(bool result)
4975 {
4976 return e2->isBool(result);
4977 }
4978
toBoolean(Scope * sc)4979 Expression *CommaExp::toBoolean(Scope *sc)
4980 {
4981 Expression *ex2 = e2->toBoolean(sc);
4982 if (ex2->op == TOKerror)
4983 return ex2;
4984 e2 = ex2;
4985 type = e2->type;
4986 return this;
4987 }
4988
addDtorHook(Scope * sc)4989 Expression *CommaExp::addDtorHook(Scope *sc)
4990 {
4991 e2 = e2->addDtorHook(sc);
4992 return this;
4993 }
4994
4995 /************************** IndexExp **********************************/
4996
4997 // e1 [ e2 ]
4998
IndexExp(Loc loc,Expression * e1,Expression * e2)4999 IndexExp::IndexExp(Loc loc, Expression *e1, Expression *e2)
5000 : BinExp(loc, TOKindex, sizeof(IndexExp), e1, e2)
5001 {
5002 //printf("IndexExp::IndexExp('%s')\n", toChars());
5003 lengthVar = NULL;
5004 modifiable = false; // assume it is an rvalue
5005 indexIsInBounds = false;
5006 }
5007
syntaxCopy()5008 Expression *IndexExp::syntaxCopy()
5009 {
5010 IndexExp *ie = new IndexExp(loc, e1->syntaxCopy(), e2->syntaxCopy());
5011 ie->lengthVar = this->lengthVar; // bug7871
5012 return ie;
5013 }
5014
isLvalue()5015 bool IndexExp::isLvalue()
5016 {
5017 return true;
5018 }
5019
toLvalue(Scope *,Expression *)5020 Expression *IndexExp::toLvalue(Scope *, Expression *)
5021 {
5022 return this;
5023 }
5024
checkModifiable(Scope * sc,int flag)5025 int IndexExp::checkModifiable(Scope *sc, int flag)
5026 {
5027 if (e1->type->ty == Tsarray ||
5028 e1->type->ty == Taarray ||
5029 (e1->op == TOKindex && e1->type->ty != Tarray) ||
5030 e1->op == TOKslice)
5031 {
5032 return e1->checkModifiable(sc, flag);
5033 }
5034 return 1;
5035 }
5036
modifiableLvalue(Scope * sc,Expression * e)5037 Expression *IndexExp::modifiableLvalue(Scope *sc, Expression *e)
5038 {
5039 //printf("IndexExp::modifiableLvalue(%s)\n", toChars());
5040 Expression *ex = markSettingAAElem();
5041 if (ex->op == TOKerror)
5042 return ex;
5043
5044 return Expression::modifiableLvalue(sc, e);
5045 }
5046
markSettingAAElem()5047 Expression *IndexExp::markSettingAAElem()
5048 {
5049 if (e1->type->toBasetype()->ty == Taarray)
5050 {
5051 Type *t2b = e2->type->toBasetype();
5052 if (t2b->ty == Tarray && t2b->nextOf()->isMutable())
5053 {
5054 error("associative arrays can only be assigned values with immutable keys, not %s", e2->type->toChars());
5055 return new ErrorExp();
5056 }
5057 modifiable = true;
5058
5059 if (e1->op == TOKindex)
5060 {
5061 Expression *ex = ((IndexExp *)e1)->markSettingAAElem();
5062 if (ex->op == TOKerror)
5063 return ex;
5064 assert(ex == e1);
5065 }
5066 }
5067 return this;
5068 }
5069
5070 /************************* PostExp ***********************************/
5071
PostExp(TOK op,Loc loc,Expression * e)5072 PostExp::PostExp(TOK op, Loc loc, Expression *e)
5073 : BinExp(loc, op, sizeof(PostExp), e,
5074 new IntegerExp(loc, 1, Type::tint32))
5075 {
5076 }
5077
5078 /************************* PreExp ***********************************/
5079
PreExp(TOK op,Loc loc,Expression * e)5080 PreExp::PreExp(TOK op, Loc loc, Expression *e)
5081 : UnaExp(loc, op, sizeof(PreExp), e)
5082 {
5083 }
5084
5085 /************************************************************/
5086
5087 /* op can be TOKassign, TOKconstruct, or TOKblit */
5088
AssignExp(Loc loc,Expression * e1,Expression * e2)5089 AssignExp::AssignExp(Loc loc, Expression *e1, Expression *e2)
5090 : BinExp(loc, TOKassign, sizeof(AssignExp), e1, e2)
5091 {
5092 memset = 0;
5093 }
5094
isLvalue()5095 bool AssignExp::isLvalue()
5096 {
5097 // Array-op 'x[] = y[]' should make an rvalue.
5098 // Setting array length 'x.length = v' should make an rvalue.
5099 if (e1->op == TOKslice ||
5100 e1->op == TOKarraylength)
5101 {
5102 return false;
5103 }
5104 return true;
5105 }
5106
toLvalue(Scope * sc,Expression * ex)5107 Expression *AssignExp::toLvalue(Scope *sc, Expression *ex)
5108 {
5109 if (e1->op == TOKslice ||
5110 e1->op == TOKarraylength)
5111 {
5112 return Expression::toLvalue(sc, ex);
5113 }
5114
5115 /* In front-end level, AssignExp should make an lvalue of e1.
5116 * Taking the address of e1 will be handled in low level layer,
5117 * so this function does nothing.
5118 */
5119 return this;
5120 }
5121
toBoolean(Scope *)5122 Expression *AssignExp::toBoolean(Scope *)
5123 {
5124 // Things like:
5125 // if (a = b) ...
5126 // are usually mistakes.
5127
5128 error("assignment cannot be used as a condition, perhaps == was meant?");
5129 return new ErrorExp();
5130 }
5131
5132 /************************************************************/
5133
ConstructExp(Loc loc,Expression * e1,Expression * e2)5134 ConstructExp::ConstructExp(Loc loc, Expression *e1, Expression *e2)
5135 : AssignExp(loc, e1, e2)
5136 {
5137 op = TOKconstruct;
5138 }
5139
ConstructExp(Loc loc,VarDeclaration * v,Expression * e2)5140 ConstructExp::ConstructExp(Loc loc, VarDeclaration *v, Expression *e2)
5141 : AssignExp(loc, new VarExp(loc, v), e2)
5142 {
5143 assert(v->type && e1->type);
5144 op = TOKconstruct;
5145
5146 if (v->storage_class & (STCref | STCout))
5147 memset |= referenceInit;
5148 }
5149
5150 /************************************************************/
5151
BlitExp(Loc loc,Expression * e1,Expression * e2)5152 BlitExp::BlitExp(Loc loc, Expression *e1, Expression *e2)
5153 : AssignExp(loc, e1, e2)
5154 {
5155 op = TOKblit;
5156 }
5157
BlitExp(Loc loc,VarDeclaration * v,Expression * e2)5158 BlitExp::BlitExp(Loc loc, VarDeclaration *v, Expression *e2)
5159 : AssignExp(loc, new VarExp(loc, v), e2)
5160 {
5161 assert(v->type && e1->type);
5162 op = TOKblit;
5163
5164 if (v->storage_class & (STCref | STCout))
5165 memset |= referenceInit;
5166 }
5167
5168 /************************************************************/
5169
AddAssignExp(Loc loc,Expression * e1,Expression * e2)5170 AddAssignExp::AddAssignExp(Loc loc, Expression *e1, Expression *e2)
5171 : BinAssignExp(loc, TOKaddass, sizeof(AddAssignExp), e1, e2)
5172 {
5173 }
5174
5175 /************************************************************/
5176
MinAssignExp(Loc loc,Expression * e1,Expression * e2)5177 MinAssignExp::MinAssignExp(Loc loc, Expression *e1, Expression *e2)
5178 : BinAssignExp(loc, TOKminass, sizeof(MinAssignExp), e1, e2)
5179 {
5180 }
5181
5182 /************************************************************/
5183
CatAssignExp(Loc loc,Expression * e1,Expression * e2)5184 CatAssignExp::CatAssignExp(Loc loc, Expression *e1, Expression *e2)
5185 : BinAssignExp(loc, TOKcatass, sizeof(CatAssignExp), e1, e2)
5186 {
5187 }
5188
5189 /************************************************************/
5190
MulAssignExp(Loc loc,Expression * e1,Expression * e2)5191 MulAssignExp::MulAssignExp(Loc loc, Expression *e1, Expression *e2)
5192 : BinAssignExp(loc, TOKmulass, sizeof(MulAssignExp), e1, e2)
5193 {
5194 }
5195
5196 /************************************************************/
5197
DivAssignExp(Loc loc,Expression * e1,Expression * e2)5198 DivAssignExp::DivAssignExp(Loc loc, Expression *e1, Expression *e2)
5199 : BinAssignExp(loc, TOKdivass, sizeof(DivAssignExp), e1, e2)
5200 {
5201 }
5202
5203 /************************************************************/
5204
ModAssignExp(Loc loc,Expression * e1,Expression * e2)5205 ModAssignExp::ModAssignExp(Loc loc, Expression *e1, Expression *e2)
5206 : BinAssignExp(loc, TOKmodass, sizeof(ModAssignExp), e1, e2)
5207 {
5208 }
5209
5210 /************************************************************/
5211
ShlAssignExp(Loc loc,Expression * e1,Expression * e2)5212 ShlAssignExp::ShlAssignExp(Loc loc, Expression *e1, Expression *e2)
5213 : BinAssignExp(loc, TOKshlass, sizeof(ShlAssignExp), e1, e2)
5214 {
5215 }
5216
5217 /************************************************************/
5218
ShrAssignExp(Loc loc,Expression * e1,Expression * e2)5219 ShrAssignExp::ShrAssignExp(Loc loc, Expression *e1, Expression *e2)
5220 : BinAssignExp(loc, TOKshrass, sizeof(ShrAssignExp), e1, e2)
5221 {
5222 }
5223
5224 /************************************************************/
5225
UshrAssignExp(Loc loc,Expression * e1,Expression * e2)5226 UshrAssignExp::UshrAssignExp(Loc loc, Expression *e1, Expression *e2)
5227 : BinAssignExp(loc, TOKushrass, sizeof(UshrAssignExp), e1, e2)
5228 {
5229 }
5230
5231 /************************************************************/
5232
AndAssignExp(Loc loc,Expression * e1,Expression * e2)5233 AndAssignExp::AndAssignExp(Loc loc, Expression *e1, Expression *e2)
5234 : BinAssignExp(loc, TOKandass, sizeof(AndAssignExp), e1, e2)
5235 {
5236 }
5237
5238 /************************************************************/
5239
OrAssignExp(Loc loc,Expression * e1,Expression * e2)5240 OrAssignExp::OrAssignExp(Loc loc, Expression *e1, Expression *e2)
5241 : BinAssignExp(loc, TOKorass, sizeof(OrAssignExp), e1, e2)
5242 {
5243 }
5244
5245 /************************************************************/
5246
XorAssignExp(Loc loc,Expression * e1,Expression * e2)5247 XorAssignExp::XorAssignExp(Loc loc, Expression *e1, Expression *e2)
5248 : BinAssignExp(loc, TOKxorass, sizeof(XorAssignExp), e1, e2)
5249 {
5250 }
5251
5252 /***************** PowAssignExp *******************************************/
5253
PowAssignExp(Loc loc,Expression * e1,Expression * e2)5254 PowAssignExp::PowAssignExp(Loc loc, Expression *e1, Expression *e2)
5255 : BinAssignExp(loc, TOKpowass, sizeof(PowAssignExp), e1, e2)
5256 {
5257 }
5258
5259 /************************* AddExp *****************************/
5260
AddExp(Loc loc,Expression * e1,Expression * e2)5261 AddExp::AddExp(Loc loc, Expression *e1, Expression *e2)
5262 : BinExp(loc, TOKadd, sizeof(AddExp), e1, e2)
5263 {
5264 }
5265
5266 /************************************************************/
5267
MinExp(Loc loc,Expression * e1,Expression * e2)5268 MinExp::MinExp(Loc loc, Expression *e1, Expression *e2)
5269 : BinExp(loc, TOKmin, sizeof(MinExp), e1, e2)
5270 {
5271 }
5272
5273 /************************* CatExp *****************************/
5274
CatExp(Loc loc,Expression * e1,Expression * e2)5275 CatExp::CatExp(Loc loc, Expression *e1, Expression *e2)
5276 : BinExp(loc, TOKcat, sizeof(CatExp), e1, e2)
5277 {
5278 }
5279
5280 /************************************************************/
5281
MulExp(Loc loc,Expression * e1,Expression * e2)5282 MulExp::MulExp(Loc loc, Expression *e1, Expression *e2)
5283 : BinExp(loc, TOKmul, sizeof(MulExp), e1, e2)
5284 {
5285 }
5286
5287 /************************************************************/
5288
DivExp(Loc loc,Expression * e1,Expression * e2)5289 DivExp::DivExp(Loc loc, Expression *e1, Expression *e2)
5290 : BinExp(loc, TOKdiv, sizeof(DivExp), e1, e2)
5291 {
5292 }
5293
5294 /************************************************************/
5295
ModExp(Loc loc,Expression * e1,Expression * e2)5296 ModExp::ModExp(Loc loc, Expression *e1, Expression *e2)
5297 : BinExp(loc, TOKmod, sizeof(ModExp), e1, e2)
5298 {
5299 }
5300
5301 /************************************************************/
5302
PowExp(Loc loc,Expression * e1,Expression * e2)5303 PowExp::PowExp(Loc loc, Expression *e1, Expression *e2)
5304 : BinExp(loc, TOKpow, sizeof(PowExp), e1, e2)
5305 {
5306 }
5307
5308 /************************************************************/
5309
ShlExp(Loc loc,Expression * e1,Expression * e2)5310 ShlExp::ShlExp(Loc loc, Expression *e1, Expression *e2)
5311 : BinExp(loc, TOKshl, sizeof(ShlExp), e1, e2)
5312 {
5313 }
5314
5315 /************************************************************/
5316
ShrExp(Loc loc,Expression * e1,Expression * e2)5317 ShrExp::ShrExp(Loc loc, Expression *e1, Expression *e2)
5318 : BinExp(loc, TOKshr, sizeof(ShrExp), e1, e2)
5319 {
5320 }
5321
5322 /************************************************************/
5323
UshrExp(Loc loc,Expression * e1,Expression * e2)5324 UshrExp::UshrExp(Loc loc, Expression *e1, Expression *e2)
5325 : BinExp(loc, TOKushr, sizeof(UshrExp), e1, e2)
5326 {
5327 }
5328
5329 /************************************************************/
5330
AndExp(Loc loc,Expression * e1,Expression * e2)5331 AndExp::AndExp(Loc loc, Expression *e1, Expression *e2)
5332 : BinExp(loc, TOKand, sizeof(AndExp), e1, e2)
5333 {
5334 }
5335
5336 /************************************************************/
5337
OrExp(Loc loc,Expression * e1,Expression * e2)5338 OrExp::OrExp(Loc loc, Expression *e1, Expression *e2)
5339 : BinExp(loc, TOKor, sizeof(OrExp), e1, e2)
5340 {
5341 }
5342
5343 /************************************************************/
5344
XorExp(Loc loc,Expression * e1,Expression * e2)5345 XorExp::XorExp(Loc loc, Expression *e1, Expression *e2)
5346 : BinExp(loc, TOKxor, sizeof(XorExp), e1, e2)
5347 {
5348 }
5349
5350 /************************************************************/
5351
LogicalExp(Loc loc,TOK op,Expression * e1,Expression * e2)5352 LogicalExp::LogicalExp(Loc loc, TOK op, Expression *e1, Expression *e2)
5353 : BinExp(loc, op, sizeof(LogicalExp), e1, e2)
5354 {
5355 }
5356
toBoolean(Scope * sc)5357 Expression *LogicalExp::toBoolean(Scope *sc)
5358 {
5359 Expression *ex2 = e2->toBoolean(sc);
5360 if (ex2->op == TOKerror)
5361 return ex2;
5362 e2 = ex2;
5363 return this;
5364 }
5365
5366 /************************************************************/
5367
InExp(Loc loc,Expression * e1,Expression * e2)5368 InExp::InExp(Loc loc, Expression *e1, Expression *e2)
5369 : BinExp(loc, TOKin, sizeof(InExp), e1, e2)
5370 {
5371 }
5372
5373 /************************************************************/
5374
5375 /* This deletes the key e1 from the associative array e2
5376 */
5377
RemoveExp(Loc loc,Expression * e1,Expression * e2)5378 RemoveExp::RemoveExp(Loc loc, Expression *e1, Expression *e2)
5379 : BinExp(loc, TOKremove, sizeof(RemoveExp), e1, e2)
5380 {
5381 type = Type::tbool;
5382 }
5383
5384 /************************************************************/
5385
CmpExp(TOK op,Loc loc,Expression * e1,Expression * e2)5386 CmpExp::CmpExp(TOK op, Loc loc, Expression *e1, Expression *e2)
5387 : BinExp(loc, op, sizeof(CmpExp), e1, e2)
5388 {
5389 }
5390
5391 /************************************************************/
5392
EqualExp(TOK op,Loc loc,Expression * e1,Expression * e2)5393 EqualExp::EqualExp(TOK op, Loc loc, Expression *e1, Expression *e2)
5394 : BinExp(loc, op, sizeof(EqualExp), e1, e2)
5395 {
5396 assert(op == TOKequal || op == TOKnotequal);
5397 }
5398
5399 /************************************************************/
5400
IdentityExp(TOK op,Loc loc,Expression * e1,Expression * e2)5401 IdentityExp::IdentityExp(TOK op, Loc loc, Expression *e1, Expression *e2)
5402 : BinExp(loc, op, sizeof(IdentityExp), e1, e2)
5403 {
5404 }
5405
5406 /****************************************************************/
5407
CondExp(Loc loc,Expression * econd,Expression * e1,Expression * e2)5408 CondExp::CondExp(Loc loc, Expression *econd, Expression *e1, Expression *e2)
5409 : BinExp(loc, TOKquestion, sizeof(CondExp), e1, e2)
5410 {
5411 this->econd = econd;
5412 }
5413
syntaxCopy()5414 Expression *CondExp::syntaxCopy()
5415 {
5416 return new CondExp(loc, econd->syntaxCopy(), e1->syntaxCopy(), e2->syntaxCopy());
5417 }
5418
hookDtors(Scope * sc)5419 void CondExp::hookDtors(Scope *sc)
5420 {
5421 class DtorVisitor : public StoppableVisitor
5422 {
5423 public:
5424 Scope *sc;
5425 CondExp *ce;
5426 VarDeclaration *vcond;
5427 bool isThen;
5428
5429 DtorVisitor(Scope *sc, CondExp *ce)
5430 {
5431 this->sc = sc;
5432 this->ce = ce;
5433 this->vcond = NULL;
5434 }
5435
5436 void visit(Expression *)
5437 {
5438 //printf("(e = %s)\n", e->toChars());
5439 }
5440
5441 void visit(DeclarationExp *e)
5442 {
5443 VarDeclaration *v = e->declaration->isVarDeclaration();
5444 if (v && !v->isDataseg())
5445 {
5446 if (v->_init)
5447 {
5448 ExpInitializer *ei = v->_init->isExpInitializer();
5449 if (ei)
5450 ei->exp->accept(this);
5451 }
5452
5453 if (v->needsScopeDtor())
5454 {
5455 if (!vcond)
5456 {
5457 vcond = copyToTemp(STCvolatile, "__cond", ce->econd);
5458 dsymbolSemantic(vcond, sc);
5459
5460 Expression *de = new DeclarationExp(ce->econd->loc, vcond);
5461 de = expressionSemantic(de, sc);
5462
5463 Expression *ve = new VarExp(ce->econd->loc, vcond);
5464 ce->econd = Expression::combine(de, ve);
5465 }
5466
5467 //printf("\t++v = %s, v->edtor = %s\n", v->toChars(), v->edtor->toChars());
5468 Expression *ve = new VarExp(vcond->loc, vcond);
5469 if (isThen)
5470 v->edtor = new LogicalExp(v->edtor->loc, TOKandand, ve, v->edtor);
5471 else
5472 v->edtor = new LogicalExp(v->edtor->loc, TOKoror, ve, v->edtor);
5473 v->edtor = expressionSemantic(v->edtor, sc);
5474 //printf("\t--v = %s, v->edtor = %s\n", v->toChars(), v->edtor->toChars());
5475 }
5476 }
5477 }
5478 };
5479
5480 DtorVisitor v(sc, this);
5481 //printf("+%s\n", toChars());
5482 v.isThen = true; walkPostorder(e1, &v);
5483 v.isThen = false; walkPostorder(e2, &v);
5484 //printf("-%s\n", toChars());
5485 }
5486
isLvalue()5487 bool CondExp::isLvalue()
5488 {
5489 return e1->isLvalue() && e2->isLvalue();
5490 }
5491
5492
toLvalue(Scope * sc,Expression *)5493 Expression *CondExp::toLvalue(Scope *sc, Expression *)
5494 {
5495 // convert (econd ? e1 : e2) to *(econd ? &e1 : &e2)
5496 CondExp *e = (CondExp *)copy();
5497 e->e1 = e1->toLvalue(sc, NULL)->addressOf();
5498 e->e2 = e2->toLvalue(sc, NULL)->addressOf();
5499 e->type = type->pointerTo();
5500 return new PtrExp(loc, e, type);
5501 }
5502
checkModifiable(Scope * sc,int flag)5503 int CondExp::checkModifiable(Scope *sc, int flag)
5504 {
5505 return e1->checkModifiable(sc, flag) && e2->checkModifiable(sc, flag);
5506 }
5507
modifiableLvalue(Scope * sc,Expression *)5508 Expression *CondExp::modifiableLvalue(Scope *sc, Expression *)
5509 {
5510 //error("conditional expression %s is not a modifiable lvalue", toChars());
5511 e1 = e1->modifiableLvalue(sc, e1);
5512 e2 = e2->modifiableLvalue(sc, e2);
5513 return toLvalue(sc, this);
5514 }
5515
toBoolean(Scope * sc)5516 Expression *CondExp::toBoolean(Scope *sc)
5517 {
5518 Expression *ex1 = e1->toBoolean(sc);
5519 Expression *ex2 = e2->toBoolean(sc);
5520 if (ex1->op == TOKerror)
5521 return ex1;
5522 if (ex2->op == TOKerror)
5523 return ex2;
5524 e1 = ex1;
5525 e2 = ex2;
5526 return this;
5527 }
5528
5529 /****************************************************************/
5530
DefaultInitExp(Loc loc,TOK subop,int size)5531 DefaultInitExp::DefaultInitExp(Loc loc, TOK subop, int size)
5532 : Expression(loc, TOKdefault, size)
5533 {
5534 this->subop = subop;
5535 }
5536
5537 /****************************************************************/
5538
FileInitExp(Loc loc,TOK tok)5539 FileInitExp::FileInitExp(Loc loc, TOK tok)
5540 : DefaultInitExp(loc, tok, sizeof(FileInitExp))
5541 {
5542 }
5543
resolveLoc(Loc loc,Scope * sc)5544 Expression *FileInitExp::resolveLoc(Loc loc, Scope *sc)
5545 {
5546 //printf("FileInitExp::resolve() %s\n", toChars());
5547 const char *s;
5548 if (subop == TOKfilefullpath)
5549 s = FileName::toAbsolute(loc.filename != NULL ? loc.filename : sc->_module->srcfile->name->toChars());
5550 else
5551 s = loc.filename != NULL ? loc.filename : sc->_module->ident->toChars();
5552
5553 Expression *e = new StringExp(loc, const_cast<char *>(s));
5554 e = expressionSemantic(e, sc);
5555 e = e->castTo(sc, type);
5556 return e;
5557 }
5558
5559 /****************************************************************/
5560
LineInitExp(Loc loc)5561 LineInitExp::LineInitExp(Loc loc)
5562 : DefaultInitExp(loc, TOKline, sizeof(LineInitExp))
5563 {
5564 }
5565
resolveLoc(Loc loc,Scope * sc)5566 Expression *LineInitExp::resolveLoc(Loc loc, Scope *sc)
5567 {
5568 Expression *e = new IntegerExp(loc, loc.linnum, Type::tint32);
5569 e = e->castTo(sc, type);
5570 return e;
5571 }
5572
5573 /****************************************************************/
5574
ModuleInitExp(Loc loc)5575 ModuleInitExp::ModuleInitExp(Loc loc)
5576 : DefaultInitExp(loc, TOKmodulestring, sizeof(ModuleInitExp))
5577 {
5578 }
5579
resolveLoc(Loc loc,Scope * sc)5580 Expression *ModuleInitExp::resolveLoc(Loc loc, Scope *sc)
5581 {
5582 const char *s;
5583 if (sc->callsc)
5584 s = sc->callsc->_module->toPrettyChars();
5585 else
5586 s = sc->_module->toPrettyChars();
5587 Expression *e = new StringExp(loc, const_cast<char *>(s));
5588 e = expressionSemantic(e, sc);
5589 e = e->castTo(sc, type);
5590 return e;
5591 }
5592
5593 /****************************************************************/
5594
FuncInitExp(Loc loc)5595 FuncInitExp::FuncInitExp(Loc loc)
5596 : DefaultInitExp(loc, TOKfuncstring, sizeof(FuncInitExp))
5597 {
5598 }
5599
resolveLoc(Loc loc,Scope * sc)5600 Expression *FuncInitExp::resolveLoc(Loc loc, Scope *sc)
5601 {
5602 const char *s;
5603 if (sc->callsc && sc->callsc->func)
5604 s = sc->callsc->func->Dsymbol::toPrettyChars();
5605 else if (sc->func)
5606 s = sc->func->Dsymbol::toPrettyChars();
5607 else
5608 s = "";
5609 Expression *e = new StringExp(loc, const_cast<char *>(s));
5610 e = expressionSemantic(e, sc);
5611 e = e->castTo(sc, type);
5612 return e;
5613 }
5614
5615 /****************************************************************/
5616
PrettyFuncInitExp(Loc loc)5617 PrettyFuncInitExp::PrettyFuncInitExp(Loc loc)
5618 : DefaultInitExp(loc, TOKprettyfunc, sizeof(PrettyFuncInitExp))
5619 {
5620 }
5621
resolveLoc(Loc loc,Scope * sc)5622 Expression *PrettyFuncInitExp::resolveLoc(Loc loc, Scope *sc)
5623 {
5624 FuncDeclaration *fd;
5625 if (sc->callsc && sc->callsc->func)
5626 fd = sc->callsc->func;
5627 else
5628 fd = sc->func;
5629
5630 const char *s;
5631 if (fd)
5632 {
5633 const char *funcStr = fd->Dsymbol::toPrettyChars();
5634 OutBuffer buf;
5635 functionToBufferWithIdent((TypeFunction *)fd->type, &buf, funcStr);
5636 s = buf.extractChars();
5637 }
5638 else
5639 {
5640 s = "";
5641 }
5642
5643 Expression *e = new StringExp(loc, const_cast<char *>(s));
5644 e = expressionSemantic(e, sc);
5645 e = e->castTo(sc, type);
5646 return e;
5647 }
5648
reorderSettingAAElem(Scope * sc)5649 Expression *BinExp::reorderSettingAAElem(Scope *sc)
5650 {
5651 BinExp *be = this;
5652
5653 if (be->e1->op != TOKindex)
5654 return be;
5655 IndexExp *ie = (IndexExp *)be->e1;
5656 if (ie->e1->type->toBasetype()->ty != Taarray)
5657 return be;
5658
5659 /* Fix evaluation order of setting AA element. (Bugzilla 3825)
5660 * Rewrite:
5661 * aa[k1][k2][k3] op= val;
5662 * as:
5663 * auto ref __aatmp = aa;
5664 * auto ref __aakey3 = k1, __aakey2 = k2, __aakey1 = k3;
5665 * auto ref __aaval = val;
5666 * __aatmp[__aakey3][__aakey2][__aakey1] op= __aaval; // assignment
5667 */
5668
5669 Expression *e0 = NULL;
5670 while (1)
5671 {
5672 Expression *de = NULL;
5673 ie->e2 = extractSideEffect(sc, "__aakey", &de, ie->e2);
5674 e0 = Expression::combine(de, e0);
5675
5676 Expression *ie1 = ie->e1;
5677 if (ie1->op != TOKindex ||
5678 ((IndexExp *)ie1)->e1->type->toBasetype()->ty != Taarray)
5679 {
5680 break;
5681 }
5682 ie = (IndexExp *)ie1;
5683 }
5684 assert(ie->e1->type->toBasetype()->ty == Taarray);
5685
5686 Expression *de = NULL;
5687 ie->e1 = extractSideEffect(sc, "__aatmp", &de, ie->e1);
5688 e0 = Expression::combine(de, e0);
5689
5690 be->e2 = extractSideEffect(sc, "__aaval", &e0, be->e2, true);
5691
5692 //printf("-e0 = %s, be = %s\n", e0->toChars(), be->toChars());
5693 return Expression::combine(e0, be);
5694 }
5695