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