Merged Delight changes to D1 into D2
[delight/core.git] / dmd2 / typinf.c
blob726a7b56e70ac7adc644ccb4e4291edffd31a188
2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2007 by Digital Mars
4 // All Rights Reserved
5 // written by Walter Bright
6 // http://www.digitalmars.com
7 // License for redistribution is by either the Artistic License
8 // in artistic.txt, or the GNU General Public License in gnu.txt.
9 // See the included readme.txt for details.
11 /* NOTE: This file has been patched from the original DMD distribution to
12 work with the GDC compiler.
14 Modified by David Friedman, September 2004
17 #include <stdio.h>
18 #include <assert.h>
20 //#include "mem.h"
22 #include "mars.h"
23 #include "module.h"
24 #include "mtype.h"
25 #include "scope.h"
26 #include "init.h"
27 #include "expression.h"
28 #include "attrib.h"
29 #include "declaration.h"
30 #include "template.h"
31 #include "id.h"
32 #include "enum.h"
33 #include "import.h"
34 #include "aggregate.h"
36 #include <mem.h>
37 #ifndef IN_GCC
38 #include "cc.h"
39 #include "global.h"
40 #include "oper.h"
41 #include "code.h"
42 #include "type.h"
43 #include "dt.h"
44 #include "cgcv.h"
45 #include "outbuf.h"
46 #include "irstate.h"
47 #else
48 #include "symbol.h"
49 #include "dt.h"
50 #include "d-dmd-gcc.h"
51 #endif
53 extern Symbol *static_sym();
55 /*******************************************
56 * Get a canonicalized form of the TypeInfo for use with the internal
57 * runtime library routines. Canonicalized in that static arrays are
58 * represented as dynamic arrays, enums are represented by their
59 * underlying type, etc. This reduces the number of TypeInfo's needed,
60 * so we can use the custom internal ones more.
63 Expression *Type::getInternalTypeInfo(Scope *sc)
64 { TypeInfoDeclaration *tid;
65 Expression *e;
66 Type *t;
67 static TypeInfoDeclaration *internalTI[TMAX];
69 //printf("Type::getInternalTypeInfo() %s\n", toChars());
70 t = toBasetype();
71 switch (t->ty)
73 case Tsarray:
74 #if 0
75 // convert to corresponding dynamic array type
76 t = t->nextOf()->mutableOf()->arrayOf();
77 #endif
78 break;
80 case Tclass:
81 if (((TypeClass *)t)->sym->isInterfaceDeclaration())
82 break;
83 goto Linternal;
85 case Tarray:
86 // convert to corresponding dynamic array type
87 t = t->nextOf()->mutableOf()->arrayOf();
88 if (t->nextOf()->ty != Tclass)
89 break;
90 goto Linternal;
92 case Tfunction:
93 case Tdelegate:
94 case Tpointer:
95 Linternal:
96 tid = internalTI[t->ty];
97 if (!tid)
98 { tid = new TypeInfoDeclaration(t, 1);
99 internalTI[t->ty] = tid;
101 e = new VarExp(0, tid);
102 e = e->addressOf(sc);
103 e->type = tid->type; // do this so we don't get redundant dereference
104 return e;
106 default:
107 break;
109 //printf("\tcalling getTypeInfo() %s\n", t->toChars());
110 return t->getTypeInfo(sc);
114 /****************************************************
115 * Get the exact TypeInfo.
118 Expression *Type::getTypeInfo(Scope *sc)
120 Expression *e;
121 Type *t;
123 //printf("Type::getTypeInfo() %p, %s\n", this, toChars());
124 t = merge(); // do this since not all Type's are merge'd
125 if (!t->vtinfo)
127 if (t->isConst())
128 t->vtinfo = new TypeInfoConstDeclaration(t);
129 else if (t->isInvariant())
130 t->vtinfo = new TypeInfoInvariantDeclaration(t);
131 else
132 t->vtinfo = t->getTypeInfoDeclaration();
133 assert(t->vtinfo);
135 /* If this has a custom implementation in std/typeinfo, then
136 * do not generate a COMDAT for it.
138 if (!t->builtinTypeInfo())
139 { // Generate COMDAT
140 if (sc) // if in semantic() pass
141 { // Find module that will go all the way to an object file
142 Module *m = sc->module->importedFrom;
143 m->members->push(t->vtinfo);
145 else // if in obj generation pass
147 t->vtinfo->toObjFile(global.params.multiobj);
151 e = new VarExp(0, t->vtinfo);
152 e = e->addressOf(sc);
153 e->type = t->vtinfo->type; // do this so we don't get redundant dereference
154 return e;
157 TypeInfoDeclaration *Type::getTypeInfoDeclaration()
159 //printf("Type::getTypeInfoDeclaration() %s\n", toChars());
160 return new TypeInfoDeclaration(this, 0);
163 TypeInfoDeclaration *TypeTypedef::getTypeInfoDeclaration()
165 return new TypeInfoTypedefDeclaration(this);
168 TypeInfoDeclaration *TypePointer::getTypeInfoDeclaration()
170 return new TypeInfoPointerDeclaration(this);
173 TypeInfoDeclaration *TypeMaybe::getTypeInfoDeclaration()
175 return new TypeInfoMaybeDeclaration(this);
178 TypeInfoDeclaration *TypeDArray::getTypeInfoDeclaration()
180 return new TypeInfoArrayDeclaration(this);
183 TypeInfoDeclaration *TypeSArray::getTypeInfoDeclaration()
185 return new TypeInfoStaticArrayDeclaration(this);
188 TypeInfoDeclaration *TypeAArray::getTypeInfoDeclaration()
190 return new TypeInfoAssociativeArrayDeclaration(this);
193 TypeInfoDeclaration *TypeStruct::getTypeInfoDeclaration()
195 return new TypeInfoStructDeclaration(this);
198 TypeInfoDeclaration *TypeClass::getTypeInfoDeclaration()
200 if (sym->isInterfaceDeclaration())
201 return new TypeInfoInterfaceDeclaration(this);
202 else
203 return new TypeInfoClassDeclaration(this);
206 TypeInfoDeclaration *TypeEnum::getTypeInfoDeclaration()
208 return new TypeInfoEnumDeclaration(this);
211 TypeInfoDeclaration *TypeFunction::getTypeInfoDeclaration()
213 return new TypeInfoFunctionDeclaration(this);
216 TypeInfoDeclaration *TypeDelegate::getTypeInfoDeclaration()
218 return new TypeInfoDelegateDeclaration(this);
221 TypeInfoDeclaration *TypeTuple::getTypeInfoDeclaration()
223 return new TypeInfoTupleDeclaration(this);
227 /****************************************************
230 #if 1
232 void TypeInfoDeclaration::toDt(dt_t **pdt)
234 //printf("TypeInfoDeclaration::toDt() %s\n", toChars());
235 dtxoff(pdt, Type::typeinfo->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo
236 dtdword(pdt, 0); // monitor
239 void TypeInfoConstDeclaration::toDt(dt_t **pdt)
241 //printf("TypeInfoConstDeclaration::toDt() %s\n", toChars());
242 dtxoff(pdt, Type::typeinfoconst->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Const
243 dtdword(pdt, 0); // monitor
244 Type *tm = tinfo->mutableOf();
245 tm = tm->merge();
246 tm->getTypeInfo(NULL);
247 dtxoff(pdt, tm->vtinfo->toSymbol(), 0, TYnptr);
250 void TypeInfoInvariantDeclaration::toDt(dt_t **pdt)
252 //printf("TypeInfoInvariantDeclaration::toDt() %s\n", toChars());
253 dtxoff(pdt, Type::typeinfoinvariant->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Invariant
254 dtdword(pdt, 0); // monitor
255 Type *tm = tinfo->mutableOf();
256 tm = tm->merge();
257 tm->getTypeInfo(NULL);
258 dtxoff(pdt, tm->vtinfo->toSymbol(), 0, TYnptr);
261 void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
263 //printf("TypeInfoTypedefDeclaration::toDt() %s\n", toChars());
265 dtxoff(pdt, Type::typeinfotypedef->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Typedef
266 dtdword(pdt, 0); // monitor
268 assert(tinfo->ty == Ttypedef);
270 TypeTypedef *tc = (TypeTypedef *)tinfo;
271 TypedefDeclaration *sd = tc->sym;
272 //printf("basetype = %s\n", sd->basetype->toChars());
274 /* Put out:
275 * TypeInfo base;
276 * char[] name;
277 * void[] m_init;
280 sd->basetype = sd->basetype->merge();
281 sd->basetype->getTypeInfo(NULL); // generate vtinfo
282 assert(sd->basetype->vtinfo);
283 dtxoff(pdt, sd->basetype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for basetype
285 char *name = sd->toPrettyChars();
286 size_t namelen = strlen(name);
287 dtdword(pdt, namelen);
288 dtabytes(pdt, TYnptr, 0, namelen + 1, name);
290 // void[] init;
291 if (tinfo->isZeroInit() || !sd->init)
292 { // 0 initializer, or the same as the base type
293 dtdword(pdt, 0); // init.length
294 dtdword(pdt, 0); // init.ptr
296 else
298 dtdword(pdt, sd->type->size()); // init.length
299 dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
303 void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
305 //printf("TypeInfoEnumDeclaration::toDt()\n");
306 dtxoff(pdt, Type::typeinfoenum->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Enum
307 dtdword(pdt, 0); // monitor
309 assert(tinfo->ty == Tenum);
311 TypeEnum *tc = (TypeEnum *)tinfo;
312 EnumDeclaration *sd = tc->sym;
314 /* Put out:
315 * TypeInfo base;
316 * char[] name;
317 * void[] m_init;
320 if (sd->memtype)
321 { sd->memtype->getTypeInfo(NULL);
322 dtxoff(pdt, sd->memtype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for enum members
324 else
325 dtdword(pdt, 0);
327 char *name = sd->toPrettyChars();
328 size_t namelen = strlen(name);
329 dtdword(pdt, namelen);
330 dtabytes(pdt, TYnptr, 0, namelen + 1, name);
332 // void[] init;
333 if (!sd->defaultval || tinfo->isZeroInit())
334 { // 0 initializer, or the same as the base type
335 dtdword(pdt, 0); // init.length
336 dtdword(pdt, 0); // init.ptr
338 else
340 dtdword(pdt, sd->type->size()); // init.length
341 dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
345 void TypeInfoPointerDeclaration::toDt(dt_t **pdt)
347 //printf("TypeInfoPointerDeclaration::toDt()\n");
348 dtxoff(pdt, Type::typeinfopointer->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Pointer
349 dtdword(pdt, 0); // monitor
351 assert(tinfo->ty == Tpointer);
353 TypePointer *tc = (TypePointer *)tinfo;
355 tc->next->getTypeInfo(NULL);
356 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for type being pointed to
359 void TypeInfoMaybeDeclaration::toDt(dt_t **pdt)
361 //printf("TypeInfoMaybeDeclaration::toDt()\n");
362 dtxoff(pdt, Type::typeinfomaybe->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Maybe
363 dtdword(pdt, 0); // monitor
365 assert(tinfo->ty == Tmaybe);
367 TypeMaybe *tc = (TypeMaybe *)tinfo;
369 tc->next->getTypeInfo(NULL);
370 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for pointer type
373 void TypeInfoArrayDeclaration::toDt(dt_t **pdt)
375 //printf("TypeInfoArrayDeclaration::toDt()\n");
376 dtxoff(pdt, Type::typeinfoarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Array
377 dtdword(pdt, 0); // monitor
379 assert(tinfo->ty == Tarray);
381 TypeDArray *tc = (TypeDArray *)tinfo;
383 tc->next->getTypeInfo(NULL);
384 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
387 void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
389 //printf("TypeInfoStaticArrayDeclaration::toDt()\n");
390 dtxoff(pdt, Type::typeinfostaticarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_StaticArray
391 dtdword(pdt, 0); // monitor
393 assert(tinfo->ty == Tsarray);
395 TypeSArray *tc = (TypeSArray *)tinfo;
397 tc->next->getTypeInfo(NULL);
398 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
400 dtdword(pdt, tc->dim->toInteger()); // length
403 void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
405 //printf("TypeInfoAssociativeArrayDeclaration::toDt()\n");
406 dtxoff(pdt, Type::typeinfoassociativearray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_AssociativeArray
407 dtdword(pdt, 0); // monitor
409 assert(tinfo->ty == Taarray);
411 TypeAArray *tc = (TypeAArray *)tinfo;
413 tc->next->getTypeInfo(NULL);
414 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
416 tc->index->getTypeInfo(NULL);
417 dtxoff(pdt, tc->index->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
420 void TypeInfoFunctionDeclaration::toDt(dt_t **pdt)
422 //printf("TypeInfoFunctionDeclaration::toDt()\n");
423 dtxoff(pdt, Type::typeinfofunction->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Function
424 dtdword(pdt, 0); // monitor
426 assert(tinfo->ty == Tfunction);
428 TypeFunction *tc = (TypeFunction *)tinfo;
430 tc->next->getTypeInfo(NULL);
431 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for function return value
434 void TypeInfoDelegateDeclaration::toDt(dt_t **pdt)
436 //printf("TypeInfoDelegateDeclaration::toDt()\n");
437 dtxoff(pdt, Type::typeinfodelegate->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Delegate
438 dtdword(pdt, 0); // monitor
440 assert(tinfo->ty == Tdelegate);
442 TypeDelegate *tc = (TypeDelegate *)tinfo;
444 tc->next->nextOf()->getTypeInfo(NULL);
445 dtxoff(pdt, tc->next->nextOf()->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for delegate return value
448 void TypeInfoStructDeclaration::toDt(dt_t **pdt)
450 //printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars());
452 unsigned offset = Type::typeinfostruct->structsize;
454 dtxoff(pdt, Type::typeinfostruct->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Struct
455 dtdword(pdt, 0); // monitor
457 assert(tinfo->ty == Tstruct);
459 TypeStruct *tc = (TypeStruct *)tinfo;
460 StructDeclaration *sd = tc->sym;
462 /* Put out:
463 * char[] name;
464 * void[] init;
465 * hash_t function(in void*) xtoHash;
466 * int function(in void*, in void*) xopEquals;
467 * int function(in void*, in void*) xopCmp;
468 * string function(const(void)*) xtoString;
469 * uint m_flags;
470 * xgetMembers;
471 * xdtor;
472 * xpostblit;
474 * name[]
477 char *name = sd->toPrettyChars();
478 size_t namelen = strlen(name);
479 dtdword(pdt, namelen);
480 //dtabytes(pdt, TYnptr, 0, namelen + 1, name);
481 dtxoff(pdt, toSymbol(), offset, TYnptr);
482 offset += namelen + 1;
484 // void[] init;
485 dtdword(pdt, sd->structsize); // init.length
486 if (sd->zeroInit)
487 dtdword(pdt, 0); // NULL for 0 initialization
488 else
489 dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
491 FuncDeclaration *fd;
492 FuncDeclaration *fdx;
493 TypeFunction *tf;
494 Type *ta;
495 Dsymbol *s;
497 static TypeFunction *tftohash;
498 static TypeFunction *tftostring;
500 if (!tftohash)
502 Scope sc;
504 tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd);
505 tftohash->mod = MODconst;
506 tftohash = (TypeFunction *)tftohash->semantic(0, &sc);
508 tftostring = new TypeFunction(NULL, Type::tchar->invariantOf()->arrayOf(), 0, LINKd);
509 tftostring = (TypeFunction *)tftostring->semantic(0, &sc);
512 TypeFunction *tfeqptr;
514 Scope sc;
515 Arguments *arguments = new Arguments;
516 Argument *arg = new Argument(STCin, tc->pointerTo(), NULL, NULL);
518 arguments->push(arg);
519 tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
520 tfeqptr->mod = MODconst;
521 tfeqptr = (TypeFunction *)tfeqptr->semantic(0, &sc);
524 #if 0
525 TypeFunction *tfeq;
527 Scope sc;
528 Array *arguments = new Array;
529 Argument *arg = new Argument(In, tc, NULL, NULL);
531 arguments->push(arg);
532 tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd);
533 tfeq = (TypeFunction *)tfeq->semantic(0, &sc);
535 #endif
537 s = search_function(sd, Id::tohash);
538 fdx = s ? s->isFuncDeclaration() : NULL;
539 if (fdx)
540 { fd = fdx->overloadExactMatch(tftohash);
541 if (fd)
542 dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
543 else
544 //fdx->error("must be declared as extern (D) uint toHash()");
545 dtdword(pdt, 0);
547 else
548 dtdword(pdt, 0);
550 s = search_function(sd, Id::eq);
551 fdx = s ? s->isFuncDeclaration() : NULL;
552 for (int i = 0; i < 2; i++)
554 if (fdx)
555 { fd = fdx->overloadExactMatch(tfeqptr);
556 if (fd)
557 dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
558 else
559 //fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars());
560 dtdword(pdt, 0);
562 else
563 dtdword(pdt, 0);
565 s = search_function(sd, Id::cmp);
566 fdx = s ? s->isFuncDeclaration() : NULL;
569 s = search_function(sd, Id::tostring);
570 fdx = s ? s->isFuncDeclaration() : NULL;
571 if (fdx)
572 { fd = fdx->overloadExactMatch(tftostring);
573 if (fd)
574 dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
575 else
576 //fdx->error("must be declared as extern (D) char[] toString()");
577 dtdword(pdt, 0);
579 else
580 dtdword(pdt, 0);
582 // uint m_flags;
583 dti32(pdt, tc->hasPointers(), false);
585 // xgetMembers
586 FuncDeclaration *sgetmembers = sd->findGetMembers();
587 if (sgetmembers)
588 dtxoff(pdt, sgetmembers->toSymbol(), 0, TYnptr);
589 else
590 dtdword(pdt, 0); // xgetMembers
592 // xdtor
593 FuncDeclaration *sdtor = sd->dtor;
594 if (sdtor)
595 dtxoff(pdt, sdtor->toSymbol(), 0, TYnptr);
596 else
597 dtdword(pdt, 0); // xdtor
599 // xpostblit
600 FuncDeclaration *spostblit = sd->postblit;
601 if (spostblit)
602 dtxoff(pdt, spostblit->toSymbol(), 0, TYnptr);
603 else
604 dtdword(pdt, 0); // xpostblit
606 // name[]
607 dtnbytes(pdt, namelen + 1, name);
610 void TypeInfoClassDeclaration::toDt(dt_t **pdt)
612 //printf("TypeInfoClassDeclaration::toDt() %s\n", tinfo->toChars());
613 dtxoff(pdt, Type::typeinfoclass->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoClass
614 dtdword(pdt, 0); // monitor
616 assert(tinfo->ty == Tclass);
618 TypeClass *tc = (TypeClass *)tinfo;
619 Symbol *s;
621 if (!tc->sym->vclassinfo)
622 tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym);
623 s = tc->sym->vclassinfo->toSymbol();
624 dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo
627 void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
629 //printf("TypeInfoInterfaceDeclaration::toDt() %s\n", tinfo->toChars());
630 dtxoff(pdt, Type::typeinfointerface->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
631 dtdword(pdt, 0); // monitor
633 assert(tinfo->ty == Tclass);
635 TypeClass *tc = (TypeClass *)tinfo;
636 Symbol *s;
638 if (!tc->sym->vclassinfo)
639 tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym);
640 s = tc->sym->vclassinfo->toSymbol();
641 dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo
644 void TypeInfoTupleDeclaration::toDt(dt_t **pdt)
646 //printf("TypeInfoTupleDeclaration::toDt() %s\n", tinfo->toChars());
647 dtxoff(pdt, Type::typeinfotypelist->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
648 dtdword(pdt, 0); // monitor
650 assert(tinfo->ty == Ttuple);
652 TypeTuple *tu = (TypeTuple *)tinfo;
654 size_t dim = tu->arguments->dim;
655 dtdword(pdt, dim); // elements.length
657 dt_t *d = NULL;
658 for (size_t i = 0; i < dim; i++)
659 { Argument *arg = (Argument *)tu->arguments->data[i];
660 Expression *e = arg->type->getTypeInfo(NULL);
661 e = e->optimize(WANTvalue);
662 e->toDt(&d);
665 Symbol *s;
666 s = static_sym();
667 s->Sdt = d;
668 outdata(s);
670 dtxoff(pdt, s, 0, TYnptr); // elements.ptr
673 void TypeInfoDeclaration::toObjFile(int multiobj)
675 Symbol *s;
676 unsigned sz;
677 Dsymbol *parent;
679 //printf("TypeInfoDeclaration::toObjFile(%p '%s') protection %d\n", this, toChars(), protection);
681 if (multiobj)
683 obj_append(this);
684 return;
687 s = toSymbol();
688 sz = type->size();
690 parent = this->toParent();
691 s->Sclass = SCcomdat;
692 s->Sfl = FLdata;
694 toDt(&s->Sdt);
696 dt_optimize(s->Sdt);
698 // See if we can convert a comdat to a comdef,
699 // which saves on exe file space.
700 if (s->Sclass == SCcomdat &&
701 s->Sdt->dt == DT_azeros &&
702 s->Sdt->DTnext == NULL)
704 s->Sclass = SCglobal;
705 s->Sdt->dt = DT_common;
708 #if ELFOBJ // Burton
709 if (s->Sdt && s->Sdt->dt == DT_azeros && s->Sdt->DTnext == NULL)
710 s->Sseg = UDATA;
711 else
712 s->Sseg = DATA;
713 #endif /* ELFOBJ */
714 outdata(s);
715 if (isExport())
716 obj_export(s,0);
719 #endif
721 /* ========================================================================= */
723 /* These decide if there's an instance for them already in std.typeinfo,
724 * because then the compiler doesn't need to build one.
727 int Type::builtinTypeInfo()
729 return 0;
732 int TypeBasic::builtinTypeInfo()
734 return mod ? 0 : 1;
737 int TypeDArray::builtinTypeInfo()
739 return !mod && next->isTypeBasic() != NULL && !next->mod;
742 /* ========================================================================= */
744 /***************************************
745 * Create a static array of TypeInfo references
746 * corresponding to an array of Expression's.
747 * Used to supply hidden _arguments[] value for variadic D functions.
750 Expression *createTypeInfoArray(Scope *sc, Expression *exps[], int dim)
752 #if 1
753 /* Get the corresponding TypeInfo_Tuple and
754 * point at its elements[].
757 /* Create the TypeTuple corresponding to the types of args[]
759 Arguments *args = new Arguments;
760 args->setDim(dim);
761 for (size_t i = 0; i < dim; i++)
762 { Argument *arg = new Argument(STCin, exps[i]->type, NULL, NULL);
763 args->data[i] = (void *)arg;
765 TypeTuple *tup = new TypeTuple(args);
766 Expression *e = tup->getTypeInfo(sc);
767 e = e->optimize(WANTvalue);
768 assert(e->op == TOKsymoff); // should be SymOffExp
770 #if BREAKABI
772 * Should just pass a reference to TypeInfo_Tuple instead,
773 * but that would require existing code to be recompiled.
774 * Source compatibility can be maintained by computing _arguments[]
775 * at the start of the called function by offseting into the
776 * TypeInfo_Tuple reference.
779 #else
780 // Advance to elements[] member of TypeInfo_Tuple
781 SymOffExp *se = (SymOffExp *)e;
782 se->offset += PTRSIZE + PTRSIZE;
784 // Set type to TypeInfo[]*
785 se->type = Type::typeinfo->type->arrayOf()->pointerTo();
787 // Indirect to get the _arguments[] value
788 e = new PtrExp(0, se);
789 e->type = se->type->next;
790 #endif
791 return e;
792 #else
793 /* Improvements:
794 * 1) create an array literal instead,
795 * as it would eliminate the extra dereference of loading the
796 * static variable.
799 ArrayInitializer *ai = new ArrayInitializer(0);
800 VarDeclaration *v;
801 Type *t;
802 Expression *e;
803 OutBuffer buf;
804 Identifier *id;
805 char *name;
807 // Generate identifier for _arguments[]
808 buf.writestring("_arguments_");
809 for (int i = 0; i < dim; i++)
810 { t = exps[i]->type;
811 t->toDecoBuffer(&buf);
813 buf.writeByte(0);
814 id = Lexer::idPool((char *)buf.data);
816 #ifdef IN_GCC
817 Module *m = d_gcc_get_output_module();
818 #else
819 Module *m = sc->module;
820 #endif
821 Dsymbol *s = m->symtab->lookup(id);
823 if (s && s->parent == m)
824 { // Use existing one
825 v = s->isVarDeclaration();
826 assert(v);
828 else
829 { // Generate new one
831 for (int i = 0; i < dim; i++)
832 { t = exps[i]->type;
833 e = t->getTypeInfo(sc);
834 ai->addInit(new IntegerExp(i), new ExpInitializer(0, e));
837 t = Type::typeinfo->type->arrayOf();
838 ai->type = t;
839 v = new VarDeclaration(0, t, id, ai);
840 m->members->push(v);
841 m->symtab->insert(v);
842 sc = sc->push();
843 sc->linkage = LINKc;
844 sc->stc = STCstatic | STCcomdat;
845 ai->semantic(sc, t);
846 v->semantic(sc);
847 v->parent = m;
848 sc = sc->pop();
850 e = new VarExp(0, v);
851 e = e->semantic(sc);
852 return e;
853 #endif