comparison dmd2/statement.c @ 1452:638d16625da2

LDC 2 compiles again.
author Robert Clipsham <robert@octarineparrot.com>
date Sat, 30 May 2009 17:23:32 +0100
parents 5fa3e0ea06e9
children 54b3c1394d62
comparison
equal deleted inserted replaced
1423:42bd767ec5a4 1452:638d16625da2
1 1
2 // Compiler implementation of the D programming language 2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2008 by Digital Mars 3 // Copyright (c) 1999-2009 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.
10 10
11 #include <stdio.h> 11 #include <stdio.h>
12 #include <stdlib.h> 12 #include <stdlib.h>
13 #include <assert.h> 13 #include <assert.h>
14 14
15 #include "mem.h" 15 #include "rmem.h"
16 16
17 #include "statement.h" 17 #include "statement.h"
18 #include "expression.h" 18 #include "expression.h"
19 #include "cond.h" 19 #include "cond.h"
20 #include "init.h" 20 #include "init.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 #include "template.h"
30 #include "attrib.h"
30 31
31 /******************************** Statement ***************************/ 32 /******************************** Statement ***************************/
32 33
33 Statement::Statement(Loc loc) 34 Statement::Statement(Loc loc)
34 : loc(loc) 35 : loc(loc)
94 va_start(ap, format); 95 va_start(ap, format);
95 ::verror(loc, format, ap); 96 ::verror(loc, format, ap);
96 va_end( ap ); 97 va_end( ap );
97 } 98 }
98 99
100 void Statement::warning(const char *format, ...)
101 {
102 if (global.params.warnings && !global.gag)
103 {
104 va_list ap;
105 va_start(ap, format);
106 ::vwarning(loc, format, ap);
107 va_end( ap );
108 }
109 }
110
99 int Statement::hasBreak() 111 int Statement::hasBreak()
100 { 112 {
101 //printf("Statement::hasBreak()\n"); 113 //printf("Statement::hasBreak()\n");
102 return FALSE; 114 return FALSE;
103 } 115 }
120 { 132 {
121 printf("Statement::blockExit(%p)\n", this); 133 printf("Statement::blockExit(%p)\n", this);
122 printf("%s\n", toChars()); 134 printf("%s\n", toChars());
123 assert(0); 135 assert(0);
124 return BEany; 136 return BEany;
125 }
126
127 // TRUE if statement may fall off the end without a throw or return
128
129 int Statement::fallOffEnd()
130 {
131 return TRUE;
132 } 137 }
133 138
134 // TRUE if statement 'comes from' somewhere else, like a goto 139 // TRUE if statement 'comes from' somewhere else, like a goto
135 140
136 int Statement::comeFrom() 141 int Statement::comeFrom()
229 result |= BEthrow; 234 result |= BEthrow;
230 } 235 }
231 return result; 236 return result;
232 } 237 }
233 238
234 int ExpStatement::fallOffEnd()
235 {
236 if (exp)
237 {
238 if (exp->op == TOKassert)
239 { AssertExp *a = (AssertExp *)exp;
240
241 if (a->e1->isBool(FALSE)) // if it's an assert(0)
242 return FALSE;
243 }
244 else if (exp->op == TOKhalt)
245 return FALSE;
246 }
247 return TRUE;
248 }
249 239
250 /******************************** CompileStatement ***************************/ 240 /******************************** CompileStatement ***************************/
251 241
252 CompileStatement::CompileStatement(Loc loc, Expression *exp) 242 CompileStatement::CompileStatement(Loc loc, Expression *exp)
253 : Statement(loc) 243 : Statement(loc)
563 { 553 {
564 //printf("result = x%x\n", result); 554 //printf("result = x%x\n", result);
565 //printf("%s\n", s->toChars()); 555 //printf("%s\n", s->toChars());
566 if (!(result & BEfallthru) && !s->comeFrom()) 556 if (!(result & BEfallthru) && !s->comeFrom())
567 { 557 {
568 if (global.params.warnings) 558 s->warning("statement is not reachable");
569 { fprintf(stdmsg, "warning - ");
570 s->error("statement is not reachable");
571 }
572 } 559 }
573 560
574 result &= ~BEfallthru; 561 result &= ~BEfallthru;
575 result |= s->blockExit(); 562 result |= s->blockExit();
576 } 563 }
577 } 564 }
578 return result; 565 return result;
579 }
580
581 int CompoundStatement::fallOffEnd()
582 { int falloff = TRUE;
583
584 //printf("CompoundStatement::fallOffEnd() %s\n", toChars());
585 for (int i = 0; i < statements->dim; i++)
586 { Statement *s = (Statement *)statements->data[i];
587
588 if (!s)
589 continue;
590
591 #if 0
592 if (!falloff && global.params.warnings && !s->comeFrom())
593 {
594 warning("%s: statement is not reachable", s->loc.toChars());
595 }
596 #endif
597 falloff = s->fallOffEnd();
598 }
599 return falloff;
600 } 566 }
601 567
602 int CompoundStatement::comeFrom() 568 int CompoundStatement::comeFrom()
603 { int comefrom = FALSE; 569 { int comefrom = FALSE;
604 570
613 } 579 }
614 return comefrom; 580 return comefrom;
615 } 581 }
616 582
617 583
618 /**************************** UnrolledLoopStatement ***************************/ 584 /******************************** CompoundDeclarationStatement ***************************/
619 585
620 UnrolledLoopStatement::UnrolledLoopStatement(Loc loc, Statements *s) 586 CompoundDeclarationStatement::CompoundDeclarationStatement(Loc loc, Statements *s)
621 : Statement(loc) 587 : CompoundStatement(loc, s)
622 { 588 {
623 statements = s; 589 statements = s;
624 enclosinghandler = NULL; 590 }
625 } 591
626 592 Statement *CompoundDeclarationStatement::syntaxCopy()
627 Statement *UnrolledLoopStatement::syntaxCopy()
628 { 593 {
629 Statements *a = new Statements(); 594 Statements *a = new Statements();
630 a->setDim(statements->dim); 595 a->setDim(statements->dim);
631 for (size_t i = 0; i < statements->dim; i++) 596 for (size_t i = 0; i < statements->dim; i++)
632 { Statement *s = (Statement *)statements->data[i]; 597 { Statement *s = (Statement *)statements->data[i];
633 if (s) 598 if (s)
634 s = s->syntaxCopy(); 599 s = s->syntaxCopy();
635 a->data[i] = s; 600 a->data[i] = s;
636 } 601 }
602 CompoundDeclarationStatement *cs = new CompoundDeclarationStatement(loc, a);
603 return cs;
604 }
605
606 void CompoundDeclarationStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
607 {
608 int nwritten = 0;
609 for (int i = 0; i < statements->dim; i++)
610 { Statement *s = (Statement *) statements->data[i];
611 if (s)
612 { DeclarationStatement *ds = s->isDeclarationStatement();
613 assert(ds);
614 DeclarationExp *de = (DeclarationExp *)ds->exp;
615 assert(de->op == TOKdeclaration);
616 Declaration *d = de->declaration->isDeclaration();
617 assert(d);
618 VarDeclaration *v = d->isVarDeclaration();
619 if (v)
620 {
621 /* This essentially copies the part of VarDeclaration::toCBuffer()
622 * that does not print the type.
623 * Should refactor this.
624 */
625 if (nwritten)
626 {
627 buf->writeByte(',');
628 buf->writestring(v->ident->toChars());
629 }
630 else
631 {
632 StorageClassDeclaration::stcToCBuffer(buf, v->storage_class);
633 if (v->type)
634 v->type->toCBuffer(buf, v->ident, hgs);
635 else
636 buf->writestring(v->ident->toChars());
637 }
638
639 if (v->init)
640 { buf->writestring(" = ");
641 #if DMDV2
642 ExpInitializer *ie = v->init->isExpInitializer();
643 if (ie && (ie->exp->op == TOKconstruct || ie->exp->op == TOKblit))
644 ((AssignExp *)ie->exp)->e2->toCBuffer(buf, hgs);
645 else
646 #endif
647 v->init->toCBuffer(buf, hgs);
648 }
649 }
650 else
651 d->toCBuffer(buf, hgs);
652 nwritten++;
653 }
654 }
655 buf->writeByte(';');
656 if (!hgs->FLinit.init)
657 buf->writenl();
658 }
659
660 /**************************** UnrolledLoopStatement ***************************/
661
662 UnrolledLoopStatement::UnrolledLoopStatement(Loc loc, Statements *s)
663 : Statement(loc)
664 {
665 statements = s;
666 }
667
668 Statement *UnrolledLoopStatement::syntaxCopy()
669 {
670 Statements *a = new Statements();
671 a->setDim(statements->dim);
672 for (size_t i = 0; i < statements->dim; i++)
673 { Statement *s = (Statement *)statements->data[i];
674 if (s)
675 s = s->syntaxCopy();
676 a->data[i] = s;
677 }
637 UnrolledLoopStatement *cs = new UnrolledLoopStatement(loc, a); 678 UnrolledLoopStatement *cs = new UnrolledLoopStatement(loc, a);
638 return cs; 679 return cs;
639 } 680 }
640 681
641 682
642 Statement *UnrolledLoopStatement::semantic(Scope *sc) 683 Statement *UnrolledLoopStatement::semantic(Scope *sc)
643 { 684 {
644 //printf("UnrolledLoopStatement::semantic(this = %p, sc = %p)\n", this, sc); 685 //printf("UnrolledLoopStatement::semantic(this = %p, sc = %p)\n", this, sc);
645
646 enclosinghandler = sc->tfOfTry;
647 686
648 sc->noctor++; 687 sc->noctor++;
649 Scope *scd = sc->push(); 688 Scope *scd = sc->push();
650 scd->sbreak = this; 689 scd->sbreak = this;
651 scd->scontinue = this; 690 scd->scontinue = this;
714 } 753 }
715 } 754 }
716 return result; 755 return result;
717 } 756 }
718 757
719 int UnrolledLoopStatement::fallOffEnd()
720 {
721 //printf("UnrolledLoopStatement::fallOffEnd()\n");
722 for (size_t i = 0; i < statements->dim; i++)
723 { Statement *s = (Statement *)statements->data[i];
724
725 if (s)
726 s->fallOffEnd();
727 }
728 return TRUE;
729 }
730 758
731 int UnrolledLoopStatement::comeFrom() 759 int UnrolledLoopStatement::comeFrom()
732 { int comefrom = FALSE; 760 { int comefrom = FALSE;
733 761
734 //printf("UnrolledLoopStatement::comeFrom()\n"); 762 //printf("UnrolledLoopStatement::comeFrom()\n");
819 { 847 {
820 //printf("ScopeStatement::blockExit(%p)\n", statement); 848 //printf("ScopeStatement::blockExit(%p)\n", statement);
821 return statement ? statement->blockExit() : BEfallthru; 849 return statement ? statement->blockExit() : BEfallthru;
822 } 850 }
823 851
824 int ScopeStatement::fallOffEnd()
825 {
826 return statement ? statement->fallOffEnd() : TRUE;
827 }
828 852
829 int ScopeStatement::comeFrom() 853 int ScopeStatement::comeFrom()
830 { 854 {
831 //printf("ScopeStatement::comeFrom()\n"); 855 //printf("ScopeStatement::comeFrom()\n");
832 return statement ? statement->comeFrom() : FALSE; 856 return statement ? statement->comeFrom() : FALSE;
849 WhileStatement::WhileStatement(Loc loc, Expression *c, Statement *b) 873 WhileStatement::WhileStatement(Loc loc, Expression *c, Statement *b)
850 : Statement(loc) 874 : Statement(loc)
851 { 875 {
852 condition = c; 876 condition = c;
853 body = b; 877 body = b;
854 enclosinghandler = NULL;
855 } 878 }
856 879
857 Statement *WhileStatement::syntaxCopy() 880 Statement *WhileStatement::syntaxCopy()
858 { 881 {
859 WhileStatement *s = new WhileStatement(loc, condition->syntaxCopy(), body ? body->syntaxCopy() : NULL); 882 WhileStatement *s = new WhileStatement(loc, condition->syntaxCopy(), body ? body->syntaxCopy() : NULL);
884 Statement *si = new IfStatement(loc, condition, sw, NULL); 907 Statement *si = new IfStatement(loc, condition, sw, NULL);
885 return si->semantic(sc); 908 return si->semantic(sc);
886 } 909 }
887 #endif 910 #endif
888 911
889 enclosinghandler = sc->tfOfTry;
890
891 condition = condition->semantic(sc); 912 condition = condition->semantic(sc);
892 condition = resolveProperties(sc, condition); 913 condition = resolveProperties(sc, condition);
893 condition = condition->optimize(WANTvalue); 914 condition = condition->optimize(WANTvalue);
894 condition = condition->checkToBoolean(); 915 condition = condition->checkToBoolean();
895 916
949 } 970 }
950 result &= ~(BEbreak | BEcontinue); 971 result &= ~(BEbreak | BEcontinue);
951 return result; 972 return result;
952 } 973 }
953 974
954 int WhileStatement::fallOffEnd()
955 {
956 if (body)
957 body->fallOffEnd();
958 return TRUE;
959 }
960 975
961 int WhileStatement::comeFrom() 976 int WhileStatement::comeFrom()
962 { 977 {
963 if (body) 978 if (body)
964 return body->comeFrom(); 979 return body->comeFrom();
980 DoStatement::DoStatement(Loc loc, Statement *b, Expression *c) 995 DoStatement::DoStatement(Loc loc, Statement *b, Expression *c)
981 : Statement(loc) 996 : Statement(loc)
982 { 997 {
983 body = b; 998 body = b;
984 condition = c; 999 condition = c;
985 enclosinghandler = NULL;
986 } 1000 }
987 1001
988 Statement *DoStatement::syntaxCopy() 1002 Statement *DoStatement::syntaxCopy()
989 { 1003 {
990 DoStatement *s = new DoStatement(loc, body ? body->syntaxCopy() : NULL, condition->syntaxCopy()); 1004 DoStatement *s = new DoStatement(loc, body ? body->syntaxCopy() : NULL, condition->syntaxCopy());
992 } 1006 }
993 1007
994 1008
995 Statement *DoStatement::semantic(Scope *sc) 1009 Statement *DoStatement::semantic(Scope *sc)
996 { 1010 {
997 enclosinghandler = sc->tfOfTry;
998
999 sc->noctor++; 1011 sc->noctor++;
1000 if (body) 1012 if (body)
1001 body = body->semanticScope(sc, this, this); 1013 body = body->semanticScope(sc, this, this);
1002 sc->noctor--; 1014 sc->noctor--;
1003 condition = condition->semantic(sc); 1015 condition = condition->semantic(sc);
1044 } 1056 }
1045 result &= ~(BEbreak | BEcontinue); 1057 result &= ~(BEbreak | BEcontinue);
1046 return result; 1058 return result;
1047 } 1059 }
1048 1060
1049 int DoStatement::fallOffEnd()
1050 {
1051 if (body)
1052 body->fallOffEnd();
1053 return TRUE;
1054 }
1055 1061
1056 int DoStatement::comeFrom() 1062 int DoStatement::comeFrom()
1057 { 1063 {
1058 if (body) 1064 if (body)
1059 return body->comeFrom(); 1065 return body->comeFrom();
1078 { 1084 {
1079 this->init = init; 1085 this->init = init;
1080 this->condition = condition; 1086 this->condition = condition;
1081 this->increment = increment; 1087 this->increment = increment;
1082 this->body = body; 1088 this->body = body;
1083 this->enclosinghandler = NULL;
1084 } 1089 }
1085 1090
1086 Statement *ForStatement::syntaxCopy() 1091 Statement *ForStatement::syntaxCopy()
1087 { 1092 {
1088 Statement *i = NULL; 1093 Statement *i = NULL;
1098 return s; 1103 return s;
1099 } 1104 }
1100 1105
1101 Statement *ForStatement::semantic(Scope *sc) 1106 Statement *ForStatement::semantic(Scope *sc)
1102 { 1107 {
1103 enclosinghandler = sc->tfOfTry;
1104
1105 ScopeDsymbol *sym = new ScopeDsymbol(); 1108 ScopeDsymbol *sym = new ScopeDsymbol();
1106 sym->parent = sc->scopesym; 1109 sym->parent = sc->scopesym;
1107 sc = sc->push(sym); 1110 sc = sc->push(sym);
1108 if (init) 1111 if (init)
1109 init = init->semantic(sc); 1112 init = init->semantic(sc);
1120 increment = resolveProperties(sc, increment); 1123 increment = resolveProperties(sc, increment);
1121 } 1124 }
1122 1125
1123 sc->sbreak = this; 1126 sc->sbreak = this;
1124 sc->scontinue = this; 1127 sc->scontinue = this;
1125 body = body->semantic(sc); 1128 if (body)
1129 body = body->semantic(sc);
1126 sc->noctor--; 1130 sc->noctor--;
1127 1131
1128 sc->pop(); 1132 sc->pop();
1129 return this; 1133 return this;
1130 } 1134 }
1169 } 1173 }
1170 else 1174 else
1171 result &= ~BEfallthru; // the body must do the exiting 1175 result &= ~BEfallthru; // the body must do the exiting
1172 if (body) 1176 if (body)
1173 { int r = body->blockExit(); 1177 { int r = body->blockExit();
1174 if (r & BEbreak) 1178 if (r & (BEbreak | BEgoto))
1175 result |= BEfallthru; 1179 result |= BEfallthru;
1176 result |= r & ~(BEbreak | BEcontinue); 1180 result |= r & ~(BEfallthru | BEbreak | BEcontinue);
1177 } 1181 }
1178 if (increment && increment->canThrow()) 1182 if (increment && increment->canThrow())
1179 result |= BEthrow; 1183 result |= BEthrow;
1180 return result; 1184 return result;
1181 } 1185 }
1182 1186
1183 int ForStatement::fallOffEnd()
1184 {
1185 if (body)
1186 body->fallOffEnd();
1187 return TRUE;
1188 }
1189 1187
1190 int ForStatement::comeFrom() 1188 int ForStatement::comeFrom()
1191 { 1189 {
1192 //printf("ForStatement::comeFrom()\n"); 1190 //printf("ForStatement::comeFrom()\n");
1193 if (body) 1191 if (body)
1202 { 1200 {
1203 buf->writestring("for ("); 1201 buf->writestring("for (");
1204 if (init) 1202 if (init)
1205 { 1203 {
1206 hgs->FLinit.init++; 1204 hgs->FLinit.init++;
1207 hgs->FLinit.decl = 0;
1208 init->toCBuffer(buf, hgs); 1205 init->toCBuffer(buf, hgs);
1209 if (hgs->FLinit.decl > 0)
1210 buf->writebyte(';');
1211 hgs->FLinit.decl = 0;
1212 hgs->FLinit.init--; 1206 hgs->FLinit.init--;
1213 } 1207 }
1214 else 1208 else
1215 buf->writebyte(';'); 1209 buf->writebyte(';');
1216 if (condition) 1210 if (condition)
1239 { 1233 {
1240 this->op = op; 1234 this->op = op;
1241 this->arguments = arguments; 1235 this->arguments = arguments;
1242 this->aggr = aggr; 1236 this->aggr = aggr;
1243 this->body = body; 1237 this->body = body;
1244 this->enclosinghandler = NULL;
1245 1238
1246 this->key = NULL; 1239 this->key = NULL;
1247 this->value = NULL; 1240 this->value = NULL;
1248 1241
1249 this->func = NULL; 1242 this->func = NULL;
1267 TypeAArray *taa = NULL; 1260 TypeAArray *taa = NULL;
1268 1261
1269 Type *tn = NULL; 1262 Type *tn = NULL;
1270 Type *tnv = NULL; 1263 Type *tnv = NULL;
1271 1264
1272 enclosinghandler = sc->tfOfTry;
1273
1274 func = sc->func; 1265 func = sc->func;
1275 if (func->fes) 1266 if (func->fes)
1276 func = func->fes->func; 1267 func = func->fes->func;
1277 1268
1278 aggr = aggr->semantic(sc); 1269 aggr = aggr->semantic(sc);
1282 { 1273 {
1283 error("invalid foreach aggregate %s", aggr->toChars()); 1274 error("invalid foreach aggregate %s", aggr->toChars());
1284 return this; 1275 return this;
1285 } 1276 }
1286 1277
1287 inferApplyArgTypes(op, arguments, aggr); 1278 inferApplyArgTypes(op, arguments, aggr, sc->module);
1288 1279
1289 /* Check for inference errors 1280 /* Check for inference errors
1290 */ 1281 */
1291 if (dim != arguments->dim) 1282 if (dim != arguments->dim)
1292 { 1283 {
1334 if (dim == 2) 1325 if (dim == 2)
1335 { // Declare key 1326 { // Declare key
1336 if (arg->storageClass & (STCout | STCref | STClazy)) 1327 if (arg->storageClass & (STCout | STCref | STClazy))
1337 error("no storage class for key %s", arg->ident->toChars()); 1328 error("no storage class for key %s", arg->ident->toChars());
1338 TY keyty = arg->type->ty; 1329 TY keyty = arg->type->ty;
1339 if (global.params.is64bit) 1330 if (keyty != Tint32 && keyty != Tuns32)
1340 { 1331 {
1341 if (keyty != Tint32 && keyty != Tuns32 && keyty != Tint64 && keyty != Tuns64) 1332 if (global.params.is64bit)
1342 { 1333 {
1343 error("foreach: key type must be int, uint, long or ulong, not %s", key->type->toChars()); 1334 if (keyty != Tint64 && keyty != Tuns64)
1344 } 1335 error("foreach: key type must be int or uint, long or ulong, not %s", arg->type->toChars());
1345 } 1336 }
1346 else if (keyty != Tint32 && keyty != Tuns32) 1337 else
1347 { 1338 error("foreach: key type must be int or uint, not %s", arg->type->toChars());
1348 error("foreach: key type must be int or uint, not %s", key->type->toChars()); 1339 }
1349 }
1350 Initializer *ie = new ExpInitializer(0, new IntegerExp(k)); 1340 Initializer *ie = new ExpInitializer(0, new IntegerExp(k));
1351 VarDeclaration *var = new VarDeclaration(loc, arg->type, arg->ident, ie); 1341 VarDeclaration *var = new VarDeclaration(loc, arg->type, arg->ident, ie);
1352 var->storage_class |= STCmanifest; 1342 var->storage_class |= STCmanifest;
1353 DeclarationExp *de = new DeclarationExp(loc, var); 1343 DeclarationExp *de = new DeclarationExp(loc, var);
1354 st->push(new ExpStatement(loc, de)); 1344 st->push(new ExpStatement(loc, de));
1441 Argument *arg = (Argument *)arguments->data[i]; 1431 Argument *arg = (Argument *)arguments->data[i];
1442 VarDeclaration *var; 1432 VarDeclaration *var;
1443 1433
1444 var = new VarDeclaration(loc, arg->type, arg->ident, NULL); 1434 var = new VarDeclaration(loc, arg->type, arg->ident, NULL);
1445 var->storage_class |= STCforeach; 1435 var->storage_class |= STCforeach;
1446 var->storage_class |= arg->storageClass & (STCin | STCout | STCref | STCconst | STCinvariant); 1436 var->storage_class |= arg->storageClass & (STCin | STCout | STCref | STC_TYPECTOR);
1447 if (dim == 2 && i == 0) 1437 if (dim == 2 && i == 0)
1448 { key = var; 1438 { key = var;
1449 //var->storage_class |= STCfinal; 1439 //var->storage_class |= STCfinal;
1450 } 1440 }
1451 else 1441 else
1479 else 1469 else
1480 error("foreach: %s is not an array of %s", 1470 error("foreach: %s is not an array of %s",
1481 tab->toChars(), value->type->toChars()); 1471 tab->toChars(), value->type->toChars());
1482 } 1472 }
1483 1473
1484 if (key) 1474 if (key && key->type->ty != Tint32 && key->type->ty != Tuns32)
1485 { 1475 {
1486 if (global.params.is64bit) 1476 if (global.params.is64bit)
1487 { 1477 {
1488 if (key->type->ty != Tint32 && key->type->ty != Tuns32 && key->type->ty != Tint64 && key->type->ty != Tuns64) 1478 if (key->type->ty != Tint64 && key->type->ty != Tuns64)
1489 { 1479 error("foreach: key type must be int or uint, long or ulong, not %s", key->type->toChars());
1490 error("foreach: key type must be int, uint, long or ulong, not %s", key->type->toChars()); 1480 }
1491 } 1481 else
1492 } 1482 error("foreach: key type must be int or uint, not %s", key->type->toChars());
1493 else if (key->type->ty != Tint32 && key->type->ty != Tuns32) 1483 }
1494 {
1495 error("foreach: key type must be int or uint, not %s", key->type->toChars());
1496 }
1497 }
1498 1484
1499 if (key && key->storage_class & (STCout | STCref)) 1485 if (key && key->storage_class & (STCout | STCref))
1500 error("foreach: key cannot be out or ref"); 1486 error("foreach: key cannot be out or ref");
1501 break; 1487 break;
1502 1488
1519 case Tclass: 1505 case Tclass:
1520 case Tstruct: 1506 case Tstruct:
1521 #if DMDV2 1507 #if DMDV2
1522 { /* Look for range iteration, i.e. the properties 1508 { /* Look for range iteration, i.e. the properties
1523 * .empty, .next, .retreat, .head and .rear 1509 * .empty, .next, .retreat, .head and .rear
1524 * foreach (e; range) { ... } 1510 * foreach (e; aggr) { ... }
1525 * translates to: 1511 * translates to:
1526 * for (auto __r = range; !__r.empty; __r.next) 1512 * for (auto __r = aggr[]; !__r.empty; __r.next)
1527 * { auto e = __r.head; 1513 * { auto e = __r.head;
1528 * ... 1514 * ...
1529 * } 1515 * }
1530 */ 1516 */
1531 if (dim != 1) // only one argument allowed with ranges 1517 if (dim != 1) // only one argument allowed with ranges
1548 goto Lapply; 1534 goto Lapply;
1549 1535
1550 /* Generate a temporary __r and initialize it with the aggregate. 1536 /* Generate a temporary __r and initialize it with the aggregate.
1551 */ 1537 */
1552 Identifier *id = Identifier::generateId("__r"); 1538 Identifier *id = Identifier::generateId("__r");
1553 VarDeclaration *r = new VarDeclaration(loc, NULL, id, new ExpInitializer(loc, aggr)); 1539 aggr = aggr->semantic(sc);
1554 r->semantic(sc); 1540 Expression *rinit = new SliceExp(loc, aggr, NULL, NULL);
1541 rinit = rinit->trySemantic(sc);
1542 if (!rinit) // if application of [] failed
1543 rinit = aggr;
1544 VarDeclaration *r = new VarDeclaration(loc, NULL, id, new ExpInitializer(loc, rinit));
1545 // r->semantic(sc);
1546 //printf("r: %s, init: %s\n", r->toChars(), r->init->toChars());
1555 Statement *init = new DeclarationStatement(loc, r); 1547 Statement *init = new DeclarationStatement(loc, r);
1548 //printf("init: %s\n", init->toChars());
1556 1549
1557 // !__r.empty 1550 // !__r.empty
1558 Expression *e = new VarExp(loc, r); 1551 Expression *e = new VarExp(loc, r);
1559 e = new DotIdExp(loc, e, Id::Fempty); 1552 e = new DotIdExp(loc, e, Id::Fempty);
1560 Expression *condition = new NotExp(loc, e); 1553 Expression *condition = new NotExp(loc, e);
1566 /* Declaration statement for e: 1559 /* Declaration statement for e:
1567 * auto e = __r.idhead; 1560 * auto e = __r.idhead;
1568 */ 1561 */
1569 e = new VarExp(loc, r); 1562 e = new VarExp(loc, r);
1570 Expression *einit = new DotIdExp(loc, e, idhead); 1563 Expression *einit = new DotIdExp(loc, e, idhead);
1571 einit = einit->semantic(sc); 1564 // einit = einit->semantic(sc);
1572 Argument *arg = (Argument *)arguments->data[0]; 1565 Argument *arg = (Argument *)arguments->data[0];
1573 VarDeclaration *ve = new VarDeclaration(loc, arg->type, arg->ident, new ExpInitializer(loc, einit)); 1566 VarDeclaration *ve = new VarDeclaration(loc, arg->type, arg->ident, new ExpInitializer(loc, einit));
1574 ve->storage_class |= STCforeach; 1567 ve->storage_class |= STCforeach;
1575 ve->storage_class |= arg->storageClass & (STCin | STCout | STCref | STCconst | STCinvariant); 1568 ve->storage_class |= arg->storageClass & (STCin | STCout | STCref | STC_TYPECTOR);
1576 1569
1577 DeclarationExp *de = new DeclarationExp(loc, ve); 1570 DeclarationExp *de = new DeclarationExp(loc, ve);
1578 1571
1579 Statement *body = new CompoundStatement(loc, 1572 Statement *body = new CompoundStatement(loc,
1580 new DeclarationStatement(loc, de), this->body); 1573 new DeclarationStatement(loc, de), this->body);
1581 1574
1582 s = new ForStatement(loc, init, condition, increment, body); 1575 s = new ForStatement(loc, init, condition, increment, body);
1576 #if 0
1577 printf("init: %s\n", init->toChars());
1578 printf("condition: %s\n", condition->toChars());
1579 printf("increment: %s\n", increment->toChars());
1580 printf("body: %s\n", body->toChars());
1581 #endif
1583 s = s->semantic(sc); 1582 s = s->semantic(sc);
1584 break; 1583 break;
1585 } 1584 }
1586 #endif 1585 #endif
1587 case Tdelegate: 1586 case Tdelegate:
1599 TypeDelegate* dgty; 1598 TypeDelegate* dgty;
1600 TypeDelegate* dgty2; 1599 TypeDelegate* dgty2;
1601 TypeDelegate* fldeTy; 1600 TypeDelegate* fldeTy;
1602 1601
1603 if (!checkForArgTypes()) 1602 if (!checkForArgTypes())
1603 { body = body->semantic(sc);
1604 return this; 1604 return this;
1605 }
1605 1606
1606 tret = func->type->nextOf(); 1607 tret = func->type->nextOf();
1607 1608
1608 // Need a variable to hold value from any return statements in body. 1609 // Need a variable to hold value from any return statements in body.
1609 if (!sc->func->vresult && tret && tret != Type::tvoid) 1610 if (!sc->func->vresult && tret && tret != Type::tvoid)
1727 { 1728 {
1728 flde = new CastExp(loc, flde, flde->type); 1729 flde = new CastExp(loc, flde, flde->type);
1729 flde->type = fldeTy; 1730 flde->type = fldeTy;
1730 } 1731 }
1731 exps->push(flde); 1732 exps->push(flde);
1732
1733 e = new CallExp(loc, ec, exps); 1733 e = new CallExp(loc, ec, exps);
1734 e->type = Type::tindex; // don't run semantic() on e 1734 e->type = Type::tindex; // don't run semantic() on e
1735 } 1735 }
1736 else if (tab->ty == Tarray || tab->ty == Tsarray) 1736 else if (tab->ty == Tarray || tab->ty == Tsarray)
1737 { 1737 {
1759 case Twchar: flag += 1; break; 1759 case Twchar: flag += 1; break;
1760 case Tdchar: flag += 2; break; 1760 case Tdchar: flag += 2; break;
1761 default: assert(0); 1761 default: assert(0);
1762 } 1762 }
1763 const char *r = (op == TOKforeach_reverse) ? "R" : ""; 1763 const char *r = (op == TOKforeach_reverse) ? "R" : "";
1764 int j = sprintf(fdname, "_aApply%s%.*s%d", r, 2, fntab[flag], dim); 1764 #ifdef __MINGW32__
1765 int j = sprintf(fdname, "_aApply%s%.*s%lu", r, 2, fntab[flag], dim);
1766 #else
1767 int j = sprintf(fdname, "_aApply%s%.*s%zu", r, 2, fntab[flag], dim);
1768 #endif
1765 assert(j < sizeof(fdname)); 1769 assert(j < sizeof(fdname));
1766 //LDC: Build arguments. 1770 //LDC: Build arguments.
1767 Arguments* args = new Arguments; 1771 Arguments* args = new Arguments;
1768 args->push(new Argument(STCin, tn->arrayOf(), NULL, NULL)); 1772 args->push(new Argument(STCin, tn->arrayOf(), NULL, NULL));
1769 if (dim == 2) { 1773 if (dim == 2) {
1792 { 1796 {
1793 flde = new CastExp(loc, flde, flde->type); 1797 flde = new CastExp(loc, flde, flde->type);
1794 flde->type = dgty; 1798 flde->type = dgty;
1795 } 1799 }
1796 exps->push(flde); 1800 exps->push(flde);
1797
1798 e = new CallExp(loc, ec, exps); 1801 e = new CallExp(loc, ec, exps);
1799 e->type = Type::tindex; // don't run semantic() on e 1802 e->type = Type::tindex; // don't run semantic() on e
1800 } 1803 }
1801 else if (tab->ty == Tdelegate) 1804 else if (tab->ty == Tdelegate)
1802 { 1805 {
1873 break; 1876 break;
1874 } 1877 }
1875 1878
1876 default: 1879 default:
1877 error("foreach: %s is not an aggregate type", aggr->type->toChars()); 1880 error("foreach: %s is not an aggregate type", aggr->type->toChars());
1881 s = NULL; // error recovery
1878 break; 1882 break;
1879 } 1883 }
1880 sc->noctor--; 1884 sc->noctor--;
1881 sc->pop(); 1885 sc->pop();
1882 return s; 1886 return s;
1883 } 1887 }
1884 1888
1885 bool ForeachStatement::checkForArgTypes() 1889 bool ForeachStatement::checkForArgTypes()
1886 { 1890 { bool result = TRUE;
1891
1887 for (size_t i = 0; i < arguments->dim; i++) 1892 for (size_t i = 0; i < arguments->dim; i++)
1888 { Argument *arg = (Argument *)arguments->data[i]; 1893 { Argument *arg = (Argument *)arguments->data[i];
1889 if (!arg->type) 1894 if (!arg->type)
1890 { 1895 {
1891 error("cannot infer type for %s", arg->ident->toChars()); 1896 error("cannot infer type for %s", arg->ident->toChars());
1892 return FALSE; 1897 arg->type = Type::terror;
1893 } 1898 result = FALSE;
1894 } 1899 }
1895 return TRUE; 1900 }
1901 return result;
1896 } 1902 }
1897 1903
1898 int ForeachStatement::hasBreak() 1904 int ForeachStatement::hasBreak()
1899 { 1905 {
1900 return TRUE; 1906 return TRUE;
1921 result |= body->blockExit() & ~(BEbreak | BEcontinue); 1927 result |= body->blockExit() & ~(BEbreak | BEcontinue);
1922 } 1928 }
1923 return result; 1929 return result;
1924 } 1930 }
1925 1931
1926 int ForeachStatement::fallOffEnd()
1927 {
1928 if (body)
1929 body->fallOffEnd();
1930 return TRUE;
1931 }
1932 1932
1933 int ForeachStatement::comeFrom() 1933 int ForeachStatement::comeFrom()
1934 { 1934 {
1935 if (body) 1935 if (body)
1936 return body->comeFrom(); 1936 return body->comeFrom();
1978 this->arg = arg; 1978 this->arg = arg;
1979 this->lwr = lwr; 1979 this->lwr = lwr;
1980 this->upr = upr; 1980 this->upr = upr;
1981 this->body = body; 1981 this->body = body;
1982 1982
1983 this->enclosinghandler = NULL;
1984
1985 this->key = NULL; 1983 this->key = NULL;
1986 } 1984 }
1987 1985
1988 Statement *ForeachRangeStatement::syntaxCopy() 1986 Statement *ForeachRangeStatement::syntaxCopy()
1989 { 1987 {
1999 { 1997 {
2000 //printf("ForeachRangeStatement::semantic() %p\n", this); 1998 //printf("ForeachRangeStatement::semantic() %p\n", this);
2001 ScopeDsymbol *sym; 1999 ScopeDsymbol *sym;
2002 Statement *s = this; 2000 Statement *s = this;
2003 2001
2004 enclosinghandler = sc->tfOfTry;
2005
2006 lwr = lwr->semantic(sc); 2002 lwr = lwr->semantic(sc);
2007 lwr = resolveProperties(sc, lwr); 2003 lwr = resolveProperties(sc, lwr);
2008 lwr = lwr->optimize(WANTvalue); 2004 lwr = lwr->optimize(WANTvalue);
2009 if (!lwr->type) 2005 if (!lwr->type)
2010 { 2006 {
2021 return this; 2017 return this;
2022 } 2018 }
2023 2019
2024 if (arg->type) 2020 if (arg->type)
2025 { 2021 {
2022 arg->type = arg->type->semantic(loc, sc);
2026 lwr = lwr->implicitCastTo(sc, arg->type); 2023 lwr = lwr->implicitCastTo(sc, arg->type);
2027 upr = upr->implicitCastTo(sc, arg->type); 2024 upr = upr->implicitCastTo(sc, arg->type);
2028 } 2025 }
2029 else 2026 else
2030 { 2027 {
2089 result |= body->blockExit() & ~(BEbreak | BEcontinue); 2086 result |= body->blockExit() & ~(BEbreak | BEcontinue);
2090 } 2087 }
2091 return result; 2088 return result;
2092 } 2089 }
2093 2090
2094 int ForeachRangeStatement::fallOffEnd()
2095 {
2096 if (body)
2097 body->fallOffEnd();
2098 return TRUE;
2099 }
2100 2091
2101 int ForeachRangeStatement::comeFrom() 2092 int ForeachRangeStatement::comeFrom()
2102 { 2093 {
2103 if (body) 2094 if (body)
2104 return body->comeFrom(); 2095 return body->comeFrom();
2195 */ 2186 */
2196 VarExp *v = new VarExp(0, match); 2187 VarExp *v = new VarExp(0, match);
2197 condition = new AssignExp(loc, v, condition); 2188 condition = new AssignExp(loc, v, condition);
2198 condition = condition->semantic(scd); 2189 condition = condition->semantic(scd);
2199 } 2190 }
2200
2201 else 2191 else
2202 scd = sc->push(); 2192 scd = sc->push();
2203 ifbody = ifbody->semantic(scd); 2193 ifbody = ifbody->semantic(scd);
2204 scd->pop(); 2194 scd->pop();
2205 2195
2249 else 2239 else
2250 result |= BEfallthru; 2240 result |= BEfallthru;
2251 } 2241 }
2252 //printf("IfStatement::blockExit(%p) = x%x\n", this, result); 2242 //printf("IfStatement::blockExit(%p) = x%x\n", this, result);
2253 return result; 2243 return result;
2254 }
2255
2256 int IfStatement::fallOffEnd()
2257 {
2258 if (!ifbody || ifbody->fallOffEnd() ||
2259 !elsebody || elsebody->fallOffEnd())
2260 return TRUE;
2261 return FALSE;
2262 } 2244 }
2263 2245
2264 2246
2265 void IfStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2247 void IfStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
2266 { 2248 {
2412 e = e->semantic(sc); 2394 e = e->semantic(sc);
2413 e = e->optimize(WANTvalue | WANTinterpret); 2395 e = e->optimize(WANTvalue | WANTinterpret);
2414 if (e->op == TOKstring) 2396 if (e->op == TOKstring)
2415 { 2397 {
2416 StringExp *se = (StringExp *)e; 2398 StringExp *se = (StringExp *)e;
2417 fprintf(stdmsg, "%.*s", (int)se->len, se->string); 2399 fprintf(stdmsg, "%.*s", (int)se->len, (char*)se->string);
2418 } 2400 }
2419 else 2401 else
2420 error("string expected for message, not '%s'", e->toChars()); 2402 error("string expected for message, not '%s'", e->toChars());
2421 } 2403 }
2422 fprintf(stdmsg, "\n"); 2404 fprintf(stdmsg, "\n");
2450 mem.free(name); 2432 mem.free(name);
2451 } 2433 }
2452 } 2434 }
2453 #endif 2435 #endif
2454 } 2436 }
2437
2438 // LDC
2439 else if (ident == Id::allow_inline)
2440 {
2441 sc->func->allowInlining = true;
2442 }
2443
2455 else if (ident == Id::startaddress) 2444 else if (ident == Id::startaddress)
2456 { 2445 {
2457 if (!args || args->dim != 1) 2446 if (!args || args->dim != 1)
2458 error("function name expected for start address"); 2447 error("function name expected for start address");
2459 else 2448 else
2470 body = body->semantic(sc); 2459 body = body->semantic(sc);
2471 } 2460 }
2472 return this; 2461 return this;
2473 } 2462 }
2474 } 2463 }
2475
2476 // LDC
2477 else if (ident == Id::allow_inline)
2478 {
2479 sc->func->allowInlining = true;
2480 }
2481
2482 else 2464 else
2483 error("unrecognized pragma(%s)", ident->toChars()); 2465 error("unrecognized pragma(%s)", ident->toChars());
2484 2466
2485 if (body) 2467 if (body)
2486 { 2468 {
2504 result |= body->blockExit(); 2486 result |= body->blockExit();
2505 #endif 2487 #endif
2506 return result; 2488 return result;
2507 } 2489 }
2508 2490
2509 int PragmaStatement::fallOffEnd()
2510 {
2511 if (body)
2512 return body->fallOffEnd();
2513 return TRUE;
2514 }
2515 2491
2516 void PragmaStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2492 void PragmaStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
2517 { 2493 {
2518 buf->writestring("pragma ("); 2494 buf->writestring("pragma (");
2519 buf->writestring(ident->toChars()); 2495 buf->writestring(ident->toChars());
2574 : Statement(loc) 2550 : Statement(loc)
2575 { 2551 {
2576 condition = c; 2552 condition = c;
2577 body = b; 2553 body = b;
2578 sdefault = NULL; 2554 sdefault = NULL;
2579 tf = NULL;
2580 cases = NULL; 2555 cases = NULL;
2581 hasNoDefault = 0; 2556 hasNoDefault = 0;
2582 hasVars = 0; 2557 hasVars = 0;
2583 // LDC 2558 // LDC
2584 enclosinghandler = NULL; 2559 enclosingScopeExit = NULL;
2585 } 2560 }
2586 2561
2587 Statement *SwitchStatement::syntaxCopy() 2562 Statement *SwitchStatement::syntaxCopy()
2588 { 2563 {
2589 SwitchStatement *s = new SwitchStatement(loc, 2564 SwitchStatement *s = new SwitchStatement(loc,
2592 } 2567 }
2593 2568
2594 Statement *SwitchStatement::semantic(Scope *sc) 2569 Statement *SwitchStatement::semantic(Scope *sc)
2595 { 2570 {
2596 //printf("SwitchStatement::semantic(%p)\n", this); 2571 //printf("SwitchStatement::semantic(%p)\n", this);
2597 tf = sc->tf;
2598 assert(!cases); // ensure semantic() is only run once 2572 assert(!cases); // ensure semantic() is only run once
2599 2573
2600 enclosinghandler = sc->tfOfTry; 2574 // LDC
2575 enclosingScopeExit = sc->enclosingScopeExit;
2601 2576
2602 condition = condition->semantic(sc); 2577 condition = condition->semantic(sc);
2603 condition = resolveProperties(sc, condition); 2578 condition = resolveProperties(sc, condition);
2604 if (condition->type->isString()) 2579 if (condition->type->isString())
2605 { 2580 {
2658 } 2633 }
2659 2634
2660 if (!sc->sw->sdefault) 2635 if (!sc->sw->sdefault)
2661 { hasNoDefault = 1; 2636 { hasNoDefault = 1;
2662 2637
2663 if (global.params.warnings) 2638 warning("switch statement has no default");
2664 { warning("%s: switch statement has no default", loc.toChars());
2665 }
2666 2639
2667 // Generate runtime error if the default is hit 2640 // Generate runtime error if the default is hit
2668 Statements *a = new Statements(); 2641 Statements *a = new Statements();
2669 CompoundStatement *cs; 2642 CompoundStatement *cs;
2670 Statement *s; 2643 Statement *s;
2676 s = new ExpStatement(loc, e); 2649 s = new ExpStatement(loc, e);
2677 } 2650 }
2678 2651
2679 a->reserve(4); 2652 a->reserve(4);
2680 a->push(body); 2653 a->push(body);
2681 a->push(new BreakStatement(loc, NULL)); 2654
2655 // LDC needs semantic to be run on break
2656 Statement *breakstmt = new BreakStatement(loc, NULL);
2657 breakstmt->semantic(sc);
2658 a->push(breakstmt);
2659
2682 sc->sw->sdefault = new DefaultStatement(loc, s); 2660 sc->sw->sdefault = new DefaultStatement(loc, s);
2683 a->push(sc->sw->sdefault); 2661 a->push(sc->sw->sdefault);
2684 cs = new CompoundStatement(loc, a); 2662 cs = new CompoundStatement(loc, a);
2685 body = cs; 2663 body = cs;
2686 } 2664 }
2715 result |= BEfallthru; 2693 result |= BEfallthru;
2716 2694
2717 return result; 2695 return result;
2718 } 2696 }
2719 2697
2720 int SwitchStatement::fallOffEnd()
2721 {
2722 if (body)
2723 body->fallOffEnd();
2724 return TRUE; // need to do this better
2725 }
2726 2698
2727 void SwitchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2699 void SwitchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
2728 { 2700 {
2729 buf->writestring("switch ("); 2701 buf->writestring("switch (");
2730 condition->toCBuffer(buf, hgs); 2702 condition->toCBuffer(buf, hgs);
2755 this->statement = s; 2727 this->statement = s;
2756 index = 0; 2728 index = 0;
2757 cblock = NULL; 2729 cblock = NULL;
2758 bodyBB = NULL; 2730 bodyBB = NULL;
2759 llvmIdx = NULL; 2731 llvmIdx = NULL;
2732 // LDC
2733 enclosingScopeExit = NULL;
2760 } 2734 }
2761 2735
2762 Statement *CaseStatement::syntaxCopy() 2736 Statement *CaseStatement::syntaxCopy()
2763 { 2737 {
2764 CaseStatement *s = new CaseStatement(loc, exp->syntaxCopy(), statement->syntaxCopy()); 2738 CaseStatement *s = new CaseStatement(loc, exp->syntaxCopy(), statement->syntaxCopy());
2770 2744
2771 //printf("CaseStatement::semantic() %s\n", toChars()); 2745 //printf("CaseStatement::semantic() %s\n", toChars());
2772 exp = exp->semantic(sc); 2746 exp = exp->semantic(sc);
2773 if (sw) 2747 if (sw)
2774 { 2748 {
2749 // LDC
2750 enclosingScopeExit = sc->enclosingScopeExit;
2751 if (enclosingScopeExit != sw->enclosingScopeExit)
2752 {
2753 error("case must be inside the same try, synchronized or volatile level as switch");
2754 }
2755
2775 exp = exp->implicitCastTo(sc, sw->condition->type); 2756 exp = exp->implicitCastTo(sc, sw->condition->type);
2776 exp = exp->optimize(WANTvalue | WANTinterpret); 2757 exp = exp->optimize(WANTvalue | WANTinterpret);
2777 2758
2778 /* This is where variables are allowed as case expressions. 2759 /* This is where variables are allowed as case expressions.
2779 */ 2760 */
2819 { 2800 {
2820 gcs->cs = this; 2801 gcs->cs = this;
2821 sw->gotoCases.remove(i); // remove from array 2802 sw->gotoCases.remove(i); // remove from array
2822 } 2803 }
2823 } 2804 }
2824 2805 #if IN_DMD
2825 if (sc->sw->tf != sc->tf) 2806 if (sc->sw->tf != sc->tf)
2826 error("switch and case are in different finally blocks"); 2807 error("switch and case are in different finally blocks");
2808 #endif
2827 } 2809 }
2828 else 2810 else
2829 error("case not in switch statement"); 2811 error("case not in switch statement");
2830 statement = statement->semantic(sc); 2812 statement = statement->semantic(sc);
2831 return this; 2813 return this;
2847 int CaseStatement::blockExit() 2829 int CaseStatement::blockExit()
2848 { 2830 {
2849 return statement->blockExit(); 2831 return statement->blockExit();
2850 } 2832 }
2851 2833
2852 int CaseStatement::fallOffEnd()
2853 {
2854 return statement->fallOffEnd();
2855 }
2856 2834
2857 int CaseStatement::comeFrom() 2835 int CaseStatement::comeFrom()
2858 { 2836 {
2859 return TRUE; 2837 return TRUE;
2860 } 2838 }
2876 this->statement = s; 2854 this->statement = s;
2877 #if IN_GCC 2855 #if IN_GCC
2878 + cblock = NULL; 2856 + cblock = NULL;
2879 #endif 2857 #endif
2880 bodyBB = NULL; 2858 bodyBB = NULL;
2859 // LDC
2860 enclosingScopeExit = NULL;
2881 } 2861 }
2882 2862
2883 Statement *DefaultStatement::syntaxCopy() 2863 Statement *DefaultStatement::syntaxCopy()
2884 { 2864 {
2885 DefaultStatement *s = new DefaultStatement(loc, statement->syntaxCopy()); 2865 DefaultStatement *s = new DefaultStatement(loc, statement->syntaxCopy());
2895 { 2875 {
2896 error("switch statement already has a default"); 2876 error("switch statement already has a default");
2897 } 2877 }
2898 sc->sw->sdefault = this; 2878 sc->sw->sdefault = this;
2899 2879
2900 if (sc->sw->tf != sc->tf) 2880 // LDC
2901 error("switch and default are in different finally blocks"); 2881 enclosingScopeExit = sc->enclosingScopeExit;
2882 if (enclosingScopeExit != sc->sw->enclosingScopeExit)
2883 {
2884 error("default must be inside the same try, synchronized or volatile level as switch");
2885 }
2902 } 2886 }
2903 else 2887 else
2904 error("default not in switch statement"); 2888 error("default not in switch statement");
2905 statement = statement->semantic(sc); 2889 statement = statement->semantic(sc);
2906 return this; 2890 return this;
2914 int DefaultStatement::blockExit() 2898 int DefaultStatement::blockExit()
2915 { 2899 {
2916 return statement->blockExit(); 2900 return statement->blockExit();
2917 } 2901 }
2918 2902
2919 int DefaultStatement::fallOffEnd()
2920 {
2921 return statement->fallOffEnd();
2922 }
2923 2903
2924 int DefaultStatement::comeFrom() 2904 int DefaultStatement::comeFrom()
2925 { 2905 {
2926 return TRUE; 2906 return TRUE;
2927 } 2907 }
2936 2916
2937 GotoDefaultStatement::GotoDefaultStatement(Loc loc) 2917 GotoDefaultStatement::GotoDefaultStatement(Loc loc)
2938 : Statement(loc) 2918 : Statement(loc)
2939 { 2919 {
2940 sw = NULL; 2920 sw = NULL;
2941 enclosinghandler = NULL;
2942 } 2921 }
2943 2922
2944 Statement *GotoDefaultStatement::syntaxCopy() 2923 Statement *GotoDefaultStatement::syntaxCopy()
2945 { 2924 {
2946 GotoDefaultStatement *s = new GotoDefaultStatement(loc); 2925 GotoDefaultStatement *s = new GotoDefaultStatement(loc);
2947 return s; 2926 return s;
2948 } 2927 }
2949 2928
2950 Statement *GotoDefaultStatement::semantic(Scope *sc) 2929 Statement *GotoDefaultStatement::semantic(Scope *sc)
2951 { 2930 {
2952 enclosinghandler = sc->tfOfTry;
2953 sw = sc->sw; 2931 sw = sc->sw;
2954 if (!sw) 2932 if (!sw)
2955 error("goto default not in switch statement"); 2933 error("goto default not in switch statement");
2956 return this; 2934 return this;
2957 } 2935 }
2959 int GotoDefaultStatement::blockExit() 2937 int GotoDefaultStatement::blockExit()
2960 { 2938 {
2961 return BEgoto; 2939 return BEgoto;
2962 } 2940 }
2963 2941
2964 int GotoDefaultStatement::fallOffEnd()
2965 {
2966 return FALSE;
2967 }
2968 2942
2969 void GotoDefaultStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2943 void GotoDefaultStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
2970 { 2944 {
2971 buf->writestring("goto default;\n"); 2945 buf->writestring("goto default;\n");
2972 } 2946 }
2976 GotoCaseStatement::GotoCaseStatement(Loc loc, Expression *exp) 2950 GotoCaseStatement::GotoCaseStatement(Loc loc, Expression *exp)
2977 : Statement(loc) 2951 : Statement(loc)
2978 { 2952 {
2979 cs = NULL; 2953 cs = NULL;
2980 this->exp = exp; 2954 this->exp = exp;
2981 enclosinghandler = NULL;
2982 sw = NULL; 2955 sw = NULL;
2983 } 2956 }
2984 2957
2985 Statement *GotoCaseStatement::syntaxCopy() 2958 Statement *GotoCaseStatement::syntaxCopy()
2986 { 2959 {
2989 return s; 2962 return s;
2990 } 2963 }
2991 2964
2992 Statement *GotoCaseStatement::semantic(Scope *sc) 2965 Statement *GotoCaseStatement::semantic(Scope *sc)
2993 { 2966 {
2994 enclosinghandler = sc->tfOfTry;
2995 if (exp) 2967 if (exp)
2996 exp = exp->semantic(sc); 2968 exp = exp->semantic(sc);
2997 2969
2998 if (!sc->sw) 2970 if (!sc->sw)
2999 error("goto case not in switch statement"); 2971 error("goto case not in switch statement");
3013 int GotoCaseStatement::blockExit() 2985 int GotoCaseStatement::blockExit()
3014 { 2986 {
3015 return BEgoto; 2987 return BEgoto;
3016 } 2988 }
3017 2989
3018 int GotoCaseStatement::fallOffEnd()
3019 {
3020 return FALSE;
3021 }
3022 2990
3023 void GotoCaseStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 2991 void GotoCaseStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3024 { 2992 {
3025 buf->writestring("goto case"); 2993 buf->writestring("goto case");
3026 if (exp) 2994 if (exp)
3041 int SwitchErrorStatement::blockExit() 3009 int SwitchErrorStatement::blockExit()
3042 { 3010 {
3043 return BEthrow; 3011 return BEthrow;
3044 } 3012 }
3045 3013
3046 int SwitchErrorStatement::fallOffEnd()
3047 {
3048 return FALSE;
3049 }
3050 3014
3051 void SwitchErrorStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3015 void SwitchErrorStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3052 { 3016 {
3053 buf->writestring("SwitchErrorStatement::toCBuffer()"); 3017 buf->writestring("SwitchErrorStatement::toCBuffer()");
3054 buf->writenl(); 3018 buf->writenl();
3058 3022
3059 ReturnStatement::ReturnStatement(Loc loc, Expression *exp) 3023 ReturnStatement::ReturnStatement(Loc loc, Expression *exp)
3060 : Statement(loc) 3024 : Statement(loc)
3061 { 3025 {
3062 this->exp = exp; 3026 this->exp = exp;
3063 this->enclosinghandler = NULL;
3064 } 3027 }
3065 3028
3066 Statement *ReturnStatement::syntaxCopy() 3029 Statement *ReturnStatement::syntaxCopy()
3067 { 3030 {
3068 Expression *e = NULL; 3031 Expression *e = NULL;
3073 } 3036 }
3074 3037
3075 Statement *ReturnStatement::semantic(Scope *sc) 3038 Statement *ReturnStatement::semantic(Scope *sc)
3076 { 3039 {
3077 //printf("ReturnStatement::semantic() %s\n", toChars()); 3040 //printf("ReturnStatement::semantic() %s\n", toChars());
3078 this->enclosinghandler = sc->tfOfTry;
3079 3041
3080 FuncDeclaration *fd = sc->parent->isFuncDeclaration(); 3042 FuncDeclaration *fd = sc->parent->isFuncDeclaration();
3081 Scope *scx = sc; 3043 Scope *scx = sc;
3082 int implicit0 = 0; 3044 int implicit0 = 0;
3083 3045
3110 exp = new IntegerExp(0); 3072 exp = new IntegerExp(0);
3111 } 3073 }
3112 3074
3113 if (sc->incontract || scx->incontract) 3075 if (sc->incontract || scx->incontract)
3114 error("return statements cannot be in contracts"); 3076 error("return statements cannot be in contracts");
3115 if (sc->tf || scx->tf) 3077 if (sc->enclosingFinally || scx->enclosingFinally)
3116 error("return statements cannot be in finally, scope(exit) or scope(success) bodies"); 3078 error("return statements cannot be in finally, scope(exit) or scope(success) bodies");
3117 3079
3118 if (fd->isCtorDeclaration()) 3080 if (fd->isCtorDeclaration())
3119 { 3081 {
3120 // Constructors implicitly do: 3082 // Constructors implicitly do:
3183 } 3145 }
3184 } 3146 }
3185 else if (tbret->ty != Tvoid) 3147 else if (tbret->ty != Tvoid)
3186 { 3148 {
3187 exp = exp->implicitCastTo(sc, tret); 3149 exp = exp->implicitCastTo(sc, tret);
3150 exp = exp->optimize(WANTvalue);
3188 } 3151 }
3189 } 3152 }
3190 else if (fd->inferRetType) 3153 else if (fd->inferRetType)
3191 { 3154 {
3192 if (fd->type->nextOf()) 3155 if (fd->type->nextOf())
3271 3234
3272 exp = new AssignExp(loc, v, exp); 3235 exp = new AssignExp(loc, v, exp);
3273 exp = exp->semantic(sc); 3236 exp = exp->semantic(sc);
3274 } 3237 }
3275 3238
3276 if (((TypeFunction *)fd->type)->isref) 3239 if (((TypeFunction *)fd->type)->isref && !fd->isCtorDeclaration())
3277 { // Function returns a reference 3240 { // Function returns a reference
3278 if (tbret->isMutable()) 3241 if (tbret->isMutable())
3279 exp = exp->modifiableLvalue(sc, exp); 3242 exp = exp->modifiableLvalue(sc, exp);
3280 else 3243 else
3281 exp = exp->toLvalue(sc, exp); 3244 exp = exp->toLvalue(sc, exp);
3344 if (exp && exp->canThrow()) 3307 if (exp && exp->canThrow())
3345 result |= BEthrow; 3308 result |= BEthrow;
3346 return result; 3309 return result;
3347 } 3310 }
3348 3311
3349 int ReturnStatement::fallOffEnd()
3350 {
3351 return FALSE;
3352 }
3353 3312
3354 void ReturnStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3313 void ReturnStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3355 { 3314 {
3356 buf->printf("return "); 3315 buf->printf("return ");
3357 if (exp) 3316 if (exp)
3364 3323
3365 BreakStatement::BreakStatement(Loc loc, Identifier *ident) 3324 BreakStatement::BreakStatement(Loc loc, Identifier *ident)
3366 : Statement(loc) 3325 : Statement(loc)
3367 { 3326 {
3368 this->ident = ident; 3327 this->ident = ident;
3369 this->enclosinghandler = NULL;
3370 } 3328 }
3371 3329
3372 Statement *BreakStatement::syntaxCopy() 3330 Statement *BreakStatement::syntaxCopy()
3373 { 3331 {
3374 BreakStatement *s = new BreakStatement(loc, ident); 3332 BreakStatement *s = new BreakStatement(loc, ident);
3376 } 3334 }
3377 3335
3378 Statement *BreakStatement::semantic(Scope *sc) 3336 Statement *BreakStatement::semantic(Scope *sc)
3379 { 3337 {
3380 //printf("BreakStatement::semantic()\n"); 3338 //printf("BreakStatement::semantic()\n");
3381 enclosinghandler = sc->tfOfTry;
3382 // If: 3339 // If:
3383 // break Identifier; 3340 // break Identifier;
3384 if (ident) 3341 if (ident)
3385 { 3342 {
3386 Scope *scx; 3343 Scope *scx;
3414 { 3371 {
3415 Statement *s = ls->statement; 3372 Statement *s = ls->statement;
3416 3373
3417 if (!s->hasBreak()) 3374 if (!s->hasBreak())
3418 error("label '%s' has no break", ident->toChars()); 3375 error("label '%s' has no break", ident->toChars());
3419 if (ls->tf != sc->tf) 3376 if (ls->enclosingFinally != sc->enclosingFinally)
3420 error("cannot break out of finally block"); 3377 error("cannot break out of finally block");
3421 3378
3422 this->target = ls; 3379 this->target = ls;
3423 return this; 3380 return this;
3424 } 3381 }
3443 { 3400 {
3444 //printf("BreakStatement::blockExit(%p) = x%x\n", this, ident ? BEgoto : BEbreak); 3401 //printf("BreakStatement::blockExit(%p) = x%x\n", this, ident ? BEgoto : BEbreak);
3445 return ident ? BEgoto : BEbreak; 3402 return ident ? BEgoto : BEbreak;
3446 } 3403 }
3447 3404
3448 int BreakStatement::fallOffEnd()
3449 {
3450 return FALSE;
3451 }
3452 3405
3453 void BreakStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3406 void BreakStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3454 { 3407 {
3455 buf->writestring("break"); 3408 buf->writestring("break");
3456 if (ident) 3409 if (ident)
3465 3418
3466 ContinueStatement::ContinueStatement(Loc loc, Identifier *ident) 3419 ContinueStatement::ContinueStatement(Loc loc, Identifier *ident)
3467 : Statement(loc) 3420 : Statement(loc)
3468 { 3421 {
3469 this->ident = ident; 3422 this->ident = ident;
3470 this->enclosinghandler = NULL;
3471 } 3423 }
3472 3424
3473 Statement *ContinueStatement::syntaxCopy() 3425 Statement *ContinueStatement::syntaxCopy()
3474 { 3426 {
3475 ContinueStatement *s = new ContinueStatement(loc, ident); 3427 ContinueStatement *s = new ContinueStatement(loc, ident);
3476 return s; 3428 return s;
3477 } 3429 }
3478 3430
3479 Statement *ContinueStatement::semantic(Scope *sc) 3431 Statement *ContinueStatement::semantic(Scope *sc)
3480 { 3432 {
3481 enclosinghandler = sc->tfOfTry;
3482 //printf("ContinueStatement::semantic() %p\n", this); 3433 //printf("ContinueStatement::semantic() %p\n", this);
3483 if (ident) 3434 if (ident)
3484 { 3435 {
3485 Scope *scx; 3436 Scope *scx;
3486 FuncDeclaration *thisfunc = sc->func; 3437 FuncDeclaration *thisfunc = sc->func;
3523 { 3474 {
3524 Statement *s = ls->statement; 3475 Statement *s = ls->statement;
3525 3476
3526 if (!s->hasContinue()) 3477 if (!s->hasContinue())
3527 error("label '%s' has no continue", ident->toChars()); 3478 error("label '%s' has no continue", ident->toChars());
3528 if (ls->tf != sc->tf) 3479 if (ls->enclosingFinally != sc->enclosingFinally)
3529 error("cannot continue out of finally block"); 3480 error("cannot continue out of finally block");
3530 3481
3531 this->target = ls; 3482 this->target = ls;
3532 return this; 3483 return this;
3533 } 3484 }
3551 int ContinueStatement::blockExit() 3502 int ContinueStatement::blockExit()
3552 { 3503 {
3553 return ident ? BEgoto : BEcontinue; 3504 return ident ? BEgoto : BEcontinue;
3554 } 3505 }
3555 3506
3556 int ContinueStatement::fallOffEnd()
3557 {
3558 return FALSE;
3559 }
3560 3507
3561 void ContinueStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3508 void ContinueStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3562 { 3509 {
3563 buf->writestring("continue"); 3510 buf->writestring("continue");
3564 if (ident) 3511 if (ident)
3575 : Statement(loc) 3522 : Statement(loc)
3576 { 3523 {
3577 this->exp = exp; 3524 this->exp = exp;
3578 this->body = body; 3525 this->body = body;
3579 this->esync = NULL; 3526 this->esync = NULL;
3580 this->enclosinghandler = NULL;
3581 // LDC 3527 // LDC
3582 this->llsync = NULL; 3528 this->llsync = NULL;
3583 } 3529 }
3584 3530
3585 SynchronizedStatement::SynchronizedStatement(Loc loc, elem *esync, Statement *body) 3531 SynchronizedStatement::SynchronizedStatement(Loc loc, elem *esync, Statement *body)
3586 : Statement(loc) 3532 : Statement(loc)
3587 { 3533 {
3588 this->exp = NULL; 3534 this->exp = NULL;
3589 this->body = body; 3535 this->body = body;
3590 this->esync = esync; 3536 this->esync = esync;
3591 this->enclosinghandler = NULL;
3592 // LDC 3537 // LDC
3593 this->llsync = NULL; 3538 this->llsync = NULL;
3594 } 3539 }
3595 3540
3596 Statement *SynchronizedStatement::syntaxCopy() 3541 Statement *SynchronizedStatement::syntaxCopy()
3618 exp = exp->semantic(sc); 3563 exp = exp->semantic(sc);
3619 } 3564 }
3620 } 3565 }
3621 if (body) 3566 if (body)
3622 { 3567 {
3623 enclosinghandler = sc->tfOfTry; 3568 Statement* oldScopeExit = sc->enclosingScopeExit;
3624 sc->tfOfTry = new EnclosingSynchro(this); 3569 sc->enclosingScopeExit = this;
3625 body = body->semantic(sc); 3570 body = body->semantic(sc);
3626 sc->tfOfTry = enclosinghandler; 3571 sc->enclosingScopeExit = oldScopeExit;
3627 } 3572 }
3628 return this; 3573 return this;
3629 } 3574 }
3630 3575
3631 int SynchronizedStatement::hasBreak() 3576 int SynchronizedStatement::hasBreak()
3646 int SynchronizedStatement::blockExit() 3591 int SynchronizedStatement::blockExit()
3647 { 3592 {
3648 return body ? body->blockExit() : BEfallthru; 3593 return body ? body->blockExit() : BEfallthru;
3649 } 3594 }
3650 3595
3651 int SynchronizedStatement::fallOffEnd()
3652 {
3653 return body ? body->fallOffEnd() : TRUE;
3654 }
3655 3596
3656 void SynchronizedStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3597 void SynchronizedStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3657 { 3598 {
3658 buf->writestring("synchronized"); 3599 buf->writestring("synchronized");
3659 if (exp) 3600 if (exp)
3768 else 3709 else
3769 result |= BEfallthru; 3710 result |= BEfallthru;
3770 return result; 3711 return result;
3771 } 3712 }
3772 3713
3773 int WithStatement::fallOffEnd()
3774 {
3775 return body ? body->fallOffEnd() : TRUE;
3776 }
3777 3714
3778 /******************************** TryCatchStatement ***************************/ 3715 /******************************** TryCatchStatement ***************************/
3779 3716
3780 TryCatchStatement::TryCatchStatement(Loc loc, Statement *body, Array *catches) 3717 TryCatchStatement::TryCatchStatement(Loc loc, Statement *body, Array *catches)
3781 : Statement(loc) 3718 : Statement(loc)
3835 { 3772 {
3836 return TRUE; 3773 return TRUE;
3837 } 3774 }
3838 3775
3839 int TryCatchStatement::blockExit() 3776 int TryCatchStatement::blockExit()
3840 { int result; 3777 {
3841
3842 assert(body); 3778 assert(body);
3843 result = body->blockExit(); 3779 int result = body->blockExit();
3844 3780
3781 int catchresult = 0;
3845 for (size_t i = 0; i < catches->dim; i++) 3782 for (size_t i = 0; i < catches->dim; i++)
3846 { 3783 {
3847 Catch *c = (Catch *)catches->data[i]; 3784 Catch *c = (Catch *)catches->data[i];
3848 result |= c->blockExit(); 3785 catchresult |= c->blockExit();
3849 } 3786
3850 return result; 3787 /* If we're catching Object, then there is no throwing
3851 } 3788 */
3852 3789 Identifier *id = c->type->toBasetype()->isClassHandle()->ident;
3853 int TryCatchStatement::fallOffEnd() 3790 if (i == 0 &&
3854 { 3791 (id == Id::Object || id == Id::Throwable || id == Id::Exception))
3855 int result = FALSE; 3792 {
3856 3793 result &= ~BEthrow;
3857 if (body) 3794 }
3858 result = body->fallOffEnd(); 3795 }
3859 for (int i = 0; i < catches->dim; i++) 3796 return result | catchresult;
3860 { Catch *c; 3797 }
3861 3798
3862 c = (Catch *)catches->data[i];
3863 if (c->handler)
3864 result |= c->handler->fallOffEnd();
3865 }
3866 return result;
3867 }
3868 3799
3869 void TryCatchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 3800 void TryCatchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
3870 { 3801 {
3871 buf->writestring("try"); 3802 buf->writestring("try");
3872 buf->writenl(); 3803 buf->writenl();
3904 { ScopeDsymbol *sym; 3835 { ScopeDsymbol *sym;
3905 3836
3906 //printf("Catch::semantic(%s)\n", ident->toChars()); 3837 //printf("Catch::semantic(%s)\n", ident->toChars());
3907 3838
3908 #ifndef IN_GCC 3839 #ifndef IN_GCC
3909 if (sc->tf) 3840 if (sc->enclosingFinally)
3910 { 3841 {
3911 /* This is because the _d_local_unwind() gets the stack munged 3842 /* This is because the _d_local_unwind() gets the stack munged
3912 * up on this. The workaround is to place any try-catches into 3843 * up on this. The workaround is to place any try-catches into
3913 * a separate function, and call that. 3844 * a separate function, and call that.
3914 * To fix, have the compiler automatically convert the finally 3845 * To fix, have the compiler automatically convert the finally
3965 TryFinallyStatement::TryFinallyStatement(Loc loc, Statement *body, Statement *finalbody) 3896 TryFinallyStatement::TryFinallyStatement(Loc loc, Statement *body, Statement *finalbody)
3966 : Statement(loc) 3897 : Statement(loc)
3967 { 3898 {
3968 this->body = body; 3899 this->body = body;
3969 this->finalbody = finalbody; 3900 this->finalbody = finalbody;
3970 this->enclosinghandler = NULL;
3971 } 3901 }
3972 3902
3973 Statement *TryFinallyStatement::syntaxCopy() 3903 Statement *TryFinallyStatement::syntaxCopy()
3974 { 3904 {
3975 TryFinallyStatement *s = new TryFinallyStatement(loc, 3905 TryFinallyStatement *s = new TryFinallyStatement(loc,
3979 3909
3980 Statement *TryFinallyStatement::semantic(Scope *sc) 3910 Statement *TryFinallyStatement::semantic(Scope *sc)
3981 { 3911 {
3982 //printf("TryFinallyStatement::semantic()\n"); 3912 //printf("TryFinallyStatement::semantic()\n");
3983 3913
3984 enclosinghandler = sc->tfOfTry; 3914 Statement* oldScopeExit = sc->enclosingScopeExit;
3985 sc->tfOfTry = new EnclosingTryFinally(this); 3915 sc->enclosingScopeExit = this;
3986 body = body->semantic(sc); 3916 body = body->semantic(sc);
3987 sc->tfOfTry = enclosinghandler; 3917 sc->enclosingScopeExit = oldScopeExit;
3988 3918
3989 sc = sc->push(); 3919 sc = sc->push();
3990 sc->tf = this; 3920 sc->enclosingFinally = this;
3991 sc->sbreak = NULL; 3921 sc->sbreak = NULL;
3992 sc->scontinue = NULL; // no break or continue out of finally block 3922 sc->scontinue = NULL; // no break or continue out of finally block
3993 finalbody = finalbody->semantic(sc); 3923 finalbody = finalbody->semantic(sc);
3994 sc->pop(); 3924 sc->pop();
3995 if (!body) 3925 if (!body)
4028 return TRUE; 3958 return TRUE;
4029 } 3959 }
4030 3960
4031 int TryFinallyStatement::blockExit() 3961 int TryFinallyStatement::blockExit()
4032 { 3962 {
4033 int result = body->blockExit(); 3963 if (body)
4034 return result; 3964 return body->blockExit();
4035 } 3965 return BEfallthru;
4036 3966 }
4037 int TryFinallyStatement::fallOffEnd() 3967
4038 { int result;
4039
4040 result = body->fallOffEnd();
4041 // if (finalbody)
4042 // result = finalbody->fallOffEnd();
4043 return result;
4044 }
4045 3968
4046 /****************************** OnScopeStatement ***************************/ 3969 /****************************** OnScopeStatement ***************************/
4047 3970
4048 OnScopeStatement::OnScopeStatement(Loc loc, TOK tok, Statement *statement) 3971 OnScopeStatement::OnScopeStatement(Loc loc, TOK tok, Statement *statement)
4049 : Statement(loc) 3972 : Statement(loc)
4161 int ThrowStatement::blockExit() 4084 int ThrowStatement::blockExit()
4162 { 4085 {
4163 return BEthrow; // obviously 4086 return BEthrow; // obviously
4164 } 4087 }
4165 4088
4166 int ThrowStatement::fallOffEnd()
4167 {
4168 return FALSE;
4169 }
4170 4089
4171 void ThrowStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 4090 void ThrowStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
4172 { 4091 {
4173 buf->printf("throw "); 4092 buf->printf("throw ");
4174 exp->toCBuffer(buf, hgs); 4093 exp->toCBuffer(buf, hgs);
4180 4099
4181 VolatileStatement::VolatileStatement(Loc loc, Statement *statement) 4100 VolatileStatement::VolatileStatement(Loc loc, Statement *statement)
4182 : Statement(loc) 4101 : Statement(loc)
4183 { 4102 {
4184 this->statement = statement; 4103 this->statement = statement;
4185 this->enclosinghandler = NULL;
4186 } 4104 }
4187 4105
4188 Statement *VolatileStatement::syntaxCopy() 4106 Statement *VolatileStatement::syntaxCopy()
4189 { 4107 {
4190 VolatileStatement *s = new VolatileStatement(loc, 4108 VolatileStatement *s = new VolatileStatement(loc,
4194 4112
4195 Statement *VolatileStatement::semantic(Scope *sc) 4113 Statement *VolatileStatement::semantic(Scope *sc)
4196 { 4114 {
4197 if (statement) 4115 if (statement)
4198 { 4116 {
4199 enclosinghandler = sc->tfOfTry; 4117 Statement* oldScopeExit = sc->enclosingScopeExit;
4200 sc->tfOfTry = new EnclosingVolatile(this); 4118 sc->enclosingScopeExit = this;
4201 statement = statement->semantic(sc); 4119 statement = statement->semantic(sc);
4202 sc->tfOfTry = enclosinghandler; 4120 sc->enclosingScopeExit = oldScopeExit;
4203 } 4121 }
4204 return this; 4122 return this;
4205 } 4123 }
4206 4124
4207 Statements *VolatileStatement::flatten(Scope *sc) 4125 Statements *VolatileStatement::flatten(Scope *sc)
4224 int VolatileStatement::blockExit() 4142 int VolatileStatement::blockExit()
4225 { 4143 {
4226 return statement ? statement->blockExit() : BEfallthru; 4144 return statement ? statement->blockExit() : BEfallthru;
4227 } 4145 }
4228 4146
4229 int VolatileStatement::fallOffEnd()
4230 {
4231 return statement ? statement->fallOffEnd() : TRUE;
4232 }
4233 4147
4234 void VolatileStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 4148 void VolatileStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
4235 { 4149 {
4236 buf->writestring("volatile"); 4150 buf->writestring("volatile");
4237 if (statement) 4151 if (statement)
4249 GotoStatement::GotoStatement(Loc loc, Identifier *ident) 4163 GotoStatement::GotoStatement(Loc loc, Identifier *ident)
4250 : Statement(loc) 4164 : Statement(loc)
4251 { 4165 {
4252 this->ident = ident; 4166 this->ident = ident;
4253 this->label = NULL; 4167 this->label = NULL;
4254 this->tf = NULL; 4168 this->enclosingFinally = NULL;
4255 this->enclosinghandler = NULL; 4169 this->enclosingScopeExit = NULL;
4256 } 4170 }
4257 4171
4258 Statement *GotoStatement::syntaxCopy() 4172 Statement *GotoStatement::syntaxCopy()
4259 { 4173 {
4260 GotoStatement *s = new GotoStatement(loc, ident); 4174 GotoStatement *s = new GotoStatement(loc, ident);
4263 4177
4264 Statement *GotoStatement::semantic(Scope *sc) 4178 Statement *GotoStatement::semantic(Scope *sc)
4265 { FuncDeclaration *fd = sc->parent->isFuncDeclaration(); 4179 { FuncDeclaration *fd = sc->parent->isFuncDeclaration();
4266 4180
4267 //printf("GotoStatement::semantic()\n"); 4181 //printf("GotoStatement::semantic()\n");
4268 tf = sc->tf; 4182 enclosingFinally = sc->enclosingFinally;
4269 enclosinghandler = sc->tfOfTry; 4183 enclosingScopeExit = sc->enclosingScopeExit;
4184
4270 label = fd->searchLabel(ident); 4185 label = fd->searchLabel(ident);
4271 if (!label->statement && sc->fes) 4186 if (!label->statement && sc->fes)
4272 { 4187 {
4273 /* Either the goto label is forward referenced or it 4188 /* Either the goto label is forward referenced or it
4274 * is in the function that the enclosing foreach is in. 4189 * is in the function that the enclosing foreach is in.
4282 a->push(this); 4197 a->push(this);
4283 s = new CompoundStatement(loc, a); 4198 s = new CompoundStatement(loc, a);
4284 sc->fes->gotos.push(s); // 'look at this later' list 4199 sc->fes->gotos.push(s); // 'look at this later' list
4285 return s; 4200 return s;
4286 } 4201 }
4287 if (label->statement && label->statement->tf != sc->tf) 4202 if (label->statement && label->statement->enclosingFinally != sc->enclosingFinally)
4288 error("cannot goto in or out of finally block"); 4203 error("cannot goto in or out of finally block");
4289 return this; 4204 return this;
4290 } 4205 }
4291 4206
4292 int GotoStatement::blockExit() 4207 int GotoStatement::blockExit()
4293 { 4208 {
4294 //printf("GotoStatement::blockExit(%p)\n", this); 4209 //printf("GotoStatement::blockExit(%p)\n", this);
4295 return BEgoto; 4210 return BEgoto;
4296 } 4211 }
4297 4212
4298 int GotoStatement::fallOffEnd()
4299 {
4300 return FALSE;
4301 }
4302 4213
4303 void GotoStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) 4214 void GotoStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
4304 { 4215 {
4305 buf->writestring("goto "); 4216 buf->writestring("goto ");
4306 buf->writestring(ident->toChars()); 4217 buf->writestring(ident->toChars());
4313 LabelStatement::LabelStatement(Loc loc, Identifier *ident, Statement *statement) 4224 LabelStatement::LabelStatement(Loc loc, Identifier *ident, Statement *statement)
4314 : Statement(loc) 4225 : Statement(loc)
4315 { 4226 {
4316 this->ident = ident; 4227 this->ident = ident;
4317 this->statement = statement; 4228 this->statement = statement;
4318 this->tf = NULL; 4229 this->enclosingFinally = NULL;
4319 this->enclosinghandler = NULL; 4230 this->enclosingScopeExit = NULL;
4320 this->lblock = NULL; 4231 this->lblock = NULL;
4321 this->isReturnLabel = 0; 4232 this->isReturnLabel = 0;
4322 this->asmLabel = false; 4233 this->asmLabel = false;
4323 } 4234 }
4324 4235
4336 ls = fd->searchLabel(ident); 4247 ls = fd->searchLabel(ident);
4337 if (ls->statement) 4248 if (ls->statement)
4338 error("Label '%s' already defined", ls->toChars()); 4249 error("Label '%s' already defined", ls->toChars());
4339 else 4250 else
4340 ls->statement = this; 4251 ls->statement = this;
4341 tf = sc->tf; 4252
4342 enclosinghandler = sc->tfOfTry; 4253 enclosingFinally = sc->enclosingFinally;
4254 enclosingScopeExit = sc->enclosingScopeExit;
4255
4343 sc = sc->push(); 4256 sc = sc->push();
4344 sc->scopesym = sc->enclosing->scopesym; 4257 sc->scopesym = sc->enclosing->scopesym;
4345 sc->callSuper |= CSXlabel; 4258 sc->callSuper |= CSXlabel;
4346 sc->slabel = this; 4259 sc->slabel = this;
4347 if (statement) 4260 if (statement)
4387 { 4300 {
4388 //printf("LabelStatement::blockExit(%p)\n", this); 4301 //printf("LabelStatement::blockExit(%p)\n", this);
4389 return statement ? statement->blockExit() : BEfallthru; 4302 return statement ? statement->blockExit() : BEfallthru;
4390 } 4303 }
4391 4304
4392 int LabelStatement::fallOffEnd()
4393 {
4394 return statement ? statement->fallOffEnd() : TRUE;
4395 }
4396 4305
4397 int LabelStatement::comeFrom() 4306 int LabelStatement::comeFrom()
4398 { 4307 {
4399 //printf("LabelStatement::comeFrom()\n"); 4308 //printf("LabelStatement::comeFrom()\n");
4400 return TRUE; 4309 return TRUE;
4414 4323
4415 LabelDsymbol::LabelDsymbol(Identifier *ident) 4324 LabelDsymbol::LabelDsymbol(Identifier *ident)
4416 : Dsymbol(ident) 4325 : Dsymbol(ident)
4417 { 4326 {
4418 statement = NULL; 4327 statement = NULL;
4328 #if IN_GCC
4329 asmLabelNum = 0;
4330 #endif
4419 } 4331 }
4420 4332
4421 LabelDsymbol *LabelDsymbol::isLabel() // is this a LabelDsymbol()? 4333 LabelDsymbol *LabelDsymbol::isLabel() // is this a LabelDsymbol()?
4422 { 4334 {
4423 return this; 4335 return this;
4424 } 4336 }
4425
4426