Mercurial > projects > ldc
comparison dmd/statement.c @ 875:330f999ade44
Merged DMD 1.038
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Tue, 06 Jan 2009 16:33:51 +0100 |
parents | bc982f1ad106 |
children | d51551cb3a85 |
comparison
equal
deleted
inserted
replaced
874:2ddee23bd70e | 875:330f999ade44 |
---|---|
122 printf("%s\n", toChars()); | 122 printf("%s\n", toChars()); |
123 assert(0); | 123 assert(0); |
124 return BEany; | 124 return BEany; |
125 } | 125 } |
126 | 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 } | |
133 | |
134 // TRUE if statement 'comes from' somewhere else, like a goto | 127 // TRUE if statement 'comes from' somewhere else, like a goto |
135 | 128 |
136 int Statement::comeFrom() | 129 int Statement::comeFrom() |
137 { | 130 { |
138 //printf("Statement::comeFrom()\n"); | 131 //printf("Statement::comeFrom()\n"); |
225 result |= BEthrow; | 218 result |= BEthrow; |
226 } | 219 } |
227 return result; | 220 return result; |
228 } | 221 } |
229 | 222 |
230 int ExpStatement::fallOffEnd() | |
231 { | |
232 if (exp) | |
233 { | |
234 if (exp->op == TOKassert) | |
235 { AssertExp *a = (AssertExp *)exp; | |
236 | |
237 if (a->e1->isBool(FALSE)) // if it's an assert(0) | |
238 return FALSE; | |
239 } | |
240 else if (exp->op == TOKhalt) | |
241 return FALSE; | |
242 } | |
243 return TRUE; | |
244 } | |
245 | 223 |
246 /******************************** CompileStatement ***************************/ | 224 /******************************** CompileStatement ***************************/ |
247 | 225 |
248 CompileStatement::CompileStatement(Loc loc, Expression *exp) | 226 CompileStatement::CompileStatement(Loc loc, Expression *exp) |
249 : Statement(loc) | 227 : Statement(loc) |
572 } | 550 } |
573 } | 551 } |
574 return result; | 552 return result; |
575 } | 553 } |
576 | 554 |
577 int CompoundStatement::fallOffEnd() | |
578 { int falloff = TRUE; | |
579 | |
580 //printf("CompoundStatement::fallOffEnd() %s\n", toChars()); | |
581 for (int i = 0; i < statements->dim; i++) | |
582 { Statement *s = (Statement *)statements->data[i]; | |
583 | |
584 if (!s) | |
585 continue; | |
586 | |
587 if (!falloff && global.params.warnings && !s->comeFrom()) | |
588 { | |
589 warning("%s: statement is not reachable", s->loc.toChars()); | |
590 } | |
591 falloff = s->fallOffEnd(); | |
592 } | |
593 return falloff; | |
594 } | |
595 | |
596 int CompoundStatement::comeFrom() | 555 int CompoundStatement::comeFrom() |
597 { int comefrom = FALSE; | 556 { int comefrom = FALSE; |
598 | 557 |
599 //printf("CompoundStatement::comeFrom()\n"); | 558 //printf("CompoundStatement::comeFrom()\n"); |
600 for (int i = 0; i < statements->dim; i++) | 559 for (int i = 0; i < statements->dim; i++) |
708 } | 667 } |
709 } | 668 } |
710 return result; | 669 return result; |
711 } | 670 } |
712 | 671 |
713 int UnrolledLoopStatement::fallOffEnd() | |
714 { | |
715 //printf("UnrolledLoopStatement::fallOffEnd()\n"); | |
716 for (size_t i = 0; i < statements->dim; i++) | |
717 { Statement *s = (Statement *)statements->data[i]; | |
718 | |
719 if (s) | |
720 s->fallOffEnd(); | |
721 } | |
722 return TRUE; | |
723 } | |
724 | |
725 int UnrolledLoopStatement::comeFrom() | 672 int UnrolledLoopStatement::comeFrom() |
726 { int comefrom = FALSE; | 673 { int comefrom = FALSE; |
727 | 674 |
728 //printf("UnrolledLoopStatement::comeFrom()\n"); | 675 //printf("UnrolledLoopStatement::comeFrom()\n"); |
729 for (size_t i = 0; i < statements->dim; i++) | 676 for (size_t i = 0; i < statements->dim; i++) |
811 | 758 |
812 int ScopeStatement::blockExit() | 759 int ScopeStatement::blockExit() |
813 { | 760 { |
814 //printf("ScopeStatement::blockExit(%p)\n", statement); | 761 //printf("ScopeStatement::blockExit(%p)\n", statement); |
815 return statement ? statement->blockExit() : BEfallthru; | 762 return statement ? statement->blockExit() : BEfallthru; |
816 } | |
817 | |
818 int ScopeStatement::fallOffEnd() | |
819 { | |
820 return statement ? statement->fallOffEnd() : TRUE; | |
821 } | 763 } |
822 | 764 |
823 int ScopeStatement::comeFrom() | 765 int ScopeStatement::comeFrom() |
824 { | 766 { |
825 //printf("ScopeStatement::comeFrom()\n"); | 767 //printf("ScopeStatement::comeFrom()\n"); |
943 } | 885 } |
944 result &= ~(BEbreak | BEcontinue); | 886 result &= ~(BEbreak | BEcontinue); |
945 return result; | 887 return result; |
946 } | 888 } |
947 | 889 |
948 int WhileStatement::fallOffEnd() | |
949 { | |
950 if (body) | |
951 body->fallOffEnd(); | |
952 return TRUE; | |
953 } | |
954 | |
955 int WhileStatement::comeFrom() | 890 int WhileStatement::comeFrom() |
956 { | 891 { |
957 if (body) | 892 if (body) |
958 return body->comeFrom(); | 893 return body->comeFrom(); |
959 return FALSE; | 894 return FALSE; |
1036 if (!(result & BEbreak) && condition->isBool(TRUE)) | 971 if (!(result & BEbreak) && condition->isBool(TRUE)) |
1037 result &= ~BEfallthru; | 972 result &= ~BEfallthru; |
1038 } | 973 } |
1039 result &= ~(BEbreak | BEcontinue); | 974 result &= ~(BEbreak | BEcontinue); |
1040 return result; | 975 return result; |
1041 } | |
1042 | |
1043 int DoStatement::fallOffEnd() | |
1044 { | |
1045 if (body) | |
1046 body->fallOffEnd(); | |
1047 return TRUE; | |
1048 } | 976 } |
1049 | 977 |
1050 int DoStatement::comeFrom() | 978 int DoStatement::comeFrom() |
1051 { | 979 { |
1052 if (body) | 980 if (body) |
1173 result |= r & ~(BEbreak | BEcontinue); | 1101 result |= r & ~(BEbreak | BEcontinue); |
1174 } | 1102 } |
1175 if (increment && increment->canThrow()) | 1103 if (increment && increment->canThrow()) |
1176 result |= BEthrow; | 1104 result |= BEthrow; |
1177 return result; | 1105 return result; |
1178 } | |
1179 | |
1180 int ForStatement::fallOffEnd() | |
1181 { | |
1182 if (body) | |
1183 body->fallOffEnd(); | |
1184 return TRUE; | |
1185 } | 1106 } |
1186 | 1107 |
1187 int ForStatement::comeFrom() | 1108 int ForStatement::comeFrom() |
1188 { | 1109 { |
1189 //printf("ForStatement::comeFrom()\n"); | 1110 //printf("ForStatement::comeFrom()\n"); |
1876 result |= body->blockExit() & ~(BEbreak | BEcontinue); | 1797 result |= body->blockExit() & ~(BEbreak | BEcontinue); |
1877 } | 1798 } |
1878 return result; | 1799 return result; |
1879 } | 1800 } |
1880 | 1801 |
1881 int ForeachStatement::fallOffEnd() | |
1882 { | |
1883 if (body) | |
1884 body->fallOffEnd(); | |
1885 return TRUE; | |
1886 } | |
1887 | |
1888 int ForeachStatement::comeFrom() | 1802 int ForeachStatement::comeFrom() |
1889 { | 1803 { |
1890 if (body) | 1804 if (body) |
1891 return body->comeFrom(); | 1805 return body->comeFrom(); |
1892 return FALSE; | 1806 return FALSE; |
2039 result |= BEfallthru; | 1953 result |= BEfallthru; |
2040 } | 1954 } |
2041 //printf("IfStatement::blockExit(%p) = x%x\n", this, result); | 1955 //printf("IfStatement::blockExit(%p) = x%x\n", this, result); |
2042 return result; | 1956 return result; |
2043 } | 1957 } |
2044 | |
2045 int IfStatement::fallOffEnd() | |
2046 { | |
2047 if (!ifbody || ifbody->fallOffEnd() || | |
2048 !elsebody || elsebody->fallOffEnd()) | |
2049 return TRUE; | |
2050 return FALSE; | |
2051 } | |
2052 | |
2053 | 1958 |
2054 void IfStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 1959 void IfStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
2055 { | 1960 { |
2056 buf->writestring("if ("); | 1961 buf->writestring("if ("); |
2057 if (arg) | 1962 if (arg) |
2266 result |= body->blockExit(); | 2171 result |= body->blockExit(); |
2267 #endif | 2172 #endif |
2268 return result; | 2173 return result; |
2269 } | 2174 } |
2270 | 2175 |
2271 int PragmaStatement::fallOffEnd() | |
2272 { | |
2273 if (body) | |
2274 return body->fallOffEnd(); | |
2275 return TRUE; | |
2276 } | |
2277 | |
2278 void PragmaStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 2176 void PragmaStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
2279 { | 2177 { |
2280 buf->writestring("pragma ("); | 2178 buf->writestring("pragma ("); |
2281 buf->writestring(ident->toChars()); | 2179 buf->writestring(ident->toChars()); |
2282 if (args && args->dim) | 2180 if (args && args->dim) |
2471 } | 2369 } |
2472 else | 2370 else |
2473 result |= BEfallthru; | 2371 result |= BEfallthru; |
2474 | 2372 |
2475 return result; | 2373 return result; |
2476 } | |
2477 | |
2478 int SwitchStatement::fallOffEnd() | |
2479 { | |
2480 if (body) | |
2481 body->fallOffEnd(); | |
2482 return TRUE; // need to do this better | |
2483 } | 2374 } |
2484 | 2375 |
2485 void SwitchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 2376 void SwitchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
2486 { | 2377 { |
2487 buf->writestring("switch ("); | 2378 buf->writestring("switch ("); |
2584 int CaseStatement::blockExit() | 2475 int CaseStatement::blockExit() |
2585 { | 2476 { |
2586 return statement->blockExit(); | 2477 return statement->blockExit(); |
2587 } | 2478 } |
2588 | 2479 |
2589 int CaseStatement::fallOffEnd() | |
2590 { | |
2591 return statement->fallOffEnd(); | |
2592 } | |
2593 | |
2594 int CaseStatement::comeFrom() | 2480 int CaseStatement::comeFrom() |
2595 { | 2481 { |
2596 return TRUE; | 2482 return TRUE; |
2597 } | 2483 } |
2598 | 2484 |
2648 int DefaultStatement::blockExit() | 2534 int DefaultStatement::blockExit() |
2649 { | 2535 { |
2650 return statement->blockExit(); | 2536 return statement->blockExit(); |
2651 } | 2537 } |
2652 | 2538 |
2653 int DefaultStatement::fallOffEnd() | |
2654 { | |
2655 return statement->fallOffEnd(); | |
2656 } | |
2657 | |
2658 int DefaultStatement::comeFrom() | 2539 int DefaultStatement::comeFrom() |
2659 { | 2540 { |
2660 return TRUE; | 2541 return TRUE; |
2661 } | 2542 } |
2662 | 2543 |
2691 } | 2572 } |
2692 | 2573 |
2693 int GotoDefaultStatement::blockExit() | 2574 int GotoDefaultStatement::blockExit() |
2694 { | 2575 { |
2695 return BEgoto; | 2576 return BEgoto; |
2696 } | |
2697 | |
2698 int GotoDefaultStatement::fallOffEnd() | |
2699 { | |
2700 return FALSE; | |
2701 } | 2577 } |
2702 | 2578 |
2703 void GotoDefaultStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 2579 void GotoDefaultStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
2704 { | 2580 { |
2705 buf->writestring("goto default;\n"); | 2581 buf->writestring("goto default;\n"); |
2747 int GotoCaseStatement::blockExit() | 2623 int GotoCaseStatement::blockExit() |
2748 { | 2624 { |
2749 return BEgoto; | 2625 return BEgoto; |
2750 } | 2626 } |
2751 | 2627 |
2752 int GotoCaseStatement::fallOffEnd() | |
2753 { | |
2754 return FALSE; | |
2755 } | |
2756 | |
2757 void GotoCaseStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 2628 void GotoCaseStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
2758 { | 2629 { |
2759 buf->writestring("goto case"); | 2630 buf->writestring("goto case"); |
2760 if (exp) | 2631 if (exp) |
2761 { buf->writebyte(' '); | 2632 { buf->writebyte(' '); |
2773 } | 2644 } |
2774 | 2645 |
2775 int SwitchErrorStatement::blockExit() | 2646 int SwitchErrorStatement::blockExit() |
2776 { | 2647 { |
2777 return BEthrow; | 2648 return BEthrow; |
2778 } | |
2779 | |
2780 int SwitchErrorStatement::fallOffEnd() | |
2781 { | |
2782 return FALSE; | |
2783 } | 2649 } |
2784 | 2650 |
2785 void SwitchErrorStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 2651 void SwitchErrorStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
2786 { | 2652 { |
2787 buf->writestring("SwitchErrorStatement::toCBuffer()"); | 2653 buf->writestring("SwitchErrorStatement::toCBuffer()"); |
3052 { int result = BEreturn; | 2918 { int result = BEreturn; |
3053 | 2919 |
3054 if (exp && exp->canThrow()) | 2920 if (exp && exp->canThrow()) |
3055 result |= BEthrow; | 2921 result |= BEthrow; |
3056 return result; | 2922 return result; |
3057 } | |
3058 | |
3059 int ReturnStatement::fallOffEnd() | |
3060 { | |
3061 return FALSE; | |
3062 } | 2923 } |
3063 | 2924 |
3064 void ReturnStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 2925 void ReturnStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
3065 { | 2926 { |
3066 buf->printf("return "); | 2927 buf->printf("return "); |
3153 { | 3014 { |
3154 //printf("BreakStatement::blockExit(%p) = x%x\n", this, ident ? BEgoto : BEbreak); | 3015 //printf("BreakStatement::blockExit(%p) = x%x\n", this, ident ? BEgoto : BEbreak); |
3155 return ident ? BEgoto : BEbreak; | 3016 return ident ? BEgoto : BEbreak; |
3156 } | 3017 } |
3157 | 3018 |
3158 int BreakStatement::fallOffEnd() | |
3159 { | |
3160 return FALSE; | |
3161 } | |
3162 | |
3163 void BreakStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 3019 void BreakStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
3164 { | 3020 { |
3165 buf->writestring("break"); | 3021 buf->writestring("break"); |
3166 if (ident) | 3022 if (ident) |
3167 { buf->writebyte(' '); | 3023 { buf->writebyte(' '); |
3261 int ContinueStatement::blockExit() | 3117 int ContinueStatement::blockExit() |
3262 { | 3118 { |
3263 return ident ? BEgoto : BEcontinue; | 3119 return ident ? BEgoto : BEcontinue; |
3264 } | 3120 } |
3265 | 3121 |
3266 int ContinueStatement::fallOffEnd() | |
3267 { | |
3268 return FALSE; | |
3269 } | |
3270 | |
3271 void ContinueStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 3122 void ContinueStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
3272 { | 3123 { |
3273 buf->writestring("continue"); | 3124 buf->writestring("continue"); |
3274 if (ident) | 3125 if (ident) |
3275 { buf->writebyte(' '); | 3126 { buf->writebyte(' '); |
3354 } | 3205 } |
3355 | 3206 |
3356 int SynchronizedStatement::blockExit() | 3207 int SynchronizedStatement::blockExit() |
3357 { | 3208 { |
3358 return body ? body->blockExit() : BEfallthru; | 3209 return body ? body->blockExit() : BEfallthru; |
3359 } | |
3360 | |
3361 int SynchronizedStatement::fallOffEnd() | |
3362 { | |
3363 return body ? body->fallOffEnd() : TRUE; | |
3364 } | 3210 } |
3365 | 3211 |
3366 void SynchronizedStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 3212 void SynchronizedStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
3367 { | 3213 { |
3368 buf->writestring("synchronized"); | 3214 buf->writestring("synchronized"); |
3478 else | 3324 else |
3479 result |= BEfallthru; | 3325 result |= BEfallthru; |
3480 return result; | 3326 return result; |
3481 } | 3327 } |
3482 | 3328 |
3483 int WithStatement::fallOffEnd() | |
3484 { | |
3485 return body ? body->fallOffEnd() : TRUE; | |
3486 } | |
3487 | |
3488 /******************************** TryCatchStatement ***************************/ | 3329 /******************************** TryCatchStatement ***************************/ |
3489 | 3330 |
3490 TryCatchStatement::TryCatchStatement(Loc loc, Statement *body, Array *catches) | 3331 TryCatchStatement::TryCatchStatement(Loc loc, Statement *body, Array *catches) |
3491 : Statement(loc) | 3332 : Statement(loc) |
3492 { | 3333 { |
3550 | 3391 |
3551 for (size_t i = 0; i < catches->dim; i++) | 3392 for (size_t i = 0; i < catches->dim; i++) |
3552 { | 3393 { |
3553 Catch *c = (Catch *)catches->data[i]; | 3394 Catch *c = (Catch *)catches->data[i]; |
3554 result |= c->blockExit(); | 3395 result |= c->blockExit(); |
3555 } | |
3556 return result; | |
3557 } | |
3558 | |
3559 int TryCatchStatement::fallOffEnd() | |
3560 { | |
3561 int result = FALSE; | |
3562 | |
3563 if (body) | |
3564 result = body->fallOffEnd(); | |
3565 for (int i = 0; i < catches->dim; i++) | |
3566 { Catch *c; | |
3567 | |
3568 c = (Catch *)catches->data[i]; | |
3569 if (c->handler) | |
3570 result |= c->handler->fallOffEnd(); | |
3571 } | 3396 } |
3572 return result; | 3397 return result; |
3573 } | 3398 } |
3574 | 3399 |
3575 void TryCatchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 3400 void TryCatchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
3726 return TRUE; | 3551 return TRUE; |
3727 } | 3552 } |
3728 | 3553 |
3729 int TryFinallyStatement::blockExit() | 3554 int TryFinallyStatement::blockExit() |
3730 { | 3555 { |
3731 int result = body->blockExit(); | 3556 if (body) |
3732 return result; | 3557 return body->blockExit(); |
3733 } | 3558 return BEfallthru; |
3734 | 3559 } |
3735 int TryFinallyStatement::fallOffEnd() | 3560 |
3736 { int result; | |
3737 | |
3738 result = body ? body->fallOffEnd() : TRUE; | |
3739 // if (finalbody) | |
3740 // result = finalbody->fallOffEnd(); | |
3741 return result; | |
3742 } | |
3743 | 3561 |
3744 /****************************** OnScopeStatement ***************************/ | 3562 /****************************** OnScopeStatement ***************************/ |
3745 | 3563 |
3746 OnScopeStatement::OnScopeStatement(Loc loc, TOK tok, Statement *statement) | 3564 OnScopeStatement::OnScopeStatement(Loc loc, TOK tok, Statement *statement) |
3747 : Statement(loc) | 3565 : Statement(loc) |
3859 int ThrowStatement::blockExit() | 3677 int ThrowStatement::blockExit() |
3860 { | 3678 { |
3861 return BEthrow; // obviously | 3679 return BEthrow; // obviously |
3862 } | 3680 } |
3863 | 3681 |
3864 int ThrowStatement::fallOffEnd() | |
3865 { | |
3866 return FALSE; | |
3867 } | |
3868 | |
3869 void ThrowStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 3682 void ThrowStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
3870 { | 3683 { |
3871 buf->printf("throw "); | 3684 buf->printf("throw "); |
3872 exp->toCBuffer(buf, hgs); | 3685 exp->toCBuffer(buf, hgs); |
3873 buf->writeByte(';'); | 3686 buf->writeByte(';'); |
3920 } | 3733 } |
3921 | 3734 |
3922 int VolatileStatement::blockExit() | 3735 int VolatileStatement::blockExit() |
3923 { | 3736 { |
3924 return statement ? statement->blockExit() : BEfallthru; | 3737 return statement ? statement->blockExit() : BEfallthru; |
3925 } | |
3926 | |
3927 int VolatileStatement::fallOffEnd() | |
3928 { | |
3929 return statement ? statement->fallOffEnd() : TRUE; | |
3930 } | 3738 } |
3931 | 3739 |
3932 void VolatileStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 3740 void VolatileStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
3933 { | 3741 { |
3934 buf->writestring("volatile"); | 3742 buf->writestring("volatile"); |
3989 | 3797 |
3990 int GotoStatement::blockExit() | 3798 int GotoStatement::blockExit() |
3991 { | 3799 { |
3992 //printf("GotoStatement::blockExit(%p)\n", this); | 3800 //printf("GotoStatement::blockExit(%p)\n", this); |
3993 return BEgoto; | 3801 return BEgoto; |
3994 } | |
3995 | |
3996 int GotoStatement::fallOffEnd() | |
3997 { | |
3998 return FALSE; | |
3999 } | 3802 } |
4000 | 3803 |
4001 void GotoStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 3804 void GotoStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
4002 { | 3805 { |
4003 buf->writestring("goto "); | 3806 buf->writestring("goto "); |
4085 { | 3888 { |
4086 //printf("LabelStatement::blockExit(%p)\n", this); | 3889 //printf("LabelStatement::blockExit(%p)\n", this); |
4087 return statement ? statement->blockExit() : BEfallthru; | 3890 return statement ? statement->blockExit() : BEfallthru; |
4088 } | 3891 } |
4089 | 3892 |
4090 int LabelStatement::fallOffEnd() | |
4091 { | |
4092 return statement ? statement->fallOffEnd() : TRUE; | |
4093 } | |
4094 | |
4095 int LabelStatement::comeFrom() | 3893 int LabelStatement::comeFrom() |
4096 { | 3894 { |
4097 //printf("LabelStatement::comeFrom()\n"); | 3895 //printf("LabelStatement::comeFrom()\n"); |
4098 return TRUE; | 3896 return TRUE; |
4099 } | 3897 } |