Mercurial > projects > ldc
comparison dmd/expression.c @ 510:6aee82889553
Merged DMD 1.034, array operations are not yet implemented ;)
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Thu, 14 Aug 2008 06:55:41 +0200 |
parents | a34078905d01 |
children | f79bbd1d0b27 |
comparison
equal
deleted
inserted
replaced
509:337554fd34f1 | 510:6aee82889553 |
---|---|
366 | 366 |
367 else if (e->op == TOKdotexp) | 367 else if (e->op == TOKdotexp) |
368 { | 368 { |
369 e->error("expression has no value"); | 369 e->error("expression has no value"); |
370 } | 370 } |
371 | |
371 } | 372 } |
372 return e; | 373 return e; |
373 } | 374 } |
374 | 375 |
375 /****************************** | 376 /****************************** |
386 e = e->semantic(sc); | 387 e = e->semantic(sc); |
387 exps->data[i] = (void *)e; | 388 exps->data[i] = (void *)e; |
388 } | 389 } |
389 } | 390 } |
390 } | 391 } |
392 | |
393 | |
394 /****************************** | |
395 * Perform canThrow() on an array of Expressions. | |
396 */ | |
397 | |
398 #if DMDV2 | |
399 int arrayExpressionCanThrow(Expressions *exps) | |
400 { | |
401 if (exps) | |
402 { | |
403 for (size_t i = 0; i < exps->dim; i++) | |
404 { Expression *e = (Expression *)exps->data[i]; | |
405 if (e && e->canThrow()) | |
406 return 1; | |
407 } | |
408 } | |
409 return 0; | |
410 } | |
411 #endif | |
391 | 412 |
392 /**************************************** | 413 /**************************************** |
393 * Expand tuples. | 414 * Expand tuples. |
394 */ | 415 */ |
395 | 416 |
501 #endif | 522 #endif |
502 | 523 |
503 /**************************************** | 524 /**************************************** |
504 * Now that we know the exact type of the function we're calling, | 525 * Now that we know the exact type of the function we're calling, |
505 * the arguments[] need to be adjusted: | 526 * the arguments[] need to be adjusted: |
506 * 1) implicitly convert argument to the corresponding parameter type | 527 * 1. implicitly convert argument to the corresponding parameter type |
507 * 2) add default arguments for any missing arguments | 528 * 2. add default arguments for any missing arguments |
508 * 3) do default promotions on arguments corresponding to ... | 529 * 3. do default promotions on arguments corresponding to ... |
509 * 4) add hidden _arguments[] argument | 530 * 4. add hidden _arguments[] argument |
510 */ | 531 */ |
511 | 532 |
512 void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *arguments) | 533 void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *arguments) |
513 { | 534 { |
514 unsigned n; | 535 unsigned n; |
800 /******************************** Expression **************************/ | 821 /******************************** Expression **************************/ |
801 | 822 |
802 Expression::Expression(Loc loc, enum TOK op, int size) | 823 Expression::Expression(Loc loc, enum TOK op, int size) |
803 : loc(loc) | 824 : loc(loc) |
804 { | 825 { |
826 //printf("Expression::Expression(op = %d) this = %p\n", op, this); | |
805 this->loc = loc; | 827 this->loc = loc; |
806 this->op = op; | 828 this->op = op; |
807 this->size = size; | 829 this->size = size; |
808 type = NULL; | 830 type = NULL; |
809 } | 831 } |
830 dump(0); | 852 dump(0); |
831 #endif | 853 #endif |
832 assert(0); | 854 assert(0); |
833 } | 855 } |
834 e = (Expression *)mem.malloc(size); | 856 e = (Expression *)mem.malloc(size); |
857 //printf("Expression::copy(op = %d) e = %p\n", op, e); | |
835 return (Expression *)memcpy(e, this, size); | 858 return (Expression *)memcpy(e, this, size); |
836 } | 859 } |
837 | 860 |
838 /************************** | 861 /************************** |
839 * Semantically analyze Expression. | 862 * Semantically analyze Expression. |
963 return this; | 986 return this; |
964 } | 987 } |
965 | 988 |
966 Expression *Expression::modifiableLvalue(Scope *sc, Expression *e) | 989 Expression *Expression::modifiableLvalue(Scope *sc, Expression *e) |
967 { | 990 { |
991 //printf("Expression::modifiableLvalue() %s, type = %s\n", toChars(), type->toChars()); | |
992 | |
968 // See if this expression is a modifiable lvalue (i.e. not const) | 993 // See if this expression is a modifiable lvalue (i.e. not const) |
969 return toLvalue(sc, e); | 994 return toLvalue(sc, e); |
970 } | 995 } |
971 | 996 |
972 /************************************ | 997 /************************************ |
1298 type = Type::tint64; | 1323 type = Type::tint64; |
1299 else | 1324 else |
1300 type = Type::tint32; | 1325 type = Type::tint32; |
1301 } | 1326 } |
1302 else | 1327 else |
1303 { type = type->semantic(loc, sc); | 1328 { if (!type->deco) |
1329 type = type->semantic(loc, sc); | |
1304 } | 1330 } |
1305 return this; | 1331 return this; |
1306 } | 1332 } |
1307 | 1333 |
1308 Expression *IntegerExp::toLvalue(Scope *sc, Expression *e) | 1334 Expression *IntegerExp::toLvalue(Scope *sc, Expression *e) |
1783 s = sc->search(loc, ident, &scopesym); | 1809 s = sc->search(loc, ident, &scopesym); |
1784 if (s) | 1810 if (s) |
1785 { Expression *e; | 1811 { Expression *e; |
1786 WithScopeSymbol *withsym; | 1812 WithScopeSymbol *withsym; |
1787 | 1813 |
1788 // See if it was a with class | 1814 /* See if the symbol was a member of an enclosing 'with' |
1815 */ | |
1789 withsym = scopesym->isWithScopeSymbol(); | 1816 withsym = scopesym->isWithScopeSymbol(); |
1790 if (withsym) | 1817 if (withsym) |
1791 { | 1818 { |
1792 s = s->toAlias(); | 1819 s = s->toAlias(); |
1793 | 1820 |
1798 e = new DotIdExp(loc, e, ident); | 1825 e = new DotIdExp(loc, e, ident); |
1799 } | 1826 } |
1800 else | 1827 else |
1801 { Type *t = withsym->withstate->wthis->type; | 1828 { Type *t = withsym->withstate->wthis->type; |
1802 if (t->ty == Tpointer) | 1829 if (t->ty == Tpointer) |
1803 t = t->next; | 1830 t = ((TypePointer *)t)->next; |
1804 e = new TypeDotIdExp(loc, t, ident); | 1831 e = new TypeDotIdExp(loc, t, ident); |
1805 } | 1832 } |
1806 } | 1833 } |
1807 else | 1834 else |
1808 { | 1835 { |
2159 if (!sc->intypeof) | 2186 if (!sc->intypeof) |
2160 sc->callSuper |= CSXthis; | 2187 sc->callSuper |= CSXthis; |
2161 return this; | 2188 return this; |
2162 | 2189 |
2163 Lerr: | 2190 Lerr: |
2164 error("'this' is only allowed in non-static member functions, not %s", sc->parent->toChars()); | 2191 error("'this' is only defined in non-static member functions, not %s", sc->parent->toChars()); |
2165 type = Type::tint32; | 2192 type = Type::terror; |
2166 return this; | 2193 return this; |
2167 } | 2194 } |
2168 | 2195 |
2169 int ThisExp::isBool(int result) | 2196 int ThisExp::isBool(int result) |
2170 { | 2197 { |
2693 if (!t0) | 2720 if (!t0) |
2694 { t0 = e->type; | 2721 { t0 = e->type; |
2695 // Convert any static arrays to dynamic arrays | 2722 // Convert any static arrays to dynamic arrays |
2696 if (t0->ty == Tsarray) | 2723 if (t0->ty == Tsarray) |
2697 { | 2724 { |
2698 t0 = t0->next->arrayOf(); | 2725 t0 = ((TypeSArray *)t0)->next->arrayOf(); |
2699 e = e->implicitCastTo(sc, t0); | 2726 e = e->implicitCastTo(sc, t0); |
2700 } | 2727 } |
2701 } | 2728 } |
2702 else | 2729 else |
2703 e = e->implicitCastTo(sc, t0); | 2730 e = e->implicitCastTo(sc, t0); |
2904 { Expression *e; | 2931 { Expression *e; |
2905 | 2932 |
2906 #if LOGSEMANTIC | 2933 #if LOGSEMANTIC |
2907 printf("StructLiteralExp::semantic('%s')\n", toChars()); | 2934 printf("StructLiteralExp::semantic('%s')\n", toChars()); |
2908 #endif | 2935 #endif |
2936 if (type) | |
2937 return this; | |
2909 | 2938 |
2910 // Run semantic() on each element | 2939 // Run semantic() on each element |
2911 for (size_t i = 0; i < elements->dim; i++) | 2940 for (size_t i = 0; i < elements->dim; i++) |
2912 { e = (Expression *)elements->data[i]; | 2941 { e = (Expression *)elements->data[i]; |
2913 if (!e) | 2942 if (!e) |
2984 * Gets expression at offset of type. | 3013 * Gets expression at offset of type. |
2985 * Returns NULL if not found. | 3014 * Returns NULL if not found. |
2986 */ | 3015 */ |
2987 | 3016 |
2988 Expression *StructLiteralExp::getField(Type *type, unsigned offset) | 3017 Expression *StructLiteralExp::getField(Type *type, unsigned offset) |
2989 { Expression *e = NULL; | 3018 { |
3019 //printf("StructLiteralExp::getField(this = %s, type = %s, offset = %u)\n", | |
3020 // /*toChars()*/"", type->toChars(), offset); | |
3021 Expression *e = NULL; | |
2990 int i = getFieldIndex(type, offset); | 3022 int i = getFieldIndex(type, offset); |
2991 | 3023 |
2992 if (i != -1) | 3024 if (i != -1) |
2993 { e = (Expression *)elements->data[i]; | 3025 { |
3026 //printf("\ti = %d\n", i); | |
3027 assert(i < elements->dim); | |
3028 e = (Expression *)elements->data[i]; | |
2994 if (e) | 3029 if (e) |
2995 { | 3030 { |
2996 e = e->copy(); | 3031 e = e->copy(); |
2997 e->type = type; | 3032 e->type = type; |
2998 } | 3033 } |
3328 * Ensure we have the right one. | 3363 * Ensure we have the right one. |
3329 */ | 3364 */ |
3330 Dsymbol *s = cd->toParent2(); | 3365 Dsymbol *s = cd->toParent2(); |
3331 ClassDeclaration *cdn = s->isClassDeclaration(); | 3366 ClassDeclaration *cdn = s->isClassDeclaration(); |
3332 | 3367 |
3333 //printf("isNested, cdn = %s\n", cdn ? cdn->toChars() : "null"); | 3368 //printf("cd isNested, cdn = %s\n", cdn ? cdn->toChars() : "null"); |
3334 if (cdn) | 3369 if (cdn) |
3335 { | 3370 { |
3336 if (!cdthis) | 3371 if (!cdthis) |
3337 { | 3372 { |
3338 // Supply an implicit 'this' and try again | 3373 // Supply an implicit 'this' and try again |
3483 arg = resolveProperties(sc, arg); | 3518 arg = resolveProperties(sc, arg); |
3484 arg = arg->implicitCastTo(sc, Type::tsize_t); | 3519 arg = arg->implicitCastTo(sc, Type::tsize_t); |
3485 if (arg->op == TOKint64 && (long long)arg->toInteger() < 0) | 3520 if (arg->op == TOKint64 && (long long)arg->toInteger() < 0) |
3486 error("negative array index %s", arg->toChars()); | 3521 error("negative array index %s", arg->toChars()); |
3487 arguments->data[i] = (void *) arg; | 3522 arguments->data[i] = (void *) arg; |
3488 tb = tb->next->toBasetype(); | 3523 tb = ((TypeDArray *)tb)->next->toBasetype(); |
3489 } | 3524 } |
3490 } | 3525 } |
3491 else if (tb->isscalar()) | 3526 else if (tb->isscalar()) |
3492 { | 3527 { |
3493 if (arguments && arguments->dim) | 3528 if (arguments && arguments->dim) |
3820 // See if this expression is a modifiable lvalue (i.e. not const) | 3855 // See if this expression is a modifiable lvalue (i.e. not const) |
3821 return toLvalue(sc, e); | 3856 return toLvalue(sc, e); |
3822 } | 3857 } |
3823 | 3858 |
3824 | 3859 |
3860 /******************************** OverExp **************************/ | |
3861 | |
3862 #if DMDV2 | |
3863 OverExp::OverExp(OverloadSet *s) | |
3864 : Expression(loc, TOKoverloadset, sizeof(OverExp)) | |
3865 { | |
3866 //printf("OverExp(this = %p, '%s')\n", this, var->toChars()); | |
3867 vars = s; | |
3868 type = Type::tvoid; | |
3869 } | |
3870 | |
3871 int OverExp::isLvalue() | |
3872 { | |
3873 return 1; | |
3874 } | |
3875 | |
3876 Expression *OverExp::toLvalue(Scope *sc, Expression *e) | |
3877 { | |
3878 return this; | |
3879 } | |
3880 #endif | |
3881 | |
3882 | |
3825 /******************************** TupleExp **************************/ | 3883 /******************************** TupleExp **************************/ |
3826 | 3884 |
3827 TupleExp::TupleExp(Loc loc, Expressions *exps) | 3885 TupleExp::TupleExp(Loc loc, Expressions *exps) |
3828 : Expression(loc, TOKtuple, sizeof(TupleExp)) | 3886 : Expression(loc, TOKtuple, sizeof(TupleExp)) |
3829 { | 3887 { |
4156 buf->writestring("typeid("); | 4214 buf->writestring("typeid("); |
4157 typeidType->toCBuffer(buf, NULL, hgs); | 4215 typeidType->toCBuffer(buf, NULL, hgs); |
4158 buf->writeByte(')'); | 4216 buf->writeByte(')'); |
4159 } | 4217 } |
4160 | 4218 |
4219 /************************ TraitsExp ************************************/ | |
4220 #if DMDV2 | |
4221 /* | |
4222 * __traits(identifier, args...) | |
4223 */ | |
4224 | |
4225 TraitsExp::TraitsExp(Loc loc, Identifier *ident, Objects *args) | |
4226 : Expression(loc, TOKtraits, sizeof(TraitsExp)) | |
4227 { | |
4228 this->ident = ident; | |
4229 this->args = args; | |
4230 } | |
4231 | |
4232 | |
4233 Expression *TraitsExp::syntaxCopy() | |
4234 { | |
4235 return new TraitsExp(loc, ident, TemplateInstance::arraySyntaxCopy(args)); | |
4236 } | |
4237 | |
4238 | |
4239 void TraitsExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | |
4240 { | |
4241 buf->writestring("__traits("); | |
4242 buf->writestring(ident->toChars()); | |
4243 if (args) | |
4244 { | |
4245 for (int i = 0; i < args->dim; i++) | |
4246 { | |
4247 buf->writeByte(','); | |
4248 Object *oarg = (Object *)args->data[i]; | |
4249 ObjectToCBuffer(buf, hgs, oarg); | |
4250 } | |
4251 } | |
4252 buf->writeByte(')'); | |
4253 } | |
4254 #endif | |
4255 | |
4161 /************************************************************/ | 4256 /************************************************************/ |
4162 | 4257 |
4163 HaltExp::HaltExp(Loc loc) | 4258 HaltExp::HaltExp(Loc loc) |
4164 : Expression(loc, TOKhalt, sizeof(HaltExp)) | 4259 : Expression(loc, TOKhalt, sizeof(HaltExp)) |
4165 { | 4260 { |
4208 } | 4303 } |
4209 | 4304 |
4210 Expression *IsExp::semantic(Scope *sc) | 4305 Expression *IsExp::semantic(Scope *sc) |
4211 { Type *tded; | 4306 { Type *tded; |
4212 | 4307 |
4213 //printf("IsExp::semantic()\n"); | 4308 /* is(targ id tok tspec) |
4309 * is(targ id == tok2) | |
4310 */ | |
4311 | |
4312 //printf("IsExp::semantic(%s)\n", toChars()); | |
4214 if (id && !(sc->flags & SCOPEstaticif)) | 4313 if (id && !(sc->flags & SCOPEstaticif)) |
4215 error("can only declare type aliases within static if conditionals"); | 4314 error("can only declare type aliases within static if conditionals"); |
4216 | 4315 |
4217 unsigned errors_save = global.errors; | 4316 unsigned errors_save = global.errors; |
4218 global.errors = 0; | 4317 global.errors = 0; |
4265 goto Lno; | 4364 goto Lno; |
4266 if (!((TypeClass *)targ)->sym->isInterfaceDeclaration()) | 4365 if (!((TypeClass *)targ)->sym->isInterfaceDeclaration()) |
4267 goto Lno; | 4366 goto Lno; |
4268 tded = targ; | 4367 tded = targ; |
4269 break; | 4368 break; |
4369 #if DMDV2 | |
4370 case TOKconst: | |
4371 if (!targ->isConst()) | |
4372 goto Lno; | |
4373 tded = targ; | |
4374 break; | |
4375 | |
4376 case TOKinvariant: | |
4377 if (!targ->isInvariant()) | |
4378 goto Lno; | |
4379 tded = targ; | |
4380 break; | |
4381 #endif | |
4270 | 4382 |
4271 case TOKsuper: | 4383 case TOKsuper: |
4272 // If class or interface, get the base class and interfaces | 4384 // If class or interface, get the base class and interfaces |
4273 if (targ->ty != Tclass) | 4385 if (targ->ty != Tclass) |
4274 goto Lno; | 4386 goto Lno; |
4291 break; | 4403 break; |
4292 | 4404 |
4293 case TOKdelegate: | 4405 case TOKdelegate: |
4294 if (targ->ty != Tdelegate) | 4406 if (targ->ty != Tdelegate) |
4295 goto Lno; | 4407 goto Lno; |
4296 tded = targ->next; // the underlying function type | 4408 tded = ((TypeDelegate *)targ)->next; // the underlying function type |
4297 break; | 4409 break; |
4298 | 4410 |
4299 case TOKfunction: | 4411 case TOKfunction: |
4300 { if (targ->ty != Tfunction) | 4412 { |
4413 if (targ->ty != Tfunction) | |
4301 goto Lno; | 4414 goto Lno; |
4302 tded = targ; | 4415 tded = targ; |
4303 | 4416 |
4304 /* Generate tuple from function parameter types. | 4417 /* Generate tuple from function parameter types. |
4305 */ | 4418 */ |
4319 case TOKreturn: | 4432 case TOKreturn: |
4320 /* Get the 'return type' for the function, | 4433 /* Get the 'return type' for the function, |
4321 * delegate, or pointer to function. | 4434 * delegate, or pointer to function. |
4322 */ | 4435 */ |
4323 if (targ->ty == Tfunction) | 4436 if (targ->ty == Tfunction) |
4324 tded = targ->next; | 4437 tded = ((TypeFunction *)targ)->next; |
4325 else if (targ->ty == Tdelegate) | 4438 else if (targ->ty == Tdelegate) |
4326 tded = targ->next->next; | 4439 tded = targ->next->next; |
4327 else if (targ->ty == Tpointer && targ->next->ty == Tfunction) | 4440 else if (targ->ty == Tpointer && targ->next->ty == Tfunction) |
4328 tded = targ->next->next; | 4441 tded = targ->next->next; |
4329 else | 4442 else |
4535 | 4648 |
4536 e = op_overload(sc); | 4649 e = op_overload(sc); |
4537 if (e) | 4650 if (e) |
4538 return e; | 4651 return e; |
4539 | 4652 |
4653 if (e1->op == TOKslice) | |
4654 { // T[] op= ... | |
4655 typeCombine(sc); | |
4656 type = e1->type; | |
4657 return arrayOp(sc); | |
4658 } | |
4659 | |
4540 e1 = e1->modifiableLvalue(sc, e1); | 4660 e1 = e1->modifiableLvalue(sc, e1); |
4541 e1->checkScalar(); | 4661 e1->checkScalar(); |
4542 type = e1->type; | 4662 type = e1->type; |
4543 if (type->toBasetype()->ty == Tbool) | 4663 if (type->toBasetype()->ty == Tbool) |
4544 { | 4664 { |
4565 e2 = resolveProperties(sc, e2); | 4685 e2 = resolveProperties(sc, e2); |
4566 | 4686 |
4567 e = op_overload(sc); | 4687 e = op_overload(sc); |
4568 if (e) | 4688 if (e) |
4569 return e; | 4689 return e; |
4690 | |
4691 if (e1->op == TOKslice) | |
4692 { // T[] op= ... | |
4693 typeCombine(sc); | |
4694 type = e1->type; | |
4695 return arrayOp(sc); | |
4696 } | |
4570 | 4697 |
4571 e1 = e1->modifiableLvalue(sc, e1); | 4698 e1 = e1->modifiableLvalue(sc, e1); |
4572 e1->checkScalar(); | 4699 e1->checkScalar(); |
4573 type = e1->type; | 4700 type = e1->type; |
4574 if (type->toBasetype()->ty == Tbool) | 4701 if (type->toBasetype()->ty == Tbool) |
4886 { | 5013 { |
4887 e1 = resolveProperties(sc, e1); | 5014 e1 = resolveProperties(sc, e1); |
4888 eleft = NULL; | 5015 eleft = NULL; |
4889 eright = e1; | 5016 eright = e1; |
4890 } | 5017 } |
5018 #if DMDV2 | |
5019 if (e1->op == TOKtuple && ident == Id::offsetof) | |
5020 { /* 'distribute' the .offsetof to each of the tuple elements. | |
5021 */ | |
5022 TupleExp *te = (TupleExp *)e1; | |
5023 Expressions *exps = new Expressions(); | |
5024 exps->setDim(te->exps->dim); | |
5025 for (int i = 0; i < exps->dim; i++) | |
5026 { Expression *e = (Expression *)te->exps->data[i]; | |
5027 e = e->semantic(sc); | |
5028 e = new DotIdExp(e->loc, e, Id::offsetof); | |
5029 exps->data[i] = (void *)e; | |
5030 } | |
5031 e = new TupleExp(loc, exps); | |
5032 e = e->semantic(sc); | |
5033 return e; | |
5034 } | |
5035 #endif | |
4891 | 5036 |
4892 if (e1->op == TOKtuple && ident == Id::length) | 5037 if (e1->op == TOKtuple && ident == Id::length) |
4893 { | 5038 { |
4894 TupleExp *te = (TupleExp *)e1; | 5039 TupleExp *te = (TupleExp *)e1; |
4895 e = new IntegerExp(loc, te->exps->dim, Type::tsize_t); | 5040 e = new IntegerExp(loc, te->exps->dim, Type::tsize_t); |
5046 ident != Id::init && ident != Id::__sizeof && | 5191 ident != Id::init && ident != Id::__sizeof && |
5047 ident != Id::alignof && ident != Id::offsetof && | 5192 ident != Id::alignof && ident != Id::offsetof && |
5048 ident != Id::mangleof && ident != Id::stringof) | 5193 ident != Id::mangleof && ident != Id::stringof) |
5049 { | 5194 { |
5050 e = new PtrExp(loc, e1); | 5195 e = new PtrExp(loc, e1); |
5051 e->type = e1->type->next; | 5196 e->type = ((TypePointer *)e1->type)->next; |
5052 return e->type->dotExp(sc, e, ident); | 5197 return e->type->dotExp(sc, e, ident); |
5053 } | 5198 } |
5054 else | 5199 else |
5055 { | 5200 { |
5056 e = e1->type->dotExp(sc, e1, ident); | 5201 e = e1->type->dotExp(sc, e1, ident); |
5174 return this; | 5319 return this; |
5175 } | 5320 } |
5176 | 5321 |
5177 Expression *DotVarExp::modifiableLvalue(Scope *sc, Expression *e) | 5322 Expression *DotVarExp::modifiableLvalue(Scope *sc, Expression *e) |
5178 { | 5323 { |
5179 //printf("DotVarExp::modifiableLvalue(%s)\n", toChars()); | 5324 #if 0 |
5325 printf("DotVarExp::modifiableLvalue(%s)\n", toChars()); | |
5326 printf("e1->type = %s\n", e1->type->toChars()); | |
5327 printf("var->type = %s\n", var->type->toChars()); | |
5328 #endif | |
5180 | 5329 |
5181 if (var->isCtorinit()) | 5330 if (var->isCtorinit()) |
5182 { // It's only modifiable if inside the right constructor | 5331 { // It's only modifiable if inside the right constructor |
5183 Dsymbol *s = sc->func; | 5332 Dsymbol *s = sc->func; |
5184 while (1) | 5333 while (1) |
5263 e1 = e1->semantic(sc); | 5412 e1 = e1->semantic(sc); |
5264 t1 = e1->type; | 5413 t1 = e1->type; |
5265 if (t1) | 5414 if (t1) |
5266 t1 = t1->toBasetype(); | 5415 t1 = t1->toBasetype(); |
5267 //t1->print(); | 5416 //t1->print(); |
5417 | |
5418 /* Extract the following from e1: | |
5419 * s: the symbol which ti should be a member of | |
5420 * eleft: if not NULL, it is the 'this' pointer for ti | |
5421 */ | |
5422 | |
5268 if (e1->op == TOKdotexp) | 5423 if (e1->op == TOKdotexp) |
5269 { DotExp *de = (DotExp *)e1; | 5424 { DotExp *de = (DotExp *)e1; |
5270 eleft = de->e1; | 5425 eleft = de->e1; |
5271 eright = de->e2; | 5426 eright = de->e2; |
5272 } | 5427 } |
5293 s = t1->toDsymbol(sc); | 5448 s = t1->toDsymbol(sc); |
5294 eleft = e1; | 5449 eleft = e1; |
5295 } | 5450 } |
5296 else if (t1 && t1->ty == Tpointer) | 5451 else if (t1 && t1->ty == Tpointer) |
5297 { | 5452 { |
5298 t1 = t1->next->toBasetype(); | 5453 t1 = ((TypePointer *)t1)->next->toBasetype(); |
5299 if (t1->ty != Tstruct) | 5454 if (t1->ty != Tstruct) |
5300 goto L1; | 5455 goto L1; |
5301 s = t1->toDsymbol(sc); | 5456 s = t1->toDsymbol(sc); |
5302 eleft = e1; | 5457 eleft = e1; |
5303 } | 5458 } |
5469 TypeFunction *tf; | 5624 TypeFunction *tf; |
5470 FuncDeclaration *f; | 5625 FuncDeclaration *f; |
5471 int i; | 5626 int i; |
5472 Type *t1; | 5627 Type *t1; |
5473 int istemp; | 5628 int istemp; |
5629 Objects *targsi = NULL; // initial list of template arguments | |
5474 | 5630 |
5475 #if LOGSEMANTIC | 5631 #if LOGSEMANTIC |
5476 printf("CallExp::semantic() %s\n", toChars()); | 5632 printf("CallExp::semantic() %s\n", toChars()); |
5477 #endif | 5633 #endif |
5478 if (type) | 5634 if (type) |
5532 e1 = new IdentifierExp(dotid->loc, dotid->ident); | 5688 e1 = new IdentifierExp(dotid->loc, dotid->ident); |
5533 } | 5689 } |
5534 } | 5690 } |
5535 } | 5691 } |
5536 | 5692 |
5693 #if DMDV2 | |
5694 /* This recognizes: | |
5695 * foo!(tiargs)(funcargs) | |
5696 */ | |
5697 if (e1->op == TOKimport && !e1->type) | |
5698 { ScopeExp *se = (ScopeExp *)e1; | |
5699 TemplateInstance *ti = se->sds->isTemplateInstance(); | |
5700 if (ti && !ti->semanticdone) | |
5701 { | |
5702 /* Attempt to instantiate ti. If that works, go with it. | |
5703 * If not, go with partial explicit specialization. | |
5704 */ | |
5705 ti->semanticTiargs(sc); | |
5706 unsigned errors = global.errors; | |
5707 global.gag++; | |
5708 ti->semantic(sc); | |
5709 global.gag--; | |
5710 if (errors != global.errors) | |
5711 { | |
5712 /* Didn't work, go with partial explicit specialization | |
5713 */ | |
5714 global.errors = errors; | |
5715 targsi = ti->tiargs; | |
5716 e1 = new IdentifierExp(loc, ti->name); | |
5717 } | |
5718 } | |
5719 } | |
5720 | |
5721 /* This recognizes: | |
5722 * expr.foo!(tiargs)(funcargs) | |
5723 */ | |
5724 if (e1->op == TOKdotti && !e1->type) | |
5725 { DotTemplateInstanceExp *se = (DotTemplateInstanceExp *)e1; | |
5726 TemplateInstance *ti = se->ti; | |
5727 if (!ti->semanticdone) | |
5728 { | |
5729 /* Attempt to instantiate ti. If that works, go with it. | |
5730 * If not, go with partial explicit specialization. | |
5731 */ | |
5732 ti->semanticTiargs(sc); | |
5733 Expression *etmp; | |
5734 unsigned errors = global.errors; | |
5735 global.gag++; | |
5736 etmp = e1->semantic(sc); | |
5737 global.gag--; | |
5738 if (errors != global.errors) | |
5739 { | |
5740 global.errors = errors; | |
5741 targsi = ti->tiargs; | |
5742 e1 = new DotIdExp(loc, se->e1, ti->name); | |
5743 } | |
5744 else | |
5745 e1 = etmp; | |
5746 } | |
5747 } | |
5748 #endif | |
5749 | |
5537 istemp = 0; | 5750 istemp = 0; |
5538 Lagain: | 5751 Lagain: |
5752 //printf("Lagain: %s\n", toChars()); | |
5539 f = NULL; | 5753 f = NULL; |
5540 if (e1->op == TOKthis || e1->op == TOKsuper) | 5754 if (e1->op == TOKthis || e1->op == TOKsuper) |
5541 { | 5755 { |
5542 // semantic() run later for these | 5756 // semantic() run later for these |
5543 } | 5757 } |
5802 return this; | 6016 return this; |
5803 } | 6017 } |
5804 else if (t1->ty != Tfunction) | 6018 else if (t1->ty != Tfunction) |
5805 { | 6019 { |
5806 if (t1->ty == Tdelegate) | 6020 if (t1->ty == Tdelegate) |
5807 { | 6021 { TypeDelegate *td = (TypeDelegate *)t1; |
5808 assert(t1->next->ty == Tfunction); | 6022 assert(td->next->ty == Tfunction); |
5809 tf = (TypeFunction *)(t1->next); | 6023 tf = (TypeFunction *)(td->next); |
5810 goto Lcheckargs; | 6024 goto Lcheckargs; |
5811 } | 6025 } |
5812 else if (t1->ty == Tpointer && t1->next->ty == Tfunction) | 6026 else if (t1->ty == Tpointer && ((TypePointer *)t1)->next->ty == Tfunction) |
5813 { Expression *e; | 6027 { Expression *e; |
5814 | 6028 |
5815 e = new PtrExp(loc, e1); | 6029 e = new PtrExp(loc, e1); |
5816 t1 = t1->next; | 6030 t1 = ((TypePointer *)t1)->next; |
5817 e->type = t1; | 6031 e->type = t1; |
5818 e1 = e; | 6032 e1 = e; |
5819 } | 6033 } |
5820 else if (e1->op == TOKtemplate) | 6034 else if (e1->op == TOKtemplate) |
5821 { | 6035 { |
5907 | 6121 |
5908 if (f && f->tintro) | 6122 if (f && f->tintro) |
5909 { | 6123 { |
5910 Type *t = type; | 6124 Type *t = type; |
5911 int offset = 0; | 6125 int offset = 0; |
5912 | 6126 TypeFunction *tf = (TypeFunction *)f->tintro; |
5913 if (f->tintro->next->isBaseOf(t, &offset) && offset) | 6127 |
5914 { | 6128 if (tf->next->isBaseOf(t, &offset) && offset) |
5915 type = f->tintro->next; | 6129 { |
6130 type = tf->next; | |
5916 return castTo(sc, t); | 6131 return castTo(sc, t); |
5917 } | 6132 } |
5918 } | 6133 } |
5919 | 6134 |
5920 return this; | 6135 return this; |
5972 { | 6187 { |
5973 DotVarExp *dve = (DotVarExp *)e1; | 6188 DotVarExp *dve = (DotVarExp *)e1; |
5974 FuncDeclaration *f = dve->var->isFuncDeclaration(); | 6189 FuncDeclaration *f = dve->var->isFuncDeclaration(); |
5975 | 6190 |
5976 if (f) | 6191 if (f) |
5977 { Expression *e; | 6192 { Expression *e = new DelegateExp(loc, dve->e1, f); |
5978 | |
5979 e = new DelegateExp(loc, dve->e1, f); | |
5980 e = e->semantic(sc); | 6193 e = e->semantic(sc); |
5981 return e; | 6194 return e; |
5982 } | 6195 } |
5983 } | 6196 } |
5984 else if (e1->op == TOKvar) | 6197 else if (e1->op == TOKvar) |
6016 | 6229 |
6017 PtrExp::PtrExp(Loc loc, Expression *e) | 6230 PtrExp::PtrExp(Loc loc, Expression *e) |
6018 : UnaExp(loc, TOKstar, sizeof(PtrExp), e) | 6231 : UnaExp(loc, TOKstar, sizeof(PtrExp), e) |
6019 { | 6232 { |
6020 if (e->type) | 6233 if (e->type) |
6021 type = e->type->next; | 6234 type = ((TypePointer *)e->type)->next; |
6022 } | 6235 } |
6023 | 6236 |
6024 PtrExp::PtrExp(Loc loc, Expression *e, Type *t) | 6237 PtrExp::PtrExp(Loc loc, Expression *e, Type *t) |
6025 : UnaExp(loc, TOKstar, sizeof(PtrExp), e) | 6238 : UnaExp(loc, TOKstar, sizeof(PtrExp), e) |
6026 { | 6239 { |
6106 e = op_overload(sc); | 6319 e = op_overload(sc); |
6107 if (e) | 6320 if (e) |
6108 return e; | 6321 return e; |
6109 | 6322 |
6110 e1->checkNoBool(); | 6323 e1->checkNoBool(); |
6111 e1->checkArithmetic(); | 6324 if (e1->op != TOKslice) |
6325 e1->checkArithmetic(); | |
6112 type = e1->type; | 6326 type = e1->type; |
6113 } | 6327 } |
6114 return this; | 6328 return this; |
6115 } | 6329 } |
6116 | 6330 |
6155 e = op_overload(sc); | 6369 e = op_overload(sc); |
6156 if (e) | 6370 if (e) |
6157 return e; | 6371 return e; |
6158 | 6372 |
6159 e1->checkNoBool(); | 6373 e1->checkNoBool(); |
6160 e1 = e1->checkIntegral(); | 6374 if (e1->op != TOKslice) |
6375 e1 = e1->checkIntegral(); | |
6161 type = e1->type; | 6376 type = e1->type; |
6162 } | 6377 } |
6163 return this; | 6378 return this; |
6164 } | 6379 } |
6165 | 6380 |
6236 error("cannot delete instance of COM interface %s", cd->toChars()); | 6451 error("cannot delete instance of COM interface %s", cd->toChars()); |
6237 } | 6452 } |
6238 break; | 6453 break; |
6239 } | 6454 } |
6240 case Tpointer: | 6455 case Tpointer: |
6241 tb = tb->next->toBasetype(); | 6456 tb = ((TypePointer *)tb)->next->toBasetype(); |
6242 if (tb->ty == Tstruct) | 6457 if (tb->ty == Tstruct) |
6243 { | 6458 { |
6244 TypeStruct *ts = (TypeStruct *)tb; | 6459 TypeStruct *ts = (TypeStruct *)tb; |
6245 StructDeclaration *sd = ts->sym; | 6460 StructDeclaration *sd = ts->sym; |
6246 FuncDeclaration *f = sd->aggDelete; | 6461 FuncDeclaration *f = sd->aggDelete; |
6567 e = e1; | 6782 e = e1; |
6568 } | 6783 } |
6569 return e; | 6784 return e; |
6570 } | 6785 } |
6571 | 6786 |
6572 type = t->next->arrayOf(); | 6787 type = t->nextOf()->arrayOf(); |
6573 return e; | 6788 return e; |
6574 | 6789 |
6575 Lerror: | 6790 Lerror: |
6576 char *s; | 6791 char *s; |
6577 if (t->ty == Tvoid) | 6792 if (t->ty == Tvoid) |
6876 if (index < 0 || index >= length) | 7091 if (index < 0 || index >= length) |
6877 error("array index [%lld] is outside array bounds [0 .. %lld]", | 7092 error("array index [%lld] is outside array bounds [0 .. %lld]", |
6878 index, length); | 7093 index, length); |
6879 } | 7094 } |
6880 #endif | 7095 #endif |
6881 e->type = t1->next; | 7096 e->type = t1->nextOf(); |
6882 break; | 7097 break; |
6883 } | 7098 } |
6884 | 7099 |
6885 case Taarray: | 7100 case Taarray: |
6886 { TypeAArray *taa = (TypeAArray *)t1; | 7101 { TypeAArray *taa = (TypeAArray *)t1; |
7197 } | 7412 } |
7198 else | 7413 else |
7199 { | 7414 { |
7200 e2 = e2->implicitCastTo(sc, e1->type); | 7415 e2 = e2->implicitCastTo(sc, e1->type); |
7201 } | 7416 } |
7417 | |
7418 /* Look for array operations | |
7419 */ | |
7420 if (e1->op == TOKslice && !ismemset && | |
7421 (e2->op == TOKadd || e2->op == TOKmin || | |
7422 e2->op == TOKmul || e2->op == TOKdiv || | |
7423 e2->op == TOKmod || e2->op == TOKxor || | |
7424 e2->op == TOKand || e2->op == TOKor || | |
7425 e2->op == TOKtilde || e2->op == TOKneg)) | |
7426 { | |
7427 type = e1->type; | |
7428 return arrayOp(sc); | |
7429 } | |
7430 | |
7202 type = e1->type; | 7431 type = e1->type; |
7203 assert(type); | 7432 assert(type); |
7204 return this; | 7433 return this; |
7205 } | 7434 } |
7206 | 7435 |
7232 | 7461 |
7233 e = op_overload(sc); | 7462 e = op_overload(sc); |
7234 if (e) | 7463 if (e) |
7235 return e; | 7464 return e; |
7236 | 7465 |
7237 e1 = e1->modifiableLvalue(sc, e1); | |
7238 | |
7239 Type *tb1 = e1->type->toBasetype(); | 7466 Type *tb1 = e1->type->toBasetype(); |
7240 Type *tb2 = e2->type->toBasetype(); | 7467 Type *tb2 = e2->type->toBasetype(); |
7241 | 7468 |
7469 if (e1->op == TOKslice) | |
7470 { | |
7471 typeCombine(sc); | |
7472 type = e1->type; | |
7473 return arrayOp(sc); | |
7474 } | |
7475 else | |
7476 { | |
7477 e1 = e1->modifiableLvalue(sc, e1); | |
7478 } | |
7479 | |
7242 if ((tb1->ty == Tarray || tb1->ty == Tsarray) && | 7480 if ((tb1->ty == Tarray || tb1->ty == Tsarray) && |
7243 (tb2->ty == Tarray || tb2->ty == Tsarray) && | 7481 (tb2->ty == Tarray || tb2->ty == Tsarray) && |
7244 tb1->next->equals(tb2->next) | 7482 tb1->nextOf()->equals(tb2->nextOf()) |
7245 ) | 7483 ) |
7246 { | 7484 { |
7247 type = e1->type; | 7485 type = e1->type; |
7248 e = this; | 7486 e = this; |
7249 } | 7487 } |
7261 { // Rewrite e1+=e2 to (v=&e1),*v=*v+e2 | 7499 { // Rewrite e1+=e2 to (v=&e1),*v=*v+e2 |
7262 VarDeclaration *v; | 7500 VarDeclaration *v; |
7263 Expression *ea; | 7501 Expression *ea; |
7264 Expression *ex; | 7502 Expression *ex; |
7265 | 7503 |
7266 char name[6+6+1]; | 7504 Identifier *id = Lexer::uniqueId("__name"); |
7267 Identifier *id; | |
7268 static int idn; | |
7269 sprintf(name, "__name%d", ++idn); | |
7270 id = Lexer::idPool(name); | |
7271 | 7505 |
7272 v = new VarDeclaration(loc, tb1->pointerTo(), id, NULL); | 7506 v = new VarDeclaration(loc, tb1->pointerTo(), id, NULL); |
7273 v->semantic(sc); | 7507 v->semantic(sc); |
7274 if (!sc->insert(v)) | 7508 if (!sc->insert(v)) |
7275 assert(0); | 7509 assert(0); |
7331 e2 = resolveProperties(sc, e2); | 7565 e2 = resolveProperties(sc, e2); |
7332 | 7566 |
7333 e = op_overload(sc); | 7567 e = op_overload(sc); |
7334 if (e) | 7568 if (e) |
7335 return e; | 7569 return e; |
7570 | |
7571 if (e1->op == TOKslice) | |
7572 { // T[] -= ... | |
7573 typeCombine(sc); | |
7574 type = e1->type; | |
7575 return arrayOp(sc); | |
7576 } | |
7336 | 7577 |
7337 e1 = e1->modifiableLvalue(sc, e1); | 7578 e1 = e1->modifiableLvalue(sc, e1); |
7338 e1->checkScalar(); | 7579 e1->checkScalar(); |
7339 e1->checkNoBool(); | 7580 e1->checkNoBool(); |
7340 if (e1->type->ty == Tpointer && e2->type->isintegral()) | 7581 if (e1->type->ty == Tpointer && e2->type->isintegral()) |
7395 e2 = e2->castTo(sc, e1->type); | 7636 e2 = e2->castTo(sc, e1->type); |
7396 type = e1->type; | 7637 type = e1->type; |
7397 e = this; | 7638 e = this; |
7398 } | 7639 } |
7399 else if ((tb1->ty == Tarray) && | 7640 else if ((tb1->ty == Tarray) && |
7400 e2->implicitConvTo(tb1->next) | 7641 e2->implicitConvTo(tb1->nextOf()) |
7401 ) | 7642 ) |
7402 { // Append element | 7643 { // Append element |
7403 e2 = e2->castTo(sc, tb1->next); | 7644 e2 = e2->castTo(sc, tb1->nextOf()); |
7404 type = e1->type; | 7645 type = e1->type; |
7405 e = this; | 7646 e = this; |
7406 } | 7647 } |
7407 else | 7648 else |
7408 { | 7649 { |
7427 e2 = resolveProperties(sc, e2); | 7668 e2 = resolveProperties(sc, e2); |
7428 | 7669 |
7429 e = op_overload(sc); | 7670 e = op_overload(sc); |
7430 if (e) | 7671 if (e) |
7431 return e; | 7672 return e; |
7673 | |
7674 if (e1->op == TOKslice) | |
7675 { // T[] -= ... | |
7676 typeCombine(sc); | |
7677 type = e1->type; | |
7678 return arrayOp(sc); | |
7679 } | |
7432 | 7680 |
7433 e1 = e1->modifiableLvalue(sc, e1); | 7681 e1 = e1->modifiableLvalue(sc, e1); |
7434 e1->checkScalar(); | 7682 e1->checkScalar(); |
7435 e1->checkNoBool(); | 7683 e1->checkNoBool(); |
7436 type = e1->type; | 7684 type = e1->type; |
7484 | 7732 |
7485 e = op_overload(sc); | 7733 e = op_overload(sc); |
7486 if (e) | 7734 if (e) |
7487 return e; | 7735 return e; |
7488 | 7736 |
7737 if (e1->op == TOKslice) | |
7738 { // T[] -= ... | |
7739 typeCombine(sc); | |
7740 type = e1->type; | |
7741 return arrayOp(sc); | |
7742 } | |
7743 | |
7489 e1 = e1->modifiableLvalue(sc, e1); | 7744 e1 = e1->modifiableLvalue(sc, e1); |
7490 e1->checkScalar(); | 7745 e1->checkScalar(); |
7491 e1->checkNoBool(); | 7746 e1->checkNoBool(); |
7492 type = e1->type; | 7747 type = e1->type; |
7493 typeCombine(sc); | 7748 typeCombine(sc); |
7688 Type *tb1 = e1->type->toBasetype(); | 7943 Type *tb1 = e1->type->toBasetype(); |
7689 Type *tb2 = e2->type->toBasetype(); | 7944 Type *tb2 = e2->type->toBasetype(); |
7690 | 7945 |
7691 if ((tb1->ty == Tarray || tb1->ty == Tsarray) && | 7946 if ((tb1->ty == Tarray || tb1->ty == Tsarray) && |
7692 (tb2->ty == Tarray || tb2->ty == Tsarray) && | 7947 (tb2->ty == Tarray || tb2->ty == Tsarray) && |
7693 tb1->next->equals(tb2->next) | 7948 tb1->nextOf()->equals(tb2->nextOf()) |
7694 ) | 7949 ) |
7695 { | 7950 { |
7696 type = e1->type; | 7951 type = e1->type; |
7697 e = this; | 7952 e = this; |
7698 } | 7953 } |
7774 d_int64 stride; | 8029 d_int64 stride; |
7775 Expression *e; | 8030 Expression *e; |
7776 | 8031 |
7777 typeCombine(sc); // make sure pointer types are compatible | 8032 typeCombine(sc); // make sure pointer types are compatible |
7778 type = Type::tptrdiff_t; | 8033 type = Type::tptrdiff_t; |
7779 stride = t2->next->size(); | 8034 stride = t2->nextOf()->size(); |
7780 if (!stride) | 8035 if (stride == 0) |
7781 return new IntegerExp(0, 0, Type::tptrdiff_t); | 8036 { |
7782 e = new DivExp(loc, this, new IntegerExp(0, stride, Type::tptrdiff_t)); | 8037 e = new IntegerExp(loc, 0, Type::tptrdiff_t); |
7783 e->type = Type::tptrdiff_t; | 8038 } |
8039 else | |
8040 { | |
8041 e = new DivExp(loc, this, new IntegerExp(0, stride, Type::tptrdiff_t)); | |
8042 e->type = Type::tptrdiff_t; | |
8043 } | |
7784 return e; | 8044 return e; |
7785 } | 8045 } |
7786 else if (t2->isintegral()) | 8046 else if (t2->isintegral()) |
7787 e = scaleFactor(sc); | 8047 e = scaleFactor(sc); |
7788 else | 8048 else |
7789 { error("incompatible types for -"); | 8049 { error("incompatible types for minus"); |
7790 return new IntegerExp(0); | 8050 return new IntegerExp(0); |
7791 } | 8051 } |
7792 } | 8052 } |
7793 else if (t2->ty == Tpointer) | 8053 else if (t2->ty == Tpointer) |
7794 { | 8054 { |
7862 e2->type->print(); | 8122 e2->type->print(); |
7863 #endif | 8123 #endif |
7864 if ((tb1->ty == Tsarray || tb1->ty == Tarray) && | 8124 if ((tb1->ty == Tsarray || tb1->ty == Tarray) && |
7865 e2->type->equals(tb1->next)) | 8125 e2->type->equals(tb1->next)) |
7866 { | 8126 { |
7867 type = tb1->next->arrayOf(); | 8127 type = tb1->nextOf()->arrayOf(); |
7868 if (tb2->ty == Tarray) | 8128 if (tb2->ty == Tarray) |
7869 { // Make e2 into [e2] | 8129 { // Make e2 into [e2] |
7870 e2 = new ArrayLiteralExp(e2->loc, e2); | 8130 e2 = new ArrayLiteralExp(e2->loc, e2); |
7871 e2->type = type; | 8131 e2->type = type; |
7872 } | 8132 } |
7873 return this; | 8133 return this; |
7874 } | 8134 } |
7875 else if ((tb2->ty == Tsarray || tb2->ty == Tarray) && | 8135 else if ((tb2->ty == Tsarray || tb2->ty == Tarray) && |
7876 e1->type->equals(tb2->next)) | 8136 e1->type->equals(tb2->next)) |
7877 { | 8137 { |
7878 type = tb2->next->arrayOf(); | 8138 type = tb2->nextOf()->arrayOf(); |
7879 if (tb1->ty == Tarray) | 8139 if (tb1->ty == Tarray) |
7880 { // Make e1 into [e1] | 8140 { // Make e1 into [e1] |
7881 e1 = new ArrayLiteralExp(e1->loc, e1); | 8141 e1 = new ArrayLiteralExp(e1->loc, e1); |
7882 e1->type = type; | 8142 e1->type = type; |
7883 } | 8143 } |
7902 { | 8162 { |
7903 e = this; | 8163 e = this; |
7904 } | 8164 } |
7905 else | 8165 else |
7906 { | 8166 { |
8167 //printf("(%s) ~ (%s)\n", e1->toChars(), e2->toChars()); | |
7907 error("Can only concatenate arrays, not (%s ~ %s)", | 8168 error("Can only concatenate arrays, not (%s ~ %s)", |
7908 e1->type->toChars(), e2->type->toChars()); | 8169 e1->type->toChars(), e2->type->toChars()); |
7909 type = Type::tint32; | 8170 type = Type::tint32; |
7910 e = this; | 8171 e = this; |
7911 } | 8172 } |
7937 e = op_overload(sc); | 8198 e = op_overload(sc); |
7938 if (e) | 8199 if (e) |
7939 return e; | 8200 return e; |
7940 | 8201 |
7941 typeCombine(sc); | 8202 typeCombine(sc); |
7942 e1->checkArithmetic(); | 8203 if (e1->op != TOKslice && e2->op != TOKslice) |
7943 e2->checkArithmetic(); | 8204 { e1->checkArithmetic(); |
8205 e2->checkArithmetic(); | |
8206 } | |
7944 if (type->isfloating()) | 8207 if (type->isfloating()) |
7945 { Type *t1 = e1->type; | 8208 { Type *t1 = e1->type; |
7946 Type *t2 = e2->type; | 8209 Type *t2 = e2->type; |
7947 | 8210 |
7948 if (t1->isreal()) | 8211 if (t1->isreal()) |
8001 e = op_overload(sc); | 8264 e = op_overload(sc); |
8002 if (e) | 8265 if (e) |
8003 return e; | 8266 return e; |
8004 | 8267 |
8005 typeCombine(sc); | 8268 typeCombine(sc); |
8006 e1->checkArithmetic(); | 8269 if (e1->op != TOKslice && e2->op != TOKslice) |
8007 e2->checkArithmetic(); | 8270 { e1->checkArithmetic(); |
8271 e2->checkArithmetic(); | |
8272 } | |
8008 if (type->isfloating()) | 8273 if (type->isfloating()) |
8009 { Type *t1 = e1->type; | 8274 { Type *t1 = e1->type; |
8010 Type *t2 = e2->type; | 8275 Type *t2 = e2->type; |
8011 | 8276 |
8012 if (t1->isreal()) | 8277 if (t1->isreal()) |
8066 e = op_overload(sc); | 8331 e = op_overload(sc); |
8067 if (e) | 8332 if (e) |
8068 return e; | 8333 return e; |
8069 | 8334 |
8070 typeCombine(sc); | 8335 typeCombine(sc); |
8071 e1->checkArithmetic(); | 8336 if (e1->op != TOKslice && e2->op != TOKslice) |
8072 e2->checkArithmetic(); | 8337 { e1->checkArithmetic(); |
8338 e2->checkArithmetic(); | |
8339 } | |
8073 if (type->isfloating()) | 8340 if (type->isfloating()) |
8074 { type = e1->type; | 8341 { type = e1->type; |
8075 if (e2->type->iscomplex()) | 8342 if (e2->type->iscomplex()) |
8076 { error("cannot perform modulo complex arithmetic"); | 8343 { error("cannot perform modulo complex arithmetic"); |
8077 return new IntegerExp(0); | 8344 return new IntegerExp(0); |
8178 e = this; | 8445 e = this; |
8179 } | 8446 } |
8180 else | 8447 else |
8181 { | 8448 { |
8182 typeCombine(sc); | 8449 typeCombine(sc); |
8183 e1->checkIntegral(); | 8450 if (e1->op != TOKslice && e2->op != TOKslice) |
8184 e2->checkIntegral(); | 8451 { e1->checkIntegral(); |
8452 e2->checkIntegral(); | |
8453 } | |
8185 } | 8454 } |
8186 } | 8455 } |
8187 return this; | 8456 return this; |
8188 } | 8457 } |
8189 | 8458 |
8209 e = this; | 8478 e = this; |
8210 } | 8479 } |
8211 else | 8480 else |
8212 { | 8481 { |
8213 typeCombine(sc); | 8482 typeCombine(sc); |
8214 e1->checkIntegral(); | 8483 if (e1->op != TOKslice && e2->op != TOKslice) |
8215 e2->checkIntegral(); | 8484 { e1->checkIntegral(); |
8485 e2->checkIntegral(); | |
8486 } | |
8216 } | 8487 } |
8217 } | 8488 } |
8218 return this; | 8489 return this; |
8219 } | 8490 } |
8220 | 8491 |
8240 e = this; | 8511 e = this; |
8241 } | 8512 } |
8242 else | 8513 else |
8243 { | 8514 { |
8244 typeCombine(sc); | 8515 typeCombine(sc); |
8245 e1->checkIntegral(); | 8516 if (e1->op != TOKslice && e2->op != TOKslice) |
8246 e2->checkIntegral(); | 8517 { e1->checkIntegral(); |
8518 e2->checkIntegral(); | |
8519 } | |
8247 } | 8520 } |
8248 } | 8521 } |
8249 return this; | 8522 return this; |
8250 } | 8523 } |
8251 | 8524 |
8412 | 8685 |
8413 // Convert key to type of key | 8686 // Convert key to type of key |
8414 e1 = e1->implicitCastTo(sc, ta->index); | 8687 e1 = e1->implicitCastTo(sc, ta->index); |
8415 | 8688 |
8416 // Return type is pointer to value | 8689 // Return type is pointer to value |
8417 type = ta->next->pointerTo(); | 8690 type = ta->nextOf()->pointerTo(); |
8418 } | 8691 } |
8419 return this; | 8692 return this; |
8420 } | 8693 } |
8421 | 8694 |
8422 int InExp::isBit() | 8695 int InExp::isBit() |
8499 e = new IntegerExp(0); | 8772 e = new IntegerExp(0); |
8500 } | 8773 } |
8501 #endif | 8774 #endif |
8502 else | 8775 else |
8503 e = this; | 8776 e = this; |
8777 //printf("CmpExp: %s\n", e->toChars()); | |
8504 return e; | 8778 return e; |
8505 } | 8779 } |
8506 | 8780 |
8507 int CmpExp::isBit() | 8781 int CmpExp::isBit() |
8508 { | 8782 { |