Mercurial > projects > ldc
comparison dmd/expression.c @ 1587:def7a1d494fd
Merge DMD 1.051
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Fri, 06 Nov 2009 23:58:01 +0100 |
parents | 05c235309d6f |
children | 2afcaab30a6a |
comparison
equal
deleted
inserted
replaced
1586:7f728c52e63c | 1587:def7a1d494fd |
---|---|
33 int isnan(double); | 33 int isnan(double); |
34 #endif | 34 #endif |
35 #endif | 35 #endif |
36 | 36 |
37 #include "rmem.h" | 37 #include "rmem.h" |
38 | 38 #include "port.h" |
39 //#include "port.h" | 39 |
40 #include "mtype.h" | 40 #include "mtype.h" |
41 #include "init.h" | 41 #include "init.h" |
42 #include "expression.h" | 42 #include "expression.h" |
43 #include "template.h" | 43 #include "template.h" |
44 #include "utf.h" | 44 #include "utf.h" |
371 { | 371 { |
372 e->error("expression has no value"); | 372 e->error("expression has no value"); |
373 } | 373 } |
374 | 374 |
375 } | 375 } |
376 else if (e->op == TOKdottd) | |
377 { | |
378 e = new CallExp(e->loc, e); | |
379 e = e->semantic(sc); | |
380 } | |
376 return e; | 381 return e; |
377 } | 382 } |
378 | 383 |
379 /****************************** | 384 /****************************** |
380 * Perform semantic() on an array of Expressions. | 385 * Perform semantic() on an array of Expressions. |
541 assert(arguments); | 546 assert(arguments); |
542 size_t nargs = arguments ? arguments->dim : 0; | 547 size_t nargs = arguments ? arguments->dim : 0; |
543 size_t nparams = Argument::dim(tf->parameters); | 548 size_t nparams = Argument::dim(tf->parameters); |
544 | 549 |
545 if (nargs > nparams && tf->varargs == 0) | 550 if (nargs > nparams && tf->varargs == 0) |
546 error(loc, "expected %zu arguments, not %zu", nparams, nargs); | 551 error(loc, "expected %zu arguments, not %zu for non-variadic function type %s", nparams, nargs, tf->toChars()); |
547 | 552 |
548 n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams) | 553 n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams) |
549 | 554 |
550 int done = 0; | 555 int done = 0; |
551 for (size_t i = 0; i < n; i++) | 556 for (size_t i = 0; i < n; i++) |
566 { | 571 { |
567 if (!p->defaultArg) | 572 if (!p->defaultArg) |
568 { | 573 { |
569 if (tf->varargs == 2 && i + 1 == nparams) | 574 if (tf->varargs == 2 && i + 1 == nparams) |
570 goto L2; | 575 goto L2; |
571 error(loc, "expected %zu arguments, not %zu", nparams, nargs); | 576 error(loc, "expected %zu function arguments, not %zu", nparams, nargs); |
572 break; | 577 break; |
573 } | 578 } |
574 arg = p->defaultArg; | 579 arg = p->defaultArg; |
575 #if DMDV2 | 580 #if DMDV2 |
576 if (arg->op == TOKdefault) | 581 if (arg->op == TOKdefault) |
588 { | 593 { |
589 //printf("\t\tvarargs == 2, p->type = '%s'\n", p->type->toChars()); | 594 //printf("\t\tvarargs == 2, p->type = '%s'\n", p->type->toChars()); |
590 if (arg->implicitConvTo(p->type)) | 595 if (arg->implicitConvTo(p->type)) |
591 { | 596 { |
592 if (nargs != nparams) | 597 if (nargs != nparams) |
593 error(loc, "expected %zu arguments, not %zu", nparams, nargs); | 598 error(loc, "expected %zu function arguments, not %zu", nparams, nargs); |
594 goto L1; | 599 goto L1; |
595 } | 600 } |
596 L2: | 601 L2: |
597 Type *tb = p->type->toBasetype(); | 602 Type *tb = p->type->toBasetype(); |
598 Type *tret = p->isLazyArray(); | 603 Type *tret = p->isLazyArray(); |
667 done = 1; | 672 done = 1; |
668 } | 673 } |
669 | 674 |
670 L1: | 675 L1: |
671 if (!(p->storageClass & STClazy && p->type->ty == Tvoid)) | 676 if (!(p->storageClass & STClazy && p->type->ty == Tvoid)) |
672 arg = arg->implicitCastTo(sc, p->type); | 677 { |
678 if (p->type != arg->type) | |
679 { | |
680 //printf("arg->type = %s, p->type = %s\n", arg->type->toChars(), p->type->toChars()); | |
681 if (arg->op == TOKtype) | |
682 arg->error("cannot pass type %s as function argument", arg->toChars()); | |
683 arg = arg->implicitCastTo(sc, p->type); | |
684 arg = arg->optimize(WANTvalue); | |
685 } | |
686 } | |
673 if (p->storageClass & (STCout | STCref)) | 687 if (p->storageClass & (STCout | STCref)) |
674 { | 688 { |
675 // BUG: should check that argument to ref is type 'invariant' | 689 // BUG: should check that argument to ref is type 'invariant' |
676 // BUG: assignments to ref should also be type 'invariant' | 690 // BUG: assignments to ref should also be type 'invariant' |
677 arg = arg->modifiableLvalue(sc, arg); | 691 arg = arg->modifiableLvalue(sc, arg); |
771 #if DMDV2 | 785 #if DMDV2 |
772 if (tb->ty == Tstruct) | 786 if (tb->ty == Tstruct) |
773 { | 787 { |
774 arg = callCpCtor(loc, sc, arg); | 788 arg = callCpCtor(loc, sc, arg); |
775 } | 789 } |
790 #endif | |
776 | 791 |
777 // Give error for overloaded function addresses | 792 // Give error for overloaded function addresses |
793 #if DMDV2 | |
778 if (arg->op == TOKsymoff) | 794 if (arg->op == TOKsymoff) |
779 { SymOffExp *se = (SymOffExp *)arg; | 795 { SymOffExp *se = (SymOffExp *)arg; |
780 if (se->hasOverloads && !se->var->isFuncDeclaration()->isUnique()) | 796 if ( |
797 se->hasOverloads && | |
798 !se->var->isFuncDeclaration()->isUnique()) | |
781 arg->error("function %s is overloaded", arg->toChars()); | 799 arg->error("function %s is overloaded", arg->toChars()); |
782 } | 800 } |
783 #endif | 801 #endif |
784 arg->rvalue(); | 802 arg->rvalue(); |
785 } | 803 } |
1212 */ | 1230 */ |
1213 | 1231 |
1214 Expression *Expression::deref() | 1232 Expression *Expression::deref() |
1215 { | 1233 { |
1216 //printf("Expression::deref()\n"); | 1234 //printf("Expression::deref()\n"); |
1217 if (type->ty == Treference) | 1235 // type could be null if forward referencing an 'auto' variable |
1218 { Expression *e; | 1236 if (type && type->ty == Treference) |
1219 | 1237 { |
1220 e = new PtrExp(loc, this); | 1238 Expression *e = new PtrExp(loc, this); |
1221 e->type = ((TypeReference *)type)->next; | 1239 e->type = ((TypeReference *)type)->next; |
1222 return e; | 1240 return e; |
1223 } | 1241 } |
1224 return this; | 1242 return this; |
1225 } | 1243 } |
2153 return e->semantic(sc); | 2171 return e->semantic(sc); |
2154 } | 2172 } |
2155 f = s->isFuncDeclaration(); | 2173 f = s->isFuncDeclaration(); |
2156 if (f) | 2174 if (f) |
2157 { //printf("'%s' is a function\n", f->toChars()); | 2175 { //printf("'%s' is a function\n", f->toChars()); |
2176 if (!f->type->deco) | |
2177 { | |
2178 error("forward reference to %s", toChars()); | |
2179 } | |
2158 return new VarExp(loc, f); | 2180 return new VarExp(loc, f); |
2159 } | 2181 } |
2160 cd = s->isClassDeclaration(); | 2182 cd = s->isClassDeclaration(); |
2161 if (cd && thiscd && cd->isBaseOf(thiscd, NULL) && sc->func->needThis()) | 2183 if (cd && thiscd && cd->isBaseOf(thiscd, NULL) && sc->func->needThis()) |
2162 { | 2184 { |
2207 return e; | 2229 return e; |
2208 } | 2230 } |
2209 | 2231 |
2210 TemplateInstance *ti = s->isTemplateInstance(); | 2232 TemplateInstance *ti = s->isTemplateInstance(); |
2211 if (ti && !global.errors) | 2233 if (ti && !global.errors) |
2212 { if (!ti->semanticdone) | 2234 { if (!ti->semanticRun) |
2213 ti->semantic(sc); | 2235 ti->semantic(sc); |
2214 s = ti->inst->toAlias(); | 2236 s = ti->inst->toAlias(); |
2215 if (!s->isTemplateInstance()) | 2237 if (!s->isTemplateInstance()) |
2216 goto Lagain; | 2238 goto Lagain; |
2217 e = new ScopeExp(loc, ti); | 2239 e = new ScopeExp(loc, ti); |
3164 else | 3186 else |
3165 { | 3187 { |
3166 if (v->init) | 3188 if (v->init) |
3167 { e = v->init->toExpression(); | 3189 { e = v->init->toExpression(); |
3168 if (!e) | 3190 if (!e) |
3169 error("cannot make expression out of initializer for %s", v->toChars()); | 3191 { error("cannot make expression out of initializer for %s", v->toChars()); |
3192 e = new ErrorExp(); | |
3193 } | |
3194 else if (v->scope) | |
3195 { // Do deferred semantic anaylsis | |
3196 Initializer *i2 = v->init->syntaxCopy(); | |
3197 i2 = i2->semantic(v->scope, v->type); | |
3198 e = i2->toExpression(); | |
3199 v->scope = NULL; | |
3200 } | |
3170 } | 3201 } |
3171 else | 3202 else |
3172 { e = v->type->defaultInit(); | 3203 { e = v->type->defaultInit(); |
3173 e->loc = loc; | 3204 e->loc = loc; |
3174 } | 3205 } |
3198 //printf("\ti = %d\n", i); | 3229 //printf("\ti = %d\n", i); |
3199 assert(i < elements->dim); | 3230 assert(i < elements->dim); |
3200 e = (Expression *)elements->data[i]; | 3231 e = (Expression *)elements->data[i]; |
3201 if (e) | 3232 if (e) |
3202 { | 3233 { |
3203 e = e->copy(); | 3234 //printf("e = %s, e->type = %s\n", e->toChars(), e->type->toChars()); |
3204 e->type = type; | 3235 |
3236 /* If type is a static array, and e is an initializer for that array, | |
3237 * then the field initializer should be an array literal of e. | |
3238 */ | |
3239 if (e->type != type && type->ty == Tsarray) | |
3240 { TypeSArray *tsa = (TypeSArray *)type; | |
3241 uinteger_t length = tsa->dim->toInteger(); | |
3242 Expressions *z = new Expressions; | |
3243 z->setDim(length); | |
3244 for (int q = 0; q < length; ++q) | |
3245 z->data[q] = e->copy(); | |
3246 e = new ArrayLiteralExp(loc, z); | |
3247 e->type = type; | |
3248 } | |
3249 else | |
3250 { | |
3251 e = e->copy(); | |
3252 e->type = type; | |
3253 } | |
3205 } | 3254 } |
3206 } | 3255 } |
3207 return e; | 3256 return e; |
3208 } | 3257 } |
3209 | 3258 |
3214 | 3263 |
3215 int StructLiteralExp::getFieldIndex(Type *type, unsigned offset) | 3264 int StructLiteralExp::getFieldIndex(Type *type, unsigned offset) |
3216 { | 3265 { |
3217 /* Find which field offset is by looking at the field offsets | 3266 /* Find which field offset is by looking at the field offsets |
3218 */ | 3267 */ |
3219 for (size_t i = 0; i < sd->fields.dim; i++) | 3268 if (elements->dim) |
3220 { | 3269 { |
3221 Dsymbol *s = (Dsymbol *)sd->fields.data[i]; | 3270 for (size_t i = 0; i < sd->fields.dim; i++) |
3222 VarDeclaration *v = s->isVarDeclaration(); | 3271 { |
3223 assert(v); | 3272 Dsymbol *s = (Dsymbol *)sd->fields.data[i]; |
3224 | 3273 VarDeclaration *v = s->isVarDeclaration(); |
3225 if (offset == v->offset && | 3274 assert(v); |
3226 type->size() == v->type->size()) | 3275 |
3227 { Expression *e = (Expression *)elements->data[i]; | 3276 if (offset == v->offset && |
3228 if (e) | 3277 type->size() == v->type->size()) |
3229 { | 3278 { Expression *e = (Expression *)elements->data[i]; |
3230 return i; | 3279 if (e) |
3231 } | 3280 { |
3232 break; | 3281 return i; |
3282 } | |
3283 break; | |
3284 } | |
3233 } | 3285 } |
3234 } | 3286 } |
3235 return -1; | 3287 return -1; |
3236 } | 3288 } |
3237 | 3289 |
3363 #endif | 3415 #endif |
3364 Lagain: | 3416 Lagain: |
3365 ti = sds->isTemplateInstance(); | 3417 ti = sds->isTemplateInstance(); |
3366 if (ti && !global.errors) | 3418 if (ti && !global.errors) |
3367 { Dsymbol *s; | 3419 { Dsymbol *s; |
3368 if (!ti->semanticdone) | 3420 if (!ti->semanticRun) |
3369 ti->semantic(sc); | 3421 ti->semantic(sc); |
3370 s = ti->inst->toAlias(); | 3422 s = ti->inst->toAlias(); |
3371 sds2 = s->isScopeDsymbol(); | 3423 sds2 = s->isScopeDsymbol(); |
3372 if (!sds2) | 3424 if (!sds2) |
3373 { Expression *e; | 3425 { Expression *e; |
3581 #endif | 3633 #endif |
3582 } | 3634 } |
3583 else if (thisexp) | 3635 else if (thisexp) |
3584 error("e.new is only for allocating nested classes"); | 3636 error("e.new is only for allocating nested classes"); |
3585 else if (fdn) | 3637 else if (fdn) |
3586 { | 3638 { |
3587 // make sure the parent context fdn of cd is reachable from sc | 3639 // make sure the parent context fdn of cd is reachable from sc |
3588 for (Dsymbol *sp = sc->parent; 1; sp = sp->parent) | 3640 for (Dsymbol *sp = sc->parent; 1; sp = sp->parent) |
3589 { | 3641 { |
3590 if (fdn == sp) | 3642 if (fdn == sp) |
3591 break; | 3643 break; |
3604 | 3656 |
3605 FuncDeclaration *f = cd->ctor; | 3657 FuncDeclaration *f = cd->ctor; |
3606 if (f) | 3658 if (f) |
3607 { | 3659 { |
3608 assert(f); | 3660 assert(f); |
3609 f = f->overloadResolve(loc, arguments, sc->module); | 3661 f = f->overloadResolve(loc, NULL, arguments, sc->module); |
3610 checkDeprecated(sc, f); | 3662 checkDeprecated(sc, f); |
3611 member = f->isCtorDeclaration(); | 3663 member = f->isCtorDeclaration(); |
3612 assert(member); | 3664 assert(member); |
3613 | 3665 |
3614 cd->accessCheck(loc, sc, member); | 3666 cd->accessCheck(loc, sc, member); |
3632 Expression *e = new IntegerExp(loc, cd->size(loc), Type::tsize_t); | 3684 Expression *e = new IntegerExp(loc, cd->size(loc), Type::tsize_t); |
3633 if (!newargs) | 3685 if (!newargs) |
3634 newargs = new Expressions(); | 3686 newargs = new Expressions(); |
3635 newargs->shift(e); | 3687 newargs->shift(e); |
3636 | 3688 |
3637 f = cd->aggNew->overloadResolve(loc, newargs, sc->module); | 3689 f = cd->aggNew->overloadResolve(loc, NULL, newargs, sc->module); |
3638 allocator = f->isNewDeclaration(); | 3690 allocator = f->isNewDeclaration(); |
3639 assert(allocator); | 3691 assert(allocator); |
3640 | 3692 |
3641 tf = (TypeFunction *)f->type; | 3693 tf = (TypeFunction *)f->type; |
3642 functionArguments(loc, sc, tf, newargs); | 3694 functionArguments(loc, sc, tf, newargs); |
3665 e = new IntegerExp(loc, sd->size(loc), Type::tuns32); | 3717 e = new IntegerExp(loc, sd->size(loc), Type::tuns32); |
3666 if (!newargs) | 3718 if (!newargs) |
3667 newargs = new Expressions(); | 3719 newargs = new Expressions(); |
3668 newargs->shift(e); | 3720 newargs->shift(e); |
3669 | 3721 |
3670 f = f->overloadResolve(loc, newargs, sc->module); | 3722 f = f->overloadResolve(loc, NULL, newargs, sc->module); |
3671 allocator = f->isNewDeclaration(); | 3723 allocator = f->isNewDeclaration(); |
3672 assert(allocator); | 3724 assert(allocator); |
3673 | 3725 |
3674 tf = (TypeFunction *)f->type; | 3726 tf = (TypeFunction *)f->type; |
3675 functionArguments(loc, sc, tf, newargs); | 3727 functionArguments(loc, sc, tf, newargs); |
4198 if (0 && exps->dim == 1) | 4250 if (0 && exps->dim == 1) |
4199 { | 4251 { |
4200 return (Expression *)exps->data[0]; | 4252 return (Expression *)exps->data[0]; |
4201 } | 4253 } |
4202 type = new TypeTuple(exps); | 4254 type = new TypeTuple(exps); |
4255 type = type->semantic(loc, sc); | |
4203 //printf("-TupleExp::semantic(%s)\n", toChars()); | 4256 //printf("-TupleExp::semantic(%s)\n", toChars()); |
4204 return this; | 4257 return this; |
4205 } | 4258 } |
4206 | 4259 |
4207 void TupleExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 4260 void TupleExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
4261 { | 4314 { |
4262 fd->semantic(sc); | 4315 fd->semantic(sc); |
4263 fd->parent = sc->parent; | 4316 fd->parent = sc->parent; |
4264 if (global.errors) | 4317 if (global.errors) |
4265 { | 4318 { |
4266 if (!fd->type->next) | |
4267 fd->type->next = Type::terror; | |
4268 } | 4319 } |
4269 else | 4320 else |
4270 { | 4321 { |
4271 fd->semantic2(sc); | 4322 fd->semantic2(sc); |
4272 if (!global.errors) | 4323 if (!global.errors || |
4324 // need to infer return type | |
4325 (fd->type && fd->type->ty == Tfunction && !fd->type->nextOf())) | |
4273 { | 4326 { |
4274 fd->semantic3(sc); | 4327 fd->semantic3(sc); |
4275 | 4328 |
4276 if (!global.errors && global.params.useInline) | 4329 if (!global.errors && global.params.useInline) |
4277 fd->inlineScan(); | 4330 fd->inlineScan(); |
4278 } | 4331 } |
4279 } | 4332 } |
4333 | |
4334 // need to infer return type | |
4335 if (global.errors && fd->type && fd->type->ty == Tfunction && !fd->type->nextOf()) | |
4336 ((TypeFunction *)fd->type)->next = Type::terror; | |
4280 | 4337 |
4281 // Type is a "delegate to" or "pointer to" the function literal | 4338 // Type is a "delegate to" or "pointer to" the function literal |
4282 if (fd->isNested()) | 4339 if (fd->isNested()) |
4283 { | 4340 { |
4284 type = new TypeDelegate(fd->type); | 4341 type = new TypeDelegate(fd->type); |
4375 } | 4432 } |
4376 } | 4433 } |
4377 } | 4434 } |
4378 if (!s->isVarDeclaration()) | 4435 if (!s->isVarDeclaration()) |
4379 { | 4436 { |
4380 declaration->semantic(sc); | 4437 Scope *sc2 = sc; |
4438 if (sc2->stc & (STCpure | STCnothrow)) | |
4439 sc2 = sc->push(); | |
4440 sc2->stc &= ~(STCpure | STCnothrow); | |
4441 declaration->semantic(sc2); | |
4442 if (sc2 != sc) | |
4443 sc2->pop(); | |
4381 s->parent = sc->parent; | 4444 s->parent = sc->parent; |
4382 } | 4445 } |
4383 if (!global.errors) | 4446 if (!global.errors) |
4384 { | 4447 { |
4385 declaration->semantic2(sc); | 4448 declaration->semantic2(sc); |
4918 e1->checkArithmetic(); | 4981 e1->checkArithmetic(); |
4919 e2->checkArithmetic(); | 4982 e2->checkArithmetic(); |
4920 | 4983 |
4921 if (op == TOKmodass && e2->type->iscomplex()) | 4984 if (op == TOKmodass && e2->type->iscomplex()) |
4922 { error("cannot perform modulo complex arithmetic"); | 4985 { error("cannot perform modulo complex arithmetic"); |
4923 return new IntegerExp(0); | 4986 return new ErrorExp(); |
4924 } | 4987 } |
4925 } | 4988 } |
4926 return this; | 4989 return this; |
4927 } | 4990 } |
4928 | 4991 |
4983 op == TOKremove) | 5046 op == TOKremove) |
4984 return 1; | 5047 return 1; |
4985 return Expression::checkSideEffect(flag); | 5048 return Expression::checkSideEffect(flag); |
4986 } | 5049 } |
4987 | 5050 |
5051 // generate an error if this is a nonsensical *=,/=, or %=, eg real *= imaginary | |
5052 void BinExp::checkComplexMulAssign() | |
5053 { | |
5054 // Any multiplication by an imaginary or complex number yields a complex result. | |
5055 // r *= c, i*=c, r*=i, i*=i are all forbidden operations. | |
5056 const char *opstr = Token::toChars(op); | |
5057 if ( e1->type->isreal() && e2->type->iscomplex()) | |
5058 { | |
5059 error("%s %s %s is undefined. Did you mean %s %s %s.re ?", | |
5060 e1->type->toChars(), opstr, e2->type->toChars(), | |
5061 e1->type->toChars(), opstr, e2->type->toChars()); | |
5062 } | |
5063 else if (e1->type->isimaginary() && e2->type->iscomplex()) | |
5064 { | |
5065 error("%s %s %s is undefined. Did you mean %s %s %s.im ?", | |
5066 e1->type->toChars(), opstr, e2->type->toChars(), | |
5067 e1->type->toChars(), opstr, e2->type->toChars()); | |
5068 } | |
5069 else if ((e1->type->isreal() || e1->type->isimaginary()) && | |
5070 e2->type->isimaginary()) | |
5071 { | |
5072 error("%s %s %s is an undefined operation", e1->type->toChars(), | |
5073 opstr, e2->type->toChars()); | |
5074 } | |
5075 } | |
5076 | |
5077 // generate an error if this is a nonsensical += or -=, eg real += imaginary | |
5078 void BinExp::checkComplexAddAssign() | |
5079 { | |
5080 // Addition or subtraction of a real and an imaginary is a complex result. | |
5081 // Thus, r+=i, r+=c, i+=r, i+=c are all forbidden operations. | |
5082 if ( (e1->type->isreal() && (e2->type->isimaginary() || e2->type->iscomplex())) || | |
5083 (e1->type->isimaginary() && (e2->type->isreal() || e2->type->iscomplex())) | |
5084 ) | |
5085 { | |
5086 error("%s %s %s is undefined (result is complex)", | |
5087 e1->type->toChars(), Token::toChars(op), e2->type->toChars()); | |
5088 } | |
5089 } | |
5090 | |
4988 void BinExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 5091 void BinExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
4989 { | 5092 { |
4990 expToCBuffer(buf, hgs, e1, precedence[op]); | 5093 expToCBuffer(buf, hgs, e1, precedence[op]); |
4991 buf->writeByte(' '); | 5094 buf->writeByte(' '); |
4992 buf->writestring(Token::toChars(op)); | 5095 buf->writestring(Token::toChars(op)); |
5092 { error("file %s cannot be found, check -Jpath", se->toChars()); | 5195 { error("file %s cannot be found, check -Jpath", se->toChars()); |
5093 goto Lerror; | 5196 goto Lerror; |
5094 } | 5197 } |
5095 | 5198 |
5096 if (global.params.verbose) | 5199 if (global.params.verbose) |
5097 printf("file %s\t(%s)\n", (char*)se->string, name); | 5200 printf("file %s\t(%s)\n", (char *)se->string, name); |
5098 | 5201 |
5099 { File f(name); | 5202 { File f(name); |
5100 if (f.read()) | 5203 if (f.read()) |
5101 { error("cannot read file %s", f.toChars()); | 5204 { error("cannot read file %s", f.toChars()); |
5102 goto Lerror; | 5205 goto Lerror; |
5175 } | 5278 } |
5176 | 5279 |
5177 #if DMDV2 | 5280 #if DMDV2 |
5178 int AssertExp::canThrow() | 5281 int AssertExp::canThrow() |
5179 { | 5282 { |
5180 return (global.params.useAssert != 0); | 5283 /* assert()s are non-recoverable errors, so functions that |
5284 * use them can be considered "nothrow" | |
5285 */ | |
5286 return 0; //(global.params.useAssert != 0); | |
5181 } | 5287 } |
5182 #endif | 5288 #endif |
5183 | 5289 |
5184 void AssertExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 5290 void AssertExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
5185 { | 5291 { |
5477 } | 5583 } |
5478 else if (e1->type->ty == Tpointer && | 5584 else if (e1->type->ty == Tpointer && |
5479 ident != Id::init && ident != Id::__sizeof && | 5585 ident != Id::init && ident != Id::__sizeof && |
5480 ident != Id::alignof && ident != Id::offsetof && | 5586 ident != Id::alignof && ident != Id::offsetof && |
5481 ident != Id::mangleof && ident != Id::stringof) | 5587 ident != Id::mangleof && ident != Id::stringof) |
5482 { | 5588 { /* Rewrite: |
5589 * p.ident | |
5590 * as: | |
5591 * (*p).ident | |
5592 */ | |
5483 e = new PtrExp(loc, e1); | 5593 e = new PtrExp(loc, e1); |
5484 e->type = ((TypePointer *)e1->type)->next; | 5594 e->type = ((TypePointer *)e1->type)->next; |
5485 return e->type->dotExp(sc, e, ident); | 5595 return e->type->dotExp(sc, e, ident); |
5486 } | 5596 } |
5487 #if DMDV2 | 5597 #if DMDV2 |
5596 | 5706 |
5597 e1 = e1->semantic(sc); | 5707 e1 = e1->semantic(sc); |
5598 type = var->type; | 5708 type = var->type; |
5599 if (!type && global.errors) | 5709 if (!type && global.errors) |
5600 { // var is goofed up, just return 0 | 5710 { // var is goofed up, just return 0 |
5601 return new IntegerExp(0); | 5711 return new ErrorExp(); |
5602 } | 5712 } |
5603 assert(type); | 5713 assert(type); |
5604 | 5714 |
5605 if (!var->isFuncDeclaration()) // for functions, do checks after overload resolution | 5715 if (!var->isFuncDeclaration()) // for functions, do checks after overload resolution |
5606 { | 5716 { |
5933 | 6043 |
5934 CallExp::CallExp(Loc loc, Expression *e, Expression *earg1) | 6044 CallExp::CallExp(Loc loc, Expression *e, Expression *earg1) |
5935 : UnaExp(loc, TOKcall, sizeof(CallExp), e) | 6045 : UnaExp(loc, TOKcall, sizeof(CallExp), e) |
5936 { | 6046 { |
5937 Expressions *arguments = new Expressions(); | 6047 Expressions *arguments = new Expressions(); |
5938 arguments->setDim(1); | 6048 if (earg1) |
5939 arguments->data[0] = (void *)earg1; | 6049 { arguments->setDim(1); |
5940 | 6050 arguments->data[0] = (void *)earg1; |
6051 } | |
5941 this->arguments = arguments; | 6052 this->arguments = arguments; |
5942 } | 6053 } |
5943 | 6054 |
5944 CallExp::CallExp(Loc loc, Expression *e, Expression *earg1, Expression *earg2) | 6055 CallExp::CallExp(Loc loc, Expression *e, Expression *earg1, Expression *earg2) |
5945 : UnaExp(loc, TOKcall, sizeof(CallExp), e) | 6056 : UnaExp(loc, TOKcall, sizeof(CallExp), e) |
6038 * foo!(tiargs)(funcargs) | 6149 * foo!(tiargs)(funcargs) |
6039 */ | 6150 */ |
6040 if (e1->op == TOKimport && !e1->type) | 6151 if (e1->op == TOKimport && !e1->type) |
6041 { ScopeExp *se = (ScopeExp *)e1; | 6152 { ScopeExp *se = (ScopeExp *)e1; |
6042 TemplateInstance *ti = se->sds->isTemplateInstance(); | 6153 TemplateInstance *ti = se->sds->isTemplateInstance(); |
6043 if (ti && !ti->semanticdone) | 6154 if (ti && !ti->semanticRun) |
6044 { | 6155 { |
6045 /* Attempt to instantiate ti. If that works, go with it. | 6156 /* Attempt to instantiate ti. If that works, go with it. |
6046 * If not, go with partial explicit specialization. | 6157 * If not, go with partial explicit specialization. |
6047 */ | 6158 */ |
6048 ti->semanticTiargs(sc); | 6159 ti->semanticTiargs(sc); |
6065 * expr.foo!(tiargs)(funcargs) | 6176 * expr.foo!(tiargs)(funcargs) |
6066 */ | 6177 */ |
6067 if (e1->op == TOKdotti && !e1->type) | 6178 if (e1->op == TOKdotti && !e1->type) |
6068 { DotTemplateInstanceExp *se = (DotTemplateInstanceExp *)e1; | 6179 { DotTemplateInstanceExp *se = (DotTemplateInstanceExp *)e1; |
6069 TemplateInstance *ti = se->ti; | 6180 TemplateInstance *ti = se->ti; |
6070 if (!ti->semanticdone) | 6181 if (!ti->semanticRun) |
6071 { | 6182 { |
6072 /* Attempt to instantiate ti. If that works, go with it. | 6183 /* Attempt to instantiate ti. If that works, go with it. |
6073 * If not, go with partial explicit specialization. | 6184 * If not, go with partial explicit specialization. |
6074 */ | 6185 */ |
6075 ti->semanticTiargs(sc); | 6186 ti->semanticTiargs(sc); |
6161 { AggregateDeclaration *ad; | 6272 { AggregateDeclaration *ad; |
6162 | 6273 |
6163 if (t1->ty == Tstruct) | 6274 if (t1->ty == Tstruct) |
6164 { | 6275 { |
6165 ad = ((TypeStruct *)t1)->sym; | 6276 ad = ((TypeStruct *)t1)->sym; |
6277 #if DMDV2 | |
6278 // First look for constructor | |
6279 if (ad->ctor && arguments && arguments->dim) | |
6280 { | |
6281 // Create variable that will get constructed | |
6282 Identifier *idtmp = Lexer::uniqueId("__ctmp"); | |
6283 VarDeclaration *tmp = new VarDeclaration(loc, t1, idtmp, NULL); | |
6284 Expression *av = new DeclarationExp(loc, tmp); | |
6285 av = new CommaExp(loc, av, new VarExp(loc, tmp)); | |
6286 | |
6287 Expression *e; | |
6288 CtorDeclaration *cf = ad->ctor->isCtorDeclaration(); | |
6289 if (cf) | |
6290 e = new DotVarExp(loc, av, cf, 1); | |
6291 else | |
6292 { TemplateDeclaration *td = ad->ctor->isTemplateDeclaration(); | |
6293 assert(td); | |
6294 e = new DotTemplateExp(loc, av, td); | |
6295 } | |
6296 e = new CallExp(loc, e, arguments); | |
6297 #if !STRUCTTHISREF | |
6298 /* Constructors return a pointer to the instance | |
6299 */ | |
6300 e = new PtrExp(loc, e); | |
6301 #endif | |
6302 e = e->semantic(sc); | |
6303 return e; | |
6304 } | |
6305 #endif | |
6306 // No constructor, look for overload of opCall | |
6166 if (search_function(ad, Id::call)) | 6307 if (search_function(ad, Id::call)) |
6167 goto L1; // overload of opCall, therefore it's a call | 6308 goto L1; // overload of opCall, therefore it's a call |
6168 | 6309 |
6169 if (e1->op != TOKtype) | 6310 if (e1->op != TOKtype) |
6170 error("%s %s does not overload ()", ad->kind(), ad->toChars()); | 6311 error("%s %s does not overload ()", ad->kind(), ad->toChars()); |
6203 { // Do overload resolution | 6344 { // Do overload resolution |
6204 dve = (DotVarExp *)(e1); | 6345 dve = (DotVarExp *)(e1); |
6205 | 6346 |
6206 f = dve->var->isFuncDeclaration(); | 6347 f = dve->var->isFuncDeclaration(); |
6207 assert(f); | 6348 assert(f); |
6208 f = f->overloadResolve(loc, arguments, sc->module); | 6349 f = f->overloadResolve(loc, NULL, arguments, sc->module); |
6209 | 6350 |
6210 ad = f->toParent()->isAggregateDeclaration(); | 6351 ad = f->toParent()->isAggregateDeclaration(); |
6211 } | 6352 } |
6212 else | 6353 else |
6213 { dte = (DotTemplateExp *)(e1); | 6354 { dte = (DotTemplateExp *)(e1); |
6304 if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor)) | 6445 if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor)) |
6305 error("multiple constructor calls"); | 6446 error("multiple constructor calls"); |
6306 sc->callSuper |= CSXany_ctor | CSXsuper_ctor; | 6447 sc->callSuper |= CSXany_ctor | CSXsuper_ctor; |
6307 } | 6448 } |
6308 | 6449 |
6309 f = f->overloadResolve(loc, arguments, sc->module); | 6450 f = f->overloadResolve(loc, NULL, arguments, sc->module); |
6310 checkDeprecated(sc, f); | 6451 checkDeprecated(sc, f); |
6311 #if DMDV2 | 6452 #if DMDV2 |
6312 checkPurity(sc, f); | 6453 checkPurity(sc, f); |
6313 #endif | 6454 #endif |
6314 e1 = new DotVarExp(e1->loc, e1, f); | 6455 e1 = new DotVarExp(e1->loc, e1, f); |
6344 error("multiple constructor calls"); | 6485 error("multiple constructor calls"); |
6345 sc->callSuper |= CSXany_ctor | CSXthis_ctor; | 6486 sc->callSuper |= CSXany_ctor | CSXthis_ctor; |
6346 } | 6487 } |
6347 | 6488 |
6348 f = cd->ctor; | 6489 f = cd->ctor; |
6349 f = f->overloadResolve(loc, arguments, sc->module); | 6490 f = f->overloadResolve(loc, NULL, arguments, sc->module); |
6350 checkDeprecated(sc, f); | 6491 checkDeprecated(sc, f); |
6351 #if DMDV2 | 6492 #if DMDV2 |
6352 checkPurity(sc, f); | 6493 checkPurity(sc, f); |
6353 #endif | 6494 #endif |
6354 e1 = new DotVarExp(e1->loc, e1, f); | 6495 e1 = new DotVarExp(e1->loc, e1, f); |
6438 istemp = 1; | 6579 istemp = 1; |
6439 goto Lagain; | 6580 goto Lagain; |
6440 } | 6581 } |
6441 } | 6582 } |
6442 | 6583 |
6443 f = f->overloadResolve(loc, arguments, sc->module); | 6584 f = f->overloadResolve(loc, NULL, arguments, sc->module); |
6444 checkDeprecated(sc, f); | 6585 checkDeprecated(sc, f); |
6445 #if DMDV2 | 6586 #if DMDV2 |
6446 checkPurity(sc, f); | 6587 checkPurity(sc, f); |
6447 #endif | 6588 #endif |
6448 | 6589 |
6521 } | 6662 } |
6522 | 6663 |
6523 #if DMDV2 | 6664 #if DMDV2 |
6524 int CallExp::canThrow() | 6665 int CallExp::canThrow() |
6525 { | 6666 { |
6667 //printf("CallExp::canThrow() %s\n", toChars()); | |
6526 if (e1->canThrow()) | 6668 if (e1->canThrow()) |
6527 return 1; | 6669 return 1; |
6528 | 6670 |
6529 /* If any of the arguments can throw, then this expression can throw | 6671 /* If any of the arguments can throw, then this expression can throw |
6530 */ | 6672 */ |
6531 for (size_t i = 0; i < arguments->dim; i++) | 6673 for (size_t i = 0; i < arguments->dim; i++) |
6532 { Expression *e = (Expression *)arguments->data[i]; | 6674 { Expression *e = (Expression *)arguments->data[i]; |
6533 | 6675 |
6534 if (e->canThrow()) | 6676 if (e && e->canThrow()) |
6535 return 1; | 6677 return 1; |
6536 } | 6678 } |
6679 | |
6680 if (global.errors && !e1->type) | |
6681 return 0; // error recovery | |
6537 | 6682 |
6538 /* If calling a function or delegate that is typed as nothrow, | 6683 /* If calling a function or delegate that is typed as nothrow, |
6539 * then this expression cannot throw. | 6684 * then this expression cannot throw. |
6540 * Note that pure functions can throw. | 6685 * Note that pure functions can throw. |
6541 */ | 6686 */ |
6550 #endif | 6695 #endif |
6551 | 6696 |
6552 #if DMDV2 | 6697 #if DMDV2 |
6553 int CallExp::isLvalue() | 6698 int CallExp::isLvalue() |
6554 { | 6699 { |
6555 if (type->toBasetype()->ty == Tstruct) | 6700 // if (type->toBasetype()->ty == Tstruct) |
6556 return 1; | 6701 // return 1; |
6557 Type *tb = e1->type->toBasetype(); | 6702 Type *tb = e1->type->toBasetype(); |
6558 if (tb->ty == Tfunction && ((TypeFunction *)tb)->isref) | 6703 if (tb->ty == Tfunction && ((TypeFunction *)tb)->isref) |
6559 return 1; // function returns a reference | 6704 return 1; // function returns a reference |
6560 return 0; | 6705 return 0; |
6561 } | 6706 } |
6562 #endif | 6707 #endif |
6563 | 6708 |
6564 Expression *CallExp::toLvalue(Scope *sc, Expression *e) | 6709 Expression *CallExp::toLvalue(Scope *sc, Expression *e) |
6565 { | 6710 { |
6711 #if 1 | |
6566 if (type->toBasetype()->ty == Tstruct) | 6712 if (type->toBasetype()->ty == Tstruct) |
6567 return this; | 6713 return this; |
6568 else | 6714 else |
6715 #endif | |
6569 return Expression::toLvalue(sc, e); | 6716 return Expression::toLvalue(sc, e); |
6717 } | |
6718 | |
6719 Expression *CallExp::modifiableLvalue(Scope *sc, Expression *e) | |
6720 { | |
6721 #if 1 | |
6722 return Expression::modifiableLvalue(sc, e); | |
6723 #else | |
6724 /* Although function return values being usable as "ref" parameters is | |
6725 * unsound, disabling it breaks existing code. | |
6726 * Bugzilla 3167 | |
6727 */ | |
6728 error("cannot assign to function call"); | |
6729 return toLvalue(sc, e); | |
6730 #endif | |
6570 } | 6731 } |
6571 | 6732 |
6572 void CallExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 6733 void CallExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
6573 { int i; | 6734 { int i; |
6574 | 6735 |
6598 UnaExp::semantic(sc); | 6759 UnaExp::semantic(sc); |
6599 e1 = e1->toLvalue(sc, NULL); | 6760 e1 = e1->toLvalue(sc, NULL); |
6600 if (!e1->type) | 6761 if (!e1->type) |
6601 { | 6762 { |
6602 error("cannot take address of %s", e1->toChars()); | 6763 error("cannot take address of %s", e1->toChars()); |
6603 type = Type::tint32; | 6764 return new ErrorExp(); |
6604 return this; | 6765 } |
6766 if (!e1->type->deco) | |
6767 { | |
6768 /* No deco means semantic() was not run on the type. | |
6769 * We have to run semantic() on the symbol to get the right type: | |
6770 * auto x = &bar; | |
6771 * pure: int bar() { return 1;} | |
6772 * otherwise the 'pure' is missing from the type assigned to x. | |
6773 */ | |
6774 | |
6775 error("forward reference to %s", e1->toChars()); | |
6776 return new ErrorExp(); | |
6605 } | 6777 } |
6606 type = e1->type->pointerTo(); | 6778 type = e1->type->pointerTo(); |
6607 | 6779 |
6608 // See if this should really be a delegate | 6780 // See if this should really be a delegate |
6609 if (e1->op == TOKdotvar) | 6781 if (e1->op == TOKdotvar) |
6651 /************************************************************/ | 6823 /************************************************************/ |
6652 | 6824 |
6653 PtrExp::PtrExp(Loc loc, Expression *e) | 6825 PtrExp::PtrExp(Loc loc, Expression *e) |
6654 : UnaExp(loc, TOKstar, sizeof(PtrExp), e) | 6826 : UnaExp(loc, TOKstar, sizeof(PtrExp), e) |
6655 { | 6827 { |
6656 if (e->type) | 6828 // if (e->type) |
6657 type = ((TypePointer *)e->type)->next; | 6829 // type = ((TypePointer *)e->type)->next; |
6658 } | 6830 } |
6659 | 6831 |
6660 PtrExp::PtrExp(Loc loc, Expression *e, Type *t) | 6832 PtrExp::PtrExp(Loc loc, Expression *e, Type *t) |
6661 : UnaExp(loc, TOKstar, sizeof(PtrExp), e) | 6833 : UnaExp(loc, TOKstar, sizeof(PtrExp), e) |
6662 { | 6834 { |
6663 type = t; | 6835 type = t; |
6664 } | 6836 } |
6665 | 6837 |
6666 Expression *PtrExp::semantic(Scope *sc) | 6838 Expression *PtrExp::semantic(Scope *sc) |
6667 { Type *tb; | 6839 { |
6668 | |
6669 #if LOGSEMANTIC | 6840 #if LOGSEMANTIC |
6670 printf("PtrExp::semantic('%s')\n", toChars()); | 6841 printf("PtrExp::semantic('%s')\n", toChars()); |
6671 #endif | 6842 #endif |
6672 UnaExp::semantic(sc); | 6843 if (!type) |
6673 e1 = resolveProperties(sc, e1); | 6844 { |
6674 if (type) | 6845 UnaExp::semantic(sc); |
6675 return this; | 6846 e1 = resolveProperties(sc, e1); |
6676 if (!e1->type) | 6847 if (!e1->type) |
6677 printf("PtrExp::semantic('%s')\n", toChars()); | 6848 printf("PtrExp::semantic('%s')\n", toChars()); |
6678 tb = e1->type->toBasetype(); | 6849 Type *tb = e1->type->toBasetype(); |
6679 switch (tb->ty) | 6850 switch (tb->ty) |
6680 { | 6851 { |
6681 case Tpointer: | 6852 case Tpointer: |
6682 type = tb->next; | 6853 type = tb->next; |
6683 if (type->isbit()) | 6854 break; |
6684 { Expression *e; | 6855 |
6685 | 6856 case Tsarray: |
6686 // Rewrite *p as p[0] | 6857 case Tarray: |
6687 e = new IndexExp(loc, e1, new IntegerExp(0)); | 6858 type = tb->next; |
6688 return e->semantic(sc); | 6859 e1 = e1->castTo(sc, type->pointerTo()); |
6689 } | 6860 break; |
6690 break; | 6861 |
6691 | 6862 default: |
6692 case Tsarray: | 6863 error("can only * a pointer, not a '%s'", e1->type->toChars()); |
6693 case Tarray: | 6864 return new ErrorExp(); |
6694 type = tb->next; | 6865 } |
6695 e1 = e1->castTo(sc, type->pointerTo()); | 6866 rvalue(); |
6696 break; | 6867 } |
6697 | |
6698 default: | |
6699 error("can only * a pointer, not a '%s'", e1->type->toChars()); | |
6700 type = Type::tint32; | |
6701 break; | |
6702 } | |
6703 rvalue(); | |
6704 return this; | 6868 return this; |
6705 } | 6869 } |
6706 | 6870 |
6707 #if DMDV2 | 6871 #if DMDV2 |
6708 int PtrExp::isLvalue() | 6872 int PtrExp::isLvalue() |
6764 e = op_overload(sc); | 6928 e = op_overload(sc); |
6765 if (e) | 6929 if (e) |
6766 return e; | 6930 return e; |
6767 | 6931 |
6768 e1->checkNoBool(); | 6932 e1->checkNoBool(); |
6769 if (e1->op != TOKslice) | 6933 if (!e1->isArrayOperand()) |
6770 e1->checkArithmetic(); | 6934 e1->checkArithmetic(); |
6771 type = e1->type; | 6935 type = e1->type; |
6772 } | 6936 } |
6773 return this; | 6937 return this; |
6774 } | 6938 } |
6814 e = op_overload(sc); | 6978 e = op_overload(sc); |
6815 if (e) | 6979 if (e) |
6816 return e; | 6980 return e; |
6817 | 6981 |
6818 e1->checkNoBool(); | 6982 e1->checkNoBool(); |
6819 if (e1->op != TOKslice) | 6983 if (!e1->isArrayOperand()) |
6820 e1 = e1->checkIntegral(); | 6984 e1 = e1->checkIntegral(); |
6821 type = e1->type; | 6985 type = e1->type; |
6822 } | 6986 } |
6823 return this; | 6987 return this; |
6824 } | 6988 } |
7010 if (e) | 7174 if (e) |
7011 { | 7175 { |
7012 return e->implicitCastTo(sc, to); | 7176 return e->implicitCastTo(sc, to); |
7013 } | 7177 } |
7014 | 7178 |
7179 if (e1->op == TOKtemplate) | |
7180 { | |
7181 error("cannot cast template %s to type %s", e1->toChars(), to->toChars()); | |
7182 return new ErrorExp(); | |
7183 } | |
7184 | |
7185 Type *t1b = e1->type->toBasetype(); | |
7015 Type *tob = to->toBasetype(); | 7186 Type *tob = to->toBasetype(); |
7016 if (tob->ty == Tstruct && | 7187 if (tob->ty == Tstruct && |
7017 !tob->equals(e1->type->toBasetype()) && | 7188 !tob->equals(t1b) && |
7018 ((TypeStruct *)to)->sym->search(0, Id::call, 0) | 7189 ((TypeStruct *)to)->sym->search(0, Id::call, 0) |
7019 ) | 7190 ) |
7020 { | 7191 { |
7021 /* Look to replace: | 7192 /* Look to replace: |
7022 * cast(S)t | 7193 * cast(S)t |
7028 e = new TypeExp(loc, to); | 7199 e = new TypeExp(loc, to); |
7029 e = new DotIdExp(loc, e, Id::call); | 7200 e = new DotIdExp(loc, e, Id::call); |
7030 e = new CallExp(loc, e, e1); | 7201 e = new CallExp(loc, e, e1); |
7031 e = e->semantic(sc); | 7202 e = e->semantic(sc); |
7032 return e; | 7203 return e; |
7204 } | |
7205 | |
7206 // Struct casts are possible only when the sizes match | |
7207 if (tob->ty == Tstruct || t1b->ty == Tstruct) | |
7208 { | |
7209 size_t fromsize = t1b->size(loc); | |
7210 size_t tosize = tob->size(loc); | |
7211 if (fromsize != tosize) | |
7212 { | |
7213 error("cannot cast from %s to %s", e1->type->toChars(), to->toChars()); | |
7214 return new ErrorExp(); | |
7215 } | |
7033 } | 7216 } |
7034 } | 7217 } |
7035 e = e1->castTo(sc, to); | 7218 e = e1->castTo(sc, to); |
7036 return e; | 7219 return e; |
7037 } | 7220 } |
7735 buf->writestring((op == TOKplusplus) ? (char *)"++" : (char *)"--"); | 7918 buf->writestring((op == TOKplusplus) ? (char *)"++" : (char *)"--"); |
7736 } | 7919 } |
7737 | 7920 |
7738 /************************************************************/ | 7921 /************************************************************/ |
7739 | 7922 |
7740 /* Can be TOKconstruct too */ | 7923 /* op can be TOKassign, TOKconstruct, or TOKblit */ |
7741 | 7924 |
7742 AssignExp::AssignExp(Loc loc, Expression *e1, Expression *e2) | 7925 AssignExp::AssignExp(Loc loc, Expression *e1, Expression *e2) |
7743 : BinExp(loc, TOKassign, sizeof(AssignExp), e1, e2) | 7926 : BinExp(loc, TOKassign, sizeof(AssignExp), e1, e2) |
7744 { | 7927 { |
7745 ismemset = 0; | 7928 ismemset = 0; |
7746 } | 7929 } |
7747 | 7930 |
7748 Expression *AssignExp::semantic(Scope *sc) | 7931 Expression *AssignExp::semantic(Scope *sc) |
7749 { Type *t1; | 7932 { |
7750 Expression *e1old = e1; | 7933 Expression *e1old = e1; |
7751 | 7934 |
7752 #if LOGSEMANTIC | 7935 #if LOGSEMANTIC |
7753 printf("AssignExp::semantic('%s')\n", toChars()); | 7936 printf("AssignExp::semantic('%s')\n", toChars()); |
7754 #endif | 7937 #endif |
7755 //printf("e1->op = %d, '%s'\n", e1->op, Token::toChars(e1->op)); | 7938 //printf("e1->op = %d, '%s'\n", e1->op, Token::toChars(e1->op)); |
7939 //printf("e2->op = %d, '%s'\n", e2->op, Token::toChars(e2->op)); | |
7940 | |
7941 if (type) | |
7942 return this; | |
7943 | |
7944 if (e2->op == TOKcomma) | |
7945 { /* Rewrite to get rid of the comma from rvalue | |
7946 */ | |
7947 AssignExp *ea = new AssignExp(loc, e1, ((CommaExp *)e2)->e2); | |
7948 ea->op = op; | |
7949 Expression *e = new CommaExp(loc, ((CommaExp *)e2)->e1, ea); | |
7950 return e->semantic(sc); | |
7951 } | |
7756 | 7952 |
7757 /* Look for operator overloading of a[i]=value. | 7953 /* Look for operator overloading of a[i]=value. |
7758 * Do it before semantic() otherwise the a[i] will have been | 7954 * Do it before semantic() otherwise the a[i] will have been |
7759 * converted to a.opIndex() already. | 7955 * converted to a.opIndex() already. |
7760 */ | 7956 */ |
7761 if (e1->op == TOKarray) | 7957 if (e1->op == TOKarray) |
7762 { Type *t1; | 7958 { |
7763 ArrayExp *ae = (ArrayExp *)e1; | 7959 ArrayExp *ae = (ArrayExp *)e1; |
7764 AggregateDeclaration *ad; | 7960 AggregateDeclaration *ad; |
7765 Identifier *id = Id::index; | 7961 Identifier *id = Id::index; |
7766 | 7962 |
7767 ae->e1 = ae->e1->semantic(sc); | 7963 ae->e1 = ae->e1->semantic(sc); |
7768 t1 = ae->e1->type->toBasetype(); | 7964 Type *t1 = ae->e1->type->toBasetype(); |
7769 if (t1->ty == Tstruct) | 7965 if (t1->ty == Tstruct) |
7770 { | 7966 { |
7771 ad = ((TypeStruct *)t1)->sym; | 7967 ad = ((TypeStruct *)t1)->sym; |
7772 goto L1; | 7968 goto L1; |
7773 } | 7969 } |
7878 e = e->semantic(sc); | 8074 e = e->semantic(sc); |
7879 return e; | 8075 return e; |
7880 } | 8076 } |
7881 } | 8077 } |
7882 | 8078 |
7883 t1 = e1->type->toBasetype(); | 8079 // Determine if this is an initialization of a reference |
8080 int refinit = 0; | |
8081 if (op == TOKconstruct && e1->op == TOKvar) | |
8082 { VarExp *ve = (VarExp *)e1; | |
8083 VarDeclaration *v = ve->var->isVarDeclaration(); | |
8084 if (v->storage_class & (STCout | STCref)) | |
8085 refinit = 1; | |
8086 } | |
8087 | |
8088 Type *t1 = e1->type->toBasetype(); | |
7884 | 8089 |
7885 if (t1->ty == Tfunction) | 8090 if (t1->ty == Tfunction) |
7886 { // Rewrite f=value to f(value) | 8091 { // Rewrite f=value to f(value) |
7887 Expression *e; | 8092 Expression *e = new CallExp(loc, e1, e2); |
7888 | |
7889 e = new CallExp(loc, e1, e2); | |
7890 e = e->semantic(sc); | 8093 e = e->semantic(sc); |
7891 return e; | 8094 return e; |
7892 } | 8095 } |
7893 | 8096 |
7894 /* If it is an assignment from a 'foreign' type, | 8097 /* If it is an assignment from a 'foreign' type, |
7916 else if (e1->op == TOKslice) | 8119 else if (e1->op == TOKslice) |
7917 ; | 8120 ; |
7918 else | 8121 else |
7919 { // Try to do a decent error message with the expression | 8122 { // Try to do a decent error message with the expression |
7920 // before it got constant folded | 8123 // before it got constant folded |
7921 e1 = e1->modifiableLvalue(sc, e1old); | 8124 if (op != TOKconstruct) |
8125 e1 = e1->modifiableLvalue(sc, e1old); | |
7922 } | 8126 } |
7923 | 8127 |
7924 if (e1->op == TOKslice && | 8128 if (e1->op == TOKslice && |
7925 t1->nextOf() && | 8129 t1->nextOf() && |
7926 e2->implicitConvTo(t1->nextOf()) | 8130 e2->implicitConvTo(t1->nextOf()) |
7928 ) | 8132 ) |
7929 { // memset | 8133 { // memset |
7930 ismemset = 1; // make it easy for back end to tell what this is | 8134 ismemset = 1; // make it easy for back end to tell what this is |
7931 e2 = e2->implicitCastTo(sc, t1->next); | 8135 e2 = e2->implicitCastTo(sc, t1->next); |
7932 } | 8136 } |
7933 else if (t1->ty == Tsarray) | 8137 else if (t1->ty == Tsarray && !refinit) |
7934 { | 8138 { |
7935 error("cannot assign to static array %s", e1->toChars()); | 8139 error("cannot assign to static array %s", e1->toChars()); |
7936 } | 8140 } |
7937 else | 8141 else |
7938 { | 8142 { |
8059 { | 8263 { |
8060 type = e1->type; | 8264 type = e1->type; |
8061 typeCombine(sc); | 8265 typeCombine(sc); |
8062 e1->checkArithmetic(); | 8266 e1->checkArithmetic(); |
8063 e2->checkArithmetic(); | 8267 e2->checkArithmetic(); |
8268 checkComplexAddAssign(); | |
8064 if (type->isreal() || type->isimaginary()) | 8269 if (type->isreal() || type->isimaginary()) |
8065 { | 8270 { |
8066 assert(global.errors || e2->type->isfloating()); | 8271 assert(global.errors || e2->type->isfloating()); |
8067 e2 = e2->castTo(sc, e1->type); | 8272 e2 = e2->castTo(sc, e1->type); |
8068 } | 8273 } |
8109 e = scaleFactor(sc); | 8314 e = scaleFactor(sc); |
8110 else | 8315 else |
8111 { | 8316 { |
8112 e1 = e1->checkArithmetic(); | 8317 e1 = e1->checkArithmetic(); |
8113 e2 = e2->checkArithmetic(); | 8318 e2 = e2->checkArithmetic(); |
8319 checkComplexAddAssign(); | |
8114 type = e1->type; | 8320 type = e1->type; |
8115 typeCombine(sc); | 8321 typeCombine(sc); |
8116 if (type->isreal() || type->isimaginary()) | 8322 if (type->isreal() || type->isimaginary()) |
8117 { | 8323 { |
8118 assert(e2->type->isfloating()); | 8324 assert(e2->type->isfloating()); |
8213 e1->checkNoBool(); | 8419 e1->checkNoBool(); |
8214 type = e1->type; | 8420 type = e1->type; |
8215 typeCombine(sc); | 8421 typeCombine(sc); |
8216 e1->checkArithmetic(); | 8422 e1->checkArithmetic(); |
8217 e2->checkArithmetic(); | 8423 e2->checkArithmetic(); |
8424 checkComplexMulAssign(); | |
8218 if (e2->type->isfloating()) | 8425 if (e2->type->isfloating()) |
8219 { Type *t1; | 8426 { Type *t1; |
8220 Type *t2; | 8427 Type *t2; |
8221 | 8428 |
8222 t1 = e1->type; | 8429 t1 = e1->type; |
8279 e1->checkNoBool(); | 8486 e1->checkNoBool(); |
8280 type = e1->type; | 8487 type = e1->type; |
8281 typeCombine(sc); | 8488 typeCombine(sc); |
8282 e1->checkArithmetic(); | 8489 e1->checkArithmetic(); |
8283 e2->checkArithmetic(); | 8490 e2->checkArithmetic(); |
8491 checkComplexMulAssign(); | |
8284 if (e2->type->isimaginary()) | 8492 if (e2->type->isimaginary()) |
8285 { Type *t1; | 8493 { Type *t1; |
8286 Type *t2; | 8494 Type *t2; |
8287 | 8495 |
8288 t1 = e1->type; | 8496 t1 = e1->type; |
8326 { | 8534 { |
8327 } | 8535 } |
8328 | 8536 |
8329 Expression *ModAssignExp::semantic(Scope *sc) | 8537 Expression *ModAssignExp::semantic(Scope *sc) |
8330 { | 8538 { |
8539 BinExp::semantic(sc); | |
8540 checkComplexMulAssign(); | |
8331 return commonSemanticAssign(sc); | 8541 return commonSemanticAssign(sc); |
8332 } | 8542 } |
8333 | 8543 |
8334 /************************************************************/ | 8544 /************************************************************/ |
8335 | 8545 |
8734 e = op_overload(sc); | 8944 e = op_overload(sc); |
8735 if (e) | 8945 if (e) |
8736 return e; | 8946 return e; |
8737 | 8947 |
8738 typeCombine(sc); | 8948 typeCombine(sc); |
8739 if (e1->op != TOKslice && e2->op != TOKslice) | 8949 if (!e1->isArrayOperand()) |
8740 { e1->checkArithmetic(); | 8950 e1->checkArithmetic(); |
8951 if (!e2->isArrayOperand()) | |
8741 e2->checkArithmetic(); | 8952 e2->checkArithmetic(); |
8742 } | |
8743 if (type->isfloating()) | 8953 if (type->isfloating()) |
8744 { Type *t1 = e1->type; | 8954 { Type *t1 = e1->type; |
8745 Type *t2 = e2->type; | 8955 Type *t2 = e2->type; |
8746 | 8956 |
8747 if (t1->isreal()) | 8957 if (t1->isreal()) |
8800 e = op_overload(sc); | 9010 e = op_overload(sc); |
8801 if (e) | 9011 if (e) |
8802 return e; | 9012 return e; |
8803 | 9013 |
8804 typeCombine(sc); | 9014 typeCombine(sc); |
8805 if (e1->op != TOKslice && e2->op != TOKslice) | 9015 if (!e1->isArrayOperand()) |
8806 { e1->checkArithmetic(); | 9016 e1->checkArithmetic(); |
9017 if (!e2->isArrayOperand()) | |
8807 e2->checkArithmetic(); | 9018 e2->checkArithmetic(); |
8808 } | |
8809 if (type->isfloating()) | 9019 if (type->isfloating()) |
8810 { Type *t1 = e1->type; | 9020 { Type *t1 = e1->type; |
8811 Type *t2 = e2->type; | 9021 Type *t2 = e2->type; |
8812 | 9022 |
8813 if (t1->isreal()) | 9023 if (t1->isreal()) |
8867 e = op_overload(sc); | 9077 e = op_overload(sc); |
8868 if (e) | 9078 if (e) |
8869 return e; | 9079 return e; |
8870 | 9080 |
8871 typeCombine(sc); | 9081 typeCombine(sc); |
8872 if (e1->op != TOKslice && e2->op != TOKslice) | 9082 if (!e1->isArrayOperand()) |
8873 { e1->checkArithmetic(); | 9083 e1->checkArithmetic(); |
9084 if (!e2->isArrayOperand()) | |
8874 e2->checkArithmetic(); | 9085 e2->checkArithmetic(); |
8875 } | |
8876 if (type->isfloating()) | 9086 if (type->isfloating()) |
8877 { type = e1->type; | 9087 { type = e1->type; |
8878 if (e2->type->iscomplex()) | 9088 if (e2->type->iscomplex()) |
8879 { error("cannot perform modulo complex arithmetic"); | 9089 { error("cannot perform modulo complex arithmetic"); |
8880 return new IntegerExp(0); | 9090 return new IntegerExp(0); |
8981 e = this; | 9191 e = this; |
8982 } | 9192 } |
8983 else | 9193 else |
8984 { | 9194 { |
8985 typeCombine(sc); | 9195 typeCombine(sc); |
8986 if (e1->op != TOKslice && e2->op != TOKslice) | 9196 if (!e1->isArrayOperand()) |
8987 { e1->checkIntegral(); | 9197 e1->checkIntegral(); |
9198 if (!e2->isArrayOperand()) | |
8988 e2->checkIntegral(); | 9199 e2->checkIntegral(); |
8989 } | |
8990 } | 9200 } |
8991 } | 9201 } |
8992 return this; | 9202 return this; |
8993 } | 9203 } |
8994 | 9204 |
9014 e = this; | 9224 e = this; |
9015 } | 9225 } |
9016 else | 9226 else |
9017 { | 9227 { |
9018 typeCombine(sc); | 9228 typeCombine(sc); |
9019 if (e1->op != TOKslice && e2->op != TOKslice) | 9229 if (!e1->isArrayOperand()) |
9020 { e1->checkIntegral(); | 9230 e1->checkIntegral(); |
9231 if (!e2->isArrayOperand()) | |
9021 e2->checkIntegral(); | 9232 e2->checkIntegral(); |
9022 } | |
9023 } | 9233 } |
9024 } | 9234 } |
9025 return this; | 9235 return this; |
9026 } | 9236 } |
9027 | 9237 |
9047 e = this; | 9257 e = this; |
9048 } | 9258 } |
9049 else | 9259 else |
9050 { | 9260 { |
9051 typeCombine(sc); | 9261 typeCombine(sc); |
9052 if (e1->op != TOKslice && e2->op != TOKslice) | 9262 if (!e1->isArrayOperand()) |
9053 { e1->checkIntegral(); | 9263 e1->checkIntegral(); |
9264 if (!e2->isArrayOperand()) | |
9054 e2->checkIntegral(); | 9265 e2->checkIntegral(); |
9055 } | |
9056 } | 9266 } |
9057 } | 9267 } |
9058 return this; | 9268 return this; |
9059 } | 9269 } |
9060 | 9270 |
9252 { | 9462 { |
9253 } | 9463 } |
9254 | 9464 |
9255 Expression *CmpExp::semantic(Scope *sc) | 9465 Expression *CmpExp::semantic(Scope *sc) |
9256 { Expression *e; | 9466 { Expression *e; |
9257 Type *t1; | |
9258 Type *t2; | |
9259 | 9467 |
9260 #if LOGSEMANTIC | 9468 #if LOGSEMANTIC |
9261 printf("CmpExp::semantic('%s')\n", toChars()); | 9469 printf("CmpExp::semantic('%s')\n", toChars()); |
9262 #endif | 9470 #endif |
9263 if (type) | 9471 if (type) |
9264 return this; | 9472 return this; |
9265 | 9473 |
9266 BinExp::semanticp(sc); | 9474 BinExp::semanticp(sc); |
9267 | 9475 |
9268 if (e1->type->toBasetype()->ty == Tclass && e2->op == TOKnull || | 9476 Type *t1 = e1->type->toBasetype(); |
9269 e2->type->toBasetype()->ty == Tclass && e1->op == TOKnull) | 9477 Type *t2 = e2->type->toBasetype(); |
9478 if (t1->ty == Tclass && e2->op == TOKnull || | |
9479 t2->ty == Tclass && e1->op == TOKnull) | |
9270 { | 9480 { |
9271 error("do not use null when comparing class types"); | 9481 error("do not use null when comparing class types"); |
9272 } | 9482 } |
9273 | 9483 |
9274 e = op_overload(sc); | 9484 e = op_overload(sc); |
9282 else | 9492 else |
9283 { e = new CmpExp(op, loc, e, new IntegerExp(loc, 0, Type::tint32)); | 9493 { e = new CmpExp(op, loc, e, new IntegerExp(loc, 0, Type::tint32)); |
9284 e = e->semantic(sc); | 9494 e = e->semantic(sc); |
9285 } | 9495 } |
9286 return e; | 9496 return e; |
9497 } | |
9498 | |
9499 /* Disallow comparing T[]==T and T==T[] | |
9500 */ | |
9501 if (e1->op == TOKslice && t1->ty == Tarray && e2->implicitConvTo(t1->nextOf()) || | |
9502 e2->op == TOKslice && t2->ty == Tarray && e1->implicitConvTo(t2->nextOf())) | |
9503 { | |
9504 incompatibleTypes(); | |
9505 return new ErrorExp(); | |
9287 } | 9506 } |
9288 | 9507 |
9289 typeCombine(sc); | 9508 typeCombine(sc); |
9290 type = Type::tboolean; | 9509 type = Type::tboolean; |
9291 | 9510 |
9335 assert(op == TOKequal || op == TOKnotequal); | 9554 assert(op == TOKequal || op == TOKnotequal); |
9336 } | 9555 } |
9337 | 9556 |
9338 Expression *EqualExp::semantic(Scope *sc) | 9557 Expression *EqualExp::semantic(Scope *sc) |
9339 { Expression *e; | 9558 { Expression *e; |
9340 Type *t1; | |
9341 Type *t2; | |
9342 | 9559 |
9343 //printf("EqualExp::semantic('%s')\n", toChars()); | 9560 //printf("EqualExp::semantic('%s')\n", toChars()); |
9344 if (type) | 9561 if (type) |
9345 return this; | 9562 return this; |
9346 | 9563 |
9365 return e; | 9582 return e; |
9366 } | 9583 } |
9367 } | 9584 } |
9368 } | 9585 } |
9369 | 9586 |
9370 if (e1->type->toBasetype()->ty == Tclass && e2->op == TOKnull || | 9587 Type *t1 = e1->type->toBasetype(); |
9371 e2->type->toBasetype()->ty == Tclass && e1->op == TOKnull) | 9588 Type *t2 = e2->type->toBasetype(); |
9589 if (t1->ty == Tclass && e2->op == TOKnull || | |
9590 t2->ty == Tclass && e1->op == TOKnull) | |
9372 { | 9591 { |
9373 error("use '%s' instead of '%s' when comparing with null", | 9592 error("use '%s' instead of '%s' when comparing with null", |
9374 Token::toChars(op == TOKequal ? TOKidentity : TOKnotidentity), | 9593 Token::toChars(op == TOKequal ? TOKidentity : TOKnotidentity), |
9375 Token::toChars(op)); | 9594 Token::toChars(op)); |
9376 } | 9595 } |
9385 e = new NotExp(e->loc, e); | 9604 e = new NotExp(e->loc, e); |
9386 e = e->semantic(sc); | 9605 e = e->semantic(sc); |
9387 } | 9606 } |
9388 return e; | 9607 return e; |
9389 } | 9608 } |
9609 } | |
9610 | |
9611 /* Disallow comparing T[]==T and T==T[] | |
9612 */ | |
9613 if (e1->op == TOKslice && t1->ty == Tarray && e2->implicitConvTo(t1->nextOf()) || | |
9614 e2->op == TOKslice && t2->ty == Tarray && e1->implicitConvTo(t2->nextOf())) | |
9615 { | |
9616 incompatibleTypes(); | |
9617 return new ErrorExp(); | |
9390 } | 9618 } |
9391 | 9619 |
9392 e = typeCombine(sc); | 9620 e = typeCombine(sc); |
9393 type = Type::tboolean; | 9621 type = Type::tboolean; |
9394 | 9622 |