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 {