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