comparison dmd/LabelStatement.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children cab4c37afb89
comparison
equal deleted inserted replaced
-1:000000000000 0:10317f0c89a5
1 module dmd.LabelStatement;
2
3 import dmd.Statement;
4 import dmd.Identifier;
5 import dmd.TryFinallyStatement;
6 import dmd.Scope;
7 import dmd.Loc;
8 import dmd.ExpStatement;
9 import dmd.ArrayTypes;
10 import dmd.Expression;
11 import dmd.InterState;
12 import dmd.InlineScanState;
13 import dmd.LabelDsymbol;
14 import dmd.FuncDeclaration;
15 import dmd.CSX;
16 import dmd.IRState;
17 import dmd.OutBuffer;
18 import dmd.HdrGenState;
19 import dmd.BE;
20
21 import dmd.backend.block;
22 import dmd.backend.Blockx;
23 import dmd.backend.Util;
24 import dmd.backend.BC;
25
26 class LabelStatement : Statement
27 {
28 Identifier ident;
29 Statement statement;
30 TryFinallyStatement tf = null;
31 block* lblock = null; // back end
32 int isReturnLabel = 0;
33
34 this(Loc loc, Identifier ident, Statement statement)
35 {
36 super(loc);
37 this.ident = ident;
38 this.statement = statement;
39 }
40
41 Statement syntaxCopy()
42 {
43 LabelStatement s = new LabelStatement(loc, ident, statement.syntaxCopy());
44 return s;
45 }
46
47 Statement semantic(Scope sc)
48 {
49 LabelDsymbol ls;
50 FuncDeclaration fd = sc.parent.isFuncDeclaration();
51
52 //printf("LabelStatement.semantic()\n");
53 ls = fd.searchLabel(ident);
54 if (ls.statement)
55 error("Label '%s' already defined", ls.toChars());
56 else
57 ls.statement = this;
58 tf = sc.tf;
59 sc = sc.push();
60 sc.scopesym = sc.enclosing.scopesym;
61 sc.callSuper |= CSXlabel;
62 sc.slabel = this;
63 if (statement)
64 statement = statement.semantic(sc);
65 sc.pop();
66 return this;
67 }
68
69 Statements flatten(Scope sc)
70 {
71 Statements a = null;
72
73 if (statement)
74 {
75 a = statement.flatten(sc);
76 if (a)
77 {
78 if (!a.dim)
79 a.push(cast(void*)new ExpStatement(loc, null));
80
81 Statement s = cast(Statement)a.data[0];
82
83 s = new LabelStatement(loc, ident, s);
84 a.data[0] = cast(void*)s;
85 }
86 }
87
88 return a;
89 }
90
91 bool usesEH()
92 {
93 return statement ? statement.usesEH() : false;
94 }
95
96 BE blockExit()
97 {
98 //printf("LabelStatement.blockExit(%p)\n", this);
99 return statement ? statement.blockExit() : BE.BEfallthru;
100 }
101
102 bool comeFrom()
103 {
104 //printf("LabelStatement.comeFrom()\n");
105 return true;
106 }
107
108 Expression interpret(InterState* istate)
109 {
110 assert(false);
111 }
112
113 void toCBuffer(OutBuffer buf, HdrGenState* hgs)
114 {
115 buf.writestring(ident.toChars());
116 buf.writebyte(':');
117 buf.writenl();
118 if (statement)
119 statement.toCBuffer(buf, hgs);
120 }
121
122 Statement inlineScan(InlineScanState* iss)
123 {
124 if (statement)
125 statement = statement.inlineScan(iss);
126 return this;
127 }
128
129 void toIR(IRState* irs)
130 {
131 //printf("LabelStatement.toIR() %p, statement = %p\n", this, statement);
132 Blockx* blx = irs.blx;
133 block* bc = blx.curblock;
134 IRState mystate = IRState(irs,this);
135 mystate.ident = ident;
136
137 if (lblock)
138 {
139 // We had made a guess about which tryblock the label is in.
140 // Error if we guessed wrong.
141 // BUG: should fix this
142 if (lblock.Btry != blx.tryblock)
143 error("cannot goto forward into different try block level");
144 }
145 else
146 lblock = block_calloc(blx);
147
148 block_next(blx,BCgoto,lblock);
149 list_append(&bc.Bsucc,blx.curblock);
150 if (statement)
151 statement.toIR(&mystate);
152 }
153 }