2 // Copyright (c) 1999-2008 by Digital Mars
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
24 #include "declaration.h"
25 #include "statement.h"
27 #include "aggregate.h"
50 #include "d-dmd-gcc.h"
53 void obj_lzext(Symbol
*s1
,Symbol
*s2
);
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
] )
63 static void find_module_deps(Module
* the_module
, Array
* out_deps
)
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
))
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");
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();
105 unsigned sizeof_ModuleInfo
= 14 * PTRSIZE
;
107 //////////////////////////////////////////////
109 csym
->Sclass
= SCglobal
;
116 char[] name; // class name
117 ModuleInfo importedModules[];
118 ClassInfo localClasses[];
119 uint flags; // initialization state
123 const(MemberInfo[]) function(string) xgetMembers; // module getMembers() function
130 dtxoff(&dt
, moduleinfo
->toVtblSymbol(), 0, TYnptr
); // vtbl for ModuleInfo
132 { //printf("moduleinfo is null\n");
133 dtdword(&dt
, 0); // BUG: should be an assert()
135 dtdword(&dt
, 0); // monitor
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
);
154 int aimports_dim
= aimports
.dim
;
159 if (! d_gcc_supports_weak())
161 find_module_deps(this, & adeps
);
162 aimports_dim
= adeps
.dim
;
167 for (int i
= 0; i
< aimports
.dim
; i
++)
168 { Module
*m
= (Module
*)aimports
.data
[i
];
169 if (!m
->needModuleInfo())
172 dtdword(&dt
, aimports_dim
);
174 dtxoff(&dt
, csym
, sizeof_ModuleInfo
, TYnptr
);
179 dtdword(&dt
, aclasses
.dim
);
181 dtxoff(&dt
, csym
, sizeof_ModuleInfo
+ aimports_dim
* PTRSIZE
, TYnptr
);
186 dti32(&dt
, 8|0, true); // flags (4 means MIstandalone)
188 dti32(&dt
, 8|4, true); // flags (4 means MIstandalone)
191 dtxoff(&dt
, sctor
, 0, TYnptr
);
196 dtxoff(&dt
, sdtor
, 0, TYnptr
);
201 dtxoff(&dt
, stest
, 0, TYnptr
);
205 FuncDeclaration
*sgetmembers
= findGetMembers();
207 dtxoff(&dt
, sgetmembers
->toSymbol(), 0, TYnptr
);
209 dtdword(&dt
, 0); // xgetMembers
212 dtxoff(&dt
, sictor
, 0, TYnptr
);
216 //////////////////////////////////////////////
220 if (! d_gcc_supports_weak())
221 for (i
= 0; i
< adeps
.dim
; i
++)
226 m
= (Module
*) adeps
.data
[i
];
228 s
->Sflags
|= SFLweak
; // doesn't do anything yet, but see d-decls.cc:Module::toSymbol
229 dtxoff(&dt
, s
, 0, TYnptr
);
234 for (int i
= 0; i
< aimports
.dim
; i
++)
235 { Module
*m
= (Module
*)aimports
.data
[i
];
237 if (m
->needModuleInfo())
238 { Symbol
*s
= m
->toSymbol();
239 s
->Sflags
|= SFLweak
;
240 dtxoff(&dt
, s
, 0, TYnptr
);
244 for (int i
= 0; i
< aclasses
.dim
; i
++)
246 ClassDeclaration
*cd
= (ClassDeclaration
*)aclasses
.data
[i
];
247 dtxoff(&dt
, cd
->toSymbol(), 0, TYnptr
);
252 // Cannot be CONST because the startup code sets flag bits in it
257 //////////////////////////////////////////////
259 obj_moduleinfo(msym
);
262 /* ================================================================== */
263 void Dsymbol::toObjFile(int multiobj
)
265 //printf("Dsymbol::toObjFile('%s')\n", toChars());
268 TupleDeclaration
* td
= this->isTupleDeclaration();
271 for (unsigned i
= 0; i
< td
->objects
->dim
; i
++)
273 Object
* o
= (Object
*) td
->objects
->data
[i
];
277 if ((o
->dyncast() == DYNCAST_EXPRESSION
) &&
278 ((Expression
*) o
)->op
== TOKdsymbol
)
280 ds
= ((DsymbolExp
*) o
)->s
;
281 d
= ds
->isDeclaration();
283 d
->toObjFile(multiobj
);
290 /* ================================================================== */
292 void ClassDeclaration::toObjFile(int multiobj
)
298 //printf("ClassDeclaration::toObjFile('%s')\n", toChars());
303 if (global
.params
.symdebug
)
306 assert(!scope
); // semantic() should have been run to completion
308 if (parent
&& parent
->isTemplateInstance())
313 // Put out the members
314 for (i
= 0; i
< members
->dim
; i
++)
318 member
= (Dsymbol
*)members
->data
[i
];
319 member
->toObjFile(0);
323 // Build destructor by aggregating dtors[]
327 // No destructors for this class
332 // One destructor, just use it directly
333 sdtor
= ((DtorDeclaration
*)dtors
.data
[0])->toSymbol();
337 { /* Build a destructor that calls all the
338 * other destructors in dtors[].
343 // Declare 'this' pointer for our new destructor
344 Symbol
*sthis
= symbol_calloc("this");
345 sthis
->Stype
= type_fake(TYnptr
);
346 sthis
->Stype
->Tcount
++;
347 sthis
->Sclass
= SCfastpar
;
351 // Call each of the destructors in dtors[]
353 for (i
= 0; i
< dtors
.dim
; i
++)
354 { DtorDeclaration
*d
= (DtorDeclaration
*)dtors
.data
[i
];
355 Symbol
*s
= d
->toSymbol();
358 e
= el_bin(OPcall
, TYvoid
, el_var(s
), el_var(sthis
));
359 edtor
= el_combine(e
, edtor
);
362 // Create type for the function
363 ::type
*t
= type_alloc(TYjfunc
);
364 t
->Tflags
|= TFprototype
| TFfixed
;
365 t
->Tmangle
= mTYman_d
;
369 // Create the function, sdtor, and write it out
371 sdtor
= toSymbolX("__dtor", SCglobal
, t
, "FZv");
372 block
*b
= block_calloc();
375 sdtor
->Sfunc
->Fstartblock
= b
;
376 cstate
.CSpsymtab
= &sdtor
->Sfunc
->Flocsym
;
383 // Generate C symbols
386 sinit
= toInitializer();
388 //////////////////////////////////////////////
390 // Generate static initializer
391 sinit
->Sclass
= scclass
;
399 //////////////////////////////////////////////
401 // Put out the ClassInfo
402 csym
->Sclass
= scclass
;
409 byte[] initializer; // static initialization data
410 char[] name; // class name
412 Interface[] interfaces;
413 ClassInfo *base; // base class
415 void *invariant; // class invariant
418 OffsetTypeInfo[] offTi;
419 void *defaultConstructor;
420 const(MemberInfo[]) function(string) xgetMembers; // module getMembers() function
424 offset
= CLASSINFO_SIZE
; // must be ClassInfo.size
427 if (classinfo
->structsize
!= CLASSINFO_SIZE
)
428 error("D compiler and phobos/object.d are mismatched");
432 dtxoff(&dt
, classinfo
->toVtblSymbol(), 0, TYnptr
); // vtbl for ClassInfo
434 dtdword(&dt
, 0); // BUG: should be an assert()
435 dtdword(&dt
, 0); // monitor
438 assert(structsize
>= 8);
439 dtdword(&dt
, structsize
); // size
440 dtxoff(&dt
, sinit
, 0, TYnptr
); // initializer
443 char *name
= ident
->toChars();
444 size_t namelen
= strlen(name
);
445 if (!(namelen
> 9 && memcmp(name
, "TypeInfo_", 9) == 0))
446 { name
= toPrettyChars();
447 namelen
= strlen(name
);
449 dtdword(&dt
, namelen
);
450 dtabytes(&dt
, TYnptr
, 0, namelen
+ 1, name
);
453 dtdword(&dt
, vtbl
.dim
);
454 dtxoff(&dt
, vtblsym
, 0, TYnptr
);
457 dtdword(&dt
, vtblInterfaces
->dim
);
458 if (vtblInterfaces
->dim
)
459 dtxoff(&dt
, csym
, offset
, TYnptr
); // (*)
465 dtxoff(&dt
, baseClass
->toSymbol(), 0, TYnptr
);
471 dtxoff(&dt
, dtor
->toSymbol(), 0, TYnptr
);
477 dtxoff(&dt
, inv
->toSymbol(), 0, TYnptr
);
482 int flags
= 16 | 4 | isCOMclass();
485 for (ClassDeclaration
*cd
= this; cd
; cd
= cd
->baseClass
)
489 for (size_t i
= 0; i
< cd
->members
->dim
; i
++)
491 Dsymbol
*sm
= (Dsymbol
*)cd
->members
->data
[i
];
492 //printf("sm = %s %s\n", sm->kind(), sm->toChars());
493 if (sm
->hasPointers())
498 flags
|= 2; // no pointers
500 dti32(&dt
, flags
, true);
505 dtxoff(&dt
, aggDelete
->toSymbol(), 0, TYnptr
);
511 dtdword(&dt
, 0); // null for now, fix later
513 // defaultConstructor
515 dtxoff(&dt
, defaultCtor
->toSymbol(), 0, TYnptr
);
519 FuncDeclaration
*sgetmembers
= findGetMembers();
521 dtxoff(&dt
, sgetmembers
->toSymbol(), 0, TYnptr
);
523 dtdword(&dt
, 0); // module getMembers() function
525 //////////////////////////////////////////////
527 // Put out vtblInterfaces->data[]. Must immediately follow csym, because
530 offset
+= vtblInterfaces
->dim
* (4 * PTRSIZE
);
531 for (i
= 0; i
< vtblInterfaces
->dim
; i
++)
532 { BaseClass
*b
= (BaseClass
*)vtblInterfaces
->data
[i
];
533 ClassDeclaration
*id
= b
->base
;
537 * ClassInfo *interface;
544 b
->fillVtbl(this, &b
->vtbl
, 1);
546 dtxoff(&dt
, id
->toSymbol(), 0, TYnptr
); // ClassInfo
549 dtdword(&dt
, id
->vtbl
.dim
);
550 dtxoff(&dt
, csym
, offset
, TYnptr
);
552 dtdword(&dt
, b
->offset
); // this offset
554 offset
+= id
->vtbl
.dim
* PTRSIZE
;
557 // Put out the vtblInterfaces->data[].vtbl[]
558 // This must be mirrored with ClassDeclaration::baseVtblOffset()
559 //printf("putting out %d interface vtbl[]s for '%s'\n", vtblInterfaces->dim, toChars());
560 for (i
= 0; i
< vtblInterfaces
->dim
; i
++)
561 { BaseClass
*b
= (BaseClass
*)vtblInterfaces
->data
[i
];
562 ClassDeclaration
*id
= b
->base
;
565 //printf(" interface[%d] is '%s'\n", i, id->toChars());
567 if (id
->vtblOffset())
569 // First entry is ClassInfo reference
570 //dtxoff(&dt, id->toSymbol(), 0, TYnptr);
572 // First entry is struct Interface reference
573 dtxoff(&dt
, csym
, CLASSINFO_SIZE
+ i
* (4 * PTRSIZE
), TYnptr
);
576 assert(id
->vtbl
.dim
== b
->vtbl
.dim
);
577 for (; j
< id
->vtbl
.dim
; j
++)
581 assert(j
< b
->vtbl
.dim
);
583 Object
*o
= (Object
*)b
->vtbl
.data
[j
];
586 printf("o = %p\n", o
);
587 assert(o
->dyncast() == DYNCAST_DSYMBOL
);
588 Dsymbol
*s
= (Dsymbol
*)o
;
589 printf("s->kind() = '%s'\n", s
->kind());
592 fd
= (FuncDeclaration
*)b
->vtbl
.data
[j
];
594 dtxoff(&dt
, fd
->toThunkSymbol(b
->offset
), 0, TYnptr
);
601 // Put out the overriding interface vtbl[]s.
602 // This must be mirrored with ClassDeclaration::baseVtblOffset()
603 //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset);
604 ClassDeclaration
*cd
;
607 for (cd
= this->baseClass
; cd
; cd
= cd
->baseClass
)
609 for (int k
= 0; k
< cd
->vtblInterfaces
->dim
; k
++)
610 { BaseClass
*bs
= (BaseClass
*)cd
->vtblInterfaces
->data
[k
];
612 if (bs
->fillVtbl(this, &bvtbl
, 0))
614 //printf("\toverriding vtbl[] for %s\n", bs->base->toChars());
615 ClassDeclaration
*id
= bs
->base
;
619 if (id
->vtblOffset())
621 // First entry is ClassInfo reference
622 //dtxoff(&dt, id->toSymbol(), 0, TYnptr);
624 // First entry is struct Interface reference
625 dtxoff(&dt
, cd
->toSymbol(), CLASSINFO_SIZE
+ k
* (4 * PTRSIZE
), TYnptr
);
629 for (; j
< id
->vtbl
.dim
; j
++)
633 assert(j
< bvtbl
.dim
);
634 fd
= (FuncDeclaration
*)bvtbl
.data
[j
];
636 dtxoff(&dt
, fd
->toThunkSymbol(bs
->offset
), 0, TYnptr
);
644 #if INTERFACE_VIRTUAL
645 // Put out the overriding interface vtbl[]s.
646 // This must be mirrored with ClassDeclaration::baseVtblOffset()
647 //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset);
648 for (i
= 0; i
< vtblInterfaces
->dim
; i
++)
649 { BaseClass
*b
= (BaseClass
*)vtblInterfaces
->data
[i
];
650 ClassDeclaration
*cd
;
652 for (cd
= this->baseClass
; cd
; cd
= cd
->baseClass
)
654 for (int k
= 0; k
< cd
->vtblInterfaces
->dim
; k
++)
655 { BaseClass
*bs
= (BaseClass
*)cd
->vtblInterfaces
->data
[k
];
657 if (b
->base
== bs
->base
)
659 //printf("\toverriding vtbl[] for %s\n", b->base->toChars());
660 ClassDeclaration
*id
= b
->base
;
664 if (id
->vtblOffset())
666 // First entry is ClassInfo reference
667 //dtxoff(&dt, id->toSymbol(), 0, TYnptr);
669 // First entry is struct Interface reference
670 dtxoff(&dt
, cd
->toSymbol(), CLASSINFO_SIZE
+ k
* (4 * PTRSIZE
), TYnptr
);
674 for (; j
< id
->vtbl
.dim
; j
++)
678 assert(j
< b
->vtbl
.dim
);
679 fd
= (FuncDeclaration
*)b
->vtbl
.data
[j
];
681 dtxoff(&dt
, fd
->toThunkSymbol(bs
->offset
), 0, TYnptr
);
694 // ClassInfo cannot be const data, because we use the monitor on it
701 //////////////////////////////////////////////
703 // Put out the vtbl[]
704 //printf("putting out %s.vtbl[]\n", toChars());
709 { dtxoff(&dt
, csym
, 0, TYnptr
); // first entry is ClassInfo reference
712 for (; i
< vtbl
.dim
; i
++)
714 FuncDeclaration
*fd
= ((Dsymbol
*)vtbl
.data
[i
])->isFuncDeclaration();
716 //printf("\tvtbl[%d] = %p\n", i, fd);
717 if (fd
&& (fd
->fbody
|| !isAbstract()))
719 if (isFuncHidden(fd
))
721 if (global
.params
.warnings
)
722 { fprintf(stdmsg
, "warning - ");
723 error("%s %s is hidden in %s\n", fd
->toParent()->toChars(), fd
->toChars(), toChars());
725 dtxoff(&dt
, rtlsym
[RTLSYM_DHIDDENFUNC
], 0, TYnptr
);
728 dtxoff(&dt
, fd
->toSymbol(), 0, TYnptr
);
734 vtblsym
->Sclass
= scclass
;
735 vtblsym
->Sfl
= FLdata
;
737 vtblsym
->Sseg
= CDATA
;
741 obj_export(vtblsym
,0);
744 /******************************************
745 * Get offset of base class's vtbl[] initializer from start of csym.
746 * Returns ~0 if not this csym.
749 unsigned ClassDeclaration::baseVtblOffset(BaseClass
*bc
)
754 //printf("ClassDeclaration::baseVtblOffset('%s', bc = %p)\n", toChars(), bc);
755 csymoffset
= CLASSINFO_SIZE
;
756 csymoffset
+= vtblInterfaces
->dim
* (4 * PTRSIZE
);
758 for (i
= 0; i
< vtblInterfaces
->dim
; i
++)
760 BaseClass
*b
= (BaseClass
*)vtblInterfaces
->data
[i
];
764 csymoffset
+= b
->base
->vtbl
.dim
* PTRSIZE
;
768 // Put out the overriding interface vtbl[]s.
769 // This must be mirrored with ClassDeclaration::baseVtblOffset()
770 //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset);
771 ClassDeclaration
*cd
;
774 for (cd
= this->baseClass
; cd
; cd
= cd
->baseClass
)
776 for (int k
= 0; k
< cd
->vtblInterfaces
->dim
; k
++)
777 { BaseClass
*bs
= (BaseClass
*)cd
->vtblInterfaces
->data
[k
];
779 if (bs
->fillVtbl(this, NULL
, 0))
782 { //printf("\tcsymoffset = x%x\n", csymoffset);
785 csymoffset
+= bs
->base
->vtbl
.dim
* PTRSIZE
;
790 #if INTERFACE_VIRTUAL
791 for (i
= 0; i
< vtblInterfaces
->dim
; i
++)
792 { BaseClass
*b
= (BaseClass
*)vtblInterfaces
->data
[i
];
793 ClassDeclaration
*cd
;
795 for (cd
= this->baseClass
; cd
; cd
= cd
->baseClass
)
797 //printf("\tbase class %s\n", cd->toChars());
798 for (int k
= 0; k
< cd
->vtblInterfaces
->dim
; k
++)
799 { BaseClass
*bs
= (BaseClass
*)cd
->vtblInterfaces
->data
[k
];
802 { //printf("\tcsymoffset = x%x\n", csymoffset);
805 if (b
->base
== bs
->base
)
806 csymoffset
+= bs
->base
->vtbl
.dim
* PTRSIZE
;
815 /* ================================================================== */
817 void InterfaceDeclaration::toObjFile(int multiobj
)
823 //printf("InterfaceDeclaration::toObjFile('%s')\n", toChars());
828 if (global
.params
.symdebug
)
831 if (parent
&& parent
->isTemplateInstance())
836 // Put out the members
837 for (i
= 0; i
< members
->dim
; i
++)
841 member
= (Dsymbol
*)members
->data
[i
];
842 if (!member
->isFuncDeclaration())
843 member
->toObjFile(0);
846 // Generate C symbols
849 //////////////////////////////////////////////
851 // Put out the ClassInfo
852 csym
->Sclass
= scclass
;
859 byte[] initializer; // static initialization data
860 char[] name; // class name
862 Interface[] interfaces;
863 Object *base; // base class
865 void *invariant; // class invariant
868 OffsetTypeInfo[] offTi;
869 void *defaultConstructor;
870 const(MemberInfo[]) function(string) xgetMembers; // module getMembers() function
876 dtxoff(&dt
, classinfo
->toVtblSymbol(), 0, TYnptr
); // vtbl for ClassInfo
878 dtdword(&dt
, 0); // BUG: should be an assert()
879 dtdword(&dt
, 0); // monitor
882 dtdword(&dt
, 0); // size
883 dtdword(&dt
, 0); // initializer
886 char *name
= toPrettyChars();
887 size_t namelen
= strlen(name
);
888 dtdword(&dt
, namelen
);
889 dtabytes(&dt
, TYnptr
, 0, namelen
+ 1, name
);
895 // vtblInterfaces->data[]
896 dtdword(&dt
, vtblInterfaces
->dim
);
897 if (vtblInterfaces
->dim
)
900 assert(classinfo
->structsize
== CLASSINFO_SIZE
);
901 offset
= CLASSINFO_SIZE
;
902 dtxoff(&dt
, csym
, offset
, TYnptr
); // (*)
918 dti32(&dt
, 4 | isCOMinterface(), true);
925 dtdword(&dt
, 0); // null for now, fix later
927 // defaultConstructor
933 //////////////////////////////////////////////
935 // Put out vtblInterfaces->data[]. Must immediately follow csym, because
938 offset
+= vtblInterfaces
->dim
* (4 * PTRSIZE
);
939 for (i
= 0; i
< vtblInterfaces
->dim
; i
++)
940 { BaseClass
*b
= (BaseClass
*)vtblInterfaces
->data
[i
];
941 ClassDeclaration
*id
= b
->base
;
944 dtxoff(&dt
, id
->toSymbol(), 0, TYnptr
);
951 dtdword(&dt
, b
->offset
);
963 /* ================================================================== */
965 void StructDeclaration::toObjFile(int multiobj
)
968 //printf("StructDeclaration::toObjFile('%s')\n", toChars());
970 // Anonymous structs/unions only exist as part of others,
971 // do not output forward referenced structs's
972 if (!isAnonymous() && members
)
974 if (global
.params
.symdebug
)
977 type
->getTypeInfo(NULL
); // generate TypeInfo
981 // Generate static initializer
984 sinit
->Sclass
= SCcomdat
;
986 if (parent
&& parent
->isTemplateInstance())
987 sinit
->Sclass
= SCcomdat
;
989 sinit
->Sclass
= SCglobal
;
995 /* For OMF, common blocks aren't pulled in from the library.
997 /* ELF comdef's generate multiple
998 * definition errors for them from the gnu linker.
999 * Need to figure out how to generate proper comdef's for ELF.
1001 // See if we can convert a comdat to a comdef,
1002 // which saves on exe file space.
1003 if (sinit
->Sclass
== SCcomdat
&&
1005 sinit
->Sdt
->dt
== DT_azeros
&&
1006 sinit
->Sdt
->DTnext
== NULL
)
1008 sinit
->Sclass
= SCglobal
;
1009 sinit
->Sdt
->dt
= DT_common
;
1013 #if ELFOBJ // Burton
1014 sinit
->Sseg
= CDATA
;
1019 // Put out the members
1020 for (i
= 0; i
< members
->dim
; i
++)
1024 member
= (Dsymbol
*)members
->data
[i
];
1025 member
->toObjFile(0);
1030 /* ================================================================== */
1032 void VarDeclaration::toObjFile(int multiobj
)
1038 //printf("VarDeclaration::toObjFile(%p '%s' type=%s) protection %d\n", this, toChars(), type->toChars(), protection);
1039 //printf("\talign = %d\n", type->alignsize());
1042 { toAlias()->toObjFile(0);
1046 // Do not store variables we cannot take the address of
1047 if (!canTakeAddressOf())
1052 if (isDataseg() && !(storage_class
& STCextern
))
1057 parent
= this->toParent();
1058 #if 0 /* private statics should still get a global symbol, in case
1059 * another module inlines a function that references it.
1061 if (/*protection == PROTprivate ||*/
1062 !parent
|| parent
->ident
== NULL
|| parent
->isFuncDeclaration())
1064 s
->Sclass
= SCstatic
;
1069 if (storage_class
& STCcomdat
)
1070 s
->Sclass
= SCcomdat
;
1072 s
->Sclass
= SCglobal
;
1076 /* Global template data members need to be in comdat's
1077 * in case multiple .obj files instantiate the same
1078 * template with the same types.
1080 if (parent
->isTemplateInstance() && !parent
->isTemplateMixin())
1083 /* These symbol constants have already been copied,
1084 * so no reason to output them.
1085 * Note that currently there is no way to take
1086 * the address of such a const.
1088 if (isConst() && type
->toBasetype()->ty
!= Tsarray
&&
1089 init
&& init
->isExpInitializer())
1092 s
->Sclass
= SCcomdat
;
1095 parent
= parent
->parent
;
1101 { s
->Sdt
= init
->toDt();
1103 // Look for static array that is block initialized
1105 ExpInitializer
*ie
= init
->isExpInitializer();
1107 tb
= type
->toBasetype();
1108 if (tb
->ty
== Tsarray
&& ie
&&
1109 !tb
->nextOf()->equals(ie
->exp
->type
->toBasetype()->nextOf()) &&
1110 ie
->exp
->implicitConvTo(tb
->nextOf())
1115 dim
= ((TypeSArray
*)tb
)->dim
->toInteger();
1117 // Duplicate Sdt 'dim-1' times, as we already have the first one
1120 ie
->exp
->toDt(&s
->Sdt
);
1124 else if (storage_class
& STCextern
)
1126 s
->Sclass
= SCextern
;
1129 // BUG: if isExport(), shouldn't we make it dllimport?
1134 type
->toDt(&s
->Sdt
);
1136 dt_optimize(s
->Sdt
);
1138 // See if we can convert a comdat to a comdef,
1139 // which saves on exe file space.
1140 if (s
->Sclass
== SCcomdat
&&
1142 s
->Sdt
->dt
== DT_azeros
&&
1143 s
->Sdt
->DTnext
== NULL
)
1145 s
->Sclass
= SCglobal
;
1146 s
->Sdt
->dt
= DT_common
;
1149 #if ELFOBJ // Burton
1150 if (s
->Sdt
&& s
->Sdt
->dt
== DT_azeros
&& s
->Sdt
->DTnext
== NULL
)
1163 // This is needed for VarDeclarations in mixins that are to be
1164 // local variables of a function. Otherwise, it would be
1165 // enough to make a check for isVarDeclaration() in
1166 // DeclarationExp::toElem.
1167 d_gcc_emit_local_variable(this);
1172 /* ================================================================== */
1174 void TypedefDeclaration::toObjFile(int multiobj
)
1176 //printf("TypedefDeclaration::toObjFile('%s')\n", toChars());
1178 if (global
.params
.symdebug
)
1181 type
->getTypeInfo(NULL
); // generate TypeInfo
1183 TypeTypedef
*tc
= (TypeTypedef
*)type
;
1184 if (type
->isZeroInit() || !tc
->sym
->init
)
1188 enum_SC scclass
= SCglobal
;
1189 for (Dsymbol
*parent
= this->parent
; parent
; parent
= parent
->parent
)
1191 if (parent
->isTemplateInstance())
1198 // Generate static initializer
1200 sinit
->Sclass
= scclass
;
1201 sinit
->Sfl
= FLdata
;
1202 #if ELFOBJ // Burton
1203 sinit
->Sseg
= CDATA
;
1206 sinit
->Sdt
= tc
->sym
->init
->toDt();
1211 /* ================================================================== */
1213 void EnumDeclaration::toObjFile(int multiobj
)
1215 //printf("EnumDeclaration::toObjFile('%s')\n", toChars());
1220 if (global
.params
.symdebug
)
1223 type
->getTypeInfo(NULL
); // generate TypeInfo
1225 TypeEnum
*tc
= (TypeEnum
*)type
;
1226 if (!tc
->sym
->defaultval
|| type
->isZeroInit())
1230 enum_SC scclass
= SCglobal
;
1231 for (Dsymbol
*parent
= this->parent
; parent
; parent
= parent
->parent
)
1233 if (parent
->isTemplateInstance())
1240 // Generate static initializer
1242 sinit
->Sclass
= scclass
;
1243 sinit
->Sfl
= FLdata
;
1244 #if ELFOBJ // Burton
1245 sinit
->Sseg
= CDATA
;
1247 tc
->sym
->defaultval
->toDt(&sinit
->Sdt
);
1248 //sinit->Sdt = tc->sym->init->toDt();