Mercurial > projects > ldc
comparison dmd/statement.c @ 145:8f704cb9969b trunk
[svn r150] fixes #16 and #17, implements GotoCaseStatement
author | ChristianK |
---|---|
date | Sat, 08 Mar 2008 15:22:07 +0100 |
parents | a27941d00351 |
children | 86d3bb8ca33e |
comparison
equal
deleted
inserted
replaced
144:a27941d00351 | 145:8f704cb9969b |
---|---|
559 | 559 |
560 UnrolledLoopStatement::UnrolledLoopStatement(Loc loc, Statements *s) | 560 UnrolledLoopStatement::UnrolledLoopStatement(Loc loc, Statements *s) |
561 : Statement(loc) | 561 : Statement(loc) |
562 { | 562 { |
563 statements = s; | 563 statements = s; |
564 enclosingtry = NULL; | |
564 } | 565 } |
565 | 566 |
566 Statement *UnrolledLoopStatement::syntaxCopy() | 567 Statement *UnrolledLoopStatement::syntaxCopy() |
567 { | 568 { |
568 Statements *a = new Statements(); | 569 Statements *a = new Statements(); |
580 | 581 |
581 Statement *UnrolledLoopStatement::semantic(Scope *sc) | 582 Statement *UnrolledLoopStatement::semantic(Scope *sc) |
582 { | 583 { |
583 //printf("UnrolledLoopStatement::semantic(this = %p, sc = %p)\n", this, sc); | 584 //printf("UnrolledLoopStatement::semantic(this = %p, sc = %p)\n", this, sc); |
584 | 585 |
586 enclosingtry = sc->tfOfTry; | |
587 | |
585 sc->noctor++; | 588 sc->noctor++; |
586 Scope *scd = sc->push(); | 589 Scope *scd = sc->push(); |
587 scd->sbreak = this; | 590 scd->sbreak = this; |
588 scd->scontinue = this; | 591 scd->scontinue = this; |
589 | 592 |
769 WhileStatement::WhileStatement(Loc loc, Expression *c, Statement *b) | 772 WhileStatement::WhileStatement(Loc loc, Expression *c, Statement *b) |
770 : Statement(loc) | 773 : Statement(loc) |
771 { | 774 { |
772 condition = c; | 775 condition = c; |
773 body = b; | 776 body = b; |
777 enclosingtry = NULL; | |
774 } | 778 } |
775 | 779 |
776 Statement *WhileStatement::syntaxCopy() | 780 Statement *WhileStatement::syntaxCopy() |
777 { | 781 { |
778 WhileStatement *s = new WhileStatement(loc, condition->syntaxCopy(), body ? body->syntaxCopy() : NULL); | 782 WhileStatement *s = new WhileStatement(loc, condition->syntaxCopy(), body ? body->syntaxCopy() : NULL); |
803 Statement *si = new IfStatement(loc, condition, sw, NULL); | 807 Statement *si = new IfStatement(loc, condition, sw, NULL); |
804 return si->semantic(sc); | 808 return si->semantic(sc); |
805 } | 809 } |
806 #endif | 810 #endif |
807 | 811 |
812 enclosingtry = sc->tfOfTry; | |
813 | |
808 condition = condition->semantic(sc); | 814 condition = condition->semantic(sc); |
809 condition = resolveProperties(sc, condition); | 815 condition = resolveProperties(sc, condition); |
810 condition = condition->optimize(WANTvalue); | 816 condition = condition->optimize(WANTvalue); |
811 condition = condition->checkToBoolean(); | 817 condition = condition->checkToBoolean(); |
812 | 818 |
868 DoStatement::DoStatement(Loc loc, Statement *b, Expression *c) | 874 DoStatement::DoStatement(Loc loc, Statement *b, Expression *c) |
869 : Statement(loc) | 875 : Statement(loc) |
870 { | 876 { |
871 body = b; | 877 body = b; |
872 condition = c; | 878 condition = c; |
879 enclosingtry = NULL; | |
873 } | 880 } |
874 | 881 |
875 Statement *DoStatement::syntaxCopy() | 882 Statement *DoStatement::syntaxCopy() |
876 { | 883 { |
877 DoStatement *s = new DoStatement(loc, body ? body->syntaxCopy() : NULL, condition->syntaxCopy()); | 884 DoStatement *s = new DoStatement(loc, body ? body->syntaxCopy() : NULL, condition->syntaxCopy()); |
879 } | 886 } |
880 | 887 |
881 | 888 |
882 Statement *DoStatement::semantic(Scope *sc) | 889 Statement *DoStatement::semantic(Scope *sc) |
883 { | 890 { |
891 enclosingtry = sc->tfOfTry; | |
892 | |
884 sc->noctor++; | 893 sc->noctor++; |
885 if (body) | 894 if (body) |
886 body = body->semanticScope(sc, this, this); | 895 body = body->semanticScope(sc, this, this); |
887 sc->noctor--; | 896 sc->noctor--; |
888 condition = condition->semantic(sc); | 897 condition = condition->semantic(sc); |
941 { | 950 { |
942 this->init = init; | 951 this->init = init; |
943 this->condition = condition; | 952 this->condition = condition; |
944 this->increment = increment; | 953 this->increment = increment; |
945 this->body = body; | 954 this->body = body; |
955 this->enclosingtry = NULL; | |
946 } | 956 } |
947 | 957 |
948 Statement *ForStatement::syntaxCopy() | 958 Statement *ForStatement::syntaxCopy() |
949 { | 959 { |
950 Statement *i = NULL; | 960 Statement *i = NULL; |
960 return s; | 970 return s; |
961 } | 971 } |
962 | 972 |
963 Statement *ForStatement::semantic(Scope *sc) | 973 Statement *ForStatement::semantic(Scope *sc) |
964 { | 974 { |
975 enclosingtry = sc->tfOfTry; | |
976 | |
965 ScopeDsymbol *sym = new ScopeDsymbol(); | 977 ScopeDsymbol *sym = new ScopeDsymbol(); |
966 sym->parent = sc->scopesym; | 978 sym->parent = sc->scopesym; |
967 sc = sc->push(sym); | 979 sc = sc->push(sym); |
968 if (init) | 980 if (init) |
969 init = init->semantic(sc); | 981 init = init->semantic(sc); |
1072 { | 1084 { |
1073 this->op = op; | 1085 this->op = op; |
1074 this->arguments = arguments; | 1086 this->arguments = arguments; |
1075 this->aggr = aggr; | 1087 this->aggr = aggr; |
1076 this->body = body; | 1088 this->body = body; |
1089 this->enclosingtry = NULL; | |
1077 | 1090 |
1078 this->key = NULL; | 1091 this->key = NULL; |
1079 this->value = NULL; | 1092 this->value = NULL; |
1080 | 1093 |
1081 this->func = NULL; | 1094 this->func = NULL; |
1099 int i; | 1112 int i; |
1100 TypeAArray *taa = NULL; | 1113 TypeAArray *taa = NULL; |
1101 | 1114 |
1102 Type *tn = NULL; | 1115 Type *tn = NULL; |
1103 Type *tnv = NULL; | 1116 Type *tnv = NULL; |
1117 | |
1118 enclosingtry = sc->tfOfTry; | |
1104 | 1119 |
1105 func = sc->func; | 1120 func = sc->func; |
1106 if (func->fes) | 1121 if (func->fes) |
1107 func = func->fes->func; | 1122 func = func->fes->func; |
1108 | 1123 |
1954 body = b; | 1969 body = b; |
1955 sdefault = NULL; | 1970 sdefault = NULL; |
1956 cases = NULL; | 1971 cases = NULL; |
1957 hasNoDefault = 0; | 1972 hasNoDefault = 0; |
1958 // LLVMDC | 1973 // LLVMDC |
1959 defaultBB = NULL; | 1974 enclosingtry = NULL; |
1960 } | 1975 } |
1961 | 1976 |
1962 Statement *SwitchStatement::syntaxCopy() | 1977 Statement *SwitchStatement::syntaxCopy() |
1963 { | 1978 { |
1964 SwitchStatement *s = new SwitchStatement(loc, | 1979 SwitchStatement *s = new SwitchStatement(loc, |
1968 | 1983 |
1969 Statement *SwitchStatement::semantic(Scope *sc) | 1984 Statement *SwitchStatement::semantic(Scope *sc) |
1970 { | 1985 { |
1971 //printf("SwitchStatement::semantic(%p)\n", this); | 1986 //printf("SwitchStatement::semantic(%p)\n", this); |
1972 assert(!cases); // ensure semantic() is only run once | 1987 assert(!cases); // ensure semantic() is only run once |
1988 | |
1989 enclosingtry = sc->tfOfTry; | |
1990 | |
1973 condition = condition->semantic(sc); | 1991 condition = condition->semantic(sc); |
1974 condition = resolveProperties(sc, condition); | 1992 condition = resolveProperties(sc, condition); |
1975 if (condition->type->isString()) | 1993 if (condition->type->isString()) |
1976 { | 1994 { |
1977 // If it's not an array, cast it to one | 1995 // If it's not an array, cast it to one |
2105 : Statement(loc) | 2123 : Statement(loc) |
2106 { | 2124 { |
2107 this->exp = exp; | 2125 this->exp = exp; |
2108 this->statement = s; | 2126 this->statement = s; |
2109 cblock = NULL; | 2127 cblock = NULL; |
2128 bodyBB = NULL; | |
2110 } | 2129 } |
2111 | 2130 |
2112 Statement *CaseStatement::syntaxCopy() | 2131 Statement *CaseStatement::syntaxCopy() |
2113 { | 2132 { |
2114 CaseStatement *s = new CaseStatement(loc, exp->syntaxCopy(), statement->syntaxCopy()); | 2133 CaseStatement *s = new CaseStatement(loc, exp->syntaxCopy(), statement->syntaxCopy()); |
2201 { | 2220 { |
2202 this->statement = s; | 2221 this->statement = s; |
2203 #if IN_GCC | 2222 #if IN_GCC |
2204 + cblock = NULL; | 2223 + cblock = NULL; |
2205 #endif | 2224 #endif |
2225 bodyBB = NULL; | |
2206 } | 2226 } |
2207 | 2227 |
2208 Statement *DefaultStatement::syntaxCopy() | 2228 Statement *DefaultStatement::syntaxCopy() |
2209 { | 2229 { |
2210 DefaultStatement *s = new DefaultStatement(loc, statement->syntaxCopy()); | 2230 DefaultStatement *s = new DefaultStatement(loc, statement->syntaxCopy()); |
2252 | 2272 |
2253 GotoDefaultStatement::GotoDefaultStatement(Loc loc) | 2273 GotoDefaultStatement::GotoDefaultStatement(Loc loc) |
2254 : Statement(loc) | 2274 : Statement(loc) |
2255 { | 2275 { |
2256 sw = NULL; | 2276 sw = NULL; |
2277 enclosingtry = NULL; | |
2257 } | 2278 } |
2258 | 2279 |
2259 Statement *GotoDefaultStatement::syntaxCopy() | 2280 Statement *GotoDefaultStatement::syntaxCopy() |
2260 { | 2281 { |
2261 GotoDefaultStatement *s = new GotoDefaultStatement(loc); | 2282 GotoDefaultStatement *s = new GotoDefaultStatement(loc); |
2262 return s; | 2283 return s; |
2263 } | 2284 } |
2264 | 2285 |
2265 Statement *GotoDefaultStatement::semantic(Scope *sc) | 2286 Statement *GotoDefaultStatement::semantic(Scope *sc) |
2266 { | 2287 { |
2288 enclosingtry = sc->tfOfTry; | |
2267 sw = sc->sw; | 2289 sw = sc->sw; |
2268 if (!sw) | 2290 if (!sw) |
2269 error("goto default not in switch statement"); | 2291 error("goto default not in switch statement"); |
2270 return this; | 2292 return this; |
2271 } | 2293 } |
2285 GotoCaseStatement::GotoCaseStatement(Loc loc, Expression *exp) | 2307 GotoCaseStatement::GotoCaseStatement(Loc loc, Expression *exp) |
2286 : Statement(loc) | 2308 : Statement(loc) |
2287 { | 2309 { |
2288 cs = NULL; | 2310 cs = NULL; |
2289 this->exp = exp; | 2311 this->exp = exp; |
2312 enclosingtry = NULL; | |
2313 sw = NULL; | |
2290 } | 2314 } |
2291 | 2315 |
2292 Statement *GotoCaseStatement::syntaxCopy() | 2316 Statement *GotoCaseStatement::syntaxCopy() |
2293 { | 2317 { |
2294 Expression *e = exp ? exp->syntaxCopy() : NULL; | 2318 Expression *e = exp ? exp->syntaxCopy() : NULL; |
2296 return s; | 2320 return s; |
2297 } | 2321 } |
2298 | 2322 |
2299 Statement *GotoCaseStatement::semantic(Scope *sc) | 2323 Statement *GotoCaseStatement::semantic(Scope *sc) |
2300 { | 2324 { |
2325 enclosingtry = sc->tfOfTry; | |
2301 if (exp) | 2326 if (exp) |
2302 exp = exp->semantic(sc); | 2327 exp = exp->semantic(sc); |
2303 | 2328 |
2304 if (!sc->sw) | 2329 if (!sc->sw) |
2305 error("goto case not in switch statement"); | 2330 error("goto case not in switch statement"); |
2306 else | 2331 else |
2307 { | 2332 { |
2333 sw = sc->sw; | |
2308 sc->sw->gotoCases.push(this); | 2334 sc->sw->gotoCases.push(this); |
2309 if (exp) | 2335 if (exp) |
2310 { | 2336 { |
2311 exp = exp->implicitCastTo(sc, sc->sw->condition->type); | 2337 exp = exp->implicitCastTo(sc, sc->sw->condition->type); |
2312 exp = exp->optimize(WANTvalue); | 2338 exp = exp->optimize(WANTvalue); |
2353 | 2379 |
2354 ReturnStatement::ReturnStatement(Loc loc, Expression *exp) | 2380 ReturnStatement::ReturnStatement(Loc loc, Expression *exp) |
2355 : Statement(loc) | 2381 : Statement(loc) |
2356 { | 2382 { |
2357 this->exp = exp; | 2383 this->exp = exp; |
2384 this->enclosingtry = NULL; | |
2358 } | 2385 } |
2359 | 2386 |
2360 Statement *ReturnStatement::syntaxCopy() | 2387 Statement *ReturnStatement::syntaxCopy() |
2361 { | 2388 { |
2362 Expression *e = NULL; | 2389 Expression *e = NULL; |
2367 } | 2394 } |
2368 | 2395 |
2369 Statement *ReturnStatement::semantic(Scope *sc) | 2396 Statement *ReturnStatement::semantic(Scope *sc) |
2370 { | 2397 { |
2371 //printf("ReturnStatement::semantic() %s\n", toChars()); | 2398 //printf("ReturnStatement::semantic() %s\n", toChars()); |
2399 this->enclosingtry = sc->tfOfTry; | |
2372 | 2400 |
2373 FuncDeclaration *fd = sc->parent->isFuncDeclaration(); | 2401 FuncDeclaration *fd = sc->parent->isFuncDeclaration(); |
2374 Scope *scx = sc; | 2402 Scope *scx = sc; |
2375 int implicit0 = 0; | 2403 int implicit0 = 0; |
2376 | 2404 |
2627 | 2655 |
2628 BreakStatement::BreakStatement(Loc loc, Identifier *ident) | 2656 BreakStatement::BreakStatement(Loc loc, Identifier *ident) |
2629 : Statement(loc) | 2657 : Statement(loc) |
2630 { | 2658 { |
2631 this->ident = ident; | 2659 this->ident = ident; |
2660 this->enclosingtry = NULL; | |
2632 } | 2661 } |
2633 | 2662 |
2634 Statement *BreakStatement::syntaxCopy() | 2663 Statement *BreakStatement::syntaxCopy() |
2635 { | 2664 { |
2636 BreakStatement *s = new BreakStatement(loc, ident); | 2665 BreakStatement *s = new BreakStatement(loc, ident); |
2637 return s; | 2666 return s; |
2638 } | 2667 } |
2639 | 2668 |
2640 Statement *BreakStatement::semantic(Scope *sc) | 2669 Statement *BreakStatement::semantic(Scope *sc) |
2641 { | 2670 { |
2671 enclosingtry = sc->tfOfTry; | |
2642 // If: | 2672 // If: |
2643 // break Identifier; | 2673 // break Identifier; |
2644 if (ident) | 2674 if (ident) |
2645 { | 2675 { |
2646 Scope *scx; | 2676 Scope *scx; |
2676 | 2706 |
2677 if (!s->hasBreak()) | 2707 if (!s->hasBreak()) |
2678 error("label '%s' has no break", ident->toChars()); | 2708 error("label '%s' has no break", ident->toChars()); |
2679 if (ls->tf != sc->tf) | 2709 if (ls->tf != sc->tf) |
2680 error("cannot break out of finally block"); | 2710 error("cannot break out of finally block"); |
2711 | |
2712 this->target = ls; | |
2681 return this; | 2713 return this; |
2682 } | 2714 } |
2683 } | 2715 } |
2684 error("enclosing label '%s' for break not found", ident->toChars()); | 2716 error("enclosing label '%s' for break not found", ident->toChars()); |
2685 } | 2717 } |
2717 | 2749 |
2718 ContinueStatement::ContinueStatement(Loc loc, Identifier *ident) | 2750 ContinueStatement::ContinueStatement(Loc loc, Identifier *ident) |
2719 : Statement(loc) | 2751 : Statement(loc) |
2720 { | 2752 { |
2721 this->ident = ident; | 2753 this->ident = ident; |
2754 this->enclosingtry = NULL; | |
2722 } | 2755 } |
2723 | 2756 |
2724 Statement *ContinueStatement::syntaxCopy() | 2757 Statement *ContinueStatement::syntaxCopy() |
2725 { | 2758 { |
2726 ContinueStatement *s = new ContinueStatement(loc, ident); | 2759 ContinueStatement *s = new ContinueStatement(loc, ident); |
2727 return s; | 2760 return s; |
2728 } | 2761 } |
2729 | 2762 |
2730 Statement *ContinueStatement::semantic(Scope *sc) | 2763 Statement *ContinueStatement::semantic(Scope *sc) |
2731 { | 2764 { |
2765 enclosingtry = sc->tfOfTry; | |
2732 //printf("ContinueStatement::semantic() %p\n", this); | 2766 //printf("ContinueStatement::semantic() %p\n", this); |
2733 if (ident) | 2767 if (ident) |
2734 { | 2768 { |
2735 Scope *scx; | 2769 Scope *scx; |
2736 FuncDeclaration *thisfunc = sc->func; | 2770 FuncDeclaration *thisfunc = sc->func; |
2775 | 2809 |
2776 if (!s->hasContinue()) | 2810 if (!s->hasContinue()) |
2777 error("label '%s' has no continue", ident->toChars()); | 2811 error("label '%s' has no continue", ident->toChars()); |
2778 if (ls->tf != sc->tf) | 2812 if (ls->tf != sc->tf) |
2779 error("cannot continue out of finally block"); | 2813 error("cannot continue out of finally block"); |
2814 | |
2815 this->target = ls; | |
2780 return this; | 2816 return this; |
2781 } | 2817 } |
2782 } | 2818 } |
2783 error("enclosing label '%s' for continue not found", ident->toChars()); | 2819 error("enclosing label '%s' for continue not found", ident->toChars()); |
2784 } | 2820 } |
3157 TryFinallyStatement::TryFinallyStatement(Loc loc, Statement *body, Statement *finalbody) | 3193 TryFinallyStatement::TryFinallyStatement(Loc loc, Statement *body, Statement *finalbody) |
3158 : Statement(loc) | 3194 : Statement(loc) |
3159 { | 3195 { |
3160 this->body = body; | 3196 this->body = body; |
3161 this->finalbody = finalbody; | 3197 this->finalbody = finalbody; |
3198 this->enclosingtry = NULL; | |
3162 } | 3199 } |
3163 | 3200 |
3164 Statement *TryFinallyStatement::syntaxCopy() | 3201 Statement *TryFinallyStatement::syntaxCopy() |
3165 { | 3202 { |
3166 TryFinallyStatement *s = new TryFinallyStatement(loc, | 3203 TryFinallyStatement *s = new TryFinallyStatement(loc, |
3169 } | 3206 } |
3170 | 3207 |
3171 Statement *TryFinallyStatement::semantic(Scope *sc) | 3208 Statement *TryFinallyStatement::semantic(Scope *sc) |
3172 { | 3209 { |
3173 //printf("TryFinallyStatement::semantic()\n"); | 3210 //printf("TryFinallyStatement::semantic()\n"); |
3211 | |
3212 enclosingtry = sc->tfOfTry; | |
3213 sc->tfOfTry = this; | |
3174 body = body->semantic(sc); | 3214 body = body->semantic(sc); |
3215 sc->tfOfTry = enclosingtry; | |
3216 | |
3175 sc = sc->push(); | 3217 sc = sc->push(); |
3176 sc->tf = this; | 3218 sc->tf = this; |
3177 sc->sbreak = NULL; | 3219 sc->sbreak = NULL; |
3178 sc->scontinue = NULL; // no break or continue out of finally block | 3220 sc->scontinue = NULL; // no break or continue out of finally block |
3179 finalbody = finalbody->semantic(sc); | 3221 finalbody = finalbody->semantic(sc); |
3403 : Statement(loc) | 3445 : Statement(loc) |
3404 { | 3446 { |
3405 this->ident = ident; | 3447 this->ident = ident; |
3406 this->label = NULL; | 3448 this->label = NULL; |
3407 this->tf = NULL; | 3449 this->tf = NULL; |
3450 this->enclosingtry = NULL; | |
3408 } | 3451 } |
3409 | 3452 |
3410 Statement *GotoStatement::syntaxCopy() | 3453 Statement *GotoStatement::syntaxCopy() |
3411 { | 3454 { |
3412 GotoStatement *s = new GotoStatement(loc, ident); | 3455 GotoStatement *s = new GotoStatement(loc, ident); |
3416 Statement *GotoStatement::semantic(Scope *sc) | 3459 Statement *GotoStatement::semantic(Scope *sc) |
3417 { FuncDeclaration *fd = sc->parent->isFuncDeclaration(); | 3460 { FuncDeclaration *fd = sc->parent->isFuncDeclaration(); |
3418 | 3461 |
3419 //printf("GotoStatement::semantic()\n"); | 3462 //printf("GotoStatement::semantic()\n"); |
3420 tf = sc->tf; | 3463 tf = sc->tf; |
3464 enclosingtry = sc->tfOfTry; | |
3421 label = fd->searchLabel(ident); | 3465 label = fd->searchLabel(ident); |
3422 if (!label->statement && sc->fes) | 3466 if (!label->statement && sc->fes) |
3423 { | 3467 { |
3424 /* Either the goto label is forward referenced or it | 3468 /* Either the goto label is forward referenced or it |
3425 * is in the function that the enclosing foreach is in. | 3469 * is in the function that the enclosing foreach is in. |
3459 : Statement(loc) | 3503 : Statement(loc) |
3460 { | 3504 { |
3461 this->ident = ident; | 3505 this->ident = ident; |
3462 this->statement = statement; | 3506 this->statement = statement; |
3463 this->tf = NULL; | 3507 this->tf = NULL; |
3508 this->enclosingtry = NULL; | |
3464 this->lblock = NULL; | 3509 this->lblock = NULL; |
3465 this->isReturnLabel = 0; | 3510 this->isReturnLabel = 0; |
3466 this->llvmBB = NULL; | 3511 this->llvmBB = NULL; |
3467 } | 3512 } |
3468 | 3513 |
3481 if (ls->statement) | 3526 if (ls->statement) |
3482 error("Label '%s' already defined", ls->toChars()); | 3527 error("Label '%s' already defined", ls->toChars()); |
3483 else | 3528 else |
3484 ls->statement = this; | 3529 ls->statement = this; |
3485 tf = sc->tf; | 3530 tf = sc->tf; |
3531 enclosingtry = sc->tfOfTry; | |
3486 sc = sc->push(); | 3532 sc = sc->push(); |
3487 sc->scopesym = sc->enclosing->scopesym; | 3533 sc->scopesym = sc->enclosing->scopesym; |
3488 sc->callSuper |= CSXlabel; | 3534 sc->callSuper |= CSXlabel; |
3489 sc->slabel = this; | 3535 sc->slabel = this; |
3490 if (statement) | 3536 if (statement) |