Mercurial > projects > ldc
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(" ? "); |