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