comparison dmd/expression.c @ 875:330f999ade44

Merged DMD 1.038
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 06 Jan 2009 16:33:51 +0100
parents bc982f1ad106
children 27a379f288bf
comparison
equal deleted inserted replaced
874:2ddee23bd70e 875:330f999ade44
10 10
11 #include <stdio.h> 11 #include <stdio.h>
12 #include <stdlib.h> 12 #include <stdlib.h>
13 #include <ctype.h> 13 #include <ctype.h>
14 #include <assert.h> 14 #include <assert.h>
15 #if _MSC_VER
15 #include <complex> 16 #include <complex>
17 #else
18 #endif
16 #include <math.h> 19 #include <math.h>
17 20
18 #if _WIN32 && __DMC__ 21 #if _WIN32 && __DMC__
19 extern "C" char * __cdecl __locale_decpoint; 22 extern "C" char * __cdecl __locale_decpoint;
20 #endif 23 #endif
66 #include "attrib.h" 69 #include "attrib.h"
67 #include "hdrgen.h" 70 #include "hdrgen.h"
68 #include "parse.h" 71 #include "parse.h"
69 72
70 Expression *createTypeInfoArray(Scope *sc, Expression *args[], int dim); 73 Expression *createTypeInfoArray(Scope *sc, Expression *args[], int dim);
74 Expression *expandVar(int result, VarDeclaration *v);
71 75
72 #define LOGSEMANTIC 0 76 #define LOGSEMANTIC 0
73 77
74 /********************************** 78 /**********************************
75 * Set operator precedence for each operator. 79 * Set operator precedence for each operator.
166 precedence[TOKuge] = PREC_rel; 170 precedence[TOKuge] = PREC_rel;
167 precedence[TOKug] = PREC_rel; 171 precedence[TOKug] = PREC_rel;
168 precedence[TOKue] = PREC_rel; 172 precedence[TOKue] = PREC_rel;
169 precedence[TOKin] = PREC_rel; 173 precedence[TOKin] = PREC_rel;
170 174
175 #if 0
171 precedence[TOKequal] = PREC_equal; 176 precedence[TOKequal] = PREC_equal;
172 precedence[TOKnotequal] = PREC_equal; 177 precedence[TOKnotequal] = PREC_equal;
173 precedence[TOKidentity] = PREC_equal; 178 precedence[TOKidentity] = PREC_equal;
174 precedence[TOKnotidentity] = PREC_equal; 179 precedence[TOKnotidentity] = PREC_equal;
180 #else
181 /* Note that we changed precedence, so that < and != have the same
182 * precedence. This change is in the parser, too.
183 */
184 precedence[TOKequal] = PREC_rel;
185 precedence[TOKnotequal] = PREC_rel;
186 precedence[TOKidentity] = PREC_rel;
187 precedence[TOKnotidentity] = PREC_rel;
188 #endif
175 189
176 precedence[TOKand] = PREC_and; 190 precedence[TOKand] = PREC_and;
177 191
178 precedence[TOKxor] = PREC_xor; 192 precedence[TOKxor] = PREC_xor;
179 193
350 //printf("resolveProperties(%s)\n", e->toChars()); 364 //printf("resolveProperties(%s)\n", e->toChars());
351 if (e->type) 365 if (e->type)
352 { 366 {
353 Type *t = e->type->toBasetype(); 367 Type *t = e->type->toBasetype();
354 368
355 if (t->ty == Tfunction) 369 if (t->ty == Tfunction /*|| e->op == TOKoverloadset*/)
356 { 370 {
357 e = new CallExp(e->loc, e); 371 e = new CallExp(e->loc, e);
358 e = e->semantic(sc); 372 e = e->semantic(sc);
359 } 373 }
360 374
537 */ 551 */
538 552
539 void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *arguments) 553 void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *arguments)
540 { 554 {
541 unsigned n; 555 unsigned n;
542 int done;
543 Type *tb;
544 556
545 //printf("functionArguments()\n"); 557 //printf("functionArguments()\n");
546 assert(arguments); 558 assert(arguments);
547 size_t nargs = arguments ? arguments->dim : 0; 559 size_t nargs = arguments ? arguments->dim : 0;
548 size_t nparams = Argument::dim(tf->parameters); 560 size_t nparams = Argument::dim(tf->parameters);
550 if (nargs > nparams && tf->varargs == 0) 562 if (nargs > nparams && tf->varargs == 0)
551 error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs); 563 error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs);
552 564
553 n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams) 565 n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams)
554 566
555 done = 0; 567 int done = 0;
556 for (size_t i = 0; i < n; i++) 568 for (size_t i = 0; i < n; i++)
557 { 569 {
558 Expression *arg; 570 Expression *arg;
559 571
560 if (i < nargs) 572 if (i < nargs)
561 arg = (Expression *)arguments->data[i]; 573 arg = (Expression *)arguments->data[i];
562 else 574 else
563 arg = NULL; 575 arg = NULL;
576 Type *tb;
564 577
565 if (i < nparams) 578 if (i < nparams)
566 { 579 {
567 Argument *p = Argument::getNth(tf->parameters, i); 580 Argument *p = Argument::getNth(tf->parameters, i);
568 581
613 { 626 {
614 arg = new NullExp(loc); 627 arg = new NullExp(loc);
615 break; 628 break;
616 } 629 }
617 #endif 630 #endif
618 static int idn; 631 Identifier *id = Lexer::uniqueId("__arrayArg");
619 char name[10 + sizeof(idn)*3 + 1]; 632 Type *t = new TypeSArray(((TypeArray *)tb)->next, new IntegerExp(nargs - i));
620 sprintf(name, "__arrayArg%d", ++idn);
621 Identifier *id = Lexer::idPool(name);
622 Type *t = new TypeSArray(tb->next, new IntegerExp(nargs - i));
623 t = t->semantic(loc, sc); 633 t = t->semantic(loc, sc);
624 VarDeclaration *v = new VarDeclaration(loc, t, id, new VoidInitializer(loc)); 634 VarDeclaration *v = new VarDeclaration(loc, t, id, new VoidInitializer(loc));
625 v->semantic(sc); 635 v->semantic(sc);
626 v->parent = sc->parent; 636 v->parent = sc->parent;
627 //sc->insert(v); 637 //sc->insert(v);
629 Expression *c = new DeclarationExp(0, v); 639 Expression *c = new DeclarationExp(0, v);
630 c->type = v->type; 640 c->type = v->type;
631 641
632 for (size_t u = i; u < nargs; u++) 642 for (size_t u = i; u < nargs; u++)
633 { Expression *a = (Expression *)arguments->data[u]; 643 { Expression *a = (Expression *)arguments->data[u];
634 if (tret && !tb->next->equals(a->type)) 644 if (tret && !((TypeArray *)tb)->next->equals(a->type))
635 a = a->toDelegate(sc, tret); 645 a = a->toDelegate(sc, tret);
636 646
637 Expression *e = new VarExp(loc, v); 647 Expression *e = new VarExp(loc, v);
638 e = new IndexExp(loc, e, new IntegerExp(u + 1 - nparams)); 648 e = new IndexExp(loc, e, new IntegerExp(u + 1 - nparams));
639 e = new AssignExp(loc, e, a); 649 AssignExp *ae = new AssignExp(loc, e, a);
650 #if DMDV2
651 ae->op = TOKconstruct;
652 #endif
640 if (c) 653 if (c)
641 c = new CommaExp(loc, c, e); 654 c = new CommaExp(loc, c, ae);
642 else 655 else
643 c = e; 656 c = ae;
644 } 657 }
645 arg = new VarExp(loc, v); 658 arg = new VarExp(loc, v);
646 if (c) 659 if (c)
647 arg = new CommaExp(loc, c, arg); 660 arg = new CommaExp(loc, c, arg);
648 break; 661 break;
692 { 705 {
693 arg = arg->checkToPointer(); 706 arg = arg->checkToPointer();
694 } 707 }
695 #endif 708 #endif
696 709
710 #if DMDV2
711 if (tb->ty == Tstruct && !(p->storageClass & (STCref | STCout)))
712 {
713 arg = callCpCtor(loc, sc, arg);
714 }
715 #endif
716
697 717
698 // Convert lazy argument to a delegate 718 // Convert lazy argument to a delegate
699 if (p->storageClass & STClazy) 719 if (p->storageClass & STClazy)
700 { 720 {
701 arg = arg->toDelegate(sc, p->type); 721 arg = arg->toDelegate(sc, p->type);
702 } 722 }
723 #if DMDV2
724 /* Look for arguments that cannot 'escape' from the called
725 * function.
726 */
727 if (!tf->parameterEscapes(p))
728 {
729 /* Function literals can only appear once, so if this
730 * appearance was scoped, there cannot be any others.
731 */
732 if (arg->op == TOKfunction)
733 { FuncExp *fe = (FuncExp *)arg;
734 fe->fd->tookAddressOf = 0;
735 }
736
737 /* For passing a delegate to a scoped parameter,
738 * this doesn't count as taking the address of it.
739 * We only worry about 'escaping' references to the function.
740 */
741 else if (arg->op == TOKdelegate)
742 { DelegateExp *de = (DelegateExp *)arg;
743 if (de->e1->op == TOKvar)
744 { VarExp *ve = (VarExp *)de->e1;
745 FuncDeclaration *f = ve->var->isFuncDeclaration();
746 if (f)
747 { f->tookAddressOf--;
748 //printf("tookAddressOf = %d\n", f->tookAddressOf);
749 }
750 }
751 }
752 }
753 #endif
703 } 754 }
704 else 755 else
705 { 756 {
706 757
707 // If not D linkage, do promotions 758 // If not D linkage, do promotions
776 */ 827 */
777 828
778 void expToCBuffer(OutBuffer *buf, HdrGenState *hgs, Expression *e, enum PREC pr) 829 void expToCBuffer(OutBuffer *buf, HdrGenState *hgs, Expression *e, enum PREC pr)
779 { 830 {
780 //if (precedence[e->op] == 0) e->dump(0); 831 //if (precedence[e->op] == 0) e->dump(0);
781 if (precedence[e->op] < pr) 832 if (precedence[e->op] < pr ||
833 /* Despite precedence, we don't allow a<b<c expressions.
834 * They must be parenthesized.
835 */
836 (pr == PREC_rel && precedence[e->op] == pr))
782 { 837 {
783 buf->writeByte('('); 838 buf->writeByte('(');
784 e->toCBuffer(buf, hgs); 839 e->toCBuffer(buf, hgs);
785 buf->writeByte(')'); 840 buf->writeByte(')');
786 } 841 }
979 1034
980 void Expression::toMangleBuffer(OutBuffer *buf) 1035 void Expression::toMangleBuffer(OutBuffer *buf)
981 { 1036 {
982 error("expression %s is not a valid template value argument", toChars()); 1037 error("expression %s is not a valid template value argument", toChars());
983 } 1038 }
1039
1040 /***************************************
1041 * Return !=0 if expression is an lvalue.
1042 */
1043 #if DMDV2
1044 int Expression::isLvalue()
1045 {
1046 return 0;
1047 }
1048 #endif
984 1049
985 /******************************* 1050 /*******************************
986 * Give error if we're not an lvalue. 1051 * Give error if we're not an lvalue.
987 * If we can, convert expression to be an lvalue. 1052 * If we can, convert expression to be an lvalue.
988 */ 1053 */
1000 Expression *Expression::modifiableLvalue(Scope *sc, Expression *e) 1065 Expression *Expression::modifiableLvalue(Scope *sc, Expression *e)
1001 { 1066 {
1002 //printf("Expression::modifiableLvalue() %s, type = %s\n", toChars(), type->toChars()); 1067 //printf("Expression::modifiableLvalue() %s, type = %s\n", toChars(), type->toChars());
1003 1068
1004 // See if this expression is a modifiable lvalue (i.e. not const) 1069 // See if this expression is a modifiable lvalue (i.e. not const)
1070 #if DMDV2
1071 if (type && (!type->isMutable() || !type->isAssignable()))
1072 error("%s is not mutable", e->toChars());
1073 #endif
1005 return toLvalue(sc, e); 1074 return toLvalue(sc, e);
1006 } 1075 }
1007 1076
1008 /************************************ 1077 /************************************
1009 * Detect cases where pointers to the stack can 'escape' the 1078 * Detect cases where pointers to the stack can 'escape' the
1046 1115
1047 void Expression::checkDeprecated(Scope *sc, Dsymbol *s) 1116 void Expression::checkDeprecated(Scope *sc, Dsymbol *s)
1048 { 1117 {
1049 s->checkDeprecated(loc, sc); 1118 s->checkDeprecated(loc, sc);
1050 } 1119 }
1120
1121 #if DMDV2
1122 void Expression::checkPurity(Scope *sc, FuncDeclaration *f)
1123 {
1124 if (sc->func && sc->func->isPure() && !sc->intypeof && !f->isPure())
1125 error("pure function '%s' cannot call impure function '%s'\n",
1126 sc->func->toChars(), f->toChars());
1127 }
1128 #endif
1051 1129
1052 /******************************** 1130 /********************************
1053 * Check for expressions that have no use. 1131 * Check for expressions that have no use.
1054 * Input: 1132 * Input:
1055 * flag 0 not going to use the result, so issue error message if no 1133 * flag 0 not going to use the result, so issue error message if no
1173 * Valid only after semantic() pass. 1251 * Valid only after semantic() pass.
1174 */ 1252 */
1175 1253
1176 int Expression::canThrow() 1254 int Expression::canThrow()
1177 { 1255 {
1256 #if DMDV2
1257 return FALSE;
1258 #else
1178 return TRUE; 1259 return TRUE;
1260 #endif
1179 } 1261 }
1180 1262
1181 1263
1182 1264
1183 Expressions *Expression::arraySyntaxCopy(Expressions *exps) 1265 Expressions *Expression::arraySyntaxCopy(Expressions *exps)
1847 if (!s->parent && scopesym->isArrayScopeSymbol()) 1929 if (!s->parent && scopesym->isArrayScopeSymbol())
1848 { // Kludge to run semantic() here because 1930 { // Kludge to run semantic() here because
1849 // ArrayScopeSymbol::search() doesn't have access to sc. 1931 // ArrayScopeSymbol::search() doesn't have access to sc.
1850 s->semantic(sc); 1932 s->semantic(sc);
1851 } 1933 }
1852 // Look to see if f is really a function template 1934 /* If f is really a function template,
1935 * then replace f with the function template declaration.
1936 */
1853 FuncDeclaration *f = s->isFuncDeclaration(); 1937 FuncDeclaration *f = s->isFuncDeclaration();
1854 if (f && f->parent) 1938 if (f && f->parent)
1855 { TemplateInstance *ti = f->parent->isTemplateInstance(); 1939 { TemplateInstance *ti = f->parent->isTemplateInstance();
1856 1940
1857 if (ti && 1941 if (ti &&
1889 buf->writestring(ident->toHChars2()); 1973 buf->writestring(ident->toHChars2());
1890 else 1974 else
1891 buf->writestring(ident->toChars()); 1975 buf->writestring(ident->toChars());
1892 } 1976 }
1893 1977
1978 #if DMDV2
1979 int IdentifierExp::isLvalue()
1980 {
1981 return 1;
1982 }
1983 #endif
1984
1894 Expression *IdentifierExp::toLvalue(Scope *sc, Expression *e) 1985 Expression *IdentifierExp::toLvalue(Scope *sc, Expression *e)
1895 { 1986 {
1896 #if 0 1987 #if 0
1897 tym = tybasic(e1->ET->Tty); 1988 tym = tybasic(e1->ET->Tty);
1898 if (!(tyscalar(tym) || 1989 if (!(tyscalar(tym) ||
1952 thiscd = sc->func->parent->isClassDeclaration(); 2043 thiscd = sc->func->parent->isClassDeclaration();
1953 2044
1954 // BUG: This should happen after overload resolution for functions, not before 2045 // BUG: This should happen after overload resolution for functions, not before
1955 if (s->needThis()) 2046 if (s->needThis())
1956 { 2047 {
1957 if (hasThis(sc) /*&& !s->isFuncDeclaration()*/) 2048 if (hasThis(sc)
2049 #if DMDV2
2050 && !s->isFuncDeclaration()
2051 #endif
2052 )
1958 { 2053 {
1959 // Supply an implicit 'this', as in 2054 // Supply an implicit 'this', as in
1960 // this.ident 2055 // this.ident
1961 2056
1962 DotVarExp *de; 2057 DotVarExp *de;
2110 void DsymbolExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2205 void DsymbolExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
2111 { 2206 {
2112 buf->writestring(s->toChars()); 2207 buf->writestring(s->toChars());
2113 } 2208 }
2114 2209
2210 #if DMDV2
2211 int DsymbolExp::isLvalue()
2212 {
2213 return 1;
2214 }
2215 #endif
2216
2115 Expression *DsymbolExp::toLvalue(Scope *sc, Expression *e) 2217 Expression *DsymbolExp::toLvalue(Scope *sc, Expression *e)
2116 { 2218 {
2117 #if 0 2219 #if 0
2118 tym = tybasic(e1->ET->Tty); 2220 tym = tybasic(e1->ET->Tty);
2119 if (!(tyscalar(tym) || 2221 if (!(tyscalar(tym) ||
2211 2313
2212 void ThisExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2314 void ThisExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
2213 { 2315 {
2214 buf->writestring("this"); 2316 buf->writestring("this");
2215 } 2317 }
2318
2319 #if DMDV2
2320 int ThisExp::isLvalue()
2321 {
2322 return 1;
2323 }
2324 #endif
2216 2325
2217 Expression *ThisExp::toLvalue(Scope *sc, Expression *e) 2326 Expression *ThisExp::toLvalue(Scope *sc, Expression *e)
2218 { 2327 {
2219 return this; 2328 return this;
2220 } 2329 }
2429 printf("StringExp::semantic() %s\n", toChars()); 2538 printf("StringExp::semantic() %s\n", toChars());
2430 #endif 2539 #endif
2431 if (!type) 2540 if (!type)
2432 { OutBuffer buffer; 2541 { OutBuffer buffer;
2433 size_t newlen = 0; 2542 size_t newlen = 0;
2434 char *p; 2543 const char *p;
2435 size_t u; 2544 size_t u;
2436 unsigned c; 2545 unsigned c;
2437 2546
2438 switch (postfix) 2547 switch (postfix)
2439 { 2548 {
2627 } 2736 }
2628 2737
2629 void StringExp::toMangleBuffer(OutBuffer *buf) 2738 void StringExp::toMangleBuffer(OutBuffer *buf)
2630 { char m; 2739 { char m;
2631 OutBuffer tmp; 2740 OutBuffer tmp;
2632 char *p; 2741 const char *p;
2633 unsigned c; 2742 unsigned c;
2634 size_t u; 2743 size_t u;
2635 unsigned char *q; 2744 unsigned char *q;
2636 unsigned qlen; 2745 unsigned qlen;
2637 2746
2770 { 2879 {
2771 size_t dim = elements ? elements->dim : 0; 2880 size_t dim = elements ? elements->dim : 0;
2772 return result ? (dim != 0) : (dim == 0); 2881 return result ? (dim != 0) : (dim == 0);
2773 } 2882 }
2774 2883
2884 #if DMDV2
2885 int ArrayLiteralExp::canThrow()
2886 {
2887 return 1; // because it can fail allocating memory
2888 }
2889 #endif
2890
2775 void ArrayLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2891 void ArrayLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
2776 { 2892 {
2777 buf->writeByte('['); 2893 buf->writeByte('[');
2778 argsToCBuffer(buf, elements, hgs); 2894 argsToCBuffer(buf, elements, hgs);
2779 buf->writeByte(']'); 2895 buf->writeByte(']');
2888 { 3004 {
2889 size_t dim = keys->dim; 3005 size_t dim = keys->dim;
2890 return result ? (dim != 0) : (dim == 0); 3006 return result ? (dim != 0) : (dim == 0);
2891 } 3007 }
2892 3008
3009 #if DMDV2
3010 int AssocArrayLiteralExp::canThrow()
3011 {
3012 return 1;
3013 }
3014 #endif
3015
2893 void AssocArrayLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3016 void AssocArrayLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
2894 { 3017 {
2895 buf->writeByte('['); 3018 buf->writeByte('[');
2896 for (size_t i = 0; i < keys->dim; i++) 3019 for (size_t i = 0; i < keys->dim; i++)
2897 { Expression *key = (Expression *)keys->data[i]; 3020 { Expression *key = (Expression *)keys->data[i];
3072 } 3195 }
3073 } 3196 }
3074 return -1; 3197 return -1;
3075 } 3198 }
3076 3199
3200 #if DMDV2
3201 int StructLiteralExp::isLvalue()
3202 {
3203 return 1;
3204 }
3205 #endif
3077 3206
3078 Expression *StructLiteralExp::toLvalue(Scope *sc, Expression *e) 3207 Expression *StructLiteralExp::toLvalue(Scope *sc, Expression *e)
3079 { 3208 {
3080 return this; 3209 return this;
3081 } 3210 }
3093 } 3222 }
3094 if (flag == 0 && f == 0) 3223 if (flag == 0 && f == 0)
3095 Expression::checkSideEffect(0); 3224 Expression::checkSideEffect(0);
3096 return f; 3225 return f;
3097 } 3226 }
3227
3228 #if DMDV2
3229 int StructLiteralExp::canThrow()
3230 {
3231 return arrayExpressionCanThrow(elements);
3232 }
3233 #endif
3098 3234
3099 void StructLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3235 void StructLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3100 { 3236 {
3101 buf->writestring(sd->toChars()); 3237 buf->writestring(sd->toChars());
3102 buf->writeByte('('); 3238 buf->writeByte('(');
3284 { 3420 {
3285 error("template %s has no value", toChars()); 3421 error("template %s has no value", toChars());
3286 } 3422 }
3287 3423
3288 /********************** NewExp **************************************/ 3424 /********************** NewExp **************************************/
3425
3426 /* thisexp.new(newargs) newtype(arguments) */
3289 3427
3290 NewExp::NewExp(Loc loc, Expression *thisexp, Expressions *newargs, 3428 NewExp::NewExp(Loc loc, Expression *thisexp, Expressions *newargs,
3291 Type *newtype, Expressions *arguments) 3429 Type *newtype, Expressions *arguments)
3292 : Expression(loc, TOKnew, sizeof(NewExp)) 3430 : Expression(loc, TOKnew, sizeof(NewExp))
3293 { 3431 {
3470 if (arguments && arguments->dim) 3608 if (arguments && arguments->dim)
3471 error("no constructor for %s", cd->toChars()); 3609 error("no constructor for %s", cd->toChars());
3472 } 3610 }
3473 3611
3474 if (cd->aggNew) 3612 if (cd->aggNew)
3475 { Expression *e; 3613 {
3476
3477 f = cd->aggNew;
3478
3479 // Prepend the uint size argument to newargs[] 3614 // Prepend the uint size argument to newargs[]
3480 e = new IntegerExp(loc, cd->size(loc), Type::tuns32); 3615 Expression *e = new IntegerExp(loc, cd->size(loc), Type::tuns32);
3481 if (!newargs) 3616 if (!newargs)
3482 newargs = new Expressions(); 3617 newargs = new Expressions();
3483 newargs->shift(e); 3618 newargs->shift(e);
3484 3619
3485 f = f->overloadResolve(loc, newargs); 3620 f = cd->aggNew->overloadResolve(loc, newargs);
3486 allocator = f->isNewDeclaration(); 3621 allocator = f->isNewDeclaration();
3487 assert(allocator); 3622 assert(allocator);
3488 3623
3489 tf = (TypeFunction *)f->type; 3624 tf = (TypeFunction *)f->type;
3490 functionArguments(loc, sc, tf, newargs); 3625 functionArguments(loc, sc, tf, newargs);
3492 else 3627 else
3493 { 3628 {
3494 if (newargs && newargs->dim) 3629 if (newargs && newargs->dim)
3495 error("no allocator for %s", cd->toChars()); 3630 error("no allocator for %s", cd->toChars());
3496 } 3631 }
3497
3498 } 3632 }
3499 else if (tb->ty == Tstruct) 3633 else if (tb->ty == Tstruct)
3500 { 3634 {
3501 TypeStruct *ts = (TypeStruct *)tb; 3635 TypeStruct *ts = (TypeStruct *)tb;
3502 StructDeclaration *sd = ts->sym; 3636 StructDeclaration *sd = ts->sym;
3573 int NewExp::checkSideEffect(int flag) 3707 int NewExp::checkSideEffect(int flag)
3574 { 3708 {
3575 return 1; 3709 return 1;
3576 } 3710 }
3577 3711
3712 #if DMDV2
3713 int NewExp::canThrow()
3714 {
3715 return 1;
3716 }
3717 #endif
3718
3578 void NewExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3719 void NewExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3579 { int i; 3720 { int i;
3580 3721
3581 if (thisexp) 3722 if (thisexp)
3582 { expToCBuffer(buf, hgs, thisexp, PREC_primary); 3723 { expToCBuffer(buf, hgs, thisexp, PREC_primary);
3640 int NewAnonClassExp::checkSideEffect(int flag) 3781 int NewAnonClassExp::checkSideEffect(int flag)
3641 { 3782 {
3642 return 1; 3783 return 1;
3643 } 3784 }
3644 3785
3786 #if DMDV2
3787 int NewAnonClassExp::canThrow()
3788 {
3789 return 1;
3790 }
3791 #endif
3792
3645 void NewAnonClassExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3793 void NewAnonClassExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3646 { int i; 3794 { int i;
3647 3795
3648 if (thisexp) 3796 if (thisexp)
3649 { expToCBuffer(buf, hgs, thisexp, PREC_primary); 3797 { expToCBuffer(buf, hgs, thisexp, PREC_primary);
3667 if (cd) 3815 if (cd)
3668 { 3816 {
3669 cd->toCBuffer(buf, hgs); 3817 cd->toCBuffer(buf, hgs);
3670 } 3818 }
3671 } 3819 }
3820
3821 /********************** SymbolExp **************************************/
3822
3823 #if DMDV2
3824 SymbolExp::SymbolExp(Loc loc, enum TOK op, int size, Declaration *var, int hasOverloads)
3825 : Expression(loc, op, size)
3826 {
3827 assert(var);
3828 this->var = var;
3829 this->hasOverloads = hasOverloads;
3830 }
3831 #endif
3672 3832
3673 /********************** SymOffExp **************************************/ 3833 /********************** SymOffExp **************************************/
3674 3834
3675 SymOffExp::SymOffExp(Loc loc, Declaration *var, unsigned offset) 3835 SymOffExp::SymOffExp(Loc loc, Declaration *var, unsigned offset)
3676 : Expression(loc, TOKsymoff, sizeof(SymOffExp)) 3836 : Expression(loc, TOKsymoff, sizeof(SymOffExp))
3758 type = new TypeDelegate(tf); 3918 type = new TypeDelegate(tf);
3759 type = type->semantic(loc, sc); 3919 type = type->semantic(loc, sc);
3760 } 3920 }
3761 #endif 3921 #endif
3762 } 3922 }
3923 /* Fix for 1161 doesn't work because it causes protection
3924 * problems when instantiating imported templates passing private
3925 * variables as alias template parameters.
3926 */
3927 //accessCheck(loc, sc, NULL, var);
3763 3928
3764 VarDeclaration *v = var->isVarDeclaration(); 3929 VarDeclaration *v = var->isVarDeclaration();
3765 if (v) 3930 if (v)
3766 { 3931 {
3767 if (v->isConst() && type->toBasetype()->ty != Tsarray && v->init) 3932 if (v->isConst() && type->toBasetype()->ty != Tsarray && v->init)
3772 //ei->exp->implicitCastTo(sc, type)->print(); 3937 //ei->exp->implicitCastTo(sc, type)->print();
3773 return ei->exp->implicitCastTo(sc, type); 3938 return ei->exp->implicitCastTo(sc, type);
3774 } 3939 }
3775 } 3940 }
3776 v->checkNestedReference(sc, loc); 3941 v->checkNestedReference(sc, loc);
3942 #if DMDV2
3943 if (sc->func && sc->func->isPure() && !sc->intypeof)
3944 {
3945 if (v->isDataseg() && !v->isInvariant())
3946 error("pure function '%s' cannot access mutable static data '%s'", sc->func->toChars(), v->toChars());
3947 }
3948 #endif
3777 } 3949 }
3778 #if 0 3950 #if 0
3779 else if ((fd = var->isFuncLiteralDeclaration()) != NULL) 3951 else if ((fd = var->isFuncLiteralDeclaration()) != NULL)
3780 { Expression *e; 3952 { Expression *e;
3781 e = new FuncExp(loc, fd); 3953 e = new FuncExp(loc, fd);
3809 else if (v->storage_class & STCvariadic) 3981 else if (v->storage_class & STCvariadic)
3810 error("escaping reference to variadic parameter %s", v->toChars()); 3982 error("escaping reference to variadic parameter %s", v->toChars());
3811 } 3983 }
3812 } 3984 }
3813 } 3985 }
3986
3987 #if DMDV2
3988 int VarExp::isLvalue()
3989 {
3990 if (var->storage_class & STClazy)
3991 return 0;
3992 return 1;
3993 }
3994 #endif
3814 3995
3815 Expression *VarExp::toLvalue(Scope *sc, Expression *e) 3996 Expression *VarExp::toLvalue(Scope *sc, Expression *e)
3816 { 3997 {
3817 #if 0 3998 #if 0
3818 tym = tybasic(e1->ET->Tty); 3999 tym = tybasic(e1->ET->Tty);
4024 if (flag == 0 && f == 0) 4205 if (flag == 0 && f == 0)
4025 Expression::checkSideEffect(0); 4206 Expression::checkSideEffect(0);
4026 return f; 4207 return f;
4027 } 4208 }
4028 4209
4210 #if DMDV2
4211 int TupleExp::canThrow()
4212 {
4213 return arrayExpressionCanThrow(exps);
4214 }
4215 #endif
4216
4029 void TupleExp::checkEscape() 4217 void TupleExp::checkEscape()
4030 { 4218 {
4031 for (size_t i = 0; i < exps->dim; i++) 4219 for (size_t i = 0; i < exps->dim; i++)
4032 { Expression *e = (Expression *)exps->data[i]; 4220 { Expression *e = (Expression *)exps->data[i];
4033 e->checkEscape(); 4221 e->checkEscape();
4192 4380
4193 int DeclarationExp::checkSideEffect(int flag) 4381 int DeclarationExp::checkSideEffect(int flag)
4194 { 4382 {
4195 return 1; 4383 return 1;
4196 } 4384 }
4385
4386 #if DMDV2
4387 int DeclarationExp::canThrow()
4388 {
4389 VarDeclaration *v = declaration->isVarDeclaration();
4390 if (v && v->init)
4391 { ExpInitializer *ie = v->init->isExpInitializer();
4392 return ie && ie->exp->canThrow();
4393 }
4394 return 0;
4395 }
4396 #endif
4197 4397
4198 void DeclarationExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 4398 void DeclarationExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
4199 { 4399 {
4200 declaration->toCBuffer(buf, hgs); 4400 declaration->toCBuffer(buf, hgs);
4201 } 4401 }
4396 goto Lno; 4596 goto Lno;
4397 tded = targ; 4597 tded = targ;
4398 break; 4598 break;
4399 4599
4400 case TOKinvariant: 4600 case TOKinvariant:
4601 case TOKimmutable:
4401 if (!targ->isInvariant()) 4602 if (!targ->isInvariant())
4402 goto Lno; 4603 goto Lno;
4403 tded = targ; 4604 tded = targ;
4404 break; 4605 break;
4405 #endif 4606 #endif
4601 e1 = e1->semantic(sc); 4802 e1 = e1->semantic(sc);
4602 // if (!e1->type) 4803 // if (!e1->type)
4603 // error("%s has no value", e1->toChars()); 4804 // error("%s has no value", e1->toChars());
4604 return this; 4805 return this;
4605 } 4806 }
4807
4808 #if DMDV2
4809 int UnaExp::canThrow()
4810 {
4811 return e1->canThrow();
4812 }
4813 #endif
4606 4814
4607 void UnaExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 4815 void UnaExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
4608 { 4816 {
4609 buf->writestring(Token::toChars(op)); 4817 buf->writestring(Token::toChars(op));
4610 expToCBuffer(buf, hgs, e1, precedence[op]); 4818 expToCBuffer(buf, hgs, e1, precedence[op]);
4771 int BinExp::isunsigned() 4979 int BinExp::isunsigned()
4772 { 4980 {
4773 return e1->type->isunsigned() || e2->type->isunsigned(); 4981 return e1->type->isunsigned() || e2->type->isunsigned();
4774 } 4982 }
4775 4983
4984 #if DMDV2
4985 int BinExp::canThrow()
4986 {
4987 return e1->canThrow() || e2->canThrow();
4988 }
4989 #endif
4990
4776 void BinExp::incompatibleTypes() 4991 void BinExp::incompatibleTypes()
4777 { 4992 {
4778 error("incompatible types for ((%s) %s (%s)): '%s' and '%s'", 4993 error("incompatible types for ((%s) %s (%s)): '%s' and '%s'",
4779 e1->toChars(), Token::toChars(op), e2->toChars(), 4994 e1->toChars(), Token::toChars(op), e2->toChars(),
4780 e1->type->toChars(), e2->type->toChars()); 4995 e1->type->toChars(), e2->type->toChars());
4803 StringExp *se = (StringExp *)e1; 5018 StringExp *se = (StringExp *)e1;
4804 se = se->toUTF8(sc); 5019 se = se->toUTF8(sc);
4805 Parser p(sc->module, (unsigned char *)se->string, se->len, 0); 5020 Parser p(sc->module, (unsigned char *)se->string, se->len, 0);
4806 p.loc = loc; 5021 p.loc = loc;
4807 p.nextToken(); 5022 p.nextToken();
5023 //printf("p.loc.linnum = %d\n", p.loc.linnum);
4808 Expression *e = p.parseExpression(); 5024 Expression *e = p.parseExpression();
4809 if (p.token.value != TOKeof) 5025 if (p.token.value != TOKeof)
4810 error("incomplete mixin expression (%s)", se->toChars()); 5026 error("incomplete mixin expression (%s)", se->toChars());
4811 return e->semantic(sc); 5027 return e->semantic(sc);
4812 } 5028 }
4875 } 5091 }
4876 Lret: 5092 Lret:
4877 return se->semantic(sc); 5093 return se->semantic(sc);
4878 5094
4879 Lerror: 5095 Lerror:
4880 se = new StringExp(loc, ""); 5096 se = new StringExp(loc, (char *)"");
4881 goto Lret; 5097 goto Lret;
4882 } 5098 }
4883 5099
4884 void FileExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 5100 void FileExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
4885 { 5101 {
4937 5153
4938 int AssertExp::checkSideEffect(int flag) 5154 int AssertExp::checkSideEffect(int flag)
4939 { 5155 {
4940 return 1; 5156 return 1;
4941 } 5157 }
5158
5159 #if DMDV2
5160 int AssertExp::canThrow()
5161 {
5162 return (global.params.useAssert != 0);
5163 }
5164 #endif
4942 5165
4943 void AssertExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 5166 void AssertExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
4944 { 5167 {
4945 buf->writestring("assert("); 5168 buf->writestring("assert(");
4946 expToCBuffer(buf, hgs, e1, PREC_assign); 5169 expToCBuffer(buf, hgs, e1, PREC_assign);
5160 e->type = f->type; 5383 e->type = f->type;
5161 } 5384 }
5162 } 5385 }
5163 return e; 5386 return e;
5164 } 5387 }
5388 #if DMDV2
5389 OverloadSet *o = s->isOverloadSet();
5390 if (o)
5391 { //printf("'%s' is an overload set\n", o->toChars());
5392 return new OverExp(o);
5393 }
5394 #endif
5165 5395
5166 Type *t = s->getType(); 5396 Type *t = s->getType();
5167 if (t) 5397 if (t)
5168 { 5398 {
5169 return new TypeExp(loc, t); 5399 return new TypeExp(loc, t);
5222 { 5452 {
5223 e = new PtrExp(loc, e1); 5453 e = new PtrExp(loc, e1);
5224 e->type = ((TypePointer *)e1->type)->next; 5454 e->type = ((TypePointer *)e1->type)->next;
5225 return e->type->dotExp(sc, e, ident); 5455 return e->type->dotExp(sc, e, ident);
5226 } 5456 }
5457 #if DMDV2
5458 else if (t1b->ty == Tarray ||
5459 t1b->ty == Tsarray ||
5460 t1b->ty == Taarray)
5461 { /* If ident is not a valid property, rewrite:
5462 * e1.ident
5463 * as:
5464 * .ident(e1)
5465 */
5466 unsigned errors = global.errors;
5467 global.gag++;
5468 e = e1->type->dotExp(sc, e1, ident);
5469 global.gag--;
5470 if (errors != global.errors) // if failed to find the property
5471 {
5472 global.errors = errors;
5473 e = new DotIdExp(loc, new IdentifierExp(loc, Id::empty), ident);
5474 e = new CallExp(loc, e, e1);
5475 }
5476 e = e->semantic(sc);
5477 return e;
5478 }
5479 #endif
5227 else 5480 else
5228 { 5481 {
5229 e = e1->type->dotExp(sc, e1, ident); 5482 e = e1->type->dotExp(sc, e1, ident);
5230 e = e->semantic(sc); 5483 e = e->semantic(sc);
5231 return e; 5484 return e;
5339 } 5592 }
5340 //printf("-DotVarExp::semantic('%s')\n", toChars()); 5593 //printf("-DotVarExp::semantic('%s')\n", toChars());
5341 return this; 5594 return this;
5342 } 5595 }
5343 5596
5597 #if DMDV2
5598 int DotVarExp::isLvalue()
5599 {
5600 return 1;
5601 }
5602 #endif
5603
5344 Expression *DotVarExp::toLvalue(Scope *sc, Expression *e) 5604 Expression *DotVarExp::toLvalue(Scope *sc, Expression *e)
5345 { 5605 {
5346 //printf("DotVarExp::toLvalue(%s)\n", toChars()); 5606 //printf("DotVarExp::toLvalue(%s)\n", toChars());
5347 return this; 5607 return this;
5348 } 5608 }
5389 } 5649 }
5390 } 5650 }
5391 break; 5651 break;
5392 } 5652 }
5393 } 5653 }
5654 #if DMDV2
5655 else
5656 {
5657 Type *t1 = e1->type->toBasetype();
5658
5659 if (!t1->isMutable() ||
5660 (t1->ty == Tpointer && !t1->nextOf()->isMutable()) ||
5661 !var->type->isMutable() ||
5662 !var->type->isAssignable() ||
5663 var->storage_class & STCmanifest
5664 )
5665 error("cannot modify const/invariant %s", toChars());
5666 }
5667 #endif
5394 return this; 5668 return this;
5395 } 5669 }
5396 5670
5397 void DotVarExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 5671 void DotVarExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5398 { 5672 {
5711 else if (e1ty == Tarray || e1ty == Tsarray || e1ty == Taarray) 5985 else if (e1ty == Tarray || e1ty == Tsarray || e1ty == Taarray)
5712 { 5986 {
5713 if (!arguments) 5987 if (!arguments)
5714 arguments = new Expressions(); 5988 arguments = new Expressions();
5715 arguments->shift(dotid->e1); 5989 arguments->shift(dotid->e1);
5990 #if DMDV2
5991 e1 = new DotIdExp(dotid->loc, new IdentifierExp(dotid->loc, Id::empty), dotid->ident);
5992 #else
5716 e1 = new IdentifierExp(dotid->loc, dotid->ident); 5993 e1 = new IdentifierExp(dotid->loc, dotid->ident);
5717 } 5994 #endif
5718 } 5995 }
5719 } 5996 }
5720 5997 }
5721 #if DMDV2 5998
5999 #if 1
5722 /* This recognizes: 6000 /* This recognizes:
5723 * foo!(tiargs)(funcargs) 6001 * foo!(tiargs)(funcargs)
5724 */ 6002 */
5725 if (e1->op == TOKimport && !e1->type) 6003 if (e1->op == TOKimport && !e1->type)
5726 { ScopeExp *se = (ScopeExp *)e1; 6004 { ScopeExp *se = (ScopeExp *)e1;
5899 TemplateDeclaration *td = dte->td; 6177 TemplateDeclaration *td = dte->td;
5900 assert(td); 6178 assert(td);
5901 if (!arguments) 6179 if (!arguments)
5902 // Should fix deduceFunctionTemplate() so it works on NULL argument 6180 // Should fix deduceFunctionTemplate() so it works on NULL argument
5903 arguments = new Expressions(); 6181 arguments = new Expressions();
5904 f = td->deduceFunctionTemplate(sc, loc, NULL, arguments); 6182 f = td->deduceFunctionTemplate(sc, loc, targsi, NULL, arguments);
5905 if (!f) 6183 if (!f)
5906 { type = Type::terror; 6184 { type = Type::terror;
5907 return this; 6185 return this;
5908 } 6186 }
5909 ad = td->toParent()->isAggregateDeclaration(); 6187 ad = td->toParent()->isAggregateDeclaration();
5923 { 6201 {
5924 error("cannot call public/export function %s from invariant", f->toChars()); 6202 error("cannot call public/export function %s from invariant", f->toChars());
5925 } 6203 }
5926 6204
5927 checkDeprecated(sc, f); 6205 checkDeprecated(sc, f);
6206 #if DMDV2
6207 checkPurity(sc, f);
6208 #endif
5928 accessCheck(loc, sc, ue->e1, f); 6209 accessCheck(loc, sc, ue->e1, f);
5929 if (!f->needThis()) 6210 if (!f->needThis())
5930 { 6211 {
5931 VarExp *ve = new VarExp(loc, f); 6212 VarExp *ve = new VarExp(loc, f);
5932 e1 = new CommaExp(loc, ue->e1, ve); 6213 e1 = new CommaExp(loc, ue->e1, ve);
5988 sc->callSuper |= CSXany_ctor | CSXsuper_ctor; 6269 sc->callSuper |= CSXany_ctor | CSXsuper_ctor;
5989 } 6270 }
5990 6271
5991 f = f->overloadResolve(loc, arguments); 6272 f = f->overloadResolve(loc, arguments);
5992 checkDeprecated(sc, f); 6273 checkDeprecated(sc, f);
6274 #if DMDV2
6275 checkPurity(sc, f);
6276 #endif
5993 e1 = new DotVarExp(e1->loc, e1, f); 6277 e1 = new DotVarExp(e1->loc, e1, f);
5994 e1 = e1->semantic(sc); 6278 e1 = e1->semantic(sc);
5995 t1 = e1->type; 6279 t1 = e1->type;
5996 } 6280 }
5997 } 6281 }
6025 } 6309 }
6026 6310
6027 f = cd->ctor; 6311 f = cd->ctor;
6028 f = f->overloadResolve(loc, arguments); 6312 f = f->overloadResolve(loc, arguments);
6029 checkDeprecated(sc, f); 6313 checkDeprecated(sc, f);
6314 #if DMDV2
6315 checkPurity(sc, f);
6316 #endif
6030 e1 = new DotVarExp(e1->loc, e1, f); 6317 e1 = new DotVarExp(e1->loc, e1, f);
6031 e1 = e1->semantic(sc); 6318 e1 = e1->semantic(sc);
6032 t1 = e1->type; 6319 t1 = e1->type;
6033 6320
6034 // BUG: this should really be done by checking the static 6321 // BUG: this should really be done by checking the static
6060 e1 = e; 6347 e1 = e;
6061 } 6348 }
6062 else if (e1->op == TOKtemplate) 6349 else if (e1->op == TOKtemplate)
6063 { 6350 {
6064 TemplateExp *te = (TemplateExp *)e1; 6351 TemplateExp *te = (TemplateExp *)e1;
6065 f = te->td->deduceFunctionTemplate(sc, loc, NULL, arguments); 6352 f = te->td->deduceFunctionTemplate(sc, loc, targsi, NULL, arguments);
6066 if (!f) 6353 if (!f)
6067 { type = Type::terror; 6354 { type = Type::terror;
6068 return this; 6355 return this;
6069 } 6356 }
6070 if (f->needThis() && hasThis(sc)) 6357 if (f->needThis() && hasThis(sc))
6116 } 6403 }
6117 } 6404 }
6118 6405
6119 f = f->overloadResolve(loc, arguments); 6406 f = f->overloadResolve(loc, arguments);
6120 checkDeprecated(sc, f); 6407 checkDeprecated(sc, f);
6408 #if DMDV2
6409 checkPurity(sc, f);
6410 #endif
6121 6411
6122 if (f->needThis() && hasThis(sc)) 6412 if (f->needThis() && hasThis(sc))
6123 { 6413 {
6124 // Supply an implicit 'this', as in 6414 // Supply an implicit 'this', as in
6125 // this.ident 6415 // this.ident
6163 return this; 6453 return this;
6164 } 6454 }
6165 6455
6166 int CallExp::checkSideEffect(int flag) 6456 int CallExp::checkSideEffect(int flag)
6167 { 6457 {
6458 #if DMDV2
6459 if (flag != 2)
6460 return 1;
6461
6462 if (e1->checkSideEffect(2))
6463 return 1;
6464
6465 /* If any of the arguments have side effects, this expression does
6466 */
6467 for (size_t i = 0; i < arguments->dim; i++)
6468 { Expression *e = (Expression *)arguments->data[i];
6469
6470 if (e->checkSideEffect(2))
6471 return 1;
6472 }
6473
6474 /* If calling a function or delegate that is typed as pure,
6475 * then this expression has no side effects.
6476 */
6477 Type *t = e1->type->toBasetype();
6478 if (t->ty == Tfunction && ((TypeFunction *)t)->ispure)
6479 return 0;
6480 if (t->ty == Tdelegate && ((TypeFunction *)((TypeDelegate *)t)->next)->ispure)
6481 return 0;
6482 #endif
6168 return 1; 6483 return 1;
6169 } 6484 }
6485
6486 #if DMDV2
6487 int CallExp::canThrow()
6488 {
6489 if (e1->canThrow())
6490 return 1;
6491
6492 /* If any of the arguments can throw, then this expression can throw
6493 */
6494 for (size_t i = 0; i < arguments->dim; i++)
6495 { Expression *e = (Expression *)arguments->data[i];
6496
6497 if (e->canThrow())
6498 return 1;
6499 }
6500
6501 /* If calling a function or delegate that is typed as nothrow,
6502 * then this expression cannot throw.
6503 * Note that pure functions can throw.
6504 */
6505 Type *t = e1->type->toBasetype();
6506 if (t->ty == Tfunction && ((TypeFunction *)t)->isnothrow)
6507 return 0;
6508 if (t->ty == Tdelegate && ((TypeFunction *)((TypeDelegate *)t)->next)->isnothrow)
6509 return 0;
6510
6511 return 1;
6512 }
6513 #endif
6514
6515 #if DMDV2
6516 int CallExp::isLvalue()
6517 {
6518 if (type->toBasetype()->ty == Tstruct)
6519 return 1;
6520 Type *tb = e1->type->toBasetype();
6521 if (tb->ty == Tfunction && ((TypeFunction *)tb)->isref)
6522 return 1; // function returns a reference
6523 return 0;
6524 }
6525 #endif
6170 6526
6171 Expression *CallExp::toLvalue(Scope *sc, Expression *e) 6527 Expression *CallExp::toLvalue(Scope *sc, Expression *e)
6172 { 6528 {
6173 if (type->toBasetype()->ty == Tstruct) 6529 if (type->toBasetype()->ty == Tstruct)
6174 return this; 6530 return this;
6307 } 6663 }
6308 rvalue(); 6664 rvalue();
6309 return this; 6665 return this;
6310 } 6666 }
6311 6667
6668 #if DMDV2
6669 int PtrExp::isLvalue()
6670 {
6671 return 1;
6672 }
6673 #endif
6674
6312 Expression *PtrExp::toLvalue(Scope *sc, Expression *e) 6675 Expression *PtrExp::toLvalue(Scope *sc, Expression *e)
6313 { 6676 {
6314 #if 0 6677 #if 0
6315 tym = tybasic(e1->ET->Tty); 6678 tym = tybasic(e1->ET->Tty);
6316 if (!(tyscalar(tym) || 6679 if (!(tyscalar(tym) ||
6318 tym == TYarray && e->Eoper == TOKaddr)) 6681 tym == TYarray && e->Eoper == TOKaddr))
6319 synerr(EM_lvalue); // lvalue expected 6682 synerr(EM_lvalue); // lvalue expected
6320 #endif 6683 #endif
6321 return this; 6684 return this;
6322 } 6685 }
6686
6687 #if DMDV2
6688 Expression *PtrExp::modifiableLvalue(Scope *sc, Expression *e)
6689 {
6690 //printf("PtrExp::modifiableLvalue() %s, type %s\n", toChars(), type->toChars());
6691
6692 if (e1->op == TOKsymoff)
6693 { SymOffExp *se = (SymOffExp *)e1;
6694 se->var->checkModify(loc, sc, type);
6695 //return toLvalue(sc, e);
6696 }
6697
6698 return Expression::modifiableLvalue(sc, e);
6699 }
6700 #endif
6323 6701
6324 void PtrExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 6702 void PtrExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
6325 { 6703 {
6326 buf->writeByte('*'); 6704 buf->writeByte('*');
6327 expToCBuffer(buf, hgs, e1, precedence[op]); 6705 expToCBuffer(buf, hgs, e1, precedence[op]);
6551 : UnaExp(loc, TOKcast, sizeof(CastExp), e) 6929 : UnaExp(loc, TOKcast, sizeof(CastExp), e)
6552 { 6930 {
6553 to = t; 6931 to = t;
6554 } 6932 }
6555 6933
6934 #if DMDV2
6935 /* For cast(const) and cast(immutable)
6936 */
6937 CastExp::CastExp(Loc loc, Expression *e, unsigned mod)
6938 : UnaExp(loc, TOKcast, sizeof(CastExp), e)
6939 {
6940 to = NULL;
6941 this->mod = mod;
6942 }
6943 #endif
6944
6556 Expression *CastExp::syntaxCopy() 6945 Expression *CastExp::syntaxCopy()
6557 { 6946 {
6558 return new CastExp(loc, e1->syntaxCopy(), to->syntaxCopy()); 6947 return new CastExp(loc, e1->syntaxCopy(), to->syntaxCopy());
6559 } 6948 }
6560 6949
6635 } 7024 }
6636 7025
6637 void CastExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 7026 void CastExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
6638 { 7027 {
6639 buf->writestring("cast("); 7028 buf->writestring("cast(");
7029 #if DMDV1
6640 to->toCBuffer(buf, NULL, hgs); 7030 to->toCBuffer(buf, NULL, hgs);
7031 #else
7032 if (to)
7033 to->toCBuffer(buf, NULL, hgs);
7034 else
7035 {
7036 switch (mod)
7037 { case 0:
7038 break;
7039 case MODconst:
7040 buf->writestring(Token::tochars[TOKconst]);
7041 break;
7042 case MODinvariant:
7043 buf->writestring(Token::tochars[TOKimmutable]);
7044 break;
7045 case MODshared:
7046 buf->writestring(Token::tochars[TOKshared]);
7047 break;
7048 case MODshared | MODconst:
7049 buf->writestring(Token::tochars[TOKshared]);
7050 buf->writeByte(' ');
7051 buf->writestring(Token::tochars[TOKconst]);
7052 break;
7053 default:
7054 assert(0);
7055 }
7056 }
7057 #endif
6641 buf->writeByte(')'); 7058 buf->writeByte(')');
6642 expToCBuffer(buf, hgs, e1, precedence[op]); 7059 expToCBuffer(buf, hgs, e1, precedence[op]);
6643 } 7060 }
6644 7061
6645 7062
6829 void SliceExp::checkEscape() 7246 void SliceExp::checkEscape()
6830 { 7247 {
6831 e1->checkEscape(); 7248 e1->checkEscape();
6832 } 7249 }
6833 7250
7251 #if DMDV2
7252 int SliceExp::isLvalue()
7253 {
7254 return 1;
7255 }
7256 #endif
7257
6834 Expression *SliceExp::toLvalue(Scope *sc, Expression *e) 7258 Expression *SliceExp::toLvalue(Scope *sc, Expression *e)
6835 { 7259 {
6836 return this; 7260 return this;
6837 } 7261 }
6838 7262
6943 e = e1; 7367 e = e1;
6944 } 7368 }
6945 return e; 7369 return e;
6946 } 7370 }
6947 7371
7372 #if DMDV2
7373 int ArrayExp::isLvalue()
7374 {
7375 if (type && type->toBasetype()->ty == Tvoid)
7376 return 0;
7377 return 1;
7378 }
7379 #endif
6948 7380
6949 Expression *ArrayExp::toLvalue(Scope *sc, Expression *e) 7381 Expression *ArrayExp::toLvalue(Scope *sc, Expression *e)
6950 { 7382 {
6951 if (type && type->toBasetype()->ty == Tvoid) 7383 if (type && type->toBasetype()->ty == Tvoid)
6952 error("voids have no value"); 7384 error("voids have no value");
7012 7444
7013 void CommaExp::checkEscape() 7445 void CommaExp::checkEscape()
7014 { 7446 {
7015 e2->checkEscape(); 7447 e2->checkEscape();
7016 } 7448 }
7449
7450 #if DMDV2
7451 int CommaExp::isLvalue()
7452 {
7453 return e2->isLvalue();
7454 }
7455 #endif
7017 7456
7018 Expression *CommaExp::toLvalue(Scope *sc, Expression *e) 7457 Expression *CommaExp::toLvalue(Scope *sc, Expression *e)
7019 { 7458 {
7020 e2 = e2->toLvalue(sc, NULL); 7459 e2 = e2->toLvalue(sc, NULL);
7021 return this; 7460 return this;
7178 type = Type::tint32; 7617 type = Type::tint32;
7179 break; 7618 break;
7180 } 7619 }
7181 return e; 7620 return e;
7182 } 7621 }
7622
7623 #if DMDV2
7624 int IndexExp::isLvalue()
7625 {
7626 return 1;
7627 }
7628 #endif
7183 7629
7184 Expression *IndexExp::toLvalue(Scope *sc, Expression *e) 7630 Expression *IndexExp::toLvalue(Scope *sc, Expression *e)
7185 { 7631 {
7186 // if (type && type->toBasetype()->ty == Tvoid) 7632 // if (type && type->toBasetype()->ty == Tvoid)
7187 // error("voids have no value"); 7633 // error("voids have no value");
9032 case Tcomplex80: 9478 case Tcomplex80:
9033 e1 = e1->castTo(sc, e2->type); 9479 e1 = e1->castTo(sc, e2->type);
9034 break; 9480 break;
9035 } 9481 }
9036 } 9482 }
9483 #if 0
9484 printf("res: %s\n", type->toChars());
9485 printf("e1 : %s\n", e1->type->toChars());
9486 printf("e2 : %s\n", e2->type->toChars());
9487 #endif
9037 return this; 9488 return this;
9038 } 9489 }
9490
9491 #if DMDV2
9492 int CondExp::isLvalue()
9493 {
9494 return e1->isLvalue() && e2->isLvalue();
9495 }
9496 #endif
9039 9497
9040 Expression *CondExp::toLvalue(Scope *sc, Expression *ex) 9498 Expression *CondExp::toLvalue(Scope *sc, Expression *ex)
9041 { 9499 {
9042 PtrExp *e; 9500 PtrExp *e;
9043 9501
9089 econd->checkSideEffect(1); 9547 econd->checkSideEffect(1);
9090 e1->checkSideEffect(flag); 9548 e1->checkSideEffect(flag);
9091 return e2->checkSideEffect(flag); 9549 return e2->checkSideEffect(flag);
9092 } 9550 }
9093 } 9551 }
9552
9553 #if DMDV2
9554 int CondExp::canThrow()
9555 {
9556 return econd->canThrow() || e1->canThrow() || e2->canThrow();
9557 }
9558 #endif
9094 9559
9095 void CondExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 9560 void CondExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
9096 { 9561 {
9097 expToCBuffer(buf, hgs, econd, PREC_oror); 9562 expToCBuffer(buf, hgs, econd, PREC_oror);
9098 buf->writestring(" ? "); 9563 buf->writestring(" ? ");