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 {