comparison dmd/statement.c @ 1141:f99a3b393c03

Reorganize EnclosingHandlers to require less changes to the frontend and allow us to implement the synchronized storage class for functions.
author Christian Kamm <kamm incasoftware de>
date Tue, 24 Mar 2009 21:18:18 +0100
parents eeb8b95ea92e
children c6d6a68bb5db
comparison
equal deleted inserted replaced
1137:45d73f0a9b43 1141:f99a3b393c03
580 580
581 UnrolledLoopStatement::UnrolledLoopStatement(Loc loc, Statements *s) 581 UnrolledLoopStatement::UnrolledLoopStatement(Loc loc, Statements *s)
582 : Statement(loc) 582 : Statement(loc)
583 { 583 {
584 statements = s; 584 statements = s;
585 enclosinghandler = NULL;
586 } 585 }
587 586
588 Statement *UnrolledLoopStatement::syntaxCopy() 587 Statement *UnrolledLoopStatement::syntaxCopy()
589 { 588 {
590 Statements *a = new Statements(); 589 Statements *a = new Statements();
602 601
603 Statement *UnrolledLoopStatement::semantic(Scope *sc) 602 Statement *UnrolledLoopStatement::semantic(Scope *sc)
604 { 603 {
605 //printf("UnrolledLoopStatement::semantic(this = %p, sc = %p)\n", this, sc); 604 //printf("UnrolledLoopStatement::semantic(this = %p, sc = %p)\n", this, sc);
606 605
607 enclosinghandler = sc->tfOfTry;
608
609 sc->noctor++; 606 sc->noctor++;
610 Scope *scd = sc->push(); 607 Scope *scd = sc->push();
611 scd->sbreak = this; 608 scd->sbreak = this;
612 scd->scontinue = this; 609 scd->scontinue = this;
613 610
793 WhileStatement::WhileStatement(Loc loc, Expression *c, Statement *b) 790 WhileStatement::WhileStatement(Loc loc, Expression *c, Statement *b)
794 : Statement(loc) 791 : Statement(loc)
795 { 792 {
796 condition = c; 793 condition = c;
797 body = b; 794 body = b;
798 enclosinghandler = NULL;
799 } 795 }
800 796
801 Statement *WhileStatement::syntaxCopy() 797 Statement *WhileStatement::syntaxCopy()
802 { 798 {
803 WhileStatement *s = new WhileStatement(loc, condition->syntaxCopy(), body ? body->syntaxCopy() : NULL); 799 WhileStatement *s = new WhileStatement(loc, condition->syntaxCopy(), body ? body->syntaxCopy() : NULL);
828 Statement *si = new IfStatement(loc, condition, sw, NULL); 824 Statement *si = new IfStatement(loc, condition, sw, NULL);
829 return si->semantic(sc); 825 return si->semantic(sc);
830 } 826 }
831 #endif 827 #endif
832 828
833 enclosinghandler = sc->tfOfTry;
834
835 condition = condition->semantic(sc); 829 condition = condition->semantic(sc);
836 condition = resolveProperties(sc, condition); 830 condition = resolveProperties(sc, condition);
837 condition = condition->optimize(WANTvalue); 831 condition = condition->optimize(WANTvalue);
838 condition = condition->checkToBoolean(); 832 condition = condition->checkToBoolean();
839 833
917 DoStatement::DoStatement(Loc loc, Statement *b, Expression *c) 911 DoStatement::DoStatement(Loc loc, Statement *b, Expression *c)
918 : Statement(loc) 912 : Statement(loc)
919 { 913 {
920 body = b; 914 body = b;
921 condition = c; 915 condition = c;
922 enclosinghandler = NULL;
923 } 916 }
924 917
925 Statement *DoStatement::syntaxCopy() 918 Statement *DoStatement::syntaxCopy()
926 { 919 {
927 DoStatement *s = new DoStatement(loc, body ? body->syntaxCopy() : NULL, condition->syntaxCopy()); 920 DoStatement *s = new DoStatement(loc, body ? body->syntaxCopy() : NULL, condition->syntaxCopy());
929 } 922 }
930 923
931 924
932 Statement *DoStatement::semantic(Scope *sc) 925 Statement *DoStatement::semantic(Scope *sc)
933 { 926 {
934 enclosinghandler = sc->tfOfTry;
935
936 sc->noctor++; 927 sc->noctor++;
937 if (body) 928 if (body)
938 body = body->semanticScope(sc, this, this); 929 body = body->semanticScope(sc, this, this);
939 sc->noctor--; 930 sc->noctor--;
940 condition = condition->semantic(sc); 931 condition = condition->semantic(sc);
1008 { 999 {
1009 this->init = init; 1000 this->init = init;
1010 this->condition = condition; 1001 this->condition = condition;
1011 this->increment = increment; 1002 this->increment = increment;
1012 this->body = body; 1003 this->body = body;
1013 this->enclosinghandler = NULL;
1014 } 1004 }
1015 1005
1016 Statement *ForStatement::syntaxCopy() 1006 Statement *ForStatement::syntaxCopy()
1017 { 1007 {
1018 Statement *i = NULL; 1008 Statement *i = NULL;
1028 return s; 1018 return s;
1029 } 1019 }
1030 1020
1031 Statement *ForStatement::semantic(Scope *sc) 1021 Statement *ForStatement::semantic(Scope *sc)
1032 { 1022 {
1033 enclosinghandler = sc->tfOfTry;
1034
1035 ScopeDsymbol *sym = new ScopeDsymbol(); 1023 ScopeDsymbol *sym = new ScopeDsymbol();
1036 sym->parent = sc->scopesym; 1024 sym->parent = sc->scopesym;
1037 sc = sc->push(sym); 1025 sc = sc->push(sym);
1038 if (init) 1026 if (init)
1039 init = init->semantic(sc); 1027 init = init->semantic(sc);
1167 { 1155 {
1168 this->op = op; 1156 this->op = op;
1169 this->arguments = arguments; 1157 this->arguments = arguments;
1170 this->aggr = aggr; 1158 this->aggr = aggr;
1171 this->body = body; 1159 this->body = body;
1172 this->enclosinghandler = NULL;
1173 1160
1174 this->key = NULL; 1161 this->key = NULL;
1175 this->value = NULL; 1162 this->value = NULL;
1176 1163
1177 this->func = NULL; 1164 this->func = NULL;
1194 size_t dim = arguments->dim; 1181 size_t dim = arguments->dim;
1195 TypeAArray *taa = NULL; 1182 TypeAArray *taa = NULL;
1196 1183
1197 Type *tn = NULL; 1184 Type *tn = NULL;
1198 Type *tnv = NULL; 1185 Type *tnv = NULL;
1199
1200 enclosinghandler = sc->tfOfTry;
1201 1186
1202 func = sc->func; 1187 func = sc->func;
1203 if (func->fes) 1188 if (func->fes)
1204 func = func->fes->func; 1189 func = func->fes->func;
1205 1190
2251 condition = c; 2236 condition = c;
2252 body = b; 2237 body = b;
2253 sdefault = NULL; 2238 sdefault = NULL;
2254 cases = NULL; 2239 cases = NULL;
2255 hasNoDefault = 0; 2240 hasNoDefault = 0;
2256 // LDC
2257 enclosinghandler = NULL;
2258 } 2241 }
2259 2242
2260 Statement *SwitchStatement::syntaxCopy() 2243 Statement *SwitchStatement::syntaxCopy()
2261 { 2244 {
2262 SwitchStatement *s = new SwitchStatement(loc, 2245 SwitchStatement *s = new SwitchStatement(loc,
2266 2249
2267 Statement *SwitchStatement::semantic(Scope *sc) 2250 Statement *SwitchStatement::semantic(Scope *sc)
2268 { 2251 {
2269 //printf("SwitchStatement::semantic(%p)\n", this); 2252 //printf("SwitchStatement::semantic(%p)\n", this);
2270 assert(!cases); // ensure semantic() is only run once 2253 assert(!cases); // ensure semantic() is only run once
2271
2272 enclosinghandler = sc->tfOfTry;
2273 2254
2274 condition = condition->semantic(sc); 2255 condition = condition->semantic(sc);
2275 condition = resolveProperties(sc, condition); 2256 condition = resolveProperties(sc, condition);
2276 if (condition->type->isString()) 2257 if (condition->type->isString())
2277 { 2258 {
2569 2550
2570 GotoDefaultStatement::GotoDefaultStatement(Loc loc) 2551 GotoDefaultStatement::GotoDefaultStatement(Loc loc)
2571 : Statement(loc) 2552 : Statement(loc)
2572 { 2553 {
2573 sw = NULL; 2554 sw = NULL;
2574 enclosinghandler = NULL;
2575 } 2555 }
2576 2556
2577 Statement *GotoDefaultStatement::syntaxCopy() 2557 Statement *GotoDefaultStatement::syntaxCopy()
2578 { 2558 {
2579 GotoDefaultStatement *s = new GotoDefaultStatement(loc); 2559 GotoDefaultStatement *s = new GotoDefaultStatement(loc);
2580 return s; 2560 return s;
2581 } 2561 }
2582 2562
2583 Statement *GotoDefaultStatement::semantic(Scope *sc) 2563 Statement *GotoDefaultStatement::semantic(Scope *sc)
2584 { 2564 {
2585 enclosinghandler = sc->tfOfTry;
2586 sw = sc->sw; 2565 sw = sc->sw;
2587 if (!sw) 2566 if (!sw)
2588 error("goto default not in switch statement"); 2567 error("goto default not in switch statement");
2589 return this; 2568 return this;
2590 } 2569 }
2604 GotoCaseStatement::GotoCaseStatement(Loc loc, Expression *exp) 2583 GotoCaseStatement::GotoCaseStatement(Loc loc, Expression *exp)
2605 : Statement(loc) 2584 : Statement(loc)
2606 { 2585 {
2607 cs = NULL; 2586 cs = NULL;
2608 this->exp = exp; 2587 this->exp = exp;
2609 enclosinghandler = NULL;
2610 sw = NULL; 2588 sw = NULL;
2611 } 2589 }
2612 2590
2613 Statement *GotoCaseStatement::syntaxCopy() 2591 Statement *GotoCaseStatement::syntaxCopy()
2614 { 2592 {
2617 return s; 2595 return s;
2618 } 2596 }
2619 2597
2620 Statement *GotoCaseStatement::semantic(Scope *sc) 2598 Statement *GotoCaseStatement::semantic(Scope *sc)
2621 { 2599 {
2622 enclosinghandler = sc->tfOfTry;
2623 if (exp) 2600 if (exp)
2624 exp = exp->semantic(sc); 2601 exp = exp->semantic(sc);
2625 2602
2626 if (!sc->sw) 2603 if (!sc->sw)
2627 error("goto case not in switch statement"); 2604 error("goto case not in switch statement");
2676 2653
2677 ReturnStatement::ReturnStatement(Loc loc, Expression *exp) 2654 ReturnStatement::ReturnStatement(Loc loc, Expression *exp)
2678 : Statement(loc) 2655 : Statement(loc)
2679 { 2656 {
2680 this->exp = exp; 2657 this->exp = exp;
2681 this->enclosinghandler = NULL;
2682 } 2658 }
2683 2659
2684 Statement *ReturnStatement::syntaxCopy() 2660 Statement *ReturnStatement::syntaxCopy()
2685 { 2661 {
2686 Expression *e = NULL; 2662 Expression *e = NULL;
2691 } 2667 }
2692 2668
2693 Statement *ReturnStatement::semantic(Scope *sc) 2669 Statement *ReturnStatement::semantic(Scope *sc)
2694 { 2670 {
2695 //printf("ReturnStatement::semantic() %s\n", toChars()); 2671 //printf("ReturnStatement::semantic() %s\n", toChars());
2696 this->enclosinghandler = sc->tfOfTry;
2697 2672
2698 FuncDeclaration *fd = sc->parent->isFuncDeclaration(); 2673 FuncDeclaration *fd = sc->parent->isFuncDeclaration();
2699 Scope *scx = sc; 2674 Scope *scx = sc;
2700 int implicit0 = 0; 2675 int implicit0 = 0;
2701 2676
2728 exp = new IntegerExp(0); 2703 exp = new IntegerExp(0);
2729 } 2704 }
2730 2705
2731 if (sc->incontract || scx->incontract) 2706 if (sc->incontract || scx->incontract)
2732 error("return statements cannot be in contracts"); 2707 error("return statements cannot be in contracts");
2733 if (sc->tf || scx->tf) 2708 if (sc->enclosingFinally || scx->enclosingFinally)
2734 error("return statements cannot be in finally, scope(exit) or scope(success) bodies"); 2709 error("return statements cannot be in finally, scope(exit) or scope(success) bodies");
2735 2710
2736 if (fd->isCtorDeclaration()) 2711 if (fd->isCtorDeclaration())
2737 { 2712 {
2738 // Constructors implicitly do: 2713 // Constructors implicitly do:
2953 2928
2954 BreakStatement::BreakStatement(Loc loc, Identifier *ident) 2929 BreakStatement::BreakStatement(Loc loc, Identifier *ident)
2955 : Statement(loc) 2930 : Statement(loc)
2956 { 2931 {
2957 this->ident = ident; 2932 this->ident = ident;
2958 this->enclosinghandler = NULL;
2959 } 2933 }
2960 2934
2961 Statement *BreakStatement::syntaxCopy() 2935 Statement *BreakStatement::syntaxCopy()
2962 { 2936 {
2963 BreakStatement *s = new BreakStatement(loc, ident); 2937 BreakStatement *s = new BreakStatement(loc, ident);
2965 } 2939 }
2966 2940
2967 Statement *BreakStatement::semantic(Scope *sc) 2941 Statement *BreakStatement::semantic(Scope *sc)
2968 { 2942 {
2969 //printf("BreakStatement::semantic()\n"); 2943 //printf("BreakStatement::semantic()\n");
2970 enclosinghandler = sc->tfOfTry;
2971 // If: 2944 // If:
2972 // break Identifier; 2945 // break Identifier;
2973 if (ident) 2946 if (ident)
2974 { 2947 {
2975 Scope *scx; 2948 Scope *scx;
3003 { 2976 {
3004 Statement *s = ls->statement; 2977 Statement *s = ls->statement;
3005 2978
3006 if (!s->hasBreak()) 2979 if (!s->hasBreak())
3007 error("label '%s' has no break", ident->toChars()); 2980 error("label '%s' has no break", ident->toChars());
3008 if (ls->tf != sc->tf) 2981 if (ls->enclosingFinally != sc->enclosingFinally)
3009 error("cannot break out of finally block"); 2982 error("cannot break out of finally block");
3010 2983
3011 this->target = ls; 2984 this->target = ls;
3012 return this; 2985 return this;
3013 } 2986 }
3049 3022
3050 ContinueStatement::ContinueStatement(Loc loc, Identifier *ident) 3023 ContinueStatement::ContinueStatement(Loc loc, Identifier *ident)
3051 : Statement(loc) 3024 : Statement(loc)
3052 { 3025 {
3053 this->ident = ident; 3026 this->ident = ident;
3054 this->enclosinghandler = NULL;
3055 } 3027 }
3056 3028
3057 Statement *ContinueStatement::syntaxCopy() 3029 Statement *ContinueStatement::syntaxCopy()
3058 { 3030 {
3059 ContinueStatement *s = new ContinueStatement(loc, ident); 3031 ContinueStatement *s = new ContinueStatement(loc, ident);
3060 return s; 3032 return s;
3061 } 3033 }
3062 3034
3063 Statement *ContinueStatement::semantic(Scope *sc) 3035 Statement *ContinueStatement::semantic(Scope *sc)
3064 { 3036 {
3065 enclosinghandler = sc->tfOfTry;
3066 //printf("ContinueStatement::semantic() %p\n", this); 3037 //printf("ContinueStatement::semantic() %p\n", this);
3067 if (ident) 3038 if (ident)
3068 { 3039 {
3069 Scope *scx; 3040 Scope *scx;
3070 FuncDeclaration *thisfunc = sc->func; 3041 FuncDeclaration *thisfunc = sc->func;
3107 { 3078 {
3108 Statement *s = ls->statement; 3079 Statement *s = ls->statement;
3109 3080
3110 if (!s->hasContinue()) 3081 if (!s->hasContinue())
3111 error("label '%s' has no continue", ident->toChars()); 3082 error("label '%s' has no continue", ident->toChars());
3112 if (ls->tf != sc->tf) 3083 if (ls->enclosingFinally != sc->enclosingFinally)
3113 error("cannot continue out of finally block"); 3084 error("cannot continue out of finally block");
3114 3085
3115 this->target = ls; 3086 this->target = ls;
3116 return this; 3087 return this;
3117 } 3088 }
3154 : Statement(loc) 3125 : Statement(loc)
3155 { 3126 {
3156 this->exp = exp; 3127 this->exp = exp;
3157 this->body = body; 3128 this->body = body;
3158 this->esync = NULL; 3129 this->esync = NULL;
3159 this->enclosinghandler = NULL;
3160 // LDC 3130 // LDC
3161 this->llsync = NULL; 3131 this->llsync = NULL;
3162 } 3132 }
3163 3133
3164 SynchronizedStatement::SynchronizedStatement(Loc loc, elem *esync, Statement *body) 3134 SynchronizedStatement::SynchronizedStatement(Loc loc, elem *esync, Statement *body)
3165 : Statement(loc) 3135 : Statement(loc)
3166 { 3136 {
3167 this->exp = NULL; 3137 this->exp = NULL;
3168 this->body = body; 3138 this->body = body;
3169 this->esync = esync; 3139 this->esync = esync;
3170 this->enclosinghandler = NULL;
3171 // LDC 3140 // LDC
3172 this->llsync = NULL; 3141 this->llsync = NULL;
3173 } 3142 }
3174 3143
3175 Statement *SynchronizedStatement::syntaxCopy() 3144 Statement *SynchronizedStatement::syntaxCopy()
3197 exp = exp->semantic(sc); 3166 exp = exp->semantic(sc);
3198 } 3167 }
3199 } 3168 }
3200 if (body) 3169 if (body)
3201 { 3170 {
3202 enclosinghandler = sc->tfOfTry; 3171 Statement* oldScopeExit = sc->enclosingScopeExit;
3203 sc->tfOfTry = new EnclosingSynchro(this); 3172 sc->enclosingScopeExit = this;
3204 body = body->semantic(sc); 3173 body = body->semantic(sc);
3205 sc->tfOfTry = enclosinghandler; 3174 sc->enclosingScopeExit = oldScopeExit;
3206 } 3175 }
3207 return this; 3176 return this;
3208 } 3177 }
3209 3178
3210 int SynchronizedStatement::hasBreak() 3179 int SynchronizedStatement::hasBreak()
3453 { ScopeDsymbol *sym; 3422 { ScopeDsymbol *sym;
3454 3423
3455 //printf("Catch::semantic(%s)\n", ident->toChars()); 3424 //printf("Catch::semantic(%s)\n", ident->toChars());
3456 3425
3457 #ifndef IN_GCC 3426 #ifndef IN_GCC
3458 if (sc->tf) 3427 if (sc->enclosingFinally)
3459 { 3428 {
3460 /* This is because the _d_local_unwind() gets the stack munged 3429 /* This is because the _d_local_unwind() gets the stack munged
3461 * up on this. The workaround is to place any try-catches into 3430 * up on this. The workaround is to place any try-catches into
3462 * a separate function, and call that. 3431 * a separate function, and call that.
3463 * To fix, have the compiler automatically convert the finally 3432 * To fix, have the compiler automatically convert the finally
3514 TryFinallyStatement::TryFinallyStatement(Loc loc, Statement *body, Statement *finalbody) 3483 TryFinallyStatement::TryFinallyStatement(Loc loc, Statement *body, Statement *finalbody)
3515 : Statement(loc) 3484 : Statement(loc)
3516 { 3485 {
3517 this->body = body; 3486 this->body = body;
3518 this->finalbody = finalbody; 3487 this->finalbody = finalbody;
3519 this->enclosinghandler = NULL;
3520 } 3488 }
3521 3489
3522 Statement *TryFinallyStatement::syntaxCopy() 3490 Statement *TryFinallyStatement::syntaxCopy()
3523 { 3491 {
3524 TryFinallyStatement *s = new TryFinallyStatement(loc, 3492 TryFinallyStatement *s = new TryFinallyStatement(loc,
3528 3496
3529 Statement *TryFinallyStatement::semantic(Scope *sc) 3497 Statement *TryFinallyStatement::semantic(Scope *sc)
3530 { 3498 {
3531 //printf("TryFinallyStatement::semantic()\n"); 3499 //printf("TryFinallyStatement::semantic()\n");
3532 3500
3533 enclosinghandler = sc->tfOfTry; 3501 Statement* oldScopeExit = sc->enclosingScopeExit;
3534 sc->tfOfTry = new EnclosingTryFinally(this); 3502 sc->enclosingScopeExit = this;
3535 body = body->semantic(sc); 3503 body = body->semantic(sc);
3536 sc->tfOfTry = enclosinghandler; 3504 sc->enclosingScopeExit = oldScopeExit;
3537 3505
3538 sc = sc->push(); 3506 sc = sc->push();
3539 sc->tf = this; 3507 sc->enclosingFinally = this;
3540 sc->sbreak = NULL; 3508 sc->sbreak = NULL;
3541 sc->scontinue = NULL; // no break or continue out of finally block 3509 sc->scontinue = NULL; // no break or continue out of finally block
3542 finalbody = finalbody->semantic(sc); 3510 finalbody = finalbody->semantic(sc);
3543 sc->pop(); 3511 sc->pop();
3544 return this; 3512 return this;
3709 3677
3710 VolatileStatement::VolatileStatement(Loc loc, Statement *statement) 3678 VolatileStatement::VolatileStatement(Loc loc, Statement *statement)
3711 : Statement(loc) 3679 : Statement(loc)
3712 { 3680 {
3713 this->statement = statement; 3681 this->statement = statement;
3714 this->enclosinghandler = NULL;
3715 } 3682 }
3716 3683
3717 Statement *VolatileStatement::syntaxCopy() 3684 Statement *VolatileStatement::syntaxCopy()
3718 { 3685 {
3719 VolatileStatement *s = new VolatileStatement(loc, 3686 VolatileStatement *s = new VolatileStatement(loc,
3723 3690
3724 Statement *VolatileStatement::semantic(Scope *sc) 3691 Statement *VolatileStatement::semantic(Scope *sc)
3725 { 3692 {
3726 if (statement) 3693 if (statement)
3727 { 3694 {
3728 enclosinghandler = sc->tfOfTry; 3695 Statement* oldScopeExit = sc->enclosingScopeExit;
3729 sc->tfOfTry = new EnclosingVolatile(this); 3696 sc->enclosingScopeExit = this;
3730 statement = statement->semantic(sc); 3697 statement = statement->semantic(sc);
3731 sc->tfOfTry = enclosinghandler; 3698 sc->enclosingScopeExit = oldScopeExit;
3732 } 3699 }
3733 return this; 3700 return this;
3734 } 3701 }
3735 3702
3736 Statements *VolatileStatement::flatten(Scope *sc) 3703 Statements *VolatileStatement::flatten(Scope *sc)
3773 GotoStatement::GotoStatement(Loc loc, Identifier *ident) 3740 GotoStatement::GotoStatement(Loc loc, Identifier *ident)
3774 : Statement(loc) 3741 : Statement(loc)
3775 { 3742 {
3776 this->ident = ident; 3743 this->ident = ident;
3777 this->label = NULL; 3744 this->label = NULL;
3778 this->tf = NULL; 3745 this->enclosingFinally = NULL;
3779 this->enclosinghandler = NULL; 3746 this->enclosingScopeExit = NULL;
3780 } 3747 }
3781 3748
3782 Statement *GotoStatement::syntaxCopy() 3749 Statement *GotoStatement::syntaxCopy()
3783 { 3750 {
3784 GotoStatement *s = new GotoStatement(loc, ident); 3751 GotoStatement *s = new GotoStatement(loc, ident);
3787 3754
3788 Statement *GotoStatement::semantic(Scope *sc) 3755 Statement *GotoStatement::semantic(Scope *sc)
3789 { FuncDeclaration *fd = sc->parent->isFuncDeclaration(); 3756 { FuncDeclaration *fd = sc->parent->isFuncDeclaration();
3790 3757
3791 //printf("GotoStatement::semantic()\n"); 3758 //printf("GotoStatement::semantic()\n");
3792 tf = sc->tf; 3759 enclosingFinally = sc->enclosingFinally;
3793 enclosinghandler = sc->tfOfTry; 3760 enclosingScopeExit = sc->enclosingScopeExit;
3761
3794 label = fd->searchLabel(ident); 3762 label = fd->searchLabel(ident);
3795 if (!label->statement && sc->fes) 3763 if (!label->statement && sc->fes)
3796 { 3764 {
3797 /* Either the goto label is forward referenced or it 3765 /* Either the goto label is forward referenced or it
3798 * is in the function that the enclosing foreach is in. 3766 * is in the function that the enclosing foreach is in.
3806 a->push(this); 3774 a->push(this);
3807 s = new CompoundStatement(loc, a); 3775 s = new CompoundStatement(loc, a);
3808 sc->fes->gotos.push(s); // 'look at this later' list 3776 sc->fes->gotos.push(s); // 'look at this later' list
3809 return s; 3777 return s;
3810 } 3778 }
3811 if (label->statement && label->statement->tf != sc->tf) 3779 if (label->statement && label->statement->enclosingFinally != sc->enclosingFinally)
3812 error("cannot goto in or out of finally block"); 3780 error("cannot goto in or out of finally block");
3813 return this; 3781 return this;
3814 } 3782 }
3815 3783
3816 int GotoStatement::blockExit() 3784 int GotoStatement::blockExit()
3832 LabelStatement::LabelStatement(Loc loc, Identifier *ident, Statement *statement) 3800 LabelStatement::LabelStatement(Loc loc, Identifier *ident, Statement *statement)
3833 : Statement(loc) 3801 : Statement(loc)
3834 { 3802 {
3835 this->ident = ident; 3803 this->ident = ident;
3836 this->statement = statement; 3804 this->statement = statement;
3837 this->tf = NULL; 3805 this->enclosingFinally = NULL;
3838 this->enclosinghandler = NULL; 3806 this->enclosingScopeExit = NULL;
3839 this->lblock = NULL; 3807 this->lblock = NULL;
3840 this->isReturnLabel = 0; 3808 this->isReturnLabel = 0;
3841 this->asmLabel = false; 3809 this->asmLabel = false;
3842 } 3810 }
3843 3811
3855 ls = fd->searchLabel(ident); 3823 ls = fd->searchLabel(ident);
3856 if (ls->statement) 3824 if (ls->statement)
3857 error("Label '%s' already defined", ls->toChars()); 3825 error("Label '%s' already defined", ls->toChars());
3858 else 3826 else
3859 ls->statement = this; 3827 ls->statement = this;
3860 tf = sc->tf; 3828
3861 enclosinghandler = sc->tfOfTry; 3829 enclosingFinally = sc->enclosingFinally;
3830 enclosingScopeExit = sc->enclosingScopeExit;
3831
3862 sc = sc->push(); 3832 sc = sc->push();
3863 sc->scopesym = sc->enclosing->scopesym; 3833 sc->scopesym = sc->enclosing->scopesym;
3864 sc->callSuper |= CSXlabel; 3834 sc->callSuper |= CSXlabel;
3865 sc->slabel = this; 3835 sc->slabel = this;
3866 if (statement) 3836 if (statement)