Mercurial > projects > ddmd
annotate dmd/SymOffExp.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 | cd48cb899aee |
children | eb38fdcb3e62 |
rev | line source |
---|---|
72 | 1 module dmd.SymOffExp; |
2 | |
114 | 3 import dmd.common; |
72 | 4 import dmd.Expression; |
179 | 5 import dmd.GlobalExpressions; |
72 | 6 import dmd.Declaration; |
7 import dmd.MATCH; | |
8 import dmd.Type; | |
179 | 9 import dmd.InterState; |
72 | 10 import dmd.OutBuffer; |
11 import dmd.Loc; | |
12 import dmd.Scope; | |
13 import dmd.InlineDoState; | |
14 import dmd.HdrGenState; | |
15 import dmd.backend.dt_t; | |
0 | 16 import dmd.SymbolExp; |
17 import dmd.VarDeclaration; | |
18 import dmd.DelegateExp; | |
19 import dmd.ThisExp; | |
20 import dmd.FuncDeclaration; | |
21 import dmd.IntegerExp; | |
22 import dmd.ErrorExp; | |
72 | 23 import dmd.TY; |
0 | 24 import dmd.TOK; |
135 | 25 import dmd.STC; |
0 | 26 |
27 import dmd.backend.Symbol; | |
28 import dmd.backend.Util; | |
29 import dmd.backend.TYM; | |
72 | 30 |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
179
diff
changeset
|
31 import dmd.DDMDExtensions; |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
179
diff
changeset
|
32 |
0 | 33 class SymOffExp : SymbolExp |
34 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
179
diff
changeset
|
35 mixin insertMemberExtension!(typeof(this)); |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
179
diff
changeset
|
36 |
0 | 37 uint offset; |
38 | |
73 | 39 this(Loc loc, Declaration var, uint offset, bool hasOverloads = false) |
0 | 40 { |
178 | 41 register(); |
0 | 42 super(loc, TOK.TOKsymoff, SymOffExp.sizeof, var, hasOverloads); |
43 | |
44 this.offset = offset; | |
45 VarDeclaration v = var.isVarDeclaration(); | |
46 if (v && v.needThis()) | |
47 error("need 'this' for address of %s", v.toChars()); | |
48 } | |
49 | |
72 | 50 override Expression semantic(Scope sc) |
0 | 51 { |
52 version(LOGSEMANTIC) { | |
53 printf("SymOffExp::semantic('%s')\n", toChars()); | |
54 } | |
55 //var.semantic(sc); | |
56 if (!type) | |
57 type = var.type.pointerTo(); | |
58 VarDeclaration v = var.isVarDeclaration(); | |
59 if (v) | |
60 v.checkNestedReference(sc, loc); | |
61 return this; | |
62 } | |
179 | 63 |
64 Expression interpret(InterState istate) | |
65 { | |
66 version (LOG) { | |
67 writef("SymOffExp::interpret() %s\n", toChars()); | |
68 } | |
69 if (var.isFuncDeclaration() && offset == 0) | |
70 { | |
71 return this; | |
72 } | |
73 error("Cannot interpret %s at compile time", toChars()); | |
74 return EXP_CANT_INTERPRET; | |
75 | |
76 } | |
0 | 77 |
72 | 78 override void checkEscape() |
0 | 79 { |
80 VarDeclaration v = var.isVarDeclaration(); | |
81 if (v) | |
82 { | |
135 | 83 if (!v.isDataseg() && !(v.storage_class & (STC.STCref | STC.STCout))) |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
84 { /* BUG: This should be allowed: |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
85 * void foo() |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
86 * { int a; |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
87 * int* bar() { return &a; } |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
88 * } |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
89 */ |
135 | 90 error("escaping reference to local %s", v.toChars()); |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
91 } |
0 | 92 } |
93 } | |
94 | |
72 | 95 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 96 { |
174 | 97 if (offset) |
98 buf.printf("(& %s+%s)", var.toChars(), offset); /// | |
99 else | |
100 buf.printf("& %s", var.toChars()); | |
0 | 101 } |
102 | |
72 | 103 override int isConst() |
0 | 104 { |
105 return 2; | |
106 } | |
107 | |
72 | 108 override bool isBool(bool result) |
0 | 109 { |
129 | 110 return result; |
0 | 111 } |
112 | |
72 | 113 override Expression doInline(InlineDoState ids) |
0 | 114 { |
115 int i; | |
116 | |
117 //printf("SymOffExp.doInline(%s)\n", toChars()); | |
118 for (i = 0; i < ids.from.dim; i++) | |
119 { | |
120 if (var is cast(Declaration)ids.from.data[i]) | |
121 { | |
122 SymOffExp se = cast(SymOffExp)copy(); | |
123 | |
124 se.var = cast(Declaration)ids.to.data[i]; | |
125 return se; | |
126 } | |
127 } | |
128 return this; | |
129 } | |
130 | |
72 | 131 override MATCH implicitConvTo(Type t) |
0 | 132 { |
133 static if (false) { | |
134 printf("SymOffExp::implicitConvTo(this=%s, type=%s, t=%s)\n", toChars(), type.toChars(), t.toChars()); | |
135 } | |
136 MATCH result = type.implicitConvTo(t); | |
137 //printf("\tresult = %d\n", result); | |
138 | |
139 if (result == MATCHnomatch) | |
140 { | |
141 // Look for pointers to functions where the functions are overloaded. | |
142 FuncDeclaration f; | |
143 | |
144 t = t.toBasetype(); | |
145 if (type.ty == Tpointer && type.nextOf().ty == Tfunction && | |
146 (t.ty == Tpointer || t.ty == Tdelegate) && t.nextOf().ty == Tfunction) | |
147 { | |
148 f = var.isFuncDeclaration(); | |
149 if (f) | |
150 { | |
151 f = f.overloadExactMatch(t.nextOf()); | |
152 if (f) | |
153 { | |
154 if ((t.ty == Tdelegate && (f.needThis() || f.isNested())) || | |
155 (t.ty == Tpointer && !(f.needThis() || f.isNested()))) | |
156 { | |
157 result = MATCHexact; | |
158 } | |
159 } | |
160 } | |
161 } | |
162 } | |
163 //printf("\tresult = %d\n", result); | |
164 return result; | |
165 } | |
166 | |
72 | 167 override Expression castTo(Scope sc, Type t) |
0 | 168 { |
169 static if (false) { | |
170 printf("SymOffExp::castTo(this=%s, type=%s, t=%s)\n", toChars(), type.toChars(), t.toChars()); | |
171 } | |
73 | 172 if (type == t && !hasOverloads) |
0 | 173 return this; |
174 | |
175 Expression e; | |
176 Type tb = t.toBasetype(); | |
177 Type typeb = type.toBasetype(); | |
178 | |
179 if (tb != typeb) | |
180 { | |
181 // Look for pointers to functions where the functions are overloaded. | |
182 FuncDeclaration f; | |
183 | |
184 if (hasOverloads && | |
185 typeb.ty == Tpointer && typeb.nextOf().ty == Tfunction && | |
186 (tb.ty == Tpointer || tb.ty == Tdelegate) && tb.nextOf().ty == Tfunction) | |
187 { | |
188 f = var.isFuncDeclaration(); | |
189 if (f) | |
190 { | |
191 f = f.overloadExactMatch(tb.nextOf()); | |
192 if (f) | |
193 { | |
194 if (tb.ty == Tdelegate) | |
195 { | |
196 if (f.needThis() && hasThis(sc)) | |
197 { | |
198 e = new DelegateExp(loc, new ThisExp(loc), f); | |
199 e = e.semantic(sc); | |
200 } | |
201 else if (f.isNested()) | |
202 { | |
203 e = new DelegateExp(loc, new IntegerExp(0), f); | |
204 e = e.semantic(sc); | |
205 } | |
206 else if (f.needThis()) | |
207 { | |
208 error("no 'this' to create delegate for %s", f.toChars()); | |
209 e = new ErrorExp(); | |
210 } | |
211 else | |
212 { | |
213 error("cannot cast from function pointer to delegate"); | |
214 e = new ErrorExp(); | |
215 } | |
216 } | |
217 else | |
218 { | |
219 e = new SymOffExp(loc, f, 0); | |
220 e.type = t; | |
221 } | |
222 version (DMDV2) { | |
223 f.tookAddressOf++; | |
224 } | |
225 return e; | |
226 } | |
227 } | |
228 } | |
229 e = Expression.castTo(sc, t); | |
230 } | |
231 else | |
232 { | |
233 e = copy(); | |
234 e.type = t; | |
73 | 235 (cast(SymOffExp)e).hasOverloads = false; |
0 | 236 } |
237 return e; | |
238 } | |
239 | |
72 | 240 override void scanForNestedRef(Scope sc) |
0 | 241 { |
72 | 242 //printf("SymOffExp.scanForNestedRef(%s)\n", toChars()); |
243 VarDeclaration v = var.isVarDeclaration(); | |
244 if (v) | |
64 | 245 v.checkNestedReference(sc, Loc(0)); |
0 | 246 } |
247 | |
72 | 248 override dt_t** toDt(dt_t** pdt) |
0 | 249 { |
250 //printf("SymOffExp.toDt('%s')\n", var.toChars()); | |
251 assert(var); | |
252 if (!(var.isDataseg() || var.isCodeseg()) || | |
253 var.needThis() || | |
254 var.isThreadlocal() | |
255 ) | |
256 { | |
257 debug writef("SymOffExp.toDt()\n"); | |
258 error("non-constant expression %s", toChars()); | |
259 return pdt; | |
260 } | |
261 | |
262 Symbol* s = var.toSymbol(); | |
263 return dtxoff(pdt, s, offset, TYnptr); | |
264 } | |
108
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
73
diff
changeset
|
265 |
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
73
diff
changeset
|
266 static if (false) |
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
73
diff
changeset
|
267 { |
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
73
diff
changeset
|
268 override elem* toElem(IRState* irs) |
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
73
diff
changeset
|
269 { |
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
73
diff
changeset
|
270 assert(false); // this function is #if 0'ed out in dmd |
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
73
diff
changeset
|
271 } |
6da99741178e
e2ir.c changes, mainly accounts for static arrays being value types now
Trass3r
parents:
73
diff
changeset
|
272 } |
0 | 273 } |
274 |