Mercurial > projects > ldc
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); |