Mercurial > projects > ldc
comparison dmd/expression.c @ 159:5acec6b2eef8 trunk
[svn r175] merged dmd 1.029
author | ChristianK |
---|---|
date | Thu, 01 May 2008 15:15:28 +0200 |
parents | 0ab29b838084 |
children | a8cd9bc1021a |
comparison
equal
deleted
inserted
replaced
158:287540c5f05e | 159:5acec6b2eef8 |
---|---|
1 | 1 |
2 // Compiler implementation of the D programming language | 2 // Compiler implementation of the D programming language |
3 // Copyright (c) 1999-2007 by Digital Mars | 3 // Copyright (c) 1999-2008 by Digital Mars |
4 // All Rights Reserved | 4 // All Rights Reserved |
5 // written by Walter Bright | 5 // written by Walter Bright |
6 // http://www.digitalmars.com | 6 // http://www.digitalmars.com |
7 // License for redistribution is by either the Artistic License | 7 // License for redistribution is by either the Artistic License |
8 // in artistic.txt, or the GNU General Public License in gnu.txt. | 8 // in artistic.txt, or the GNU General Public License in gnu.txt. |
87 | 87 |
88 enum PREC precedence[TOKMAX]; | 88 enum PREC precedence[TOKMAX]; |
89 | 89 |
90 void initPrecedence() | 90 void initPrecedence() |
91 { | 91 { |
92 precedence[TOKdotvar] = PREC_primary; | |
92 precedence[TOKimport] = PREC_primary; | 93 precedence[TOKimport] = PREC_primary; |
93 precedence[TOKidentifier] = PREC_primary; | 94 precedence[TOKidentifier] = PREC_primary; |
94 precedence[TOKthis] = PREC_primary; | 95 precedence[TOKthis] = PREC_primary; |
95 precedence[TOKsuper] = PREC_primary; | 96 precedence[TOKsuper] = PREC_primary; |
96 precedence[TOKint64] = PREC_primary; | 97 precedence[TOKint64] = PREC_primary; |
168 precedence[TOKoror] = PREC_oror; | 169 precedence[TOKoror] = PREC_oror; |
169 | 170 |
170 precedence[TOKquestion] = PREC_cond; | 171 precedence[TOKquestion] = PREC_cond; |
171 | 172 |
172 precedence[TOKassign] = PREC_assign; | 173 precedence[TOKassign] = PREC_assign; |
174 precedence[TOKconstruct] = PREC_assign; | |
175 precedence[TOKblit] = PREC_assign; | |
173 precedence[TOKaddass] = PREC_assign; | 176 precedence[TOKaddass] = PREC_assign; |
174 precedence[TOKminass] = PREC_assign; | 177 precedence[TOKminass] = PREC_assign; |
175 precedence[TOKcatass] = PREC_assign; | 178 precedence[TOKcatass] = PREC_assign; |
176 precedence[TOKmulass] = PREC_assign; | 179 precedence[TOKmulass] = PREC_assign; |
177 precedence[TOKdivass] = PREC_assign; | 180 precedence[TOKdivass] = PREC_assign; |
643 { Expression *arg = (Expression *)arguments->data[i]; | 646 { Expression *arg = (Expression *)arguments->data[i]; |
644 | 647 |
645 if (i) | 648 if (i) |
646 buf->writeByte(','); | 649 buf->writeByte(','); |
647 argbuf.reset(); | 650 argbuf.reset(); |
648 arg->type->toCBuffer2(&argbuf, NULL, hgs); | 651 arg->type->toCBuffer2(&argbuf, hgs, 0); |
649 buf->write(&argbuf); | 652 buf->write(&argbuf); |
650 } | 653 } |
651 } | 654 } |
652 } | 655 } |
653 | 656 |
2494 Type *t0 = NULL; | 2497 Type *t0 = NULL; |
2495 | 2498 |
2496 #if LOGSEMANTIC | 2499 #if LOGSEMANTIC |
2497 printf("ArrayLiteralExp::semantic('%s')\n", toChars()); | 2500 printf("ArrayLiteralExp::semantic('%s')\n", toChars()); |
2498 #endif | 2501 #endif |
2502 if (type) | |
2503 return this; | |
2499 | 2504 |
2500 // Run semantic() on each element | 2505 // Run semantic() on each element |
2501 for (int i = 0; i < elements->dim; i++) | 2506 for (int i = 0; i < elements->dim; i++) |
2502 { e = (Expression *)elements->data[i]; | 2507 { e = (Expression *)elements->data[i]; |
2503 e = e->semantic(sc); | 2508 e = e->semantic(sc); |
2825 return e; | 2830 return e; |
2826 } | 2831 } |
2827 | 2832 |
2828 /************************************ | 2833 /************************************ |
2829 * Get index of field. | 2834 * Get index of field. |
2830 * Returns -1 if not found. | 2835 * Returns -1 if not found. |
2831 */ | 2836 */ |
2832 | 2837 |
2833 int StructLiteralExp::getFieldIndex(Type *type, unsigned offset) | 2838 int StructLiteralExp::getFieldIndex(Type *type, unsigned offset) |
2834 { | 2839 { |
2835 /* Find which field offset is by looking at the field offsets | 2840 /* Find which field offset is by looking at the field offsets |
4406 int BinExp::checkSideEffect(int flag) | 4411 int BinExp::checkSideEffect(int flag) |
4407 { | 4412 { |
4408 if (op == TOKplusplus || | 4413 if (op == TOKplusplus || |
4409 op == TOKminusminus || | 4414 op == TOKminusminus || |
4410 op == TOKassign || | 4415 op == TOKassign || |
4416 op == TOKconstruct || | |
4417 op == TOKblit || | |
4411 op == TOKaddass || | 4418 op == TOKaddass || |
4412 op == TOKminass || | 4419 op == TOKminass || |
4413 op == TOKcatass || | 4420 op == TOKcatass || |
4414 op == TOKmulass || | 4421 op == TOKmulass || |
4415 op == TOKdivass || | 4422 op == TOKdivass || |
4879 | 4886 |
4880 // Mainly just a placeholder | 4887 // Mainly just a placeholder |
4881 | 4888 |
4882 DotTemplateExp::DotTemplateExp(Loc loc, Expression *e, TemplateDeclaration *td) | 4889 DotTemplateExp::DotTemplateExp(Loc loc, Expression *e, TemplateDeclaration *td) |
4883 : UnaExp(loc, TOKdottd, sizeof(DotTemplateExp), e) | 4890 : UnaExp(loc, TOKdottd, sizeof(DotTemplateExp), e) |
4884 | 4891 |
4885 { | 4892 { |
4886 this->td = td; | 4893 this->td = td; |
4887 } | 4894 } |
4888 | 4895 |
4889 void DotTemplateExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 4896 void DotTemplateExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
4993 s = s->toParent(); | 5000 s = s->toParent(); |
4994 } | 5001 } |
4995 if (s && s->isClassDeclaration()) | 5002 if (s && s->isClassDeclaration()) |
4996 e1->type = s->isClassDeclaration()->type; | 5003 e1->type = s->isClassDeclaration()->type; |
4997 | 5004 |
5005 e1 = e1->semantic(sc); | |
4998 goto L1; | 5006 goto L1; |
4999 } | 5007 } |
5000 #ifdef DEBUG | 5008 #ifdef DEBUG |
5001 printf("2: "); | 5009 printf("2: "); |
5002 #endif | 5010 #endif |
5516 { | 5524 { |
5517 DotVarExp *dve; | 5525 DotVarExp *dve; |
5518 DotTemplateExp *dte; | 5526 DotTemplateExp *dte; |
5519 AggregateDeclaration *ad; | 5527 AggregateDeclaration *ad; |
5520 UnaExp *ue = (UnaExp *)(e1); | 5528 UnaExp *ue = (UnaExp *)(e1); |
5521 | 5529 |
5522 if (e1->op == TOKdotvar) | 5530 if (e1->op == TOKdotvar) |
5523 { // Do overload resolution | 5531 { // Do overload resolution |
5524 dve = (DotVarExp *)(e1); | 5532 dve = (DotVarExp *)(e1); |
5525 | 5533 |
5526 f = dve->var->isFuncDeclaration(); | 5534 f = dve->var->isFuncDeclaration(); |
5540 if (!f) | 5548 if (!f) |
5541 { type = Type::terror; | 5549 { type = Type::terror; |
5542 return this; | 5550 return this; |
5543 } | 5551 } |
5544 ad = td->toParent()->isAggregateDeclaration(); | 5552 ad = td->toParent()->isAggregateDeclaration(); |
5545 } | 5553 } |
5546 /* Now that we have the right function f, we need to get the | 5554 /* Now that we have the right function f, we need to get the |
5547 * right 'this' pointer if f is in an outer class, but our | 5555 * right 'this' pointer if f is in an outer class, but our |
5548 * existing 'this' pointer is in an inner class. | 5556 * existing 'this' pointer is in an inner class. |
5549 * This code is analogous to that used for variables | 5557 * This code is analogous to that used for variables |
5550 * in DotVarExp::semantic(). | 5558 * in DotVarExp::semantic(). |
5587 e1 = new CommaExp(loc, ue->e1, ve); | 5595 e1 = new CommaExp(loc, ue->e1, ve); |
5588 e1->type = f->type; | 5596 e1->type = f->type; |
5589 } | 5597 } |
5590 else | 5598 else |
5591 { | 5599 { |
5592 if (e1->op == TOKdotvar) | 5600 if (e1->op == TOKdotvar) |
5593 dve->var = f; | 5601 dve->var = f; |
5594 else | 5602 else |
5595 e1 = new DotVarExp(loc, dte->e1, f); | 5603 e1 = new DotVarExp(loc, dte->e1, f); |
5596 e1->type = f->type; | 5604 e1->type = f->type; |
5597 | 5605 |
6133 StructDeclaration *sd = ts->sym; | 6141 StructDeclaration *sd = ts->sym; |
6134 FuncDeclaration *f = sd->aggDelete; | 6142 FuncDeclaration *f = sd->aggDelete; |
6135 | 6143 |
6136 if (f) | 6144 if (f) |
6137 { | 6145 { |
6138 Expression *e; | |
6139 Expression *ec; | |
6140 Type *tpv = Type::tvoid->pointerTo(); | 6146 Type *tpv = Type::tvoid->pointerTo(); |
6141 | 6147 |
6142 e = e1; | 6148 Expression *e = e1->castTo(sc, tpv); |
6143 e->type = tpv; | 6149 Expression *ec = new VarExp(loc, f); |
6144 ec = new VarExp(loc, f); | |
6145 e = new CallExp(loc, ec, e); | 6150 e = new CallExp(loc, ec, e); |
6146 return e->semantic(sc); | 6151 return e->semantic(sc); |
6147 } | 6152 } |
6148 } | 6153 } |
6149 break; | 6154 break; |
6231 { | 6236 { |
6232 return e->implicitCastTo(sc, to); | 6237 return e->implicitCastTo(sc, to); |
6233 } | 6238 } |
6234 | 6239 |
6235 Type *tob = to->toBasetype(); | 6240 Type *tob = to->toBasetype(); |
6236 if (tob->ty == Tstruct && !tob->equals(e1->type->toBasetype())) | 6241 if (tob->ty == Tstruct && |
6242 !tob->equals(e1->type->toBasetype()) && | |
6243 ((TypeStruct *)to)->sym->search(0, Id::call, 0) | |
6244 ) | |
6237 { | 6245 { |
6238 /* Look to replace: | 6246 /* Look to replace: |
6239 * cast(S)t | 6247 * cast(S)t |
6240 * with: | 6248 * with: |
6241 * S(t) | 6249 * S(t) |
7269 | 7277 |
7270 e1 = e1->modifiableLvalue(sc, e1); | 7278 e1 = e1->modifiableLvalue(sc, e1); |
7271 | 7279 |
7272 Type *tb1 = e1->type->toBasetype(); | 7280 Type *tb1 = e1->type->toBasetype(); |
7273 Type *tb2 = e2->type->toBasetype(); | 7281 Type *tb2 = e2->type->toBasetype(); |
7282 | |
7283 e2->rvalue(); | |
7274 | 7284 |
7275 if ((tb1->ty == Tarray) && | 7285 if ((tb1->ty == Tarray) && |
7276 (tb2->ty == Tarray || tb2->ty == Tsarray) && | 7286 (tb2->ty == Tarray || tb2->ty == Tsarray) && |
7277 e2->implicitConvTo(e1->type) | 7287 e2->implicitConvTo(e1->type) |
7278 //e1->type->next->equals(e2->type->next) | 7288 //e1->type->next->equals(e2->type->next) |
8337 #endif | 8347 #endif |
8338 if (type) | 8348 if (type) |
8339 return this; | 8349 return this; |
8340 | 8350 |
8341 BinExp::semanticp(sc); | 8351 BinExp::semanticp(sc); |
8352 | |
8353 if (e1->type->toBasetype()->ty == Tclass && e2->op == TOKnull || | |
8354 e2->type->toBasetype()->ty == Tclass && e1->op == TOKnull) | |
8355 { | |
8356 error("do not use null when comparing class types"); | |
8357 } | |
8358 | |
8342 e = op_overload(sc); | 8359 e = op_overload(sc); |
8343 if (e) | 8360 if (e) |
8344 { | 8361 { |
8345 e = new CmpExp(op, loc, e, new IntegerExp(loc, 0, Type::tint32)); | 8362 e = new CmpExp(op, loc, e, new IntegerExp(loc, 0, Type::tint32)); |
8346 e = e->semantic(sc); | 8363 e = e->semantic(sc); |
8390 /************************************************************/ | 8407 /************************************************************/ |
8391 | 8408 |
8392 EqualExp::EqualExp(enum TOK op, Loc loc, Expression *e1, Expression *e2) | 8409 EqualExp::EqualExp(enum TOK op, Loc loc, Expression *e1, Expression *e2) |
8393 : BinExp(loc, op, sizeof(EqualExp), e1, e2) | 8410 : BinExp(loc, op, sizeof(EqualExp), e1, e2) |
8394 { | 8411 { |
8412 assert(op == TOKequal || op == TOKnotequal); | |
8395 } | 8413 } |
8396 | 8414 |
8397 Expression *EqualExp::semantic(Scope *sc) | 8415 Expression *EqualExp::semantic(Scope *sc) |
8398 { Expression *e; | 8416 { Expression *e; |
8399 Type *t1; | 8417 Type *t1; |
8422 // They are the same, result is 'true' for ==, 'false' for != | 8440 // They are the same, result is 'true' for ==, 'false' for != |
8423 e = new IntegerExp(loc, (op == TOKequal), Type::tboolean); | 8441 e = new IntegerExp(loc, (op == TOKequal), Type::tboolean); |
8424 return e; | 8442 return e; |
8425 } | 8443 } |
8426 } | 8444 } |
8445 } | |
8446 | |
8447 if (e1->type->toBasetype()->ty == Tclass && e2->op == TOKnull || | |
8448 e2->type->toBasetype()->ty == Tclass && e1->op == TOKnull) | |
8449 { | |
8450 error("use '%s' instead of '%s' when comparing with null", | |
8451 Token::toChars(op == TOKequal ? TOKidentity : TOKnotidentity), | |
8452 Token::toChars(op)); | |
8427 } | 8453 } |
8428 | 8454 |
8429 //if (e2->op != TOKnull) | 8455 //if (e2->op != TOKnull) |
8430 { | 8456 { |
8431 e = op_overload(sc); | 8457 e = op_overload(sc); |