Mercurial > projects > ddmd
annotate dmd/Catch.d @ 187:b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
author | Abscissa |
---|---|
date | Tue, 07 Jun 2011 23:37:34 -0400 |
parents | e3afd1303184 |
children |
rev | line source |
---|---|
0 | 1 module dmd.Catch; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.Loc; |
5 import dmd.Type; | |
6 import dmd.Scope; | |
7 import dmd.Identifier; | |
8 import dmd.VarDeclaration; | |
9 import dmd.Statement; | |
10 import dmd.OutBuffer; | |
11 import dmd.Id; | |
12 import dmd.TypeIdentifier; | |
13 import dmd.Util; | |
14 import dmd.ScopeDsymbol; | |
15 import dmd.HdrGenState; | |
16 import dmd.BE; | |
17 | |
178 | 18 import dmd.TObject; |
19 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
20 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
|
21 |
178 | 22 class Catch : TObject |
0 | 23 { |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
24 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
|
25 |
0 | 26 Loc loc; |
27 Type type; | |
28 Identifier ident; | |
29 VarDeclaration var = null; | |
30 Statement handler; | |
31 | |
32 this(Loc loc, Type t, Identifier id, Statement handler) | |
33 { | |
178 | 34 register(); |
35 | |
0 | 36 //printf("Catch(%s, loc = %s)\n", id.toChars(), loc.toChars()); |
37 this.loc = loc; | |
38 this.type = t; | |
39 this.ident = id; | |
40 this.handler = handler; | |
41 } | |
42 | |
43 Catch syntaxCopy() | |
44 { | |
63 | 45 Catch c = new Catch(loc, (type ? type.syntaxCopy() : null), ident, (handler ? handler.syntaxCopy() : null)); |
46 return c; | |
0 | 47 } |
48 | |
49 void semantic(Scope sc) | |
50 { | |
51 ScopeDsymbol sym; | |
52 | |
53 //printf("Catch.semantic(%s)\n", ident.toChars()); | |
54 | |
55 version (IN_GCC) { | |
56 } else { | |
57 if (sc.tf) | |
58 { | |
59 /* This is because the _d_local_unwind() gets the stack munged | |
60 * up on this. The workaround is to place any try-catches into | |
61 * a separate function, and call that. | |
62 * To fix, have the compiler automatically convert the finally | |
63 * body into a nested function. | |
64 */ | |
65 error(loc, "cannot put catch statement inside finally block"); | |
66 } | |
67 } | |
68 | |
69 sym = new ScopeDsymbol(); | |
70 sym.parent = sc.scopesym; | |
71 sc = sc.push(sym); | |
72 | |
73 if (!type) | |
74 type = new TypeIdentifier(Loc(0), Id.Object_); | |
75 type = type.semantic(loc, sc); | |
76 if (!type.toBasetype().isClassHandle()) | |
77 error("can only catch class objects, not '%s'", type.toChars()); | |
78 else if (ident) | |
79 { | |
80 var = new VarDeclaration(loc, type, ident, null); | |
81 var.parent = sc.parent; | |
82 sc.insert(var); | |
83 } | |
84 handler = handler.semantic(sc); | |
85 | |
86 sc.pop(); | |
87 } | |
88 | |
89 BE blockExit() | |
90 { | |
91 return handler ? handler.blockExit() : BE.BEfallthru; | |
92 } | |
93 | |
94 void toCBuffer(OutBuffer buf, HdrGenState* hgs) | |
95 { | |
174 | 96 buf.writestring("catch"); |
97 if (type) | |
98 { | |
99 buf.writebyte('('); | |
100 type.toCBuffer(buf, ident, hgs); | |
101 buf.writebyte(')'); | |
102 } | |
103 buf.writenl(); | |
104 buf.writebyte('{'); | |
105 buf.writenl(); | |
106 if (handler) | |
107 handler.toCBuffer(buf, hgs); | |
108 buf.writebyte('}'); | |
109 buf.writenl(); | |
0 | 110 } |
111 } |