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