Mercurial > projects > ddmd
annotate dmd/GotoStatement.d @ 161:584dc990e12f
type fixed
author | korDen |
---|---|
date | Mon, 20 Sep 2010 01:19:36 +0400 |
parents | c77e9f4f1793 |
children | e3afd1303184 |
rev | line source |
---|---|
0 | 1 module dmd.GotoStatement; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.Loc; |
5 import dmd.Scope; | |
6 import dmd.Statement; | |
7 import dmd.Identifier; | |
8 import dmd.CompoundStatement; | |
9 import dmd.LabelDsymbol; | |
10 import dmd.TryFinallyStatement; | |
11 import dmd.FuncDeclaration; | |
12 import dmd.OutBuffer; | |
13 import dmd.HdrGenState; | |
14 import dmd.Expression; | |
15 import dmd.InterState; | |
16 import dmd.IRState; | |
17 import dmd.ArrayTypes; | |
18 import dmd.BE; | |
19 | |
20 import dmd.codegen.Util; | |
21 import dmd.backend.Util; | |
22 import dmd.backend.block; | |
23 import dmd.backend.Blockx; | |
24 import dmd.backend.BC; | |
25 | |
26 class GotoStatement : Statement | |
27 { | |
28 Identifier ident; | |
29 LabelDsymbol label = null; | |
30 TryFinallyStatement tf = null; | |
31 | |
32 this(Loc loc, Identifier ident) | |
33 { | |
34 super(loc); | |
35 this.ident = ident; | |
36 } | |
37 | |
72 | 38 override Statement syntaxCopy() |
0 | 39 { |
40 GotoStatement s = new GotoStatement(loc, ident); | |
41 return s; | |
42 } | |
43 | |
72 | 44 override Statement semantic(Scope sc) |
0 | 45 { |
46 FuncDeclaration fd = sc.parent.isFuncDeclaration(); | |
47 | |
48 //printf("GotoStatement.semantic()\n"); | |
49 tf = sc.tf; | |
50 label = fd.searchLabel(ident); | |
51 if (!label.statement && sc.fes) | |
52 { | |
53 /* Either the goto label is forward referenced or it | |
54 * is in the function that the enclosing foreach is in. | |
55 * Can't know yet, so wrap the goto in a compound statement | |
56 * so we can patch it later, and add it to a 'look at this later' | |
57 * list. | |
58 */ | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
59 auto a = new Statements(); |
0 | 60 Statement s; |
61 | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
62 a.push(this); |
0 | 63 s = new CompoundStatement(loc, a); |
64 sc.fes.gotos.push(cast(void*)s); // 'look at this later' list | |
65 return s; | |
66 } | |
67 | |
68 if (label.statement && label.statement.tf != sc.tf) | |
69 error("cannot goto in or out of finally block"); | |
70 return this; | |
71 } | |
72 | |
72 | 73 override BE blockExit() |
0 | 74 { |
75 //printf("GotoStatement.blockExit(%p)\n", this); | |
76 return BE.BEgoto; | |
77 } | |
78 | |
72 | 79 override Expression interpret(InterState istate) |
0 | 80 { |
81 assert(false); | |
82 } | |
83 | |
72 | 84 override void toIR(IRState* irs) |
0 | 85 { |
86 block* b; | |
87 block* bdest; | |
88 Blockx* blx = irs.blx; | |
89 | |
90 if (!label.statement) | |
91 { | |
92 error("label %s is undefined", label.toChars()); | |
93 return; | |
94 } | |
95 if (tf !is label.statement.tf) | |
96 error("cannot goto forward out of or into finally block"); | |
97 | |
98 bdest = labelToBlock(loc, blx, label); | |
99 if (!bdest) | |
100 return; | |
101 b = blx.curblock; | |
102 incUsage(irs, loc); | |
103 | |
104 // Adjust exception handler scope index if in different try blocks | |
105 if (b.Btry != bdest.Btry) | |
106 { | |
107 // Check that bdest is in an enclosing try block | |
108 for (block* bt = b.Btry; bt != bdest.Btry; bt = bt.Btry) | |
109 { | |
110 if (!bt) | |
111 { | |
112 //printf("b.Btry = %p, bdest.Btry = %p\n", b.Btry, bdest.Btry); | |
113 error("cannot goto into try block"); | |
114 break; | |
115 } | |
116 } | |
117 | |
118 //setScopeIndex(blx, b, bdest.Btry ? bdest.Btry.Bscope_index : -1); | |
119 } | |
120 | |
121 list_append(&b.Bsucc,bdest); | |
122 block_next(blx,BCgoto,null); | |
123 } | |
124 | |
72 | 125 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 126 { |
127 buf.writestring("goto "); | |
128 buf.writestring(ident.toChars()); | |
129 buf.writebyte(';'); | |
130 buf.writenl(); | |
131 } | |
132 | |
72 | 133 override GotoStatement isGotoStatement() { return this; } |
134 } |