Mercurial > projects > ddmd
annotate dmd/TypeStruct.d @ 187:b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
author | Abscissa |
---|---|
date | Tue, 07 Jun 2011 23:37:34 -0400 |
parents | e3afd1303184 |
children |
rev | line source |
---|---|
0 | 1 module dmd.TypeStruct; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.Type; |
55 | 5 import dmd.TypeInstance; |
0 | 6 import dmd.StructDeclaration; |
7 import dmd.Declaration; | |
8 import dmd.STC; | |
9 import dmd.MOD; | |
10 import dmd.OutBuffer; | |
11 import dmd.DotVarExp; | |
12 import dmd.TemplateMixin; | |
13 import dmd.DotTemplateExp; | |
14 import dmd.DsymbolExp; | |
15 import dmd.TypeExp; | |
16 import dmd.EnumMember; | |
17 import dmd.Id; | |
18 import dmd.DotIdExp; | |
19 import dmd.ScopeExp; | |
20 import dmd.TupleExp; | |
21 import dmd.TemplateDeclaration; | |
22 import dmd.OverloadSet; | |
23 import dmd.Import; | |
24 import dmd.DotExp; | |
25 import dmd.ErrorExp; | |
26 import dmd.Loc; | |
27 import dmd.Scope; | |
28 import dmd.Dsymbol; | |
29 import dmd.HdrGenState; | |
30 import dmd.Expression; | |
31 import dmd.Identifier; | |
32 import dmd.MATCH; | |
33 import dmd.ArrayTypes; | |
55 | 34 import dmd.DYNCAST; |
0 | 35 import dmd.TemplateInstance; |
36 import dmd.FuncDeclaration; | |
37 import dmd.VarExp; | |
38 import dmd.CommaExp; | |
39 import dmd.ThisExp; | |
135 | 40 import dmd.StructLiteralExp; |
0 | 41 import dmd.SymbolDeclaration; |
42 import dmd.TypeInfoDeclaration; | |
43 import dmd.TypeInfoStructDeclaration; | |
44 import dmd.TY; | |
45 import dmd.TOK; | |
46 import dmd.Global; | |
47 import dmd.VarDeclaration; | |
48 import dmd.Util; | |
49 import dmd.expression.Util; | |
50 | |
51 import dmd.backend.TYPE; | |
52 import dmd.backend.dt_t; | |
53 import dmd.backend.Symbol; | |
54 import dmd.backend.Util; | |
55 import dmd.backend.STR; | |
56 import dmd.backend.TYM; | |
57 import dmd.backend.Classsym; | |
58 import dmd.backend.SC; | |
59 import dmd.backend.LIST; | |
60 | |
61 import std.string : toStringz; | |
62 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
63 import dmd.DDMDExtensions; |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
64 |
0 | 65 class TypeStruct : Type |
66 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
67 mixin insertMemberExtension!(typeof(this)); |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
68 |
0 | 69 StructDeclaration sym; |
70 | |
71 this(StructDeclaration sym) | |
72 { | |
178 | 73 register(); |
0 | 74 super(TY.Tstruct); |
75 this.sym = sym; | |
76 } | |
72 | 77 override ulong size(Loc loc) |
0 | 78 { |
79 return sym.size(loc); | |
80 } | |
174 | 81 |
72 | 82 override uint alignsize() |
0 | 83 { |
84 uint sz; | |
85 | |
86 sym.size(Loc(0)); // give error for forward references | |
87 sz = sym.alignsize; | |
88 if (sz > sym.structalign) | |
89 sz = sym.structalign; | |
90 return sz; | |
91 } | |
174 | 92 |
72 | 93 override string toChars() |
0 | 94 { |
55 | 95 //printf("sym.parent: %s, deco = %s\n", sym.parent.toChars(), deco); |
96 if (mod) | |
97 return Type.toChars(); | |
98 TemplateInstance ti = sym.parent.isTemplateInstance(); | |
99 if (ti && ti.toAlias() == sym) | |
100 { | |
101 return ti.toChars(); | |
102 } | |
103 return sym.toChars(); | |
0 | 104 } |
174 | 105 |
72 | 106 override Type syntaxCopy() |
0 | 107 { |
108 assert(false); | |
109 } | |
174 | 110 |
72 | 111 override Type semantic(Loc loc, Scope sc) |
0 | 112 { |
113 //printf("TypeStruct.semantic('%s')\n", sym.toChars()); | |
114 | |
115 /* Cannot do semantic for sym because scope chain may not | |
116 * be right. | |
117 */ | |
118 //sym.semantic(sc); | |
119 | |
120 return merge(); | |
121 } | |
174 | 122 |
72 | 123 override Dsymbol toDsymbol(Scope sc) |
0 | 124 { |
125 return sym; | |
126 } | |
174 | 127 |
72 | 128 override void toDecoBuffer(OutBuffer buf, int flag) |
0 | 129 { |
130 string name = sym.mangle(); | |
131 //printf("TypeStruct.toDecoBuffer('%s') = '%s'\n", toChars(), name); | |
132 Type.toDecoBuffer(buf, flag); | |
133 buf.printf("%s", name); | |
134 } | |
174 | 135 |
72 | 136 override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) |
0 | 137 { |
138 if (mod != this.mod) | |
174 | 139 { |
0 | 140 toCBuffer3(buf, hgs, mod); |
141 return; | |
142 } | |
143 TemplateInstance ti = sym.parent.isTemplateInstance(); | |
144 if (ti && ti.toAlias() == sym) | |
145 buf.writestring(ti.toChars()); | |
146 else | |
147 buf.writestring(sym.toChars()); | |
148 } | |
174 | 149 |
72 | 150 override Expression dotExp(Scope sc, Expression e, Identifier ident) |
0 | 151 { |
152 uint offset; | |
153 | |
154 VarDeclaration v; | |
155 Dsymbol s; | |
156 DotVarExp de; | |
157 Declaration d; | |
158 | |
159 version (LOGDOTEXP) { | |
160 printf("TypeStruct.dotExp(e = '%s', ident = '%s')\n", e.toChars(), ident.toChars()); | |
161 } | |
162 if (!sym.members) | |
163 { | |
164 error(e.loc, "struct %s is forward referenced", sym.toChars()); | |
165 return new ErrorExp(); | |
166 } | |
167 | |
168 /* If e.tupleof | |
169 */ | |
170 if (ident is Id.tupleof_) | |
171 { | |
172 /* Create a TupleExp out of the fields of the struct e: | |
173 * (e.field0, e.field1, e.field2, ...) | |
174 */ | |
175 e = e.semantic(sc); // do this before turning on noaccesscheck | |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
176 auto exps = new Expressions; |
0 | 177 exps.reserve(sym.fields.dim); |
178 for (size_t i = 0; i < sym.fields.dim; i++) | |
174 | 179 { |
79 | 180 VarDeclaration v2 = cast(VarDeclaration)sym.fields[i]; |
0 | 181 Expression fe = new DotVarExp(e.loc, e, v2); |
84
be2ab491772e
Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
182 exps.push(fe); |
0 | 183 } |
184 e = new TupleExp(e.loc, exps); | |
185 sc = sc.push(); | |
186 sc.noaccesscheck = 1; | |
187 e = e.semantic(sc); | |
188 sc.pop(); | |
189 return e; | |
190 } | |
191 | |
192 if (e.op == TOK.TOKdotexp) | |
174 | 193 { |
0 | 194 DotExp de2 = cast(DotExp)e; |
195 | |
196 if (de2.e1.op == TOK.TOKimport) | |
197 { | |
198 assert(0); // cannot find a case where this happens; leave | |
199 // assert in until we do | |
200 ScopeExp se = cast(ScopeExp)de2.e1; | |
201 | |
202 s = se.sds.search(e.loc, ident, 0); | |
203 e = de2.e1; | |
204 goto L1; | |
205 } | |
206 } | |
207 | |
208 s = sym.search(e.loc, ident, 0); | |
209 L1: | |
210 if (!s) | |
211 { | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
212 return noMember(sc, e, ident); |
0 | 213 } |
214 | |
215 if (!s.isFuncDeclaration()) // because of overloading | |
216 s.checkDeprecated(e.loc, sc); | |
217 | |
218 s = s.toAlias(); | |
219 | |
220 v = s.isVarDeclaration(); | |
221 if (v && !v.isDataseg()) | |
222 { | |
223 Expression ei = v.getConstInitializer(); | |
224 if (ei) | |
174 | 225 { |
0 | 226 e = ei.copy(); // need to copy it if it's a StringExp |
227 e = e.semantic(sc); | |
228 return e; | |
229 } | |
230 } | |
231 | |
232 if (s.getType()) | |
233 { | |
234 //return new DotTypeExp(e.loc, e, s); | |
235 return new TypeExp(e.loc, s.getType()); | |
236 } | |
237 | |
238 EnumMember em = s.isEnumMember(); | |
239 if (em) | |
240 { | |
241 assert(em.value); | |
242 return em.value.copy(); | |
243 } | |
244 | |
245 TemplateMixin tm = s.isTemplateMixin(); | |
246 if (tm) | |
247 { | |
248 Expression de2 = new DotExp(e.loc, e, new ScopeExp(e.loc, tm)); | |
249 de2.type = e.type; | |
250 return de2; | |
251 } | |
252 | |
253 TemplateDeclaration td = s.isTemplateDeclaration(); | |
254 if (td) | |
255 { | |
256 e = new DotTemplateExp(e.loc, e, td); | |
257 e.semantic(sc); | |
258 return e; | |
259 } | |
260 | |
261 TemplateInstance ti = s.isTemplateInstance(); | |
262 if (ti) | |
174 | 263 { |
0 | 264 if (!ti.semanticRun) |
265 ti.semantic(sc); | |
266 s = ti.inst.toAlias(); | |
267 if (!s.isTemplateInstance()) | |
268 goto L1; | |
269 Expression de2 = new DotExp(e.loc, e, new ScopeExp(e.loc, ti)); | |
270 de2.type = e.type; | |
271 return de2; | |
272 } | |
273 | |
274 Import timp = s.isImport(); | |
275 if (timp) | |
276 { | |
277 e = new DsymbolExp(e.loc, s, 0); | |
278 e = e.semantic(sc); | |
279 return e; | |
280 } | |
281 | |
282 OverloadSet o = s.isOverloadSet(); | |
283 if (o) | |
174 | 284 { |
0 | 285 /* We really should allow this, triggered by: |
286 * template c() | |
287 * { | |
288 * void a(); | |
289 * void b () { this.a(); } | |
290 * } | |
291 * struct S | |
292 * { | |
293 * mixin c; | |
294 * mixin c; | |
295 * } | |
296 * alias S e; | |
297 */ | |
298 error(e.loc, "overload set for %s.%s not allowed in struct declaration", e.toChars(), ident.toChars()); | |
299 return new ErrorExp(); | |
300 } | |
301 | |
302 d = s.isDeclaration(); | |
303 | |
304 debug { | |
305 if (!d) | |
306 writef("d = %s '%s'\n", s.kind(), s.toChars()); | |
307 } | |
308 assert(d); | |
309 | |
310 if (e.op == TOK.TOKtype) | |
174 | 311 { |
0 | 312 FuncDeclaration fd = sc.func; |
313 | |
314 if (d.isTupleDeclaration()) | |
315 { | |
316 e = new TupleExp(e.loc, d.isTupleDeclaration()); | |
317 e = e.semantic(sc); | |
318 return e; | |
319 } | |
320 | |
321 if (d.needThis() && fd && fd.vthis) | |
322 { | |
323 e = new DotVarExp(e.loc, new ThisExp(e.loc), d); | |
324 e = e.semantic(sc); | |
325 return e; | |
326 } | |
327 | |
328 return new VarExp(e.loc, d, 1); | |
329 } | |
330 | |
331 if (d.isDataseg()) | |
332 { | |
333 // (e, d) | |
334 accessCheck(e.loc, sc, e, d); | |
335 VarExp ve = new VarExp(e.loc, d); | |
336 e = new CommaExp(e.loc, e, ve); | |
337 e.type = d.type; | |
338 return e; | |
339 } | |
340 | |
341 if (v) | |
342 { | |
343 if (v.toParent() != sym) | |
344 sym.error(e.loc, "'%s' is not a member", v.toChars()); | |
345 | |
346 // *(&e + offset) | |
347 accessCheck(e.loc, sc, e, d); | |
348 static if (false) { | |
349 Expression b = new AddrExp(e.loc, e); | |
350 b.type = e.type.pointerTo(); | |
351 b = new AddExp(e.loc, b, new IntegerExp(e.loc, v.offset, Type.tint32)); | |
352 b.type = v.type.pointerTo(); | |
353 b = new PtrExp(e.loc, b); | |
354 b.type = v.type.addMod(e.type.mod); | |
355 return b; | |
356 } | |
357 } | |
358 | |
359 de = new DotVarExp(e.loc, e, d); | |
360 return de.semantic(sc); | |
361 } | |
174 | 362 |
72 | 363 override uint memalign(uint salign) |
0 | 364 { |
365 sym.size(Loc(0)); // give error for forward references | |
366 return sym.structalign; | |
367 } | |
174 | 368 |
72 | 369 override Expression defaultInit(Loc loc) |
0 | 370 { |
371 version (LOGDEFAULTINIT) { | |
372 printf("TypeStruct::defaultInit() '%s'\n", toChars()); | |
373 } | |
135 | 374 Symbol *s = sym.toInitializer(); |
375 Declaration d = new SymbolDeclaration(sym.loc, s, sym); | |
0 | 376 assert(d); |
377 d.type = this; | |
378 return new VarExp(sym.loc, d); | |
379 } | |
174 | 380 |
135 | 381 /*************************************** |
382 * Use when we prefer the default initializer to be a literal, | |
383 * rather than a global immutable variable. | |
384 */ | |
154
14feb7ae01a6
* changed the build system to build a release version if the debug one compiles
trass3r
parents:
135
diff
changeset
|
385 override Expression defaultInitLiteral(Loc loc) |
135 | 386 { |
387 version (LOGDEFAULTINIT) { | |
388 printf("TypeStruct::defaultInitLiteral() '%s'\n", toChars()); | |
389 } | |
390 auto structelems = new Expressions(); | |
391 structelems.setDim(sym.fields.dim); | |
392 for (size_t j = 0; j < structelems.dim; j++) | |
393 { | |
394 auto vd = cast(VarDeclaration)(sym.fields[j]); | |
395 Expression e; | |
396 if (vd.init) | |
397 e = vd.init.toExpression(); | |
398 else | |
174 | 399 e = vd.type.defaultInitLiteral(Loc(0)); |
135 | 400 structelems[j] = e; |
401 } | |
402 auto structinit = new StructLiteralExp(loc, cast(StructDeclaration)sym, structelems); | |
403 // Why doesn't the StructLiteralExp constructor do this, when | |
404 // sym->type != NULL ? | |
405 structinit.type = sym.type; | |
406 return structinit; | |
407 } | |
408 | |
72 | 409 override bool isZeroInit(Loc loc) |
0 | 410 { |
411 return sym.zeroInit; | |
412 } | |
174 | 413 |
73 | 414 override bool isAssignable() |
0 | 415 { |
416 /* If any of the fields are const or invariant, | |
417 * then one cannot assign this struct. | |
418 */ | |
419 for (size_t i = 0; i < sym.fields.dim; i++) | |
174 | 420 { |
79 | 421 VarDeclaration v = cast(VarDeclaration)sym.fields[i]; |
135 | 422 if (v.isConst() || v.isImmutable()) |
0 | 423 return false; |
424 } | |
425 return true; | |
426 } | |
174 | 427 |
72 | 428 override bool checkBoolean() |
0 | 429 { |
430 return false; | |
431 } | |
174 | 432 |
72 | 433 override dt_t** toDt(dt_t** pdt) |
0 | 434 { |
435 sym.toDt(pdt); | |
436 return pdt; | |
437 } | |
174 | 438 |
72 | 439 override MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) |
0 | 440 { |
55 | 441 //printf("TypeStruct.deduceType()\n"); |
442 //printf("\tthis.parent = %s, ", sym.parent.toChars()); print(); | |
443 //printf("\ttparam = %d, ", tparam.ty); tparam.print(); | |
444 | |
445 /* If this struct is a template struct, and we're matching | |
446 * it against a template instance, convert the struct type | |
447 * to a template instance, too, and try again. | |
448 */ | |
449 TemplateInstance ti = sym.parent.isTemplateInstance(); | |
450 | |
451 if (tparam && tparam.ty == Tinstance) | |
452 { | |
453 if (ti && ti.toAlias() == sym) | |
454 { | |
455 TypeInstance t = new TypeInstance(Loc(0), ti); | |
456 return t.deduceType(sc, tparam, parameters, dedtypes); | |
457 } | |
458 | |
459 /* Match things like: | |
460 * S!(T).foo | |
461 */ | |
462 TypeInstance tpi = cast(TypeInstance)tparam; | |
463 if (tpi.idents.dim) | |
464 { Identifier id = cast(Identifier)tpi.idents.data[tpi.idents.dim - 1]; | |
465 if (id.dyncast() == DYNCAST.DYNCAST_IDENTIFIER && sym.ident.equals(id)) | |
466 { | |
467 Type tparent = sym.parent.getType(); | |
468 if (tparent) | |
469 { | |
470 /* Slice off the .foo in S!(T).foo | |
471 */ | |
472 tpi.idents.dim--; | |
473 MATCH m = tparent.deduceType(sc, tpi, parameters, dedtypes); | |
474 tpi.idents.dim++; | |
475 return m; | |
476 } | |
477 } | |
478 } | |
479 } | |
480 | |
481 // Extra check | |
482 if (tparam && tparam.ty == Tstruct) | |
483 { | |
484 TypeStruct tp = cast(TypeStruct)tparam; | |
485 | |
486 if (sym != tp.sym) | |
487 return MATCHnomatch; | |
488 } | |
489 return Type.deduceType(sc, tparam, parameters, dedtypes); | |
0 | 490 } |
174 | 491 |
72 | 492 override TypeInfoDeclaration getTypeInfoDeclaration() |
0 | 493 { |
494 return new TypeInfoStructDeclaration(this); | |
495 } | |
174 | 496 |
72 | 497 override bool hasPointers() |
0 | 498 { |
135 | 499 // Probably should cache this information in sym rather than recompute |
0 | 500 StructDeclaration s = sym; |
501 | |
502 sym.size(Loc(0)); // give error for forward references | |
85
8e69d041a99d
Previous commit didn't compile. Fixed.
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
503 foreach (VarDeclaration sm; s.fields) |
0 | 504 { |
505 Declaration d = sm.isDeclaration(); | |
506 if (d.storage_class & STC.STCref || d.hasPointers()) | |
507 return true; | |
508 } | |
509 | |
510 return false; | |
511 } | |
174 | 512 |
72 | 513 override MATCH implicitConvTo(Type to) |
0 | 514 { |
515 MATCH m; | |
516 | |
517 //printf("TypeStruct.implicitConvTo(%s => %s)\n", toChars(), to.toChars()); | |
518 if (ty == to.ty && sym == (cast(TypeStruct)to).sym) | |
174 | 519 { |
0 | 520 m = MATCHexact; // exact match |
521 if (mod != to.mod) | |
522 { | |
135 | 523 if (MODimplicitConv(mod, to.mod)) |
0 | 524 m = MATCHconst; |
525 else | |
526 { /* Check all the fields. If they can all be converted, | |
527 * allow the conversion. | |
528 */ | |
85
8e69d041a99d
Previous commit didn't compile. Fixed.
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
84
diff
changeset
|
529 foreach (VarDeclaration v; sym.fields) |
174 | 530 { |
0 | 531 assert(v && v.storage_class & STCfield); |
532 | |
533 // 'from' type | |
534 Type tvf = v.type.addMod(mod); | |
535 | |
536 // 'to' type | |
537 Type tv = v.type.castMod(to.mod); | |
538 | |
539 //printf("\t%s => %s, match = %d\n", v.type.toChars(), tv.toChars(), tvf.implicitConvTo(tv)); | |
540 if (tvf.implicitConvTo(tv) < MATCHconst) | |
541 return MATCHnomatch; | |
542 } | |
543 m = MATCHconst; | |
544 } | |
545 } | |
546 } | |
547 else if (sym.aliasthis) | |
548 { | |
549 m = MATCHnomatch; | |
550 Declaration d = sym.aliasthis.isDeclaration(); | |
551 if (d) | |
174 | 552 { |
0 | 553 assert(d.type); |
554 Type t = d.type.addMod(mod); | |
555 m = t.implicitConvTo(to); | |
556 } | |
557 } | |
558 else | |
559 m = MATCHnomatch; // no match | |
560 return m; | |
561 } | |
174 | 562 |
72 | 563 override MATCH constConv(Type to) |
0 | 564 { |
565 if (equals(to)) | |
566 return MATCHexact; | |
135 | 567 if (ty == to.ty && sym == (cast(TypeStruct)to).sym && |
568 MODimplicitConv(mod, to.mod)) | |
0 | 569 return MATCHconst; |
570 return MATCHnomatch; | |
571 } | |
174 | 572 |
72 | 573 override Type toHeadMutable() |
0 | 574 { |
575 assert(false); | |
576 } | |
174 | 577 |
0 | 578 version (CPP_MANGLE) { |
579 void toCppMangle(OutBuffer buf, CppMangleState* cms) | |
580 { | |
581 assert(false); | |
582 } | |
583 } | |
584 | |
72 | 585 override type* toCtype() |
0 | 586 { |
587 type* t; | |
588 Symbol* s; | |
589 | |
590 if (ctype) | |
591 return ctype; | |
592 | |
593 //printf("TypeStruct.toCtype() '%s'\n", sym.toChars()); | |
594 s = symbol_calloc(toStringz(sym.toPrettyChars())); | |
595 s.Sclass = SC.SCstruct; | |
596 s.Sstruct = struct_calloc(); | |
597 s.Sstruct.Sflags |= 0; /// huh? | |
598 s.Sstruct.Salignsize = sym.alignsize; | |
599 s.Sstruct.Sstructalign = cast(ubyte)sym.structalign; | |
600 s.Sstruct.Sstructsize = sym.structsize; | |
601 | |
602 if (sym.isUnionDeclaration()) | |
603 s.Sstruct.Sflags |= STR.STRunion; | |
604 | |
605 t = type_alloc(TYM.TYstruct); | |
606 t.Ttag = cast(Classsym*)s; // structure tag name | |
607 t.Tcount++; | |
608 s.Stype = t; | |
609 slist_add(s); | |
610 ctype = t; | |
611 | |
612 /* Add in fields of the struct | |
613 * (after setting ctype to avoid infinite recursion) | |
614 */ | |
615 if (global.params.symdebug) { | |
616 for (int i = 0; i < sym.fields.dim; i++) | |
174 | 617 { |
79 | 618 VarDeclaration v = cast(VarDeclaration)sym.fields[i]; |
0 | 619 |
620 Symbol* s2 = symbol_name(toStringz(v.ident.toChars()), SC.SCmember, v.type.toCtype()); | |
621 s2.Smemoff = v.offset; | |
622 list_append(&s.Sstruct.Sfldlst, s2); | |
623 } | |
624 } | |
625 | |
626 //printf("t = %p, Tflags = x%x\n", t, t.Tflags); | |
627 return t; | |
628 } | |
72 | 629 } |