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);