comparison dmd/statement.c @ 846:bc982f1ad106

Merged DMD 1.037 frontend
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Sat, 13 Dec 2008 13:15:31 +0100
parents 661384d6a936
children 330f999ade44
comparison
equal deleted inserted replaced
845:d128381e086e 846:bc982f1ad106
24 #include "declaration.h" 24 #include "declaration.h"
25 #include "aggregate.h" 25 #include "aggregate.h"
26 #include "id.h" 26 #include "id.h"
27 #include "hdrgen.h" 27 #include "hdrgen.h"
28 #include "parse.h" 28 #include "parse.h"
29 #include "template.h"
29 30
30 /******************************** Statement ***************************/ 31 /******************************** Statement ***************************/
31 32
32 Statement::Statement(Loc loc) 33 Statement::Statement(Loc loc)
33 : loc(loc) 34 : loc(loc)
449 a->push(statements->data[j]); 450 a->push(statements->data[j]);
450 } 451 }
451 body = new CompoundStatement(0, a); 452 body = new CompoundStatement(0, a);
452 body = new ScopeStatement(0, body); 453 body = new ScopeStatement(0, body);
453 454
454 static int num; 455 Identifier *id = Lexer::uniqueId("__o");
455 char name[3 + sizeof(num) * 3 + 1];
456 sprintf(name, "__o%d", ++num);
457 Identifier *id = Lexer::idPool(name);
458 456
459 Statement *handler = new ThrowStatement(0, new IdentifierExp(0, id)); 457 Statement *handler = new ThrowStatement(0, new IdentifierExp(0, id));
460 handler = new CompoundStatement(0, sexception, handler); 458 handler = new CompoundStatement(0, sexception, handler);
461 459
462 Array *catches = new Array(); 460 Array *catches = new Array();
1105 init = init->semantic(sc); 1103 init = init->semantic(sc);
1106 if (!condition) 1104 if (!condition)
1107 // Use a default value 1105 // Use a default value
1108 condition = new IntegerExp(loc, 1, Type::tboolean); 1106 condition = new IntegerExp(loc, 1, Type::tboolean);
1109 sc->noctor++; 1107 sc->noctor++;
1110 condition = condition->semantic(sc); 1108 if (condition)
1111 condition = resolveProperties(sc, condition); 1109 {
1112 condition = condition->optimize(WANTvalue); 1110 condition = condition->semantic(sc);
1113 condition = condition->checkToBoolean(); 1111 condition = resolveProperties(sc, condition);
1112 condition = condition->optimize(WANTvalue);
1113 condition = condition->checkToBoolean();
1114 }
1114 if (increment) 1115 if (increment)
1115 increment = increment->semantic(sc); 1116 { increment = increment->semantic(sc);
1117 increment = resolveProperties(sc, increment);
1118 }
1116 1119
1117 sc->sbreak = this; 1120 sc->sbreak = this;
1118 sc->scontinue = this; 1121 sc->scontinue = this;
1119 body = body->semantic(sc); 1122 body = body->semantic(sc);
1120 sc->noctor--; 1123 sc->noctor--;
1255 Statement *ForeachStatement::semantic(Scope *sc) 1258 Statement *ForeachStatement::semantic(Scope *sc)
1256 { 1259 {
1257 //printf("ForeachStatement::semantic() %p\n", this); 1260 //printf("ForeachStatement::semantic() %p\n", this);
1258 ScopeDsymbol *sym; 1261 ScopeDsymbol *sym;
1259 Statement *s = this; 1262 Statement *s = this;
1260 int dim = arguments->dim; 1263 size_t dim = arguments->dim;
1261 int i;
1262 TypeAArray *taa = NULL; 1264 TypeAArray *taa = NULL;
1263 1265
1264 Type *tn = NULL; 1266 Type *tn = NULL;
1265 Type *tnv = NULL; 1267 Type *tnv = NULL;
1266 1268
1270 if (func->fes) 1272 if (func->fes)
1271 func = func->fes->func; 1273 func = func->fes->func;
1272 1274
1273 aggr = aggr->semantic(sc); 1275 aggr = aggr->semantic(sc);
1274 aggr = resolveProperties(sc, aggr); 1276 aggr = resolveProperties(sc, aggr);
1277 aggr = aggr->optimize(WANTvalue);
1275 if (!aggr->type) 1278 if (!aggr->type)
1276 { 1279 {
1277 error("invalid foreach aggregate %s", aggr->toChars()); 1280 error("invalid foreach aggregate %s", aggr->toChars());
1278 return this; 1281 return this;
1279 } 1282 }
1385 s = new UnrolledLoopStatement(loc, statements); 1388 s = new UnrolledLoopStatement(loc, statements);
1386 s = s->semantic(sc); 1389 s = s->semantic(sc);
1387 return s; 1390 return s;
1388 } 1391 }
1389 1392
1390 for (i = 0; i < dim; i++) 1393 for (size_t i = 0; i < dim; i++)
1391 { Argument *arg = (Argument *)arguments->data[i]; 1394 { Argument *arg = (Argument *)arguments->data[i];
1392 if (!arg->type) 1395 if (!arg->type)
1393 { 1396 {
1394 error("cannot infer type for %s", arg->ident->toChars()); 1397 error("cannot infer type for %s", arg->ident->toChars());
1395 return this; 1398 return this;
1417 */ 1420 */
1418 tn = tab->nextOf()->toBasetype(); 1421 tn = tab->nextOf()->toBasetype();
1419 if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar) 1422 if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar)
1420 { Argument *arg; 1423 { Argument *arg;
1421 1424
1422 i = (dim == 1) ? 0 : 1; // index of value 1425 int i = (dim == 1) ? 0 : 1; // index of value
1423 arg = (Argument *)arguments->data[i]; 1426 arg = (Argument *)arguments->data[i];
1424 arg->type = arg->type->semantic(loc, sc); 1427 arg->type = arg->type->semantic(loc, sc);
1425 tnv = arg->type->toBasetype(); 1428 tnv = arg->type->toBasetype();
1426 if (tnv->ty != tn->ty && 1429 if (tnv->ty != tn->ty &&
1427 (tnv->ty == Tchar || tnv->ty == Twchar || tnv->ty == Tdchar)) 1430 (tnv->ty == Tchar || tnv->ty == Twchar || tnv->ty == Tdchar))
1435 } 1438 }
1436 goto Lapply; 1439 goto Lapply;
1437 } 1440 }
1438 } 1441 }
1439 1442
1440 for (i = 0; i < dim; i++) 1443 for (size_t i = 0; i < dim; i++)
1441 { // Declare args 1444 { // Declare args
1442 Argument *arg = (Argument *)arguments->data[i]; 1445 Argument *arg = (Argument *)arguments->data[i];
1443 VarDeclaration *var; 1446 VarDeclaration *var;
1444 1447
1445 var = new VarDeclaration(loc, arg->type, arg->ident, NULL); 1448 var = new VarDeclaration(loc, arg->type, arg->ident, NULL);
1466 if (!value->type->equals(tab->next)) 1469 if (!value->type->equals(tab->next))
1467 { 1470 {
1468 if (aggr->op == TOKstring) 1471 if (aggr->op == TOKstring)
1469 aggr = aggr->implicitCastTo(sc, value->type->arrayOf()); 1472 aggr = aggr->implicitCastTo(sc, value->type->arrayOf());
1470 else 1473 else
1471 error("foreach: %s is not an array of %s", tab->toChars(), value->type->toChars()); 1474 error("foreach: %s is not an array of %s",
1475 tab->toChars(), value->type->toChars());
1472 } 1476 }
1473 1477
1474 if (key) 1478 if (key)
1475 { 1479 {
1476 if (global.params.is64bit) 1480 if (global.params.is64bit)
1503 } 1507 }
1504 goto Lapply; 1508 goto Lapply;
1505 1509
1506 case Tclass: 1510 case Tclass:
1507 case Tstruct: 1511 case Tstruct:
1512 #if DMDV2
1513 { /* Look for range iteration, i.e. the properties
1514 * .empty, .next, .retreat, .head and .rear
1515 * foreach (e; range) { ... }
1516 * translates to:
1517 * for (auto __r = range; !__r.empty; __r.next)
1518 * { auto e = __r.head;
1519 * ...
1520 * }
1521 */
1522 if (dim != 1) // only one argument allowed with ranges
1523 goto Lapply;
1524 AggregateDeclaration *ad = (tab->ty == Tclass)
1525 ? (AggregateDeclaration *)((TypeClass *)tab)->sym
1526 : (AggregateDeclaration *)((TypeStruct *)tab)->sym;
1527 Identifier *idhead;
1528 Identifier *idnext;
1529 if (op == TOKforeach)
1530 { idhead = Id::Fhead;
1531 idnext = Id::Fnext;
1532 }
1533 else
1534 { idhead = Id::Frear;
1535 idnext = Id::Fretreat;
1536 }
1537 Dsymbol *shead = search_function(ad, idhead);
1538 if (!shead)
1539 goto Lapply;
1540
1541 /* Generate a temporary __r and initialize it with the aggregate.
1542 */
1543 Identifier *id = Identifier::generateId("__r");
1544 VarDeclaration *r = new VarDeclaration(loc, NULL, id, new ExpInitializer(loc, aggr));
1545 r->semantic(sc);
1546 Statement *init = new DeclarationStatement(loc, r);
1547
1548 // !__r.empty
1549 Expression *e = new VarExp(loc, r);
1550 e = new DotIdExp(loc, e, Id::Fempty);
1551 Expression *condition = new NotExp(loc, e);
1552
1553 // __r.next
1554 e = new VarExp(loc, r);
1555 Expression *increment = new DotIdExp(loc, e, idnext);
1556
1557 /* Declaration statement for e:
1558 * auto e = __r.idhead;
1559 */
1560 e = new VarExp(loc, r);
1561 Expression *einit = new DotIdExp(loc, e, idhead);
1562 einit = einit->semantic(sc);
1563 Argument *arg = (Argument *)arguments->data[0];
1564 VarDeclaration *ve = new VarDeclaration(loc, arg->type, arg->ident, new ExpInitializer(loc, einit));
1565 ve->storage_class |= STCforeach;
1566 ve->storage_class |= arg->storageClass & (STCin | STCout | STCref | STCconst | STCinvariant);
1567
1568 DeclarationExp *de = new DeclarationExp(loc, ve);
1569
1570 Statement *body = new CompoundStatement(loc,
1571 new DeclarationStatement(loc, de), this->body);
1572
1573 s = new ForStatement(loc, init, condition, increment, body);
1574 s = s->semantic(sc);
1575 break;
1576 }
1577 #endif
1508 case Tdelegate: 1578 case Tdelegate:
1509 Lapply: 1579 Lapply:
1510 { FuncDeclaration *fdapply; 1580 { FuncDeclaration *fdapply;
1511 Arguments *args; 1581 Arguments *args;
1512 Expression *ec; 1582 Expression *ec;
1538 1608
1539 /* Turn body into the function literal: 1609 /* Turn body into the function literal:
1540 * int delegate(ref T arg) { body } 1610 * int delegate(ref T arg) { body }
1541 */ 1611 */
1542 args = new Arguments(); 1612 args = new Arguments();
1543 for (i = 0; i < dim; i++) 1613 for (size_t i = 0; i < dim; i++)
1544 { Argument *arg = (Argument *)arguments->data[i]; 1614 { Argument *arg = (Argument *)arguments->data[i];
1545 1615
1546 arg->type = arg->type->semantic(loc, sc); 1616 arg->type = arg->type->semantic(loc, sc);
1547 if (arg->storageClass & STCref) 1617 if (arg->storageClass & STCref)
1548 id = arg->ident; 1618 id = arg->ident;
1549 else 1619 else
1550 { // Make a copy of the ref argument so it isn't 1620 { // Make a copy of the ref argument so it isn't
1551 // a reference. 1621 // a reference.
1552 VarDeclaration *v; 1622 VarDeclaration *v;
1553 Initializer *ie; 1623 Initializer *ie;
1554 char applyArg[10 + sizeof(i)*3 + 1]; 1624
1555 1625 id = Lexer::uniqueId("__applyArg", i);
1556 sprintf(applyArg, "__applyArg%d", i);
1557 id = Lexer::idPool(applyArg);
1558 1626
1559 ie = new ExpInitializer(0, new IdentifierExp(0, id)); 1627 ie = new ExpInitializer(0, new IdentifierExp(0, id));
1560 v = new VarDeclaration(0, arg->type, arg->ident, ie); 1628 v = new VarDeclaration(0, arg->type, arg->ident, ie);
1561 s = new DeclarationStatement(0, v); 1629 s = new DeclarationStatement(0, v);
1562 body = new CompoundStatement(loc, s, body); 1630 body = new CompoundStatement(loc, s, body);
2143 fprintf(stdmsg, "\n"); 2211 fprintf(stdmsg, "\n");
2144 } 2212 }
2145 } 2213 }
2146 else if (ident == Id::lib) 2214 else if (ident == Id::lib)
2147 { 2215 {
2216 #if 1
2217 /* Should this be allowed?
2218 */
2219 error("pragma(lib) not allowed as statement");
2220 #else
2148 if (!args || args->dim != 1) 2221 if (!args || args->dim != 1)
2149 error("string expected for library name"); 2222 error("string expected for library name");
2150 else 2223 else
2151 { 2224 {
2152 Expression *e = (Expression *)args->data[0]; 2225 Expression *e = (Expression *)args->data[0];
2164 name[se->len] = 0; 2237 name[se->len] = 0;
2165 printf("library %s\n", name); 2238 printf("library %s\n", name);
2166 mem.free(name); 2239 mem.free(name);
2167 } 2240 }
2168 } 2241 }
2242 #endif
2169 } 2243 }
2170 else 2244 else
2171 error("unrecognized pragma(%s)", ident->toChars()); 2245 error("unrecognized pragma(%s)", ident->toChars());
2172 2246
2173 if (body) 2247 if (body)
2452 { SwitchStatement *sw = sc->sw; 2526 { SwitchStatement *sw = sc->sw;
2453 2527
2454 //printf("CaseStatement::semantic() %s\n", toChars()); 2528 //printf("CaseStatement::semantic() %s\n", toChars());
2455 exp = exp->semantic(sc); 2529 exp = exp->semantic(sc);
2456 if (sw) 2530 if (sw)
2457 { int i; 2531 {
2458
2459 exp = exp->implicitCastTo(sc, sw->condition->type); 2532 exp = exp->implicitCastTo(sc, sw->condition->type);
2460 exp = exp->optimize(WANTvalue | WANTinterpret); 2533 exp = exp->optimize(WANTvalue | WANTinterpret);
2461 if (exp->op != TOKstring && exp->op != TOKint64) 2534 if (exp->op != TOKstring && exp->op != TOKint64)
2462 { 2535 {
2463 error("case must be a string or an integral constant, not %s", exp->toChars()); 2536 error("case must be a string or an integral constant, not %s", exp->toChars());
2464 exp = new IntegerExp(0); 2537 exp = new IntegerExp(0);
2465 } 2538 }
2466 2539
2467 for (i = 0; i < sw->cases->dim; i++) 2540 for (int i = 0; i < sw->cases->dim; i++)
2468 { 2541 {
2469 CaseStatement *cs = (CaseStatement *)sw->cases->data[i]; 2542 CaseStatement *cs = (CaseStatement *)sw->cases->data[i];
2470 2543
2471 //printf("comparing '%s' with '%s'\n", exp->toChars(), cs->exp->toChars()); 2544 //printf("comparing '%s' with '%s'\n", exp->toChars(), cs->exp->toChars());
2472 if (cs->exp->equals(exp)) 2545 if (cs->exp->equals(exp))
2476 } 2549 }
2477 2550
2478 sw->cases->push(this); 2551 sw->cases->push(this);
2479 2552
2480 // Resolve any goto case's with no exp to this case statement 2553 // Resolve any goto case's with no exp to this case statement
2481 for (i = 0; i < sw->gotoCases.dim; i++) 2554 for (size_t i = 0; i < sw->gotoCases.dim; i++)
2482 { 2555 {
2483 GotoCaseStatement *gcs = (GotoCaseStatement *)sw->gotoCases.data[i]; 2556 GotoCaseStatement *gcs = (GotoCaseStatement *)sw->gotoCases.data[i];
2484 2557
2485 if (!gcs->exp) 2558 if (!gcs->exp)
2486 { 2559 {
2873 exp->op == TOKimaginary80 || exp->op == TOKcomplex80 || 2946 exp->op == TOKimaginary80 || exp->op == TOKcomplex80 ||
2874 exp->op == TOKthis || exp->op == TOKsuper || exp->op == TOKnull || 2947 exp->op == TOKthis || exp->op == TOKsuper || exp->op == TOKnull ||
2875 exp->op == TOKstring) 2948 exp->op == TOKstring)
2876 { 2949 {
2877 sc->fes->cases.push(this); 2950 sc->fes->cases.push(this);
2951 // Construct: return cases.dim+1;
2878 s = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1)); 2952 s = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
2879 } 2953 }
2880 else if (fd->type->nextOf()->toBasetype() == Type::tvoid) 2954 else if (fd->type->nextOf()->toBasetype() == Type::tvoid)
2881 { 2955 {
2882 Statement *s1;
2883 Statement *s2;
2884
2885 s = new ReturnStatement(0, NULL); 2956 s = new ReturnStatement(0, NULL);
2886 sc->fes->cases.push(s); 2957 sc->fes->cases.push(s);
2887 2958
2888 // Construct: { exp; return cases.dim + 1; } 2959 // Construct: { exp; return cases.dim + 1; }
2889 s1 = new ExpStatement(loc, exp); 2960 Statement *s1 = new ExpStatement(loc, exp);
2890 s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1)); 2961 Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
2891 s = new CompoundStatement(loc, s1, s2); 2962 s = new CompoundStatement(loc, s1, s2);
2892 } 2963 }
2893 else 2964 else
2894 { 2965 {
2895 VarExp *v;
2896 Statement *s1;
2897 Statement *s2;
2898
2899 // Construct: return vresult; 2966 // Construct: return vresult;
2900 if (!fd->vresult) 2967 if (!fd->vresult)
2901 { VarDeclaration *v; 2968 { // Declare vresult
2902 2969 VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL);
2903 v = new VarDeclaration(loc, tret, Id::result, NULL);
2904 v->noauto = 1; 2970 v->noauto = 1;
2905 v->semantic(scx); 2971 v->semantic(scx);
2906 if (!scx->insert(v)) 2972 if (!scx->insert(v))
2907 assert(0); 2973 assert(0);
2908 v->parent = fd; 2974 v->parent = fd;
2909 fd->vresult = v; 2975 fd->vresult = v;
2910 } 2976 }
2911 2977
2912 v = new VarExp(0, fd->vresult); 2978 s = new ReturnStatement(0, new VarExp(0, fd->vresult));
2913 s = new ReturnStatement(0, v);
2914 sc->fes->cases.push(s); 2979 sc->fes->cases.push(s);
2915 2980
2916 // Construct: { vresult = exp; return cases.dim + 1; } 2981 // Construct: { vresult = exp; return cases.dim + 1; }
2917 v = new VarExp(0, fd->vresult); 2982 exp = new AssignExp(loc, new VarExp(0, fd->vresult), exp);
2918 exp = new AssignExp(loc, v, exp);
2919 exp = exp->semantic(sc); 2983 exp = exp->semantic(sc);
2920 s1 = new ExpStatement(loc, exp); 2984 Statement *s1 = new ExpStatement(loc, exp);
2921 s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1)); 2985 Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
2922 s = new CompoundStatement(loc, s1, s2); 2986 s = new CompoundStatement(loc, s1, s2);
2923 } 2987 }
2924 return s; 2988 return s;
2925 } 2989 }
2926 2990
2957 { 3021 {
2958 GotoStatement *gs = new GotoStatement(loc, Id::returnLabel); 3022 GotoStatement *gs = new GotoStatement(loc, Id::returnLabel);
2959 3023
2960 gs->label = fd->returnLabel; 3024 gs->label = fd->returnLabel;
2961 if (exp) 3025 if (exp)
2962 { Statement *s; 3026 { /* Replace: return exp;
2963 3027 * with: exp; goto returnLabel;
2964 s = new ExpStatement(0, exp); 3028 */
3029 Statement *s = new ExpStatement(0, exp);
2965 return new CompoundStatement(loc, s, gs); 3030 return new CompoundStatement(loc, s, gs);
2966 } 3031 }
2967 return gs; 3032 return gs;
2968 } 3033 }
2969 3034
3737 /* Create: 3802 /* Create:
3738 * sentry: int x = 0; 3803 * sentry: int x = 0;
3739 * sexception: x = 1; 3804 * sexception: x = 1;
3740 * sfinally: if (!x) statement; 3805 * sfinally: if (!x) statement;
3741 */ 3806 */
3742 static int num; 3807 Identifier *id = Lexer::uniqueId("__os");
3743 char name[5 + sizeof(num) * 3 + 1];
3744 sprintf(name, "__osf%d", ++num);
3745 Identifier *id = Lexer::idPool(name);
3746 3808
3747 ExpInitializer *ie = new ExpInitializer(loc, new IntegerExp(0)); 3809 ExpInitializer *ie = new ExpInitializer(loc, new IntegerExp(0));
3748 VarDeclaration *v = new VarDeclaration(loc, Type::tint32, id, ie); 3810 VarDeclaration *v = new VarDeclaration(loc, Type::tint32, id, ie);
3749 *sentry = new DeclarationStatement(loc, v); 3811 *sentry = new DeclarationStatement(loc, v);
3750 3812