0
|
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 } |