Mercurial > projects > ldc
comparison dmd2/statement.c @ 1526:54b3c1394d62
Merged dmdfe 2.031.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Tue, 07 Jul 2009 02:26:11 +0100 |
parents | 638d16625da2 |
children | e4f7b5d9c68a |
comparison
equal
deleted
inserted
replaced
1525:d28cd7c45267 | 1526:54b3c1394d62 |
---|---|
139 // TRUE if statement 'comes from' somewhere else, like a goto | 139 // TRUE if statement 'comes from' somewhere else, like a goto |
140 | 140 |
141 int Statement::comeFrom() | 141 int Statement::comeFrom() |
142 { | 142 { |
143 //printf("Statement::comeFrom()\n"); | 143 //printf("Statement::comeFrom()\n"); |
144 return FALSE; | |
145 } | |
146 | |
147 // Return TRUE if statement has no code in it | |
148 int Statement::isEmpty() | |
149 { | |
150 //printf("Statement::isEmpty()\n"); | |
144 return FALSE; | 151 return FALSE; |
145 } | 152 } |
146 | 153 |
147 /**************************************** | 154 /**************************************** |
148 * If this statement has code that needs to run in a finally clause | 155 * If this statement has code that needs to run in a finally clause |
578 comefrom |= s->comeFrom(); | 585 comefrom |= s->comeFrom(); |
579 } | 586 } |
580 return comefrom; | 587 return comefrom; |
581 } | 588 } |
582 | 589 |
590 int CompoundStatement::isEmpty() | |
591 { | |
592 for (int i = 0; i < statements->dim; i++) | |
593 { Statement *s = (Statement *) statements->data[i]; | |
594 if (s && !s->isEmpty()) | |
595 return FALSE; | |
596 } | |
597 return TRUE; | |
598 } | |
599 | |
583 | 600 |
584 /******************************** CompoundDeclarationStatement ***************************/ | 601 /******************************** CompoundDeclarationStatement ***************************/ |
585 | 602 |
586 CompoundDeclarationStatement::CompoundDeclarationStatement(Loc loc, Statements *s) | 603 CompoundDeclarationStatement::CompoundDeclarationStatement(Loc loc, Statements *s) |
587 : CompoundStatement(loc, s) | 604 : CompoundStatement(loc, s) |
854 { | 871 { |
855 //printf("ScopeStatement::comeFrom()\n"); | 872 //printf("ScopeStatement::comeFrom()\n"); |
856 return statement ? statement->comeFrom() : FALSE; | 873 return statement ? statement->comeFrom() : FALSE; |
857 } | 874 } |
858 | 875 |
876 int ScopeStatement::isEmpty() | |
877 { | |
878 //printf("ScopeStatement::isEmpty() %d\n", statement ? statement->isEmpty() : TRUE); | |
879 return statement ? statement->isEmpty() : TRUE; | |
880 } | |
881 | |
859 void ScopeStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 882 void ScopeStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
860 { | 883 { |
861 buf->writeByte('{'); | 884 buf->writeByte('{'); |
862 buf->writenl(); | 885 buf->writenl(); |
863 | 886 |
1534 goto Lapply; | 1557 goto Lapply; |
1535 | 1558 |
1536 /* Generate a temporary __r and initialize it with the aggregate. | 1559 /* Generate a temporary __r and initialize it with the aggregate. |
1537 */ | 1560 */ |
1538 Identifier *id = Identifier::generateId("__r"); | 1561 Identifier *id = Identifier::generateId("__r"); |
1539 aggr = aggr->semantic(sc); | |
1540 Expression *rinit = new SliceExp(loc, aggr, NULL, NULL); | 1562 Expression *rinit = new SliceExp(loc, aggr, NULL, NULL); |
1541 rinit = rinit->trySemantic(sc); | 1563 rinit = rinit->trySemantic(sc); |
1542 if (!rinit) // if application of [] failed | 1564 if (!rinit) // if application of [] failed |
1543 rinit = aggr; | 1565 rinit = aggr; |
1544 VarDeclaration *r = new VarDeclaration(loc, NULL, id, new ExpInitializer(loc, rinit)); | 1566 VarDeclaration *r = new VarDeclaration(loc, NULL, id, new ExpInitializer(loc, rinit)); |
1868 s = new CaseStatement(0, new IntegerExp(i + 2), s); | 1890 s = new CaseStatement(0, new IntegerExp(i + 2), s); |
1869 a->push(s); | 1891 a->push(s); |
1870 } | 1892 } |
1871 | 1893 |
1872 s = new CompoundStatement(loc, a); | 1894 s = new CompoundStatement(loc, a); |
1873 s = new SwitchStatement(loc, e, s); | 1895 s = new SwitchStatement(loc, e, s, FALSE); |
1874 s = s->semantic(sc); | 1896 s = s->semantic(sc); |
1875 } | 1897 } |
1876 break; | 1898 break; |
1877 } | 1899 } |
1878 | 1900 |
2544 } | 2566 } |
2545 | 2567 |
2546 | 2568 |
2547 /******************************** SwitchStatement ***************************/ | 2569 /******************************** SwitchStatement ***************************/ |
2548 | 2570 |
2549 SwitchStatement::SwitchStatement(Loc loc, Expression *c, Statement *b) | 2571 SwitchStatement::SwitchStatement(Loc loc, Expression *c, Statement *b, bool isFinal) |
2550 : Statement(loc) | 2572 : Statement(loc) |
2551 { | 2573 { |
2552 condition = c; | 2574 this->condition = c; |
2553 body = b; | 2575 this->body = b; |
2576 this->isFinal = isFinal; | |
2554 sdefault = NULL; | 2577 sdefault = NULL; |
2555 cases = NULL; | 2578 cases = NULL; |
2556 hasNoDefault = 0; | 2579 hasNoDefault = 0; |
2557 hasVars = 0; | 2580 hasVars = 0; |
2558 // LDC | 2581 #if IN_LLVM |
2559 enclosingScopeExit = NULL; | 2582 enclosingScopeExit = NULL; |
2583 #endif | |
2560 } | 2584 } |
2561 | 2585 |
2562 Statement *SwitchStatement::syntaxCopy() | 2586 Statement *SwitchStatement::syntaxCopy() |
2563 { | 2587 { |
2564 SwitchStatement *s = new SwitchStatement(loc, | 2588 SwitchStatement *s = new SwitchStatement(loc, |
2565 condition->syntaxCopy(), body->syntaxCopy()); | 2589 condition->syntaxCopy(), body->syntaxCopy(), isFinal); |
2566 return s; | 2590 return s; |
2567 } | 2591 } |
2568 | 2592 |
2569 Statement *SwitchStatement::semantic(Scope *sc) | 2593 Statement *SwitchStatement::semantic(Scope *sc) |
2570 { | 2594 { |
2571 //printf("SwitchStatement::semantic(%p)\n", this); | 2595 //printf("SwitchStatement::semantic(%p)\n", this); |
2572 assert(!cases); // ensure semantic() is only run once | 2596 assert(!cases); // ensure semantic() is only run once |
2573 | 2597 |
2574 // LDC | 2598 #if IN_LLVM |
2575 enclosingScopeExit = sc->enclosingScopeExit; | 2599 enclosingScopeExit = sc->enclosingScopeExit; |
2600 #endif | |
2576 | 2601 |
2577 condition = condition->semantic(sc); | 2602 condition = condition->semantic(sc); |
2578 condition = resolveProperties(sc, condition); | 2603 condition = resolveProperties(sc, condition); |
2579 if (condition->type->isString()) | 2604 if (condition->type->isString()) |
2580 { | 2605 { |
2660 sc->sw->sdefault = new DefaultStatement(loc, s); | 2685 sc->sw->sdefault = new DefaultStatement(loc, s); |
2661 a->push(sc->sw->sdefault); | 2686 a->push(sc->sw->sdefault); |
2662 cs = new CompoundStatement(loc, a); | 2687 cs = new CompoundStatement(loc, a); |
2663 body = cs; | 2688 body = cs; |
2664 } | 2689 } |
2690 | |
2691 #if DMDV2 | |
2692 if (isFinal) | |
2693 { Type *t = condition->type; | |
2694 while (t->ty == Ttypedef) | |
2695 { // Don't use toBasetype() because that will skip past enums | |
2696 t = ((TypeTypedef *)t)->sym->basetype; | |
2697 } | |
2698 if (condition->type->ty == Tenum) | |
2699 { TypeEnum *te = (TypeEnum *)condition->type; | |
2700 EnumDeclaration *ed = te->toDsymbol(sc)->isEnumDeclaration(); | |
2701 assert(ed); | |
2702 size_t dim = ed->members->dim; | |
2703 for (size_t i = 0; i < dim; i++) | |
2704 { | |
2705 EnumMember *em = ((Dsymbol *)ed->members->data[i])->isEnumMember(); | |
2706 if (em) | |
2707 { | |
2708 for (size_t j = 0; j < cases->dim; j++) | |
2709 { CaseStatement *cs = (CaseStatement *)cases->data[j]; | |
2710 if (cs->exp->equals(em->value)) | |
2711 goto L1; | |
2712 } | |
2713 error("enum member %s not represented in final switch", em->toChars()); | |
2714 } | |
2715 L1: | |
2716 ; | |
2717 } | |
2718 } | |
2719 } | |
2720 #endif | |
2665 | 2721 |
2666 sc->pop(); | 2722 sc->pop(); |
2667 return this; | 2723 return this; |
2668 } | 2724 } |
2669 | 2725 |
2744 | 2800 |
2745 //printf("CaseStatement::semantic() %s\n", toChars()); | 2801 //printf("CaseStatement::semantic() %s\n", toChars()); |
2746 exp = exp->semantic(sc); | 2802 exp = exp->semantic(sc); |
2747 if (sw) | 2803 if (sw) |
2748 { | 2804 { |
2749 // LDC | 2805 #if IN_LLVM |
2750 enclosingScopeExit = sc->enclosingScopeExit; | 2806 enclosingScopeExit = sc->enclosingScopeExit; |
2751 if (enclosingScopeExit != sw->enclosingScopeExit) | 2807 if (enclosingScopeExit != sw->enclosingScopeExit) |
2752 { | 2808 { |
2753 error("case must be inside the same try, synchronized or volatile level as switch"); | 2809 error("case must be inside the same try, synchronized or volatile level as switch"); |
2754 } | 2810 } |
2755 | 2811 #endif |
2756 exp = exp->implicitCastTo(sc, sw->condition->type); | 2812 exp = exp->implicitCastTo(sc, sw->condition->type); |
2757 exp = exp->optimize(WANTvalue | WANTinterpret); | 2813 exp = exp->optimize(WANTvalue | WANTinterpret); |
2758 | 2814 |
2759 /* This is where variables are allowed as case expressions. | 2815 /* This is where variables are allowed as case expressions. |
2760 */ | 2816 */ |
2765 if (v && (t->isintegral() || t->ty == Tclass)) | 2821 if (v && (t->isintegral() || t->ty == Tclass)) |
2766 { /* Flag that we need to do special code generation | 2822 { /* Flag that we need to do special code generation |
2767 * for this, i.e. generate a sequence of if-then-else | 2823 * for this, i.e. generate a sequence of if-then-else |
2768 */ | 2824 */ |
2769 sw->hasVars = 1; | 2825 sw->hasVars = 1; |
2826 if (sw->isFinal) | |
2827 error("case variables not allowed in final switch statements"); | |
2770 goto L1; | 2828 goto L1; |
2771 } | 2829 } |
2772 } | 2830 } |
2773 | 2831 |
2774 if (exp->op != TOKstring && exp->op != TOKint64) | 2832 if (exp->op != TOKstring && exp->op != TOKint64) |
2843 exp->toCBuffer(buf, hgs); | 2901 exp->toCBuffer(buf, hgs); |
2844 buf->writebyte(':'); | 2902 buf->writebyte(':'); |
2845 buf->writenl(); | 2903 buf->writenl(); |
2846 statement->toCBuffer(buf, hgs); | 2904 statement->toCBuffer(buf, hgs); |
2847 } | 2905 } |
2906 | |
2907 /******************************** CaseRangeStatement ***************************/ | |
2908 | |
2909 #if DMDV2 | |
2910 | |
2911 CaseRangeStatement::CaseRangeStatement(Loc loc, Expression *first, | |
2912 Expression *last, Statement *s) | |
2913 : Statement(loc) | |
2914 { | |
2915 this->first = first; | |
2916 this->last = last; | |
2917 this->statement = s; | |
2918 } | |
2919 | |
2920 Statement *CaseRangeStatement::syntaxCopy() | |
2921 { | |
2922 CaseRangeStatement *s = new CaseRangeStatement(loc, | |
2923 first->syntaxCopy(), last->syntaxCopy(), statement->syntaxCopy()); | |
2924 return s; | |
2925 } | |
2926 | |
2927 Statement *CaseRangeStatement::semantic(Scope *sc) | |
2928 { SwitchStatement *sw = sc->sw; | |
2929 | |
2930 //printf("CaseRangeStatement::semantic() %s\n", toChars()); | |
2931 if (sw->isFinal) | |
2932 error("case ranges not allowed in final switch"); | |
2933 | |
2934 first = first->semantic(sc); | |
2935 first = first->implicitCastTo(sc, sw->condition->type); | |
2936 first = first->optimize(WANTvalue | WANTinterpret); | |
2937 dinteger_t fval = first->toInteger(); | |
2938 | |
2939 last = last->semantic(sc); | |
2940 last = last->implicitCastTo(sc, sw->condition->type); | |
2941 last = last->optimize(WANTvalue | WANTinterpret); | |
2942 dinteger_t lval = last->toInteger(); | |
2943 | |
2944 if (lval - fval > 256) | |
2945 { error("more than 256 cases in case range"); | |
2946 lval = fval + 256; | |
2947 } | |
2948 | |
2949 /* This works by replacing the CaseRange with an array of Case's. | |
2950 * | |
2951 * case a: .. case b: s; | |
2952 * => | |
2953 * case a: | |
2954 * [...] | |
2955 * case b: | |
2956 * s; | |
2957 */ | |
2958 | |
2959 Statements *statements = new Statements(); | |
2960 for (dinteger_t i = fval; i <= lval; i++) | |
2961 { | |
2962 Statement *s = statement; | |
2963 if (i != lval) | |
2964 s = new ExpStatement(loc, NULL); | |
2965 Expression *e = new IntegerExp(loc, i, first->type); | |
2966 Statement *cs = new CaseStatement(loc, e, s); | |
2967 statements->push(cs); | |
2968 } | |
2969 Statement *s = new CompoundStatement(loc, statements); | |
2970 s = s->semantic(sc); | |
2971 return s; | |
2972 } | |
2973 | |
2974 void CaseRangeStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | |
2975 { | |
2976 buf->writestring("case "); | |
2977 first->toCBuffer(buf, hgs); | |
2978 buf->writestring(": .. case "); | |
2979 last->toCBuffer(buf, hgs); | |
2980 buf->writenl(); | |
2981 statement->toCBuffer(buf, hgs); | |
2982 } | |
2983 | |
2984 #endif | |
2848 | 2985 |
2849 /******************************** DefaultStatement ***************************/ | 2986 /******************************** DefaultStatement ***************************/ |
2850 | 2987 |
2851 DefaultStatement::DefaultStatement(Loc loc, Statement *s) | 2988 DefaultStatement::DefaultStatement(Loc loc, Statement *s) |
2852 : Statement(loc) | 2989 : Statement(loc) |
2875 { | 3012 { |
2876 error("switch statement already has a default"); | 3013 error("switch statement already has a default"); |
2877 } | 3014 } |
2878 sc->sw->sdefault = this; | 3015 sc->sw->sdefault = this; |
2879 | 3016 |
2880 // LDC | 3017 #if IN_LLVM |
2881 enclosingScopeExit = sc->enclosingScopeExit; | 3018 enclosingScopeExit = sc->enclosingScopeExit; |
2882 if (enclosingScopeExit != sc->sw->enclosingScopeExit) | 3019 if (enclosingScopeExit != sc->sw->enclosingScopeExit) |
2883 { | 3020 { |
2884 error("default must be inside the same try, synchronized or volatile level as switch"); | 3021 error("default must be inside the same try, synchronized or volatile level as switch"); |
2885 } | 3022 } |
3023 | |
3024 if (sc->sw->isFinal) | |
3025 { | |
3026 error("default statement not allowed in final switch statement"); | |
3027 } | |
3028 #endif | |
2886 } | 3029 } |
2887 else | 3030 else |
2888 error("default not in switch statement"); | 3031 error("default not in switch statement"); |
2889 statement = statement->semantic(sc); | 3032 statement = statement->semantic(sc); |
2890 return this; | 3033 return this; |
3215 s = new ReturnStatement(0, new VarExp(0, fd->vresult)); | 3358 s = new ReturnStatement(0, new VarExp(0, fd->vresult)); |
3216 sc->fes->cases.push(s); | 3359 sc->fes->cases.push(s); |
3217 | 3360 |
3218 // Construct: { vresult = exp; return cases.dim + 1; } | 3361 // Construct: { vresult = exp; return cases.dim + 1; } |
3219 exp = new AssignExp(loc, new VarExp(0, fd->vresult), exp); | 3362 exp = new AssignExp(loc, new VarExp(0, fd->vresult), exp); |
3363 exp->op = TOKconstruct; | |
3220 exp = exp->semantic(sc); | 3364 exp = exp->semantic(sc); |
3221 Statement *s1 = new ExpStatement(loc, exp); | 3365 Statement *s1 = new ExpStatement(loc, exp); |
3222 Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1)); | 3366 Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1)); |
3223 s = new CompoundStatement(loc, s1, s2); | 3367 s = new CompoundStatement(loc, s1, s2); |
3224 } | 3368 } |
3231 { | 3375 { |
3232 assert(fd->vresult); | 3376 assert(fd->vresult); |
3233 VarExp *v = new VarExp(0, fd->vresult); | 3377 VarExp *v = new VarExp(0, fd->vresult); |
3234 | 3378 |
3235 exp = new AssignExp(loc, v, exp); | 3379 exp = new AssignExp(loc, v, exp); |
3380 exp->op = TOKconstruct; | |
3236 exp = exp->semantic(sc); | 3381 exp = exp->semantic(sc); |
3237 } | 3382 } |
3238 | 3383 |
3239 if (((TypeFunction *)fd->type)->isref && !fd->isCtorDeclaration()) | 3384 if (((TypeFunction *)fd->type)->isref && !fd->isCtorDeclaration()) |
3240 { // Function returns a reference | 3385 { // Function returns a reference |
3755 if (c->type->toBasetype()->implicitConvTo(cj->type->toBasetype())) | 3900 if (c->type->toBasetype()->implicitConvTo(cj->type->toBasetype())) |
3756 error("catch at %s hides catch at %s", sj, si); | 3901 error("catch at %s hides catch at %s", sj, si); |
3757 } | 3902 } |
3758 } | 3903 } |
3759 | 3904 |
3760 if (!body) | 3905 if (!body || body->isEmpty()) |
3906 { | |
3761 return NULL; | 3907 return NULL; |
3762 | 3908 } |
3763 return this; | 3909 return this; |
3764 } | 3910 } |
3765 | 3911 |
3766 int TryCatchStatement::hasBreak() | 3912 int TryCatchStatement::hasBreak() |
3767 { | 3913 { |