comparison dmd/expression.c @ 336:aaade6ded589 trunk

[svn r357] Merged DMD 1.033
author lindquist
date Sat, 12 Jul 2008 19:38:31 +0200
parents 7086a84ab3d6
children 62715be72a06
comparison
equal deleted inserted replaced
335:17b844102023 336:aaade6ded589
109 precedence[TOKtypeid] = PREC_primary; 109 precedence[TOKtypeid] = PREC_primary;
110 precedence[TOKis] = PREC_primary; 110 precedence[TOKis] = PREC_primary;
111 precedence[TOKassert] = PREC_primary; 111 precedence[TOKassert] = PREC_primary;
112 precedence[TOKfunction] = PREC_primary; 112 precedence[TOKfunction] = PREC_primary;
113 precedence[TOKvar] = PREC_primary; 113 precedence[TOKvar] = PREC_primary;
114 #if DMDV2
115 precedence[TOKdefault] = PREC_primary;
116 #endif
114 117
115 // post 118 // post
116 precedence[TOKdotti] = PREC_primary; 119 precedence[TOKdotti] = PREC_primary;
117 precedence[TOKdot] = PREC_primary; 120 precedence[TOKdot] = PREC_primary;
118 // precedence[TOKarrow] = PREC_primary; 121 // precedence[TOKarrow] = PREC_primary;
193 precedence[TOKxorass] = PREC_assign; 196 precedence[TOKxorass] = PREC_assign;
194 197
195 precedence[TOKcomma] = PREC_expr; 198 precedence[TOKcomma] = PREC_expr;
196 } 199 }
197 200
201 /*************************************************************
202 * Given var, we need to get the
203 * right 'this' pointer if var is in an outer class, but our
204 * existing 'this' pointer is in an inner class.
205 * Input:
206 * e1 existing 'this'
207 * ad struct or class we need the correct 'this' for
208 * var the specific member of ad we're accessing
209 */
210
211 Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad,
212 Expression *e1, Declaration *var)
213 {
214 //printf("\ngetRightThis(e1 = %s, ad = %s, var = %s)\n", e1->toChars(), ad->toChars(), var->toChars());
215 L1:
216 Type *t = e1->type->toBasetype();
217 //printf("e1->type = %s, var->type = %s\n", e1->type->toChars(), var->type->toChars());
218
219 /* If e1 is not the 'this' pointer for ad
220 */
221 if (ad &&
222 !(t->ty == Tpointer && t->nextOf()->ty == Tstruct &&
223 ((TypeStruct *)t->nextOf())->sym == ad)
224 &&
225 !(t->ty == Tstruct &&
226 ((TypeStruct *)t)->sym == ad)
227 )
228 {
229 ClassDeclaration *cd = ad->isClassDeclaration();
230 ClassDeclaration *tcd = t->isClassHandle();
231
232 /* e1 is the right this if ad is a base class of e1
233 */
234 if (!cd || !tcd ||
235 !(tcd == cd || cd->isBaseOf(tcd, NULL))
236 )
237 {
238 /* Only classes can be inner classes with an 'outer'
239 * member pointing to the enclosing class instance
240 */
241 if (tcd && tcd->isNested())
242 { /* e1 is the 'this' pointer for an inner class: tcd.
243 * Rewrite it as the 'this' pointer for the outer class.
244 */
245
246 e1 = new DotVarExp(loc, e1, tcd->vthis);
247 e1->type = tcd->vthis->type;
248 // Do not call checkNestedRef()
249 //e1 = e1->semantic(sc);
250
251 // Skip up over nested functions, and get the enclosing
252 // class type.
253 int n = 0;
254 Dsymbol *s;
255 for (s = tcd->toParent();
256 s && s->isFuncDeclaration();
257 s = s->toParent())
258 { FuncDeclaration *f = s->isFuncDeclaration();
259 if (f->vthis)
260 {
261 //printf("rewriting e1 to %s's this\n", f->toChars());
262 n++;
263 e1 = new VarExp(loc, f->vthis);
264 }
265 }
266 if (s && s->isClassDeclaration())
267 { e1->type = s->isClassDeclaration()->type;
268 if (n > 1)
269 e1 = e1->semantic(sc);
270 }
271 else
272 e1 = e1->semantic(sc);
273 goto L1;
274 }
275 /* Can't find a path from e1 to ad
276 */
277 e1->error("this for %s needs to be type %s not type %s",
278 var->toChars(), ad->toChars(), t->toChars());
279 }
280 }
281 return e1;
282 }
283
198 /***************************************** 284 /*****************************************
199 * Determine if 'this' is available. 285 * Determine if 'this' is available.
200 * If it is, return the FuncDeclaration that has it. 286 * If it is, return the FuncDeclaration that has it.
201 */ 287 */
202 288
381 #endif 467 #endif
382 } 468 }
383 } 469 }
384 } 470 }
385 471
472 /*********************************************
473 * Call copy constructor for struct value argument.
474 */
475 #if DMDV2
476 Expression *callCpCtor(Loc loc, Scope *sc, Expression *e)
477 {
478 Type *tb = e->type->toBasetype();
479 assert(tb->ty == Tstruct);
480 StructDeclaration *sd = ((TypeStruct *)tb)->sym;
481 if (sd->cpctor)
482 {
483 /* Create a variable tmp, and replace the argument e with:
484 * (tmp = e),tmp
485 * and let AssignExp() handle the construction.
486 * This is not the most efficent, ideally tmp would be constructed
487 * directly onto the stack.
488 */
489 Identifier *idtmp = Lexer::uniqueId("__tmp");
490 VarDeclaration *tmp = new VarDeclaration(loc, tb, idtmp, new ExpInitializer(0, e));
491 Expression *ae = new DeclarationExp(loc, tmp);
492 e = new CommaExp(loc, ae, new VarExp(loc, tmp));
493 e = e->semantic(sc);
494 }
495 return e;
496 }
497 #endif
386 498
387 /**************************************** 499 /****************************************
388 * Now that we know the exact type of the function we're calling, 500 * Now that we know the exact type of the function we're calling,
389 * the arguments[] need to be adjusted: 501 * the arguments[] need to be adjusted:
390 * 1) implicitly convert argument to the corresponding parameter type 502 * 1) implicitly convert argument to the corresponding parameter type
430 if (tf->varargs == 2 && i + 1 == nparams) 542 if (tf->varargs == 2 && i + 1 == nparams)
431 goto L2; 543 goto L2;
432 error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs); 544 error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs);
433 break; 545 break;
434 } 546 }
435 arg = p->defaultArg->copy(); 547 arg = p->defaultArg;
548 #if DMDV2
549 if (arg->op == TOKdefault)
550 { DefaultInitExp *de = (DefaultInitExp *)arg;
551 arg = de->resolve(loc, sc);
552 }
553 else
554 #endif
555 arg = arg->copy();
436 arguments->push(arg); 556 arguments->push(arg);
437 nargs++; 557 nargs++;
438 } 558 }
439 559
440 if (tf->varargs == 2 && i + 1 == nparams) 560 if (tf->varargs == 2 && i + 1 == nparams)
570 690
571 // Convert static arrays to dynamic arrays 691 // Convert static arrays to dynamic arrays
572 tb = arg->type->toBasetype(); 692 tb = arg->type->toBasetype();
573 if (tb->ty == Tsarray) 693 if (tb->ty == Tsarray)
574 { TypeSArray *ts = (TypeSArray *)tb; 694 { TypeSArray *ts = (TypeSArray *)tb;
575 Type *ta = tb->next->arrayOf(); 695 Type *ta = ts->next->arrayOf();
576 if (ts->size(arg->loc) == 0) 696 if (ts->size(arg->loc) == 0)
577 { arg = new NullExp(arg->loc); 697 { arg = new NullExp(arg->loc);
578 arg->type = ta; 698 arg->type = ta;
579 } 699 }
580 else 700 else
581 arg = arg->castTo(sc, ta); 701 arg = arg->castTo(sc, ta);
582 } 702 }
583 703 #if DMDV2
704 if (tb->ty == Tstruct)
705 {
706 arg = callCpCtor(loc, sc, arg);
707 }
708
709 // Give error for overloaded function addresses
710 if (arg->op == TOKsymoff)
711 { SymOffExp *se = (SymOffExp *)arg;
712 if (se->hasOverloads && !se->var->isFuncDeclaration()->isUnique())
713 arg->error("function %s is overloaded", arg->toChars());
714 }
715 #endif
584 arg->rvalue(); 716 arg->rvalue();
585 } 717 }
586 arg = arg->optimize(WANTvalue); 718 arg = arg->optimize(WANTvalue);
587 arguments->data[i] = (void *) arg; 719 arguments->data[i] = (void *) arg;
588 if (done) 720 if (done)
607 * in ( ) if its precedence is less than pr. 739 * in ( ) if its precedence is less than pr.
608 */ 740 */
609 741
610 void expToCBuffer(OutBuffer *buf, HdrGenState *hgs, Expression *e, enum PREC pr) 742 void expToCBuffer(OutBuffer *buf, HdrGenState *hgs, Expression *e, enum PREC pr)
611 { 743 {
744 //if (precedence[e->op] == 0) e->dump(0);
612 if (precedence[e->op] < pr) 745 if (precedence[e->op] < pr)
613 { 746 {
614 buf->writeByte('('); 747 buf->writeByte('(');
615 e->toCBuffer(buf, hgs); 748 e->toCBuffer(buf, hgs);
616 buf->writeByte(')'); 749 buf->writeByte(')');
704 */ 837 */
705 838
706 Expression *Expression::semantic(Scope *sc) 839 Expression *Expression::semantic(Scope *sc)
707 { 840 {
708 #if LOGSEMANTIC 841 #if LOGSEMANTIC
709 printf("Expression::semantic()\n"); 842 printf("Expression::semantic() %s\n", toChars());
710 #endif 843 #endif
711 if (type) 844 if (type)
712 type = type->semantic(loc, sc); 845 type = type->semantic(loc, sc);
713 else 846 else
714 type = Type::tvoid; 847 type = Type::tvoid;
745 { error("expression %s is void and has no value", toChars()); 878 { error("expression %s is void and has no value", toChars());
746 #if 0 879 #if 0
747 dump(0); 880 dump(0);
748 halt(); 881 halt();
749 #endif 882 #endif
883 type = Type::tint32;
750 } 884 }
751 } 885 }
752 886
753 Expression *Expression::combine(Expression *e1, Expression *e2) 887 Expression *Expression::combine(Expression *e1, Expression *e2)
754 { 888 {
937 { TypeSArray *ts = (TypeSArray *)tb; 1071 { TypeSArray *ts = (TypeSArray *)tb;
938 if (ts->size(loc) == 0) 1072 if (ts->size(loc) == 0)
939 e = new NullExp(loc); 1073 e = new NullExp(loc);
940 else 1074 else
941 e = new AddrExp(loc, this); 1075 e = new AddrExp(loc, this);
942 e->type = tb->next->pointerTo(); 1076 e->type = ts->next->pointerTo();
943 } 1077 }
944 return e; 1078 return e;
945 } 1079 }
946 1080
947 /****************************** 1081 /******************************
968 //printf("Expression::deref()\n"); 1102 //printf("Expression::deref()\n");
969 if (type->ty == Treference) 1103 if (type->ty == Treference)
970 { Expression *e; 1104 { Expression *e;
971 1105
972 e = new PtrExp(loc, this); 1106 e = new PtrExp(loc, this);
973 e->type = type->next; 1107 e->type = ((TypeReference *)type)->next;
974 return e; 1108 return e;
975 } 1109 }
976 return this; 1110 return this;
977 } 1111 }
978 1112
991 1125
992 int Expression::isBit() 1126 int Expression::isBit()
993 { 1127 {
994 return FALSE; 1128 return FALSE;
995 } 1129 }
1130
1131 /********************************
1132 * Can this expression throw an exception?
1133 * Valid only after semantic() pass.
1134 */
1135
1136 int Expression::canThrow()
1137 {
1138 return TRUE;
1139 }
1140
1141
996 1142
997 Expressions *Expression::arraySyntaxCopy(Expressions *exps) 1143 Expressions *Expression::arraySyntaxCopy(Expressions *exps)
998 { Expressions *a = NULL; 1144 { Expressions *a = NULL;
999 1145
1000 if (exps) 1146 if (exps)
1017 : Expression(loc, TOKint64, sizeof(IntegerExp)) 1163 : Expression(loc, TOKint64, sizeof(IntegerExp))
1018 { 1164 {
1019 //printf("IntegerExp(value = %lld, type = '%s')\n", value, type ? type->toChars() : ""); 1165 //printf("IntegerExp(value = %lld, type = '%s')\n", value, type ? type->toChars() : "");
1020 if (type && !type->isscalar()) 1166 if (type && !type->isscalar())
1021 { 1167 {
1168 //printf("%s, loc = %d\n", toChars(), loc.linnum);
1022 error("integral constant must be scalar type, not %s", type->toChars()); 1169 error("integral constant must be scalar type, not %s", type->toChars());
1023 type = Type::terror; 1170 type = Type::terror;
1024 } 1171 }
1025 this->type = type; 1172 this->type = type;
1026 this->value = value; 1173 this->value = value;
1091 t = tt->sym->basetype; 1238 t = tt->sym->basetype;
1092 continue; 1239 continue;
1093 } 1240 }
1094 1241
1095 default: 1242 default:
1096 print(); 1243 /* This can happen if errors, such as
1097 type->print(); 1244 * the type is painted on like in fromConstInitializer().
1098 assert(0); 1245 */
1246 if (!global.errors)
1247 { type->print();
1248 assert(0);
1249 }
1099 break; 1250 break;
1100 } 1251 }
1101 break; 1252 break;
1102 } 1253 }
1103 return value; 1254 return value;
1244 buf->writestring(t->toChars()); 1395 buf->writestring(t->toChars());
1245 buf->writeByte(')'); 1396 buf->writeByte(')');
1246 goto L3; 1397 goto L3;
1247 1398
1248 default: 1399 default:
1400 /* This can happen if errors, such as
1401 * the type is painted on like in fromConstInitializer().
1402 */
1403 if (!global.errors)
1404 {
1249 #ifdef DEBUG 1405 #ifdef DEBUG
1250 t->print(); 1406 t->print();
1251 #endif 1407 #endif
1252 assert(0); 1408 assert(0);
1409 }
1410 break;
1253 } 1411 }
1254 } 1412 }
1255 else if (v & 0x8000000000000000LL) 1413 else if (v & 0x8000000000000000LL)
1256 buf->printf("0x%llx", v); 1414 buf->printf("0x%llx", v);
1257 else 1415 else
1991 fdthis->getLevel(loc, fd); 2149 fdthis->getLevel(loc, fd);
1992 fd->vthis->nestedref = 1; 2150 fd->vthis->nestedref = 1;
1993 fd->nestedFrameRef = 1; 2151 fd->nestedFrameRef = 1;
1994 } 2152 }
1995 #endif 2153 #endif
1996 sc->callSuper |= CSXthis; 2154 if (!sc->intypeof)
2155 sc->callSuper |= CSXthis;
1997 return this; 2156 return this;
1998 2157
1999 Lerr: 2158 Lerr:
2000 error("'this' is only allowed in non-static member functions, not %s", sc->parent->toChars()); 2159 error("'this' is only allowed in non-static member functions, not %s", sc->parent->toChars());
2001 type = Type::tint32; 2160 type = Type::tint32;
2100 fd->vthis->nestedref = 1; 2259 fd->vthis->nestedref = 1;
2101 fd->nestedFrameRef = 1; 2260 fd->nestedFrameRef = 1;
2102 } 2261 }
2103 #endif 2262 #endif
2104 2263
2105 sc->callSuper |= CSXsuper; 2264 if (!sc->intypeof)
2265 sc->callSuper |= CSXsuper;
2106 return this; 2266 return this;
2107 2267
2108 2268
2109 Lerr: 2269 Lerr:
2110 error("'super' is only allowed in non-static class member functions"); 2270 error("'super' is only allowed in non-static class member functions");
3394 3554
3395 Expression *NewAnonClassExp::semantic(Scope *sc) 3555 Expression *NewAnonClassExp::semantic(Scope *sc)
3396 { 3556 {
3397 #if LOGSEMANTIC 3557 #if LOGSEMANTIC
3398 printf("NewAnonClassExp::semantic() %s\n", toChars()); 3558 printf("NewAnonClassExp::semantic() %s\n", toChars());
3559 //printf("thisexp = %p\n", thisexp);
3399 //printf("type: %s\n", type->toChars()); 3560 //printf("type: %s\n", type->toChars());
3400 #endif 3561 #endif
3401 3562
3402 Expression *d = new DeclarationExp(loc, cd); 3563 Expression *d = new DeclarationExp(loc, cd);
3403 d = d->semantic(sc); 3564 d = d->semantic(sc);
3980 #if LOGSEMANTIC 4141 #if LOGSEMANTIC
3981 printf("TypeidExp::semantic()\n"); 4142 printf("TypeidExp::semantic()\n");
3982 #endif 4143 #endif
3983 typeidType = typeidType->semantic(loc, sc); 4144 typeidType = typeidType->semantic(loc, sc);
3984 e = typeidType->getTypeInfo(sc); 4145 e = typeidType->getTypeInfo(sc);
4146 if (e->loc.linnum == 0)
4147 e->loc = loc; // so there's at least some line number info
3985 return e; 4148 return e;
3986 } 4149 }
3987 4150
3988 void TypeidExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 4151 void TypeidExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3989 { 4152 {
4256 buf->writestring(" : "); 4419 buf->writestring(" : ");
4257 else 4420 else
4258 buf->writestring(" == "); 4421 buf->writestring(" == ");
4259 tspec->toCBuffer(buf, NULL, hgs); 4422 tspec->toCBuffer(buf, NULL, hgs);
4260 } 4423 }
4261 #if V2 4424 #if DMDV2
4262 if (parameters) 4425 if (parameters)
4263 { // First parameter is already output, so start with second 4426 { // First parameter is already output, so start with second
4264 for (int i = 1; i < parameters->dim; i++) 4427 for (int i = 1; i < parameters->dim; i++)
4265 { 4428 {
4266 buf->writeByte(','); 4429 buf->writeByte(',');
4828 if (t) 4991 if (t)
4829 { 4992 {
4830 return new TypeExp(loc, t); 4993 return new TypeExp(loc, t);
4831 } 4994 }
4832 4995
4996 TupleDeclaration *tup = s->isTupleDeclaration();
4997 if (tup)
4998 {
4999 if (eleft)
5000 error("cannot have e.tuple");
5001 e = new TupleExp(loc, tup);
5002 e = e->semantic(sc);
5003 return e;
5004 }
5005
4833 ScopeDsymbol *sds = s->isScopeDsymbol(); 5006 ScopeDsymbol *sds = s->isScopeDsymbol();
4834 if (sds) 5007 if (sds)
4835 { 5008 {
4836 //printf("it's a ScopeDsymbol\n"); 5009 //printf("it's a ScopeDsymbol\n");
4837 e = new ScopeExp(loc, sds); 5010 e = new ScopeExp(loc, sds);
4971 assert(type); 5144 assert(type);
4972 5145
4973 if (!var->isFuncDeclaration()) // for functions, do checks after overload resolution 5146 if (!var->isFuncDeclaration()) // for functions, do checks after overload resolution
4974 { 5147 {
4975 AggregateDeclaration *ad = var->toParent()->isAggregateDeclaration(); 5148 AggregateDeclaration *ad = var->toParent()->isAggregateDeclaration();
4976 L1: 5149 e1 = getRightThis(loc, sc, ad, e1, var);
4977 Type *t = e1->type->toBasetype(); 5150 if (!sc->noaccesscheck)
4978 5151 accessCheck(loc, sc, e1, var);
4979 if (ad && 5152
4980 !(t->ty == Tpointer && t->next->ty == Tstruct && 5153 VarDeclaration *v = var->isVarDeclaration();
4981 ((TypeStruct *)t->next)->sym == ad) 5154 if (v && v->isConst())
4982 && 5155 { ExpInitializer *ei = v->getExpInitializer();
4983 !(t->ty == Tstruct && 5156 if (ei)
4984 ((TypeStruct *)t)->sym == ad) 5157 { Expression *e = ei->exp->copy();
4985 ) 5158 e = e->semantic(sc);
4986 { 5159 return e;
4987 ClassDeclaration *cd = ad->isClassDeclaration();
4988 ClassDeclaration *tcd = t->isClassHandle();
4989
4990 if (!cd || !tcd ||
4991 !(tcd == cd || cd->isBaseOf(tcd, NULL))
4992 )
4993 {
4994 if (tcd && tcd->isNested())
4995 { // Try again with outer scope
4996
4997 e1 = new DotVarExp(loc, e1, tcd->vthis);
4998 e1 = e1->semantic(sc);
4999
5000 // Skip over nested functions, and get the enclosing
5001 // class type.
5002 Dsymbol *s = tcd->toParent();
5003 while (s && s->isFuncDeclaration())
5004 { FuncDeclaration *f = s->isFuncDeclaration();
5005 if (f->vthis)
5006 {
5007 e1 = new VarExp(loc, f->vthis);
5008 }
5009 s = s->toParent();
5010 }
5011 if (s && s->isClassDeclaration())
5012 e1->type = s->isClassDeclaration()->type;
5013
5014 e1 = e1->semantic(sc);
5015 goto L1;
5016 }
5017 #ifdef DEBUG
5018 printf("2: ");
5019 #endif
5020 error("this for %s needs to be type %s not type %s",
5021 var->toChars(), ad->toChars(), t->toChars());
5022 } 5160 }
5023 } 5161 }
5024 accessCheck(loc, sc, e1, var);
5025 } 5162 }
5026 } 5163 }
5027 //printf("-DotVarExp::semantic('%s')\n", toChars()); 5164 //printf("-DotVarExp::semantic('%s')\n", toChars());
5028 return this; 5165 return this;
5029 } 5166 }
5209 } 5346 }
5210 e = e->semantic(sc); 5347 e = e->semantic(sc);
5211 return e; 5348 return e;
5212 5349
5213 Lerr: 5350 Lerr:
5214 return new IntegerExp(0); 5351 return new IntegerExp(loc, 0, Type::tint32);
5215 } 5352 }
5216 5353
5217 void DotTemplateInstanceExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 5354 void DotTemplateInstanceExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5218 { 5355 {
5219 expToCBuffer(buf, hgs, e1, PREC_primary); 5356 expToCBuffer(buf, hgs, e1, PREC_primary);
5237 if (!type) 5374 if (!type)
5238 { 5375 {
5239 e1 = e1->semantic(sc); 5376 e1 = e1->semantic(sc);
5240 type = new TypeDelegate(func->type); 5377 type = new TypeDelegate(func->type);
5241 type = type->semantic(loc, sc); 5378 type = type->semantic(loc, sc);
5242 //-----------------
5243 /* For func, we need to get the
5244 * right 'this' pointer if func is in an outer class, but our
5245 * existing 'this' pointer is in an inner class.
5246 * This code is analogous to that used for variables
5247 * in DotVarExp::semantic().
5248 */
5249 AggregateDeclaration *ad = func->toParent()->isAggregateDeclaration(); 5379 AggregateDeclaration *ad = func->toParent()->isAggregateDeclaration();
5250 L10: 5380 if (func->needThis())
5251 Type *t = e1->type; 5381 e1 = getRightThis(loc, sc, ad, e1, func);
5252 if (func->needThis() && ad &&
5253 !(t->ty == Tpointer && t->next->ty == Tstruct &&
5254 ((TypeStruct *)t->next)->sym == ad) &&
5255 !(t->ty == Tstruct && ((TypeStruct *)t)->sym == ad)
5256 )
5257 {
5258 ClassDeclaration *cd = ad->isClassDeclaration();
5259 ClassDeclaration *tcd = t->isClassHandle();
5260
5261 if (!cd || !tcd ||
5262 !(tcd == cd || cd->isBaseOf(tcd, NULL))
5263 )
5264 {
5265 if (tcd && tcd->isNested())
5266 { // Try again with outer scope
5267
5268 e1 = new DotVarExp(loc, e1, tcd->vthis);
5269 e1 = e1->semantic(sc);
5270 goto L10;
5271 }
5272 #ifdef DEBUG
5273 printf("3: ");
5274 #endif
5275 error("this for %s needs to be type %s not type %s",
5276 func->toChars(), ad->toChars(), t->toChars());
5277 }
5278 }
5279 //-----------------
5280 } 5382 }
5281 return this; 5383 return this;
5282 } 5384 }
5283 5385
5284 void DelegateExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 5386 void DelegateExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
5533 { 5635 {
5534 DotVarExp *dve; 5636 DotVarExp *dve;
5535 DotTemplateExp *dte; 5637 DotTemplateExp *dte;
5536 AggregateDeclaration *ad; 5638 AggregateDeclaration *ad;
5537 UnaExp *ue = (UnaExp *)(e1); 5639 UnaExp *ue = (UnaExp *)(e1);
5538 5640
5539 if (e1->op == TOKdotvar) 5641 if (e1->op == TOKdotvar)
5540 { // Do overload resolution 5642 { // Do overload resolution
5541 dve = (DotVarExp *)(e1); 5643 dve = (DotVarExp *)(e1);
5542 5644
5543 f = dve->var->isFuncDeclaration(); 5645 f = dve->var->isFuncDeclaration();
5558 { type = Type::terror; 5660 { type = Type::terror;
5559 return this; 5661 return this;
5560 } 5662 }
5561 ad = td->toParent()->isAggregateDeclaration(); 5663 ad = td->toParent()->isAggregateDeclaration();
5562 } 5664 }
5563 /* Now that we have the right function f, we need to get the 5665 if (f->needThis())
5564 * right 'this' pointer if f is in an outer class, but our 5666 {
5565 * existing 'this' pointer is in an inner class. 5667 ue->e1 = getRightThis(loc, sc, ad, ue->e1, f);
5566 * This code is analogous to that used for variables 5668 }
5567 * in DotVarExp::semantic(). 5669
5670 /* Cannot call public functions from inside invariant
5671 * (because then the invariant would have infinite recursion)
5568 */ 5672 */
5569 L10: 5673 if (sc->func && sc->func->isInvariantDeclaration() &&
5570 Type *t = ue->e1->type->toBasetype(); 5674 ue->e1->op == TOKthis &&
5571 if (f->needThis() && ad && 5675 f->addPostInvariant()
5572 !(t->ty == Tpointer && t->next->ty == Tstruct &&
5573 ((TypeStruct *)t->next)->sym == ad) &&
5574 !(t->ty == Tstruct && ((TypeStruct *)t)->sym == ad)
5575 ) 5676 )
5576 { 5677 {
5577 ClassDeclaration *cd = ad->isClassDeclaration(); 5678 error("cannot call public/export function %s from invariant", f->toChars());
5578 ClassDeclaration *tcd = t->isClassHandle();
5579
5580 if (!cd || !tcd ||
5581 !(tcd == cd || cd->isBaseOf(tcd, NULL))
5582 )
5583 {
5584 if (tcd && tcd->isNested())
5585 { // Try again with outer scope
5586
5587 ue->e1 = new DotVarExp(loc, ue->e1, tcd->vthis);
5588 ue->e1 = ue->e1->semantic(sc);
5589 goto L10;
5590 }
5591 #ifdef DEBUG
5592 printf("1: ");
5593 #endif
5594 error("this for %s needs to be type %s not type %s",
5595 f->toChars(), ad->toChars(), t->toChars());
5596 }
5597 } 5679 }
5598 5680
5599 checkDeprecated(sc, f); 5681 checkDeprecated(sc, f);
5600 accessCheck(loc, sc, ue->e1, f); 5682 accessCheck(loc, sc, ue->e1, f);
5601 if (!f->needThis()) 5683 if (!f->needThis())
5645 type = Type::terror; 5727 type = Type::terror;
5646 return this; 5728 return this;
5647 } 5729 }
5648 else 5730 else
5649 { 5731 {
5732 if (!sc->intypeof)
5733 {
5650 #if 0 5734 #if 0
5651 if (sc->callSuper & (CSXthis | CSXsuper)) 5735 if (sc->callSuper & (CSXthis | CSXsuper))
5652 error("reference to this before super()"); 5736 error("reference to this before super()");
5653 #endif 5737 #endif
5654 if (sc->noctor || sc->callSuper & CSXlabel) 5738 if (sc->noctor || sc->callSuper & CSXlabel)
5655 error("constructor calls not allowed in loops or after labels"); 5739 error("constructor calls not allowed in loops or after labels");
5656 if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor)) 5740 if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor))
5657 error("multiple constructor calls"); 5741 error("multiple constructor calls");
5658 sc->callSuper |= CSXany_ctor | CSXsuper_ctor; 5742 sc->callSuper |= CSXany_ctor | CSXsuper_ctor;
5743 }
5659 5744
5660 f = f->overloadResolve(loc, arguments); 5745 f = f->overloadResolve(loc, arguments);
5661 checkDeprecated(sc, f); 5746 checkDeprecated(sc, f);
5662 e1 = new DotVarExp(e1->loc, e1, f); 5747 e1 = new DotVarExp(e1->loc, e1, f);
5663 e1 = e1->semantic(sc); 5748 e1 = e1->semantic(sc);
5678 type = Type::terror; 5763 type = Type::terror;
5679 return this; 5764 return this;
5680 } 5765 }
5681 else 5766 else
5682 { 5767 {
5768 if (!sc->intypeof)
5769 {
5683 #if 0 5770 #if 0
5684 if (sc->callSuper & (CSXthis | CSXsuper)) 5771 if (sc->callSuper & (CSXthis | CSXsuper))
5685 error("reference to this before super()"); 5772 error("reference to this before super()");
5686 #endif 5773 #endif
5687 if (sc->noctor || sc->callSuper & CSXlabel) 5774 if (sc->noctor || sc->callSuper & CSXlabel)
5688 error("constructor calls not allowed in loops or after labels"); 5775 error("constructor calls not allowed in loops or after labels");
5689 if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor)) 5776 if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor))
5690 error("multiple constructor calls"); 5777 error("multiple constructor calls");
5691 sc->callSuper |= CSXany_ctor | CSXthis_ctor; 5778 sc->callSuper |= CSXany_ctor | CSXthis_ctor;
5779 }
5692 5780
5693 f = cd->ctor; 5781 f = cd->ctor;
5694 f = f->overloadResolve(loc, arguments); 5782 f = f->overloadResolve(loc, arguments);
5695 checkDeprecated(sc, f); 5783 checkDeprecated(sc, f);
5696 e1 = new DotVarExp(e1->loc, e1, f); 5784 e1 = new DotVarExp(e1->loc, e1, f);