Don't include dynamic arrays in non-null checks
[delight/core.git] / dmd2 / typinf.c
blobab3baf12148dd78d1fd7c6b59dcd05ed42aabd90
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 *TypeDArray::getTypeInfoDeclaration()
175 return new TypeInfoArrayDeclaration(this);
178 TypeInfoDeclaration *TypeSArray::getTypeInfoDeclaration()
180 return new TypeInfoStaticArrayDeclaration(this);
183 TypeInfoDeclaration *TypeAArray::getTypeInfoDeclaration()
185 return new TypeInfoAssociativeArrayDeclaration(this);
188 TypeInfoDeclaration *TypeStruct::getTypeInfoDeclaration()
190 return new TypeInfoStructDeclaration(this);
193 TypeInfoDeclaration *TypeClass::getTypeInfoDeclaration()
195 if (sym->isInterfaceDeclaration())
196 return new TypeInfoInterfaceDeclaration(this);
197 else
198 return new TypeInfoClassDeclaration(this);
201 TypeInfoDeclaration *TypeEnum::getTypeInfoDeclaration()
203 return new TypeInfoEnumDeclaration(this);
206 TypeInfoDeclaration *TypeFunction::getTypeInfoDeclaration()
208 return new TypeInfoFunctionDeclaration(this);
211 TypeInfoDeclaration *TypeDelegate::getTypeInfoDeclaration()
213 return new TypeInfoDelegateDeclaration(this);
216 TypeInfoDeclaration *TypeTuple::getTypeInfoDeclaration()
218 return new TypeInfoTupleDeclaration(this);
222 /****************************************************
225 #if 1
227 void TypeInfoDeclaration::toDt(dt_t **pdt)
229 //printf("TypeInfoDeclaration::toDt() %s\n", toChars());
230 dtxoff(pdt, Type::typeinfo->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo
231 dtdword(pdt, 0); // monitor
234 void TypeInfoConstDeclaration::toDt(dt_t **pdt)
236 //printf("TypeInfoConstDeclaration::toDt() %s\n", toChars());
237 dtxoff(pdt, Type::typeinfoconst->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Const
238 dtdword(pdt, 0); // monitor
239 Type *tm = tinfo->mutableOf();
240 tm = tm->merge();
241 tm->getTypeInfo(NULL);
242 dtxoff(pdt, tm->vtinfo->toSymbol(), 0, TYnptr);
245 void TypeInfoInvariantDeclaration::toDt(dt_t **pdt)
247 //printf("TypeInfoInvariantDeclaration::toDt() %s\n", toChars());
248 dtxoff(pdt, Type::typeinfoinvariant->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Invariant
249 dtdword(pdt, 0); // monitor
250 Type *tm = tinfo->mutableOf();
251 tm = tm->merge();
252 tm->getTypeInfo(NULL);
253 dtxoff(pdt, tm->vtinfo->toSymbol(), 0, TYnptr);
256 void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
258 //printf("TypeInfoTypedefDeclaration::toDt() %s\n", toChars());
260 dtxoff(pdt, Type::typeinfotypedef->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Typedef
261 dtdword(pdt, 0); // monitor
263 assert(tinfo->ty == Ttypedef);
265 TypeTypedef *tc = (TypeTypedef *)tinfo;
266 TypedefDeclaration *sd = tc->sym;
267 //printf("basetype = %s\n", sd->basetype->toChars());
269 /* Put out:
270 * TypeInfo base;
271 * char[] name;
272 * void[] m_init;
275 sd->basetype = sd->basetype->merge();
276 sd->basetype->getTypeInfo(NULL); // generate vtinfo
277 assert(sd->basetype->vtinfo);
278 dtxoff(pdt, sd->basetype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for basetype
280 char *name = sd->toPrettyChars();
281 size_t namelen = strlen(name);
282 dtdword(pdt, namelen);
283 dtabytes(pdt, TYnptr, 0, namelen + 1, name);
285 // void[] init;
286 if (tinfo->isZeroInit() || !sd->init)
287 { // 0 initializer, or the same as the base type
288 dtdword(pdt, 0); // init.length
289 dtdword(pdt, 0); // init.ptr
291 else
293 dtdword(pdt, sd->type->size()); // init.length
294 dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
298 void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
300 //printf("TypeInfoEnumDeclaration::toDt()\n");
301 dtxoff(pdt, Type::typeinfoenum->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Enum
302 dtdword(pdt, 0); // monitor
304 assert(tinfo->ty == Tenum);
306 TypeEnum *tc = (TypeEnum *)tinfo;
307 EnumDeclaration *sd = tc->sym;
309 /* Put out:
310 * TypeInfo base;
311 * char[] name;
312 * void[] m_init;
315 if (sd->memtype)
316 { sd->memtype->getTypeInfo(NULL);
317 dtxoff(pdt, sd->memtype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for enum members
319 else
320 dtdword(pdt, 0);
322 char *name = sd->toPrettyChars();
323 size_t namelen = strlen(name);
324 dtdword(pdt, namelen);
325 dtabytes(pdt, TYnptr, 0, namelen + 1, name);
327 // void[] init;
328 if (!sd->defaultval || tinfo->isZeroInit())
329 { // 0 initializer, or the same as the base type
330 dtdword(pdt, 0); // init.length
331 dtdword(pdt, 0); // init.ptr
333 else
335 dtdword(pdt, sd->type->size()); // init.length
336 dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
340 void TypeInfoPointerDeclaration::toDt(dt_t **pdt)
342 //printf("TypeInfoPointerDeclaration::toDt()\n");
343 dtxoff(pdt, Type::typeinfopointer->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Pointer
344 dtdword(pdt, 0); // monitor
346 assert(tinfo->ty == Tpointer);
348 TypePointer *tc = (TypePointer *)tinfo;
350 tc->next->getTypeInfo(NULL);
351 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for type being pointed to
354 void TypeInfoArrayDeclaration::toDt(dt_t **pdt)
356 //printf("TypeInfoArrayDeclaration::toDt()\n");
357 dtxoff(pdt, Type::typeinfoarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Array
358 dtdword(pdt, 0); // monitor
360 assert(tinfo->ty == Tarray);
362 TypeDArray *tc = (TypeDArray *)tinfo;
364 tc->next->getTypeInfo(NULL);
365 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
368 void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
370 //printf("TypeInfoStaticArrayDeclaration::toDt()\n");
371 dtxoff(pdt, Type::typeinfostaticarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_StaticArray
372 dtdword(pdt, 0); // monitor
374 assert(tinfo->ty == Tsarray);
376 TypeSArray *tc = (TypeSArray *)tinfo;
378 tc->next->getTypeInfo(NULL);
379 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
381 dtdword(pdt, tc->dim->toInteger()); // length
384 void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
386 //printf("TypeInfoAssociativeArrayDeclaration::toDt()\n");
387 dtxoff(pdt, Type::typeinfoassociativearray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_AssociativeArray
388 dtdword(pdt, 0); // monitor
390 assert(tinfo->ty == Taarray);
392 TypeAArray *tc = (TypeAArray *)tinfo;
394 tc->next->getTypeInfo(NULL);
395 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
397 tc->index->getTypeInfo(NULL);
398 dtxoff(pdt, tc->index->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
401 void TypeInfoFunctionDeclaration::toDt(dt_t **pdt)
403 //printf("TypeInfoFunctionDeclaration::toDt()\n");
404 dtxoff(pdt, Type::typeinfofunction->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Function
405 dtdword(pdt, 0); // monitor
407 assert(tinfo->ty == Tfunction);
409 TypeFunction *tc = (TypeFunction *)tinfo;
411 tc->next->getTypeInfo(NULL);
412 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for function return value
415 void TypeInfoDelegateDeclaration::toDt(dt_t **pdt)
417 //printf("TypeInfoDelegateDeclaration::toDt()\n");
418 dtxoff(pdt, Type::typeinfodelegate->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Delegate
419 dtdword(pdt, 0); // monitor
421 assert(tinfo->ty == Tdelegate);
423 TypeDelegate *tc = (TypeDelegate *)tinfo;
425 tc->next->nextOf()->getTypeInfo(NULL);
426 dtxoff(pdt, tc->next->nextOf()->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for delegate return value
429 void TypeInfoStructDeclaration::toDt(dt_t **pdt)
431 //printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars());
433 unsigned offset = Type::typeinfostruct->structsize;
435 dtxoff(pdt, Type::typeinfostruct->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Struct
436 dtdword(pdt, 0); // monitor
438 assert(tinfo->ty == Tstruct);
440 TypeStruct *tc = (TypeStruct *)tinfo;
441 StructDeclaration *sd = tc->sym;
443 /* Put out:
444 * char[] name;
445 * void[] init;
446 * hash_t function(in void*) xtoHash;
447 * int function(in void*, in void*) xopEquals;
448 * int function(in void*, in void*) xopCmp;
449 * string function(const(void)*) xtoString;
450 * uint m_flags;
451 * xgetMembers;
452 * xdtor;
453 * xpostblit;
455 * name[]
458 char *name = sd->toPrettyChars();
459 size_t namelen = strlen(name);
460 dtdword(pdt, namelen);
461 //dtabytes(pdt, TYnptr, 0, namelen + 1, name);
462 dtxoff(pdt, toSymbol(), offset, TYnptr);
463 offset += namelen + 1;
465 // void[] init;
466 dtdword(pdt, sd->structsize); // init.length
467 if (sd->zeroInit)
468 dtdword(pdt, 0); // NULL for 0 initialization
469 else
470 dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
472 FuncDeclaration *fd;
473 FuncDeclaration *fdx;
474 TypeFunction *tf;
475 Type *ta;
476 Dsymbol *s;
478 static TypeFunction *tftohash;
479 static TypeFunction *tftostring;
481 if (!tftohash)
483 Scope sc;
485 tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd);
486 tftohash->mod = MODconst;
487 tftohash = (TypeFunction *)tftohash->semantic(0, &sc);
489 tftostring = new TypeFunction(NULL, Type::tchar->invariantOf()->arrayOf(), 0, LINKd);
490 tftostring = (TypeFunction *)tftostring->semantic(0, &sc);
493 TypeFunction *tfeqptr;
495 Scope sc;
496 Arguments *arguments = new Arguments;
497 Argument *arg = new Argument(STCin, tc->pointerTo(), NULL, NULL);
499 arguments->push(arg);
500 tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
501 tfeqptr->mod = MODconst;
502 tfeqptr = (TypeFunction *)tfeqptr->semantic(0, &sc);
505 #if 0
506 TypeFunction *tfeq;
508 Scope sc;
509 Array *arguments = new Array;
510 Argument *arg = new Argument(In, tc, NULL, NULL);
512 arguments->push(arg);
513 tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd);
514 tfeq = (TypeFunction *)tfeq->semantic(0, &sc);
516 #endif
518 s = search_function(sd, Id::tohash);
519 fdx = s ? s->isFuncDeclaration() : NULL;
520 if (fdx)
521 { fd = fdx->overloadExactMatch(tftohash);
522 if (fd)
523 dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
524 else
525 //fdx->error("must be declared as extern (D) uint toHash()");
526 dtdword(pdt, 0);
528 else
529 dtdword(pdt, 0);
531 s = search_function(sd, Id::eq);
532 fdx = s ? s->isFuncDeclaration() : NULL;
533 for (int i = 0; i < 2; i++)
535 if (fdx)
536 { fd = fdx->overloadExactMatch(tfeqptr);
537 if (fd)
538 dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
539 else
540 //fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars());
541 dtdword(pdt, 0);
543 else
544 dtdword(pdt, 0);
546 s = search_function(sd, Id::cmp);
547 fdx = s ? s->isFuncDeclaration() : NULL;
550 s = search_function(sd, Id::tostring);
551 fdx = s ? s->isFuncDeclaration() : NULL;
552 if (fdx)
553 { fd = fdx->overloadExactMatch(tftostring);
554 if (fd)
555 dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
556 else
557 //fdx->error("must be declared as extern (D) char[] toString()");
558 dtdword(pdt, 0);
560 else
561 dtdword(pdt, 0);
563 // uint m_flags;
564 dti32(pdt, tc->hasPointers(), false);
566 // xgetMembers
567 FuncDeclaration *sgetmembers = sd->findGetMembers();
568 if (sgetmembers)
569 dtxoff(pdt, sgetmembers->toSymbol(), 0, TYnptr);
570 else
571 dtdword(pdt, 0); // xgetMembers
573 // xdtor
574 FuncDeclaration *sdtor = sd->dtor;
575 if (sdtor)
576 dtxoff(pdt, sdtor->toSymbol(), 0, TYnptr);
577 else
578 dtdword(pdt, 0); // xdtor
580 // xpostblit
581 FuncDeclaration *spostblit = sd->postblit;
582 if (spostblit)
583 dtxoff(pdt, spostblit->toSymbol(), 0, TYnptr);
584 else
585 dtdword(pdt, 0); // xpostblit
587 // name[]
588 dtnbytes(pdt, namelen + 1, name);
591 void TypeInfoClassDeclaration::toDt(dt_t **pdt)
593 //printf("TypeInfoClassDeclaration::toDt() %s\n", tinfo->toChars());
594 dtxoff(pdt, Type::typeinfoclass->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoClass
595 dtdword(pdt, 0); // monitor
597 assert(tinfo->ty == Tclass);
599 TypeClass *tc = (TypeClass *)tinfo;
600 Symbol *s;
602 if (!tc->sym->vclassinfo)
603 tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym);
604 s = tc->sym->vclassinfo->toSymbol();
605 dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo
608 void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
610 //printf("TypeInfoInterfaceDeclaration::toDt() %s\n", tinfo->toChars());
611 dtxoff(pdt, Type::typeinfointerface->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
612 dtdword(pdt, 0); // monitor
614 assert(tinfo->ty == Tclass);
616 TypeClass *tc = (TypeClass *)tinfo;
617 Symbol *s;
619 if (!tc->sym->vclassinfo)
620 tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym);
621 s = tc->sym->vclassinfo->toSymbol();
622 dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo
625 void TypeInfoTupleDeclaration::toDt(dt_t **pdt)
627 //printf("TypeInfoTupleDeclaration::toDt() %s\n", tinfo->toChars());
628 dtxoff(pdt, Type::typeinfotypelist->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
629 dtdword(pdt, 0); // monitor
631 assert(tinfo->ty == Ttuple);
633 TypeTuple *tu = (TypeTuple *)tinfo;
635 size_t dim = tu->arguments->dim;
636 dtdword(pdt, dim); // elements.length
638 dt_t *d = NULL;
639 for (size_t i = 0; i < dim; i++)
640 { Argument *arg = (Argument *)tu->arguments->data[i];
641 Expression *e = arg->type->getTypeInfo(NULL);
642 e = e->optimize(WANTvalue);
643 e->toDt(&d);
646 Symbol *s;
647 s = static_sym();
648 s->Sdt = d;
649 outdata(s);
651 dtxoff(pdt, s, 0, TYnptr); // elements.ptr
654 void TypeInfoDeclaration::toObjFile(int multiobj)
656 Symbol *s;
657 unsigned sz;
658 Dsymbol *parent;
660 //printf("TypeInfoDeclaration::toObjFile(%p '%s') protection %d\n", this, toChars(), protection);
662 if (multiobj)
664 obj_append(this);
665 return;
668 s = toSymbol();
669 sz = type->size();
671 parent = this->toParent();
672 s->Sclass = SCcomdat;
673 s->Sfl = FLdata;
675 toDt(&s->Sdt);
677 dt_optimize(s->Sdt);
679 // See if we can convert a comdat to a comdef,
680 // which saves on exe file space.
681 if (s->Sclass == SCcomdat &&
682 s->Sdt->dt == DT_azeros &&
683 s->Sdt->DTnext == NULL)
685 s->Sclass = SCglobal;
686 s->Sdt->dt = DT_common;
689 #if ELFOBJ // Burton
690 if (s->Sdt && s->Sdt->dt == DT_azeros && s->Sdt->DTnext == NULL)
691 s->Sseg = UDATA;
692 else
693 s->Sseg = DATA;
694 #endif /* ELFOBJ */
695 outdata(s);
696 if (isExport())
697 obj_export(s,0);
700 #endif
702 /* ========================================================================= */
704 /* These decide if there's an instance for them already in std.typeinfo,
705 * because then the compiler doesn't need to build one.
708 int Type::builtinTypeInfo()
710 return 0;
713 int TypeBasic::builtinTypeInfo()
715 return mod ? 0 : 1;
718 int TypeDArray::builtinTypeInfo()
720 return !mod && next->isTypeBasic() != NULL && !next->mod;
723 /* ========================================================================= */
725 /***************************************
726 * Create a static array of TypeInfo references
727 * corresponding to an array of Expression's.
728 * Used to supply hidden _arguments[] value for variadic D functions.
731 Expression *createTypeInfoArray(Scope *sc, Expression *exps[], int dim)
733 #if 1
734 /* Get the corresponding TypeInfo_Tuple and
735 * point at its elements[].
738 /* Create the TypeTuple corresponding to the types of args[]
740 Arguments *args = new Arguments;
741 args->setDim(dim);
742 for (size_t i = 0; i < dim; i++)
743 { Argument *arg = new Argument(STCin, exps[i]->type, NULL, NULL);
744 args->data[i] = (void *)arg;
746 TypeTuple *tup = new TypeTuple(args);
747 Expression *e = tup->getTypeInfo(sc);
748 e = e->optimize(WANTvalue);
749 assert(e->op == TOKsymoff); // should be SymOffExp
751 #if BREAKABI
753 * Should just pass a reference to TypeInfo_Tuple instead,
754 * but that would require existing code to be recompiled.
755 * Source compatibility can be maintained by computing _arguments[]
756 * at the start of the called function by offseting into the
757 * TypeInfo_Tuple reference.
760 #else
761 // Advance to elements[] member of TypeInfo_Tuple
762 SymOffExp *se = (SymOffExp *)e;
763 se->offset += PTRSIZE + PTRSIZE;
765 // Set type to TypeInfo[]*
766 se->type = Type::typeinfo->type->arrayOf()->pointerTo();
768 // Indirect to get the _arguments[] value
769 e = new PtrExp(0, se);
770 e->type = se->type->next;
771 #endif
772 return e;
773 #else
774 /* Improvements:
775 * 1) create an array literal instead,
776 * as it would eliminate the extra dereference of loading the
777 * static variable.
780 ArrayInitializer *ai = new ArrayInitializer(0);
781 VarDeclaration *v;
782 Type *t;
783 Expression *e;
784 OutBuffer buf;
785 Identifier *id;
786 char *name;
788 // Generate identifier for _arguments[]
789 buf.writestring("_arguments_");
790 for (int i = 0; i < dim; i++)
791 { t = exps[i]->type;
792 t->toDecoBuffer(&buf);
794 buf.writeByte(0);
795 id = Lexer::idPool((char *)buf.data);
797 #ifdef IN_GCC
798 Module *m = d_gcc_get_output_module();
799 #else
800 Module *m = sc->module;
801 #endif
802 Dsymbol *s = m->symtab->lookup(id);
804 if (s && s->parent == m)
805 { // Use existing one
806 v = s->isVarDeclaration();
807 assert(v);
809 else
810 { // Generate new one
812 for (int i = 0; i < dim; i++)
813 { t = exps[i]->type;
814 e = t->getTypeInfo(sc);
815 ai->addInit(new IntegerExp(i), new ExpInitializer(0, e));
818 t = Type::typeinfo->type->arrayOf();
819 ai->type = t;
820 v = new VarDeclaration(0, t, id, ai);
821 m->members->push(v);
822 m->symtab->insert(v);
823 sc = sc->push();
824 sc->linkage = LINKc;
825 sc->stc = STCstatic | STCcomdat;
826 ai->semantic(sc, t);
827 v->semantic(sc);
828 v->parent = m;
829 sc = sc->pop();
831 e = new VarExp(0, v);
832 e = e->semantic(sc);
833 return e;
834 #endif