Mercurial > projects > ddmd
annotate dmd/GotoStatement.d @ 192:eb38fdcb3e62 default tip
updated to compile with dmd2.062
author | korDen |
---|---|
date | Sat, 02 Mar 2013 01:25:52 -0800 |
parents | b0d41ff5e0df |
children |
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 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
26 import dmd.DDMDExtensions; |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
27 |
0 | 28 class GotoStatement : Statement |
29 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
30 mixin insertMemberExtension!(typeof(this)); |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
31 |
0 | 32 Identifier ident; |
33 LabelDsymbol label = null; | |
34 TryFinallyStatement tf = null; | |
35 | |
36 this(Loc loc, Identifier ident) | |
37 { | |
178 | 38 register(); |
0 | 39 super(loc); |
40 this.ident = ident; | |
41 } | |
42 | |
72 | 43 override Statement syntaxCopy() |
0 | 44 { |
45 GotoStatement s = new GotoStatement(loc, ident); | |
46 return s; | |
47 } | |
48 | |
72 | 49 override Statement semantic(Scope sc) |
0 | 50 { |
51 FuncDeclaration fd = sc.parent.isFuncDeclaration(); | |
52 | |
53 //printf("GotoStatement.semantic()\n"); | |
54 tf = sc.tf; | |
55 label = fd.searchLabel(ident); | |
56 if (!label.statement && sc.fes) | |
57 { | |
58 /* Either the goto label is forward referenced or it | |
59 * is in the function that the enclosing foreach is in. | |
60 * Can't know yet, so wrap the goto in a compound statement | |
61 * so we can patch it later, and add it to a 'look at this later' | |
62 * list. | |
63 */ | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
64 auto a = new Statements(); |
0 | 65 Statement s; |
66 | |
122
c77e9f4f1793
Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
67 a.push(this); |
0 | 68 s = new CompoundStatement(loc, a); |
69 sc.fes.gotos.push(cast(void*)s); // 'look at this later' list | |
70 return s; | |
71 } | |
72 | |
73 if (label.statement && label.statement.tf != sc.tf) | |
74 error("cannot goto in or out of finally block"); | |
75 return this; | |
76 } | |
77 | |
72 | 78 override BE blockExit() |
0 | 79 { |
80 //printf("GotoStatement.blockExit(%p)\n", this); | |
81 return BE.BEgoto; | |
82 } | |
83 | |
72 | 84 override Expression interpret(InterState istate) |
0 | 85 { |
86 assert(false); | |
87 } | |
88 | |
72 | 89 override void toIR(IRState* irs) |
0 | 90 { |
91 block* b; | |
92 block* bdest; | |
93 Blockx* blx = irs.blx; | |
94 | |
95 if (!label.statement) | |
96 { | |
97 error("label %s is undefined", label.toChars()); | |
98 return; | |
99 } | |
100 if (tf !is label.statement.tf) | |
101 error("cannot goto forward out of or into finally block"); | |
102 | |
103 bdest = labelToBlock(loc, blx, label); | |
104 if (!bdest) | |
105 return; | |
106 b = blx.curblock; | |
107 incUsage(irs, loc); | |
108 | |
109 // Adjust exception handler scope index if in different try blocks | |
110 if (b.Btry != bdest.Btry) | |
111 { | |
112 // Check that bdest is in an enclosing try block | |
113 for (block* bt = b.Btry; bt != bdest.Btry; bt = bt.Btry) | |
114 { | |
115 if (!bt) | |
116 { | |
117 //printf("b.Btry = %p, bdest.Btry = %p\n", b.Btry, bdest.Btry); | |
118 error("cannot goto into try block"); | |
119 break; | |
120 } | |
121 } | |
122 | |
123 //setScopeIndex(blx, b, bdest.Btry ? bdest.Btry.Bscope_index : -1); | |
124 } | |
125 | |
126 list_append(&b.Bsucc,bdest); | |
127 block_next(blx,BCgoto,null); | |
128 } | |
129 | |
72 | 130 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 131 { |
132 buf.writestring("goto "); | |
133 buf.writestring(ident.toChars()); | |
134 buf.writebyte(';'); | |
135 buf.writenl(); | |
136 } | |
137 | |
72 | 138 override GotoStatement isGotoStatement() { return this; } |
139 } |