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