Ignore maybe attributes when matching templates
[delight/core.git] / dmd / toobj.c
blobb5f027217648325ffc740fe699610a314a408e3f
2 // Copyright (c) 1999-2008 by Digital Mars
3 // All Rights Reserved
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
10 /* NOTE: This file has been patched from the original DMD distribution to
11 work with the GDC compiler.
13 Modified by David Friedman, September 2004
16 #include <stdio.h>
17 #include <stddef.h>
18 #include <time.h>
19 #include <assert.h>
21 #include "mars.h"
22 #include "module.h"
23 #include "mtype.h"
24 #include "declaration.h"
25 #include "statement.h"
26 #include "enum.h"
27 #include "aggregate.h"
28 #include "init.h"
29 #include "attrib.h"
30 #include "id.h"
31 #include "import.h"
32 #include "template.h"
34 #include <mem.h>
35 #ifndef IN_GCC
36 #include "cc.h"
37 #include "global.h"
38 #include "oper.h"
39 #include "code.h"
40 #include "type.h"
41 #include "dt.h"
42 #include "cgcv.h"
43 #include "outbuf.h"
44 #include "irstate.h"
45 #else
46 #include "dt.h"
47 #endif
49 #ifdef IN_GCC
50 #include "d-dmd-gcc.h"
51 #endif
53 void obj_lzext(Symbol *s1,Symbol *s2);
55 #ifdef IN_GCC
56 #if 0
57 static bool m_in_a(Module * m, Array * a) {
58 for (unsigned i = 0; i < a->dim; i++)
59 if ( m == (Module *) a->data[i] )
60 return true;
61 return false;
63 static void find_module_deps(Module * the_module, Array * out_deps)
65 Array work;
66 unsigned wi = 0;
68 work.push(the_module);
69 while (wi < work.dim) {
70 Module * a_module = (Module *) work.data[wi];
71 for (unsigned i = 0; i < a_module->aimports.dim; i++) {
72 Module * an_imp = (Module*) a_module->aimports.data[i];
73 if (! an_imp->needModuleInfo() ||
74 m_in_a(an_imp, & work) || m_in_a(an_imp, out_deps))
75 continue;
76 if (an_imp->strictlyneedmoduleinfo)
78 out_deps->push(an_imp);
79 fprintf(stderr, "idep: %s -> %s", the_module->toPrettyChars(),
80 an_imp->toPrettyChars());
81 if (a_module != the_module)
82 fprintf(stderr, " (via %s)", a_module->toPrettyChars());
83 fprintf(stderr, "\n");
85 else
86 work.push(an_imp);
88 wi++;
91 #endif
92 #endif
95 /* ================================================================== */
97 // Put out instance of ModuleInfo for this Module
99 void Module::genmoduleinfo()
101 //printf("Module::genmoduleinfo() %s\n", toChars());
103 Symbol *msym = toSymbol();
104 unsigned offset;
105 unsigned sizeof_ModuleInfo = 14 * PTRSIZE;
107 //////////////////////////////////////////////
109 csym->Sclass = SCglobal;
110 csym->Sfl = FLdata;
112 /* The layout is:
114 void **vptr;
115 monitor_t monitor;
116 char[] name; // class name
117 ModuleInfo importedModules[];
118 ClassInfo localClasses[];
119 uint flags; // initialization state
120 void *ctor;
121 void *dtor;
122 void *unitTest;
123 const(MemberInfo[]) function(string) xgetMembers; // module getMembers() function
124 void *ictor;
127 dt_t *dt = NULL;
129 if (moduleinfo)
130 dtxoff(&dt, moduleinfo->toVtblSymbol(), 0, TYnptr); // vtbl for ModuleInfo
131 else
132 { //printf("moduleinfo is null\n");
133 dtdword(&dt, 0); // BUG: should be an assert()
135 dtdword(&dt, 0); // monitor
137 // name[]
138 char *name = toPrettyChars();
139 size_t namelen = strlen(name);
140 dtdword(&dt, namelen);
141 dtabytes(&dt, TYnptr, 0, namelen + 1, name);
143 ClassDeclarations aclasses;
145 //printf("members->dim = %d\n", members->dim);
146 for (int i = 0; i < members->dim; i++)
147 { Dsymbol *member = (Dsymbol *)members->data[i];
149 //printf("\tmember '%s'\n", member->toChars());
150 member->addLocalClass(&aclasses);
153 // importedModules[]
154 int aimports_dim = aimports.dim;
155 #ifdef IN_GCC
156 #if 0
157 Array adeps;
159 if (! d_gcc_supports_weak())
161 find_module_deps(this, & adeps);
162 aimports_dim = adeps.dim;
164 else
165 #endif
166 #endif
167 for (int i = 0; i < aimports.dim; i++)
168 { Module *m = (Module *)aimports.data[i];
169 if (!m->needModuleInfo())
170 aimports_dim--;
172 dtdword(&dt, aimports_dim);
173 if (aimports.dim)
174 dtxoff(&dt, csym, sizeof_ModuleInfo, TYnptr);
175 else
176 dtdword(&dt, 0);
178 // localClasses[]
179 dtdword(&dt, aclasses.dim);
180 if (aclasses.dim)
181 dtxoff(&dt, csym, sizeof_ModuleInfo + aimports_dim * PTRSIZE, TYnptr);
182 else
183 dtdword(&dt, 0);
185 if (needmoduleinfo)
186 dti32(&dt, 8|0, true); // flags (4 means MIstandalone)
187 else
188 dti32(&dt, 8|4, true); // flags (4 means MIstandalone)
190 if (sctor)
191 dtxoff(&dt, sctor, 0, TYnptr);
192 else
193 dtdword(&dt, 0);
195 if (sdtor)
196 dtxoff(&dt, sdtor, 0, TYnptr);
197 else
198 dtdword(&dt, 0);
200 if (stest)
201 dtxoff(&dt, stest, 0, TYnptr);
202 else
203 dtdword(&dt, 0);
205 dtdword(&dt, 0); // xgetMembers
207 if (sictor)
208 dtxoff(&dt, sictor, 0, TYnptr);
209 else
210 dtdword(&dt, 0);
212 //////////////////////////////////////////////
214 #ifdef IN_GCC
215 #if 0
216 if (! d_gcc_supports_weak())
217 for (i = 0; i < adeps.dim; i++)
219 Module *m;
220 Symbol *s;
222 m = (Module *) adeps.data[i];
223 s = m->toSymbol();
224 s->Sflags |= SFLweak; // doesn't do anything yet, but see d-decls.cc:Module::toSymbol
225 dtxoff(&dt, s, 0, TYnptr);
227 else
228 #endif
229 #endif
230 for (int i = 0; i < aimports.dim; i++)
231 { Module *m = (Module *)aimports.data[i];
233 if (m->needModuleInfo())
234 { Symbol *s = m->toSymbol();
235 s->Sflags |= SFLweak;
236 dtxoff(&dt, s, 0, TYnptr);
240 for (int i = 0; i < aclasses.dim; i++)
242 ClassDeclaration *cd = (ClassDeclaration *)aclasses.data[i];
243 dtxoff(&dt, cd->toSymbol(), 0, TYnptr);
246 csym->Sdt = dt;
247 #if ELFOBJ
248 // Cannot be CONST because the startup code sets flag bits in it
249 csym->Sseg = DATA;
250 #endif
251 outdata(csym);
253 //////////////////////////////////////////////
255 obj_moduleinfo(msym);
258 /* ================================================================== */
260 void Dsymbol::toObjFile(int multiobj)
262 //printf("Dsymbol::toObjFile('%s')\n", toChars());
263 // ignore
264 #ifdef IN_GCC
265 TupleDeclaration * td = this->isTupleDeclaration();
266 if (td)
268 for (unsigned i = 0; i < td->objects->dim; i++)
270 Object * o = (Object *) td->objects->data[i];
271 Expression * e;
272 Dsymbol *ds;
273 Declaration *d;
274 if ((o->dyncast() == DYNCAST_EXPRESSION) &&
275 ((Expression *) o)->op == TOKdsymbol)
277 ds = ((DsymbolExp *) o)->s;
278 d = ds->isDeclaration();
279 if (d)
280 d->toObjFile(multiobj);
285 #endif
287 /* ================================================================== */
289 void ClassDeclaration::toObjFile(int multiobj)
290 { unsigned i;
291 unsigned offset;
292 Symbol *sinit;
293 enum_SC scclass;
295 //printf("ClassDeclaration::toObjFile('%s')\n", toChars());
297 if (!members)
298 return;
300 if (global.params.symdebug)
301 toDebug();
303 assert(!scope); // semantic() should have been run to completion
305 if (parent && parent->isTemplateInstance())
306 scclass = SCcomdat;
307 else
308 scclass = SCglobal;
310 // Put out the members
311 for (i = 0; i < members->dim; i++)
313 Dsymbol *member;
315 member = (Dsymbol *)members->data[i];
316 member->toObjFile(0);
319 #if 0
320 // Build destructor by aggregating dtors[]
321 Symbol *sdtor;
322 switch (dtors.dim)
323 { case 0:
324 // No destructors for this class
325 sdtor = NULL;
326 break;
328 case 1:
329 // One destructor, just use it directly
330 sdtor = ((DtorDeclaration *)dtors.data[0])->toSymbol();
331 break;
333 default:
334 { /* Build a destructor that calls all the
335 * other destructors in dtors[].
338 elem *edtor = NULL;
340 // Declare 'this' pointer for our new destructor
341 Symbol *sthis = symbol_calloc("this");
342 sthis->Stype = type_fake(TYnptr);
343 sthis->Stype->Tcount++;
344 sthis->Sclass = SCfastpar;
345 sthis->Spreg = AX;
346 sthis->Sfl = FLauto;
348 // Call each of the destructors in dtors[]
349 // in reverse order
350 for (i = 0; i < dtors.dim; i++)
351 { DtorDeclaration *d = (DtorDeclaration *)dtors.data[i];
352 Symbol *s = d->toSymbol();
353 elem *e;
355 e = el_bin(OPcall, TYvoid, el_var(s), el_var(sthis));
356 edtor = el_combine(e, edtor);
359 // Create type for the function
360 ::type *t = type_alloc(TYjfunc);
361 t->Tflags |= TFprototype | TFfixed;
362 t->Tmangle = mTYman_d;
363 t->Tnext = tsvoid;
364 tsvoid->Tcount++;
366 // Create the function, sdtor, and write it out
367 localgot = NULL;
368 sdtor = toSymbolX("__dtor", SCglobal, t, "FZv");
369 block *b = block_calloc();
370 b->BC = BCret;
371 b->Belem = edtor;
372 sdtor->Sfunc->Fstartblock = b;
373 cstate.CSpsymtab = &sdtor->Sfunc->Flocsym;
374 symbol_add(sthis);
375 writefunc(sdtor);
378 #endif
380 // Generate C symbols
381 toSymbol();
382 toVtblSymbol();
383 sinit = toInitializer();
385 //////////////////////////////////////////////
387 // Generate static initializer
388 sinit->Sclass = scclass;
389 sinit->Sfl = FLdata;
390 #if ELFOBJ // Burton
391 sinit->Sseg = CDATA;
392 #endif /* ELFOBJ */
393 toDt(&sinit->Sdt);
394 outdata(sinit);
396 //////////////////////////////////////////////
398 // Put out the ClassInfo
399 csym->Sclass = scclass;
400 csym->Sfl = FLdata;
402 /* The layout is:
404 void **vptr;
405 monitor_t monitor;
406 byte[] initializer; // static initialization data
407 char[] name; // class name
408 void *[] vtbl;
409 Interface[] interfaces;
410 ClassInfo *base; // base class
411 void *destructor;
412 void *invariant; // class invariant
413 uint flags;
414 void *deallocator;
415 OffsetTypeInfo[] offTi;
416 void *defaultConstructor;
419 dt_t *dt = NULL;
420 offset = CLASSINFO_SIZE; // must be ClassInfo.size
421 if (classinfo)
423 if (classinfo->structsize != CLASSINFO_SIZE)
424 error("D compiler and phobos/object.d are mismatched");
427 if (classinfo)
428 dtxoff(&dt, classinfo->toVtblSymbol(), 0, TYnptr); // vtbl for ClassInfo
429 else
430 dtdword(&dt, 0); // BUG: should be an assert()
431 dtdword(&dt, 0); // monitor
433 // initializer[]
434 assert(structsize >= 8);
435 dtdword(&dt, structsize); // size
436 dtxoff(&dt, sinit, 0, TYnptr); // initializer
438 // name[]
439 char *name = ident->toChars();
440 size_t namelen = strlen(name);
441 if (!(namelen > 9 && memcmp(name, "TypeInfo_", 9) == 0))
442 { name = toPrettyChars();
443 namelen = strlen(name);
445 dtdword(&dt, namelen);
446 dtabytes(&dt, TYnptr, 0, namelen + 1, name);
448 // vtbl[]
449 dtdword(&dt, vtbl.dim);
450 dtxoff(&dt, vtblsym, 0, TYnptr);
452 // interfaces[]
453 dtdword(&dt, vtblInterfaces->dim);
454 if (vtblInterfaces->dim)
455 dtxoff(&dt, csym, offset, TYnptr); // (*)
456 else
457 dtdword(&dt, 0);
459 // base
460 if (baseClass)
461 dtxoff(&dt, baseClass->toSymbol(), 0, TYnptr);
462 else
463 dtdword(&dt, 0);
465 // destructor
466 if (dtor)
467 dtxoff(&dt, dtor->toSymbol(), 0, TYnptr);
468 else
469 dtdword(&dt, 0);
471 // invariant
472 if (inv)
473 dtxoff(&dt, inv->toSymbol(), 0, TYnptr);
474 else
475 dtdword(&dt, 0);
477 // flags
478 int flags = 4 | isCOMclass();
479 if (ctor)
480 flags |= 8;
481 for (ClassDeclaration *cd = this; cd; cd = cd->baseClass)
483 if (cd->members)
485 for (size_t i = 0; i < cd->members->dim; i++)
487 Dsymbol *sm = (Dsymbol *)cd->members->data[i];
488 //printf("sm = %s %s\n", sm->kind(), sm->toChars());
489 if (sm->hasPointers())
490 goto L2;
494 flags |= 2; // no pointers
496 dti32(&dt, flags, true);
499 // deallocator
500 if (aggDelete)
501 dtxoff(&dt, aggDelete->toSymbol(), 0, TYnptr);
502 else
503 dtdword(&dt, 0);
505 // offTi[]
506 dtdword(&dt, 0);
507 dtdword(&dt, 0); // null for now, fix later
509 // defaultConstructor
510 if (defaultCtor)
511 dtxoff(&dt, defaultCtor->toSymbol(), 0, TYnptr);
512 else
513 dtdword(&dt, 0);
515 //////////////////////////////////////////////
517 // Put out vtblInterfaces->data[]. Must immediately follow csym, because
518 // of the fixup (*)
520 offset += vtblInterfaces->dim * (4 * PTRSIZE);
521 for (i = 0; i < vtblInterfaces->dim; i++)
522 { BaseClass *b = (BaseClass *)vtblInterfaces->data[i];
523 ClassDeclaration *id = b->base;
525 /* The layout is:
527 * ClassInfo *interface;
528 * void *[] vtbl;
529 * unsigned offset;
533 // Fill in vtbl[]
534 b->fillVtbl(this, &b->vtbl, 1);
536 dtxoff(&dt, id->toSymbol(), 0, TYnptr); // ClassInfo
538 // vtbl[]
539 dtdword(&dt, id->vtbl.dim);
540 dtxoff(&dt, csym, offset, TYnptr);
542 dtdword(&dt, b->offset); // this offset
544 offset += id->vtbl.dim * PTRSIZE;
547 // Put out the vtblInterfaces->data[].vtbl[]
548 // This must be mirrored with ClassDeclaration::baseVtblOffset()
549 //printf("putting out %d interface vtbl[]s for '%s'\n", vtblInterfaces->dim, toChars());
550 for (i = 0; i < vtblInterfaces->dim; i++)
551 { BaseClass *b = (BaseClass *)vtblInterfaces->data[i];
552 ClassDeclaration *id = b->base;
553 int j;
555 //printf(" interface[%d] is '%s'\n", i, id->toChars());
556 j = 0;
557 if (id->vtblOffset())
559 // First entry is ClassInfo reference
560 //dtxoff(&dt, id->toSymbol(), 0, TYnptr);
562 // First entry is struct Interface reference
563 dtxoff(&dt, csym, CLASSINFO_SIZE + i * (4 * PTRSIZE), TYnptr);
564 j = 1;
566 assert(id->vtbl.dim == b->vtbl.dim);
567 for (; j < id->vtbl.dim; j++)
569 FuncDeclaration *fd;
571 assert(j < b->vtbl.dim);
572 #if 0
573 Object *o = (Object *)b->vtbl.data[j];
574 if (o)
576 printf("o = %p\n", o);
577 assert(o->dyncast() == DYNCAST_DSYMBOL);
578 Dsymbol *s = (Dsymbol *)o;
579 printf("s->kind() = '%s'\n", s->kind());
581 #endif
582 fd = (FuncDeclaration *)b->vtbl.data[j];
583 if (fd)
584 dtxoff(&dt, fd->toThunkSymbol(b->offset), 0, TYnptr);
585 else
586 dtdword(&dt, 0);
590 #if 1
591 // Put out the overriding interface vtbl[]s.
592 // This must be mirrored with ClassDeclaration::baseVtblOffset()
593 //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset);
594 ClassDeclaration *cd;
595 Array bvtbl;
597 for (cd = this->baseClass; cd; cd = cd->baseClass)
599 for (int k = 0; k < cd->vtblInterfaces->dim; k++)
600 { BaseClass *bs = (BaseClass *)cd->vtblInterfaces->data[k];
602 if (bs->fillVtbl(this, &bvtbl, 0))
604 //printf("\toverriding vtbl[] for %s\n", bs->base->toChars());
605 ClassDeclaration *id = bs->base;
606 int j;
608 j = 0;
609 if (id->vtblOffset())
611 // First entry is ClassInfo reference
612 //dtxoff(&dt, id->toSymbol(), 0, TYnptr);
614 // First entry is struct Interface reference
615 dtxoff(&dt, cd->toSymbol(), CLASSINFO_SIZE + k * (4 * PTRSIZE), TYnptr);
616 j = 1;
619 for (; j < id->vtbl.dim; j++)
621 FuncDeclaration *fd;
623 assert(j < bvtbl.dim);
624 fd = (FuncDeclaration *)bvtbl.data[j];
625 if (fd)
626 dtxoff(&dt, fd->toThunkSymbol(bs->offset), 0, TYnptr);
627 else
628 dtdword(&dt, 0);
633 #endif
634 #if INTERFACE_VIRTUAL
635 // Put out the overriding interface vtbl[]s.
636 // This must be mirrored with ClassDeclaration::baseVtblOffset()
637 //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset);
638 for (i = 0; i < vtblInterfaces->dim; i++)
639 { BaseClass *b = (BaseClass *)vtblInterfaces->data[i];
640 ClassDeclaration *cd;
642 for (cd = this->baseClass; cd; cd = cd->baseClass)
644 for (int k = 0; k < cd->vtblInterfaces->dim; k++)
645 { BaseClass *bs = (BaseClass *)cd->vtblInterfaces->data[k];
647 if (b->base == bs->base)
649 //printf("\toverriding vtbl[] for %s\n", b->base->toChars());
650 ClassDeclaration *id = b->base;
651 int j;
653 j = 0;
654 if (id->vtblOffset())
656 // First entry is ClassInfo reference
657 //dtxoff(&dt, id->toSymbol(), 0, TYnptr);
659 // First entry is struct Interface reference
660 dtxoff(&dt, cd->toSymbol(), CLASSINFO_SIZE + k * (4 * PTRSIZE), TYnptr);
661 j = 1;
664 for (; j < id->vtbl.dim; j++)
666 FuncDeclaration *fd;
668 assert(j < b->vtbl.dim);
669 fd = (FuncDeclaration *)b->vtbl.data[j];
670 if (fd)
671 dtxoff(&dt, fd->toThunkSymbol(bs->offset), 0, TYnptr);
672 else
673 dtdword(&dt, 0);
679 #endif
682 csym->Sdt = dt;
683 #if ELFOBJ // Burton
684 // ClassInfo cannot be const data, because we use the monitor on it
685 csym->Sseg = DATA;
686 #endif /* ELFOBJ */
687 outdata(csym);
688 if (isExport())
689 obj_export(csym,0);
691 //////////////////////////////////////////////
693 // Put out the vtbl[]
694 //printf("putting out %s.vtbl[]\n", toChars());
695 dt = NULL;
696 if (0)
697 i = 0;
698 else
699 { dtxoff(&dt, csym, 0, TYnptr); // first entry is ClassInfo reference
700 i = 1;
702 for (; i < vtbl.dim; i++)
704 FuncDeclaration *fd = ((Dsymbol *)vtbl.data[i])->isFuncDeclaration();
706 //printf("\tvtbl[%d] = %p\n", i, fd);
707 if (fd && (fd->fbody || !isAbstract()))
709 dtxoff(&dt, fd->toSymbol(), 0, TYnptr);
711 else
712 dtdword(&dt, 0);
714 vtblsym->Sdt = dt;
715 vtblsym->Sclass = scclass;
716 vtblsym->Sfl = FLdata;
717 #if ELFOBJ // Burton
718 vtblsym->Sseg = CDATA;
719 #endif /* ELFOBJ */
720 outdata(vtblsym);
721 if (isExport())
722 obj_export(vtblsym,0);
725 /******************************************
726 * Get offset of base class's vtbl[] initializer from start of csym.
727 * Returns ~0 if not this csym.
730 unsigned ClassDeclaration::baseVtblOffset(BaseClass *bc)
732 unsigned csymoffset;
733 int i;
735 //printf("ClassDeclaration::baseVtblOffset('%s', bc = %p)\n", toChars(), bc);
736 csymoffset = CLASSINFO_SIZE;
737 csymoffset += vtblInterfaces->dim * (4 * PTRSIZE);
739 for (i = 0; i < vtblInterfaces->dim; i++)
741 BaseClass *b = (BaseClass *)vtblInterfaces->data[i];
743 if (b == bc)
744 return csymoffset;
745 csymoffset += b->base->vtbl.dim * PTRSIZE;
748 #if 1
749 // Put out the overriding interface vtbl[]s.
750 // This must be mirrored with ClassDeclaration::baseVtblOffset()
751 //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset);
752 ClassDeclaration *cd;
753 Array bvtbl;
755 for (cd = this->baseClass; cd; cd = cd->baseClass)
757 for (int k = 0; k < cd->vtblInterfaces->dim; k++)
758 { BaseClass *bs = (BaseClass *)cd->vtblInterfaces->data[k];
760 if (bs->fillVtbl(this, NULL, 0))
762 if (bc == bs)
763 { //printf("\tcsymoffset = x%x\n", csymoffset);
764 return csymoffset;
766 csymoffset += bs->base->vtbl.dim * PTRSIZE;
770 #endif
771 #if INTERFACE_VIRTUAL
772 for (i = 0; i < vtblInterfaces->dim; i++)
773 { BaseClass *b = (BaseClass *)vtblInterfaces->data[i];
774 ClassDeclaration *cd;
776 for (cd = this->baseClass; cd; cd = cd->baseClass)
778 //printf("\tbase class %s\n", cd->toChars());
779 for (int k = 0; k < cd->vtblInterfaces->dim; k++)
780 { BaseClass *bs = (BaseClass *)cd->vtblInterfaces->data[k];
782 if (bc == bs)
783 { //printf("\tcsymoffset = x%x\n", csymoffset);
784 return csymoffset;
786 if (b->base == bs->base)
787 csymoffset += bs->base->vtbl.dim * PTRSIZE;
791 #endif
793 return ~0;
796 /* ================================================================== */
798 void InterfaceDeclaration::toObjFile(int multiobj)
799 { unsigned i;
800 unsigned offset;
801 Symbol *sinit;
802 enum_SC scclass;
804 //printf("InterfaceDeclaration::toObjFile('%s')\n", toChars());
806 if (!members)
807 return;
809 if (global.params.symdebug)
810 toDebug();
812 if (parent && parent->isTemplateInstance())
813 scclass = SCcomdat;
814 else
815 scclass = SCglobal;
817 // Put out the members
818 for (i = 0; i < members->dim; i++)
820 Dsymbol *member;
822 member = (Dsymbol *)members->data[i];
823 if (!member->isFuncDeclaration())
824 member->toObjFile(0);
827 // Generate C symbols
828 toSymbol();
830 //////////////////////////////////////////////
832 // Put out the ClassInfo
833 csym->Sclass = scclass;
834 csym->Sfl = FLdata;
836 /* The layout is:
838 void **vptr;
839 monitor_t monitor;
840 byte[] initializer; // static initialization data
841 char[] name; // class name
842 void *[] vtbl;
843 Interface[] interfaces;
844 Object *base; // base class
845 void *destructor;
846 void *invariant; // class invariant
847 uint flags;
848 void *deallocator;
849 OffsetTypeInfo[] offTi;
850 void *defaultConstructor;
853 dt_t *dt = NULL;
855 if (classinfo)
856 dtxoff(&dt, classinfo->toVtblSymbol(), 0, TYnptr); // vtbl for ClassInfo
857 else
858 dtdword(&dt, 0); // BUG: should be an assert()
859 dtdword(&dt, 0); // monitor
861 // initializer[]
862 dtdword(&dt, 0); // size
863 dtdword(&dt, 0); // initializer
865 // name[]
866 char *name = toPrettyChars();
867 size_t namelen = strlen(name);
868 dtdword(&dt, namelen);
869 dtabytes(&dt, TYnptr, 0, namelen + 1, name);
871 // vtbl[]
872 dtdword(&dt, 0);
873 dtdword(&dt, 0);
875 // vtblInterfaces->data[]
876 dtdword(&dt, vtblInterfaces->dim);
877 if (vtblInterfaces->dim)
879 if (classinfo)
880 assert(classinfo->structsize == CLASSINFO_SIZE);
881 offset = CLASSINFO_SIZE;
882 dtxoff(&dt, csym, offset, TYnptr); // (*)
884 else
885 dtdword(&dt, 0);
887 // base
888 assert(!baseClass);
889 dtdword(&dt, 0);
891 // dtor
892 dtdword(&dt, 0);
894 // invariant
895 dtdword(&dt, 0);
897 // flags
898 dti32(&dt, 4 | isCOMinterface(), true);
900 // deallocator
901 dtdword(&dt, 0);
903 // offTi[]
904 dtdword(&dt, 0);
905 dtdword(&dt, 0); // null for now, fix later
907 // defaultConstructor
908 dtdword(&dt, 0);
910 //////////////////////////////////////////////
912 // Put out vtblInterfaces->data[]. Must immediately follow csym, because
913 // of the fixup (*)
915 offset += vtblInterfaces->dim * (4 * PTRSIZE);
916 for (i = 0; i < vtblInterfaces->dim; i++)
917 { BaseClass *b = (BaseClass *)vtblInterfaces->data[i];
918 ClassDeclaration *id = b->base;
920 // ClassInfo
921 dtxoff(&dt, id->toSymbol(), 0, TYnptr);
923 // vtbl[]
924 dtdword(&dt, 0);
925 dtdword(&dt, 0);
927 // this offset
928 dtdword(&dt, b->offset);
931 csym->Sdt = dt;
932 #if ELFOBJ // Burton
933 csym->Sseg = CDATA;
934 #endif /* ELFOBJ */
935 outdata(csym);
936 if (isExport())
937 obj_export(csym,0);
940 /* ================================================================== */
942 void StructDeclaration::toObjFile(int multiobj)
943 { unsigned i;
945 //printf("StructDeclaration::toObjFile('%s')\n", toChars());
947 // Anonymous structs/unions only exist as part of others,
948 // do not output forward referenced structs's
949 if (!isAnonymous() && members)
951 if (global.params.symdebug)
952 toDebug();
954 type->getTypeInfo(NULL); // generate TypeInfo
956 if (1)
958 // Generate static initializer
959 toInitializer();
960 #if 0
961 sinit->Sclass = SCcomdat;
962 #else
963 if (parent && parent->isTemplateInstance())
964 sinit->Sclass = SCcomdat;
965 else
966 sinit->Sclass = SCglobal;
967 #endif
968 sinit->Sfl = FLdata;
969 toDt(&sinit->Sdt);
971 #if !ELFOBJ
972 /* For OMF, common blocks aren't pulled in from the library.
974 /* ELF comdef's generate multiple
975 * definition errors for them from the gnu linker.
976 * Need to figure out how to generate proper comdef's for ELF.
978 // See if we can convert a comdat to a comdef,
979 // which saves on exe file space.
980 if (sinit->Sclass == SCcomdat &&
981 sinit->Sdt &&
982 sinit->Sdt->dt == DT_azeros &&
983 sinit->Sdt->DTnext == NULL)
985 sinit->Sclass = SCglobal;
986 sinit->Sdt->dt = DT_common;
988 #endif
990 #if ELFOBJ // Burton
991 sinit->Sseg = CDATA;
992 #endif
993 outdata(sinit);
996 // Put out the members
997 for (i = 0; i < members->dim; i++)
999 Dsymbol *member;
1001 member = (Dsymbol *)members->data[i];
1002 member->toObjFile(0);
1007 /* ================================================================== */
1009 void VarDeclaration::toObjFile(int multiobj)
1011 Symbol *s;
1012 unsigned sz;
1013 Dsymbol *parent;
1015 //printf("VarDeclaration::toObjFile(%p '%s' type=%s) protection %d\n", this, toChars(), type->toChars(), protection);
1016 //printf("\talign = %d\n", type->alignsize());
1018 if (aliassym)
1019 { toAlias()->toObjFile(0);
1020 return;
1023 if (isDataseg() && !(storage_class & STCextern))
1025 s = toSymbol();
1026 sz = type->size();
1028 parent = this->toParent();
1029 #if 1 /* private statics should still get a global symbol, in case
1030 * another module inlines a function that references it.
1032 if (/*protection == PROTprivate ||*/
1033 !parent || parent->ident == NULL || parent->isFuncDeclaration())
1035 s->Sclass = SCstatic;
1037 else
1038 #endif
1040 if (storage_class & STCcomdat)
1041 s->Sclass = SCcomdat;
1042 else
1043 s->Sclass = SCglobal;
1047 /* Global template data members need to be in comdat's
1048 * in case multiple .obj files instantiate the same
1049 * template with the same types.
1051 if (parent->isTemplateInstance() && !parent->isTemplateMixin())
1053 /* These symbol constants have already been copied,
1054 * so no reason to output them.
1055 * Note that currently there is no way to take
1056 * the address of such a const.
1058 if (isConst() && type->toBasetype()->ty != Tsarray &&
1059 init && init->isExpInitializer())
1060 return;
1062 s->Sclass = SCcomdat;
1063 break;
1065 parent = parent->parent;
1066 } while (parent);
1068 s->Sfl = FLdata;
1070 if (init)
1071 { s->Sdt = init->toDt();
1073 // Look for static array that is block initialized
1074 Type *tb;
1075 ExpInitializer *ie = init->isExpInitializer();
1077 tb = type->toBasetype();
1078 if (tb->ty == Tsarray && ie &&
1079 !tb->nextOf()->equals(ie->exp->type->toBasetype()->nextOf()) &&
1080 ie->exp->implicitConvTo(tb->nextOf())
1083 int dim;
1085 dim = ((TypeSArray *)tb)->dim->toInteger();
1087 // Duplicate Sdt 'dim-1' times, as we already have the first one
1088 while (--dim > 0)
1090 ie->exp->toDt(&s->Sdt);
1094 else if (storage_class & STCextern)
1096 s->Sclass = SCextern;
1097 s->Sfl = FLextern;
1098 s->Sdt = NULL;
1099 // BUG: if isExport(), shouldn't we make it dllimport?
1100 return;
1102 else
1104 type->toDt(&s->Sdt);
1106 dt_optimize(s->Sdt);
1108 // See if we can convert a comdat to a comdef,
1109 // which saves on exe file space.
1110 if (s->Sclass == SCcomdat &&
1111 s->Sdt &&
1112 s->Sdt->dt == DT_azeros &&
1113 s->Sdt->DTnext == NULL)
1115 s->Sclass = SCglobal;
1116 s->Sdt->dt = DT_common;
1119 #if ELFOBJ // Burton
1120 if (s->Sdt && s->Sdt->dt == DT_azeros && s->Sdt->DTnext == NULL)
1121 s->Sseg = UDATA;
1122 else
1123 s->Sseg = DATA;
1124 #endif /* ELFOBJ */
1125 if (sz)
1126 { outdata(s);
1127 if (isExport())
1128 obj_export(s,0);
1131 #ifdef IN_GCC
1132 else {
1133 // This is needed for VarDeclarations in mixins that are to be
1134 // local variables of a function. Otherwise, it would be
1135 // enough to make a check for isVarDeclaration() in
1136 // DeclarationExp::toElem.
1137 d_gcc_emit_local_variable(this);
1139 #endif
1142 /* ================================================================== */
1144 void TypedefDeclaration::toObjFile(int multiobj)
1146 //printf("TypedefDeclaration::toObjFile('%s')\n", toChars());
1148 if (global.params.symdebug)
1149 toDebug();
1151 type->getTypeInfo(NULL); // generate TypeInfo
1153 TypeTypedef *tc = (TypeTypedef *)type;
1154 if (type->isZeroInit() || !tc->sym->init)
1156 else
1158 enum_SC scclass = SCglobal;
1159 for (Dsymbol *parent = this->parent; parent; parent = parent->parent)
1161 if (parent->isTemplateInstance())
1163 scclass = SCcomdat;
1164 break;
1168 // Generate static initializer
1169 toInitializer();
1170 sinit->Sclass = scclass;
1171 sinit->Sfl = FLdata;
1172 #if ELFOBJ // Burton
1173 sinit->Sseg = CDATA;
1174 #endif /* ELFOBJ */
1175 if (! sinit->Sdt)
1176 sinit->Sdt = tc->sym->init->toDt();
1177 outdata(sinit);
1181 /* ================================================================== */
1183 void EnumDeclaration::toObjFile(int multiobj)
1185 //printf("EnumDeclaration::toObjFile('%s')\n", toChars());
1187 if (global.params.symdebug)
1188 toDebug();
1190 type->getTypeInfo(NULL); // generate TypeInfo
1192 TypeEnum *tc = (TypeEnum *)type;
1193 if (type->isZeroInit() || !tc->sym->defaultval)
1195 else
1197 enum_SC scclass = SCglobal;
1198 for (Dsymbol *parent = this->parent; parent; parent = parent->parent)
1200 if (parent->isTemplateInstance())
1202 scclass = SCcomdat;
1203 break;
1207 // Generate static initializer
1208 toInitializer();
1209 sinit->Sclass = scclass;
1210 sinit->Sfl = FLdata;
1211 #if ELFOBJ // Burton
1212 sinit->Sseg = CDATA;
1213 #endif /* ELFOBJ */
1214 #ifndef IN_GCC
1215 dtnbytes(&sinit->Sdt, tc->size(0), (char *)&tc->sym->defaultval);
1216 #else
1217 Expression * e = new IntegerExp(0, tc->sym->defaultval, tc);
1218 e->toDt(& sinit->Sdt);
1219 #endif
1220 //sinit->Sdt = tc->sym->init->toDt();
1221 outdata(sinit);