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