Mercurial > projects > ddmd
annotate dmd/TypeDArray.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 | fa9a71a9f5a8 |
children | 190ba98276b3 |
rev | line source |
---|---|
0 | 1 module dmd.TypeDArray; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.TypeArray; |
5 import dmd.MOD; | |
6 import dmd.Id; | |
7 import dmd.TOK; | |
8 import dmd.StringExp; | |
9 import dmd.IntegerExp; | |
10 import dmd.ArrayLengthExp; | |
11 import dmd.Type; | |
12 import dmd.Loc; | |
13 import dmd.Scope; | |
14 import dmd.OutBuffer; | |
15 import dmd.HdrGenState; | |
16 import dmd.Expression; | |
17 import dmd.Identifier; | |
18 import dmd.MATCH; | |
19 import dmd.ArrayTypes; | |
20 import dmd.TypeInfoDeclaration; | |
21 import dmd.TypeInfoArrayDeclaration; | |
22 import dmd.NullExp; | |
23 import dmd.TY; | |
24 import dmd.TypeStruct; | |
25 import dmd.Util; | |
26 import dmd.TypePointer; | |
27 import dmd.Global; | |
28 | |
29 import dmd.backend.TYPE; | |
30 import dmd.backend.Symbol; | |
31 import dmd.backend.Classsym; | |
32 import dmd.backend.Util; | |
33 import dmd.backend.SC; | |
34 import dmd.backend.TYM; | |
35 import dmd.backend.LIST; | |
36 | |
37 import core.stdc.stdlib; | |
38 import core.stdc.stdio; | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
39 version (Bug4054) import core.memory; |
0 | 40 |
41 // Dynamic array, no dimension | |
42 class TypeDArray : TypeArray | |
43 { | |
44 this(Type t) | |
45 { | |
178 | 46 register(); |
0 | 47 super(TY.Tarray, t); |
48 //printf("TypeDArray(t = %p)\n", t); | |
49 } | |
50 | |
72 | 51 override Type syntaxCopy() |
0 | 52 { |
53 Type t = next.syntaxCopy(); | |
54 if (t == next) | |
55 t = this; | |
56 else | |
57 { | |
58 t = new TypeDArray(t); | |
59 t.mod = mod; | |
60 } | |
61 return t; | |
62 } | |
63 | |
72 | 64 override ulong size(Loc loc) |
0 | 65 { |
66 //printf("TypeDArray.size()\n"); | |
67 return PTRSIZE * 2; | |
68 } | |
69 | |
72 | 70 override uint alignsize() |
0 | 71 { |
72 // A DArray consists of two ptr-sized values, so align it on pointer size | |
73 // boundary | |
74 return PTRSIZE; | |
75 } | |
76 | |
72 | 77 override Type semantic(Loc loc, Scope sc) |
0 | 78 { |
79 Type tn = next; | |
80 | |
81 tn = next.semantic(loc,sc); | |
82 Type tbn = tn.toBasetype(); | |
83 switch (tbn.ty) | |
84 { | |
85 case TY.Tfunction: | |
86 case TY.Tnone: | |
87 case TY.Ttuple: | |
88 error(loc, "can't have array of %s", tbn.toChars()); | |
89 tn = next = tint32; | |
90 break; | |
91 case TY.Tstruct: | |
92 { | |
93 TypeStruct ts = cast(TypeStruct)tbn; | |
94 if (ts.sym.isnested) | |
95 error(loc, "cannot have array of inner structs %s", ts.toChars()); | |
96 break; | |
97 } | |
98 | |
99 default: | |
100 break; /// | |
101 } | |
102 if (tn.isauto()) | |
103 error(loc, "cannot have array of auto %s", tn.toChars()); | |
104 | |
105 next = tn; | |
106 transitive(); | |
107 return merge(); | |
108 } | |
109 | |
72 | 110 override void toDecoBuffer(OutBuffer buf, int flag) |
0 | 111 { |
112 Type.toDecoBuffer(buf, flag); | |
113 if (next) | |
114 next.toDecoBuffer(buf, (flag & 0x100) ? 0 : mod); | |
115 } | |
116 | |
96 | 117 override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) |
0 | 118 { |
119 if (mod != this.mod) | |
120 { | |
121 toCBuffer3(buf, hgs, mod); | |
122 return; | |
123 } | |
176 | 124 if (equals(global.tstring)) |
96 | 125 buf.writestring("string"); |
126 else | |
127 { | |
128 next.toCBuffer2(buf, hgs, this.mod); | |
129 buf.writestring("[]"); | |
130 } | |
0 | 131 } |
132 | |
72 | 133 override Expression dotExp(Scope sc, Expression e, Identifier ident) |
0 | 134 { |
135 version (LOGDOTEXP) { | |
136 printf("TypeDArray.dotExp(e = '%s', ident = '%s')\n", e.toChars(), ident.toChars()); | |
137 } | |
138 if (ident is Id.length) | |
139 { | |
140 if (e.op == TOK.TOKstring) | |
141 { | |
142 StringExp se = cast(StringExp)e; | |
143 | |
144 return new IntegerExp(se.loc, se.len, Type.tindex); | |
145 } | |
146 e = new ArrayLengthExp(e.loc, e); | |
147 e.type = Type.tsize_t; | |
148 return e; | |
149 } | |
150 else if (ident is Id.ptr) | |
151 { | |
152 e = e.castTo(sc, next.pointerTo()); | |
153 return e; | |
154 } | |
155 else | |
156 { | |
157 e = TypeArray.dotExp(sc, e, ident); | |
158 } | |
159 return e; | |
160 } | |
161 | |
72 | 162 override bool isString() |
0 | 163 { |
12
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
164 TY nty = next.toBasetype().ty; |
832f71e6f96c
*Exp and *AssignExp arrayOp implementation added (might be a bit incomplete)
korDen
parents:
0
diff
changeset
|
165 return nty == Tchar || nty == Twchar || nty == Tdchar; |
0 | 166 } |
167 | |
72 | 168 override bool isZeroInit(Loc loc) |
0 | 169 { |
170 return true; | |
171 } | |
172 | |
72 | 173 override bool checkBoolean() |
0 | 174 { |
175 return true; | |
176 } | |
177 | |
72 | 178 override MATCH implicitConvTo(Type to) |
0 | 179 { |
180 //printf("TypeDArray.implicitConvTo(to = %s) this = %s\n", to.toChars(), toChars()); | |
181 if (equals(to)) | |
182 return MATCHexact; | |
183 | |
184 // Allow implicit conversion of array to pointer | |
185 if (IMPLICIT_ARRAY_TO_PTR && to.ty == Tpointer) | |
186 { | |
187 TypePointer tp = cast(TypePointer)to; | |
188 | |
189 /* Allow conversion to void* | |
190 */ | |
191 if (tp.next.ty == Tvoid && | |
135 | 192 MODimplicitConv(next.mod, tp.next.mod)) |
0 | 193 { |
194 return MATCHconvert; | |
195 } | |
196 | |
197 return next.constConv(to); | |
198 } | |
199 | |
200 if (to.ty == Tarray) | |
201 { | |
202 int offset = 0; | |
203 TypeDArray ta = cast(TypeDArray)to; | |
204 | |
135 | 205 if (!MODimplicitConv(next.mod, ta.next.mod)) |
0 | 206 return MATCHnomatch; // not const-compatible |
207 | |
208 /* Allow conversion to void[] | |
209 */ | |
210 if (next.ty != Tvoid && ta.next.ty == Tvoid) | |
211 { | |
212 return MATCHconvert; | |
213 } | |
214 | |
215 MATCH m = next.constConv(ta.next); | |
216 if (m != MATCHnomatch) | |
217 { | |
218 if (m == MATCHexact && mod != to.mod) | |
219 m = MATCHconst; | |
220 return m; | |
221 } | |
222 | |
135 | 223 static if(false) { |
0 | 224 /* Allow conversions of T[][] to const(T)[][] |
225 */ | |
226 if (mod == ta.mod && next.ty == Tarray && ta.next.ty == Tarray) | |
227 { | |
228 m = next.implicitConvTo(ta.next); | |
229 if (m == MATCHconst) | |
230 return m; | |
231 } | |
135 | 232 } |
0 | 233 /* Conversion of array of derived to array of base |
234 */ | |
235 if (ta.next.isBaseOf(next, &offset) && offset == 0) | |
236 return MATCHconvert; | |
237 } | |
238 return Type.implicitConvTo(to); | |
239 } | |
240 | |
72 | 241 override Expression defaultInit(Loc loc) |
0 | 242 { |
243 version (LOGDEFAULTINIT) { | |
244 printf("TypeDArray.defaultInit() '%s'\n", toChars()); | |
245 } | |
135 | 246 return new NullExp(loc, this); |
0 | 247 } |
248 | |
72 | 249 override bool builtinTypeInfo() |
0 | 250 { |
251 version (DMDV2) { | |
252 return !mod && (next.isTypeBasic() !is null && !next.mod || | |
253 // strings are so common, make them builtin | |
135 | 254 next.ty == Tchar && next.mod == MODimmutable); |
0 | 255 } else { |
256 return next.isTypeBasic() !is null; | |
257 } | |
258 } | |
259 version (DMDV2) { | |
72 | 260 override MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) |
0 | 261 { |
262 static if (false) { | |
263 printf("TypeDArray.deduceType()\n"); | |
264 printf("\tthis = %d, ", ty); print(); | |
265 printf("\ttparam = %d, ", tparam.ty); tparam.print(); | |
266 } | |
267 return Type.deduceType(sc, tparam, parameters, dedtypes); | |
268 | |
269 Lnomatch: | |
270 return MATCHnomatch; | |
271 } | |
272 } | |
72 | 273 override TypeInfoDeclaration getTypeInfoDeclaration() |
0 | 274 { |
275 return new TypeInfoArrayDeclaration(this); | |
276 } | |
277 | |
72 | 278 override bool hasPointers() |
0 | 279 { |
280 return true; | |
281 } | |
282 | |
283 version (CPP_MANGLE) { | |
284 void toCppMangle(OutBuffer buf, CppMangleState* cms); | |
285 } | |
286 | |
72 | 287 override type* toCtype() |
0 | 288 { |
289 type *t; | |
290 | |
291 if (ctype) | |
292 return ctype; | |
293 | |
294 if (0 && global.params.symdebug) | |
295 { | |
296 /* Create a C type out of: | |
297 * struct _Array_T { size_t length; T* data; } | |
298 */ | |
299 Symbol* s; | |
300 char *id; | |
301 | |
302 assert(next.deco); | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
303 version (Bug4054) |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
304 id = cast(char*) GC.malloc(7 + next.deco.length + 1); |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
305 else |
0 | 306 id = cast(char*) alloca(7 + next.deco.length + 1); |
307 sprintf(id, "_Array_%.*s", next.deco); | |
308 s = symbol_calloc(id); | |
309 s.Sclass = SC.SCstruct; | |
310 s.Sstruct = struct_calloc(); | |
311 s.Sstruct.Sflags |= 0; | |
312 s.Sstruct.Salignsize = alignsize(); | |
313 s.Sstruct.Sstructalign = cast(ubyte)global.structalign; | |
314 s.Sstruct.Sstructsize = cast(uint)size(Loc(0)); | |
315 slist_add(s); | |
316 | |
317 Symbol* s1 = symbol_name("length", SC.SCmember, Type.tsize_t.toCtype()); | |
318 list_append(&s.Sstruct.Sfldlst, s1); | |
319 | |
320 Symbol* s2 = symbol_name("data", SC.SCmember, next.pointerTo().toCtype()); | |
321 s2.Smemoff = cast(uint)Type.tsize_t.size(); | |
322 list_append(&s.Sstruct.Sfldlst, s2); | |
323 | |
324 t = type_alloc(TYM.TYstruct); | |
325 t.Ttag = cast(Classsym*)s; // structure tag name | |
326 t.Tcount++; | |
327 s.Stype = t; | |
328 } | |
329 else | |
330 { | |
331 if (global.params.symdebug == 1) | |
332 { | |
333 // Generate D symbolic debug info, rather than C | |
334 t = type_allocn(TYM.TYdarray, next.toCtype()); | |
335 } | |
336 else | |
337 t = type_fake(TYM.TYdarray); | |
338 } | |
339 t.Tcount++; | |
340 ctype = t; | |
341 return t; | |
342 } | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
343 } |