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 dtdword(&dt
, 0); // xgetMembers
208 dtxoff(&dt
, sictor
, 0, TYnptr
);
212 //////////////////////////////////////////////
216 if (! d_gcc_supports_weak())
217 for (i
= 0; i
< adeps
.dim
; i
++)
222 m
= (Module
*) adeps
.data
[i
];
224 s
->Sflags
|= SFLweak
; // doesn't do anything yet, but see d-decls.cc:Module::toSymbol
225 dtxoff(&dt
, s
, 0, TYnptr
);
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
);
248 // Cannot be CONST because the startup code sets flag bits in it
253 //////////////////////////////////////////////
255 obj_moduleinfo(msym
);
258 /* ================================================================== */
260 void Dsymbol::toObjFile(int multiobj
)
262 //printf("Dsymbol::toObjFile('%s')\n", toChars());
265 TupleDeclaration
* td
= this->isTupleDeclaration();
268 for (unsigned i
= 0; i
< td
->objects
->dim
; i
++)
270 Object
* o
= (Object
*) td
->objects
->data
[i
];
274 if ((o
->dyncast() == DYNCAST_EXPRESSION
) &&
275 ((Expression
*) o
)->op
== TOKdsymbol
)
277 ds
= ((DsymbolExp
*) o
)->s
;
278 d
= ds
->isDeclaration();
280 d
->toObjFile(multiobj
);
287 /* ================================================================== */
289 void ClassDeclaration::toObjFile(int multiobj
)
295 //printf("ClassDeclaration::toObjFile('%s')\n", toChars());
300 if (global
.params
.symdebug
)
303 assert(!scope
); // semantic() should have been run to completion
305 if (parent
&& parent
->isTemplateInstance())
310 // Put out the members
311 for (i
= 0; i
< members
->dim
; i
++)
315 member
= (Dsymbol
*)members
->data
[i
];
316 member
->toObjFile(0);
320 // Build destructor by aggregating dtors[]
324 // No destructors for this class
329 // One destructor, just use it directly
330 sdtor
= ((DtorDeclaration
*)dtors
.data
[0])->toSymbol();
334 { /* Build a destructor that calls all the
335 * other destructors in dtors[].
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
;
348 // Call each of the destructors in dtors[]
350 for (i
= 0; i
< dtors
.dim
; i
++)
351 { DtorDeclaration
*d
= (DtorDeclaration
*)dtors
.data
[i
];
352 Symbol
*s
= d
->toSymbol();
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
;
366 // Create the function, sdtor, and write it out
368 sdtor
= toSymbolX("__dtor", SCglobal
, t
, "FZv");
369 block
*b
= block_calloc();
372 sdtor
->Sfunc
->Fstartblock
= b
;
373 cstate
.CSpsymtab
= &sdtor
->Sfunc
->Flocsym
;
380 // Generate C symbols
383 sinit
= toInitializer();
385 //////////////////////////////////////////////
387 // Generate static initializer
388 sinit
->Sclass
= scclass
;
396 //////////////////////////////////////////////
398 // Put out the ClassInfo
399 csym
->Sclass
= scclass
;
406 byte[] initializer; // static initialization data
407 char[] name; // class name
409 Interface[] interfaces;
410 ClassInfo *base; // base class
412 void *invariant; // class invariant
415 OffsetTypeInfo[] offTi;
416 void *defaultConstructor;
420 offset
= CLASSINFO_SIZE
; // must be ClassInfo.size
423 if (classinfo
->structsize
!= CLASSINFO_SIZE
)
424 error("D compiler and phobos/object.d are mismatched");
428 dtxoff(&dt
, classinfo
->toVtblSymbol(), 0, TYnptr
); // vtbl for ClassInfo
430 dtdword(&dt
, 0); // BUG: should be an assert()
431 dtdword(&dt
, 0); // monitor
434 assert(structsize
>= 8);
435 dtdword(&dt
, structsize
); // size
436 dtxoff(&dt
, sinit
, 0, TYnptr
); // initializer
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
);
449 dtdword(&dt
, vtbl
.dim
);
450 dtxoff(&dt
, vtblsym
, 0, TYnptr
);
453 dtdword(&dt
, vtblInterfaces
->dim
);
454 if (vtblInterfaces
->dim
)
455 dtxoff(&dt
, csym
, offset
, TYnptr
); // (*)
461 dtxoff(&dt
, baseClass
->toSymbol(), 0, TYnptr
);
467 dtxoff(&dt
, dtor
->toSymbol(), 0, TYnptr
);
473 dtxoff(&dt
, inv
->toSymbol(), 0, TYnptr
);
478 int flags
= 4 | isCOMclass();
481 for (ClassDeclaration
*cd
= this; cd
; cd
= cd
->baseClass
)
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())
494 flags
|= 2; // no pointers
496 dti32(&dt
, flags
, true);
501 dtxoff(&dt
, aggDelete
->toSymbol(), 0, TYnptr
);
507 dtdword(&dt
, 0); // null for now, fix later
509 // defaultConstructor
511 dtxoff(&dt
, defaultCtor
->toSymbol(), 0, TYnptr
);
515 //////////////////////////////////////////////
517 // Put out vtblInterfaces->data[]. Must immediately follow csym, because
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
;
527 * ClassInfo *interface;
534 b
->fillVtbl(this, &b
->vtbl
, 1);
536 dtxoff(&dt
, id
->toSymbol(), 0, TYnptr
); // ClassInfo
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
;
555 //printf(" interface[%d] is '%s'\n", i, id->toChars());
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
);
566 assert(id
->vtbl
.dim
== b
->vtbl
.dim
);
567 for (; j
< id
->vtbl
.dim
; j
++)
571 assert(j
< b
->vtbl
.dim
);
573 Object
*o
= (Object
*)b
->vtbl
.data
[j
];
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());
582 fd
= (FuncDeclaration
*)b
->vtbl
.data
[j
];
584 dtxoff(&dt
, fd
->toThunkSymbol(b
->offset
), 0, TYnptr
);
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
;
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
;
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
);
619 for (; j
< id
->vtbl
.dim
; j
++)
623 assert(j
< bvtbl
.dim
);
624 fd
= (FuncDeclaration
*)bvtbl
.data
[j
];
626 dtxoff(&dt
, fd
->toThunkSymbol(bs
->offset
), 0, TYnptr
);
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
;
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
);
664 for (; j
< id
->vtbl
.dim
; j
++)
668 assert(j
< b
->vtbl
.dim
);
669 fd
= (FuncDeclaration
*)b
->vtbl
.data
[j
];
671 dtxoff(&dt
, fd
->toThunkSymbol(bs
->offset
), 0, TYnptr
);
684 // ClassInfo cannot be const data, because we use the monitor on it
691 //////////////////////////////////////////////
693 // Put out the vtbl[]
694 //printf("putting out %s.vtbl[]\n", toChars());
699 { dtxoff(&dt
, csym
, 0, TYnptr
); // first entry is ClassInfo reference
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
);
715 vtblsym
->Sclass
= scclass
;
716 vtblsym
->Sfl
= FLdata
;
718 vtblsym
->Sseg
= CDATA
;
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
)
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
];
745 csymoffset
+= b
->base
->vtbl
.dim
* PTRSIZE
;
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
;
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))
763 { //printf("\tcsymoffset = x%x\n", csymoffset);
766 csymoffset
+= bs
->base
->vtbl
.dim
* PTRSIZE
;
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
];
783 { //printf("\tcsymoffset = x%x\n", csymoffset);
786 if (b
->base
== bs
->base
)
787 csymoffset
+= bs
->base
->vtbl
.dim
* PTRSIZE
;
796 /* ================================================================== */
798 void InterfaceDeclaration::toObjFile(int multiobj
)
804 //printf("InterfaceDeclaration::toObjFile('%s')\n", toChars());
809 if (global
.params
.symdebug
)
812 if (parent
&& parent
->isTemplateInstance())
817 // Put out the members
818 for (i
= 0; i
< members
->dim
; i
++)
822 member
= (Dsymbol
*)members
->data
[i
];
823 if (!member
->isFuncDeclaration())
824 member
->toObjFile(0);
827 // Generate C symbols
830 //////////////////////////////////////////////
832 // Put out the ClassInfo
833 csym
->Sclass
= scclass
;
840 byte[] initializer; // static initialization data
841 char[] name; // class name
843 Interface[] interfaces;
844 Object *base; // base class
846 void *invariant; // class invariant
849 OffsetTypeInfo[] offTi;
850 void *defaultConstructor;
856 dtxoff(&dt
, classinfo
->toVtblSymbol(), 0, TYnptr
); // vtbl for ClassInfo
858 dtdword(&dt
, 0); // BUG: should be an assert()
859 dtdword(&dt
, 0); // monitor
862 dtdword(&dt
, 0); // size
863 dtdword(&dt
, 0); // initializer
866 char *name
= toPrettyChars();
867 size_t namelen
= strlen(name
);
868 dtdword(&dt
, namelen
);
869 dtabytes(&dt
, TYnptr
, 0, namelen
+ 1, name
);
875 // vtblInterfaces->data[]
876 dtdword(&dt
, vtblInterfaces
->dim
);
877 if (vtblInterfaces
->dim
)
880 assert(classinfo
->structsize
== CLASSINFO_SIZE
);
881 offset
= CLASSINFO_SIZE
;
882 dtxoff(&dt
, csym
, offset
, TYnptr
); // (*)
898 dti32(&dt
, 4 | isCOMinterface(), true);
905 dtdword(&dt
, 0); // null for now, fix later
907 // defaultConstructor
910 //////////////////////////////////////////////
912 // Put out vtblInterfaces->data[]. Must immediately follow csym, because
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
;
921 dtxoff(&dt
, id
->toSymbol(), 0, TYnptr
);
928 dtdword(&dt
, b
->offset
);
940 /* ================================================================== */
942 void StructDeclaration::toObjFile(int multiobj
)
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
)
954 type
->getTypeInfo(NULL
); // generate TypeInfo
958 // Generate static initializer
961 sinit
->Sclass
= SCcomdat
;
963 if (parent
&& parent
->isTemplateInstance())
964 sinit
->Sclass
= SCcomdat
;
966 sinit
->Sclass
= SCglobal
;
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
&&
982 sinit
->Sdt
->dt
== DT_azeros
&&
983 sinit
->Sdt
->DTnext
== NULL
)
985 sinit
->Sclass
= SCglobal
;
986 sinit
->Sdt
->dt
= DT_common
;
996 // Put out the members
997 for (i
= 0; i
< members
->dim
; i
++)
1001 member
= (Dsymbol
*)members
->data
[i
];
1002 member
->toObjFile(0);
1007 /* ================================================================== */
1009 void VarDeclaration::toObjFile(int multiobj
)
1015 //printf("VarDeclaration::toObjFile(%p '%s' type=%s) protection %d\n", this, toChars(), type->toChars(), protection);
1016 //printf("\talign = %d\n", type->alignsize());
1019 { toAlias()->toObjFile(0);
1023 if (isDataseg() && !(storage_class
& STCextern
))
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
;
1040 if (storage_class
& STCcomdat
)
1041 s
->Sclass
= SCcomdat
;
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())
1062 s
->Sclass
= SCcomdat
;
1065 parent
= parent
->parent
;
1071 { s
->Sdt
= init
->toDt();
1073 // Look for static array that is block initialized
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())
1085 dim
= ((TypeSArray
*)tb
)->dim
->toInteger();
1087 // Duplicate Sdt 'dim-1' times, as we already have the first one
1090 ie
->exp
->toDt(&s
->Sdt
);
1094 else if (storage_class
& STCextern
)
1096 s
->Sclass
= SCextern
;
1099 // BUG: if isExport(), shouldn't we make it dllimport?
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
&&
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
)
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);
1142 /* ================================================================== */
1144 void TypedefDeclaration::toObjFile(int multiobj
)
1146 //printf("TypedefDeclaration::toObjFile('%s')\n", toChars());
1148 if (global
.params
.symdebug
)
1151 type
->getTypeInfo(NULL
); // generate TypeInfo
1153 TypeTypedef
*tc
= (TypeTypedef
*)type
;
1154 if (type
->isZeroInit() || !tc
->sym
->init
)
1158 enum_SC scclass
= SCglobal
;
1159 for (Dsymbol
*parent
= this->parent
; parent
; parent
= parent
->parent
)
1161 if (parent
->isTemplateInstance())
1168 // Generate static initializer
1170 sinit
->Sclass
= scclass
;
1171 sinit
->Sfl
= FLdata
;
1172 #if ELFOBJ // Burton
1173 sinit
->Sseg
= CDATA
;
1176 sinit
->Sdt
= tc
->sym
->init
->toDt();
1181 /* ================================================================== */
1183 void EnumDeclaration::toObjFile(int multiobj
)
1185 //printf("EnumDeclaration::toObjFile('%s')\n", toChars());
1187 if (global
.params
.symdebug
)
1190 type
->getTypeInfo(NULL
); // generate TypeInfo
1192 TypeEnum
*tc
= (TypeEnum
*)type
;
1193 if (type
->isZeroInit() || !tc
->sym
->defaultval
)
1197 enum_SC scclass
= SCglobal
;
1198 for (Dsymbol
*parent
= this->parent
; parent
; parent
= parent
->parent
)
1200 if (parent
->isTemplateInstance())
1207 // Generate static initializer
1209 sinit
->Sclass
= scclass
;
1210 sinit
->Sfl
= FLdata
;
1211 #if ELFOBJ // Burton
1212 sinit
->Sseg
= CDATA
;
1215 dtnbytes(&sinit
->Sdt
, tc
->size(0), (char *)&tc
->sym
->defaultval
);
1217 Expression
* e
= new IntegerExp(0, tc
->sym
->defaultval
, tc
);
1218 e
->toDt(& sinit
->Sdt
);
1220 //sinit->Sdt = tc->sym->init->toDt();