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 }