Document search flags
[delight/core.git] / dmd2 / typinf.c
blob9f9d4a95ddbc6b43504a3c41fce14a5dbe5a5419
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 Expression *TypeMaybe::getTypeInfo(Scope *sc)
175 return next->getTypeInfo(sc);
178 TypeInfoDeclaration *TypeMaybe::getTypeInfoDeclaration()
180 return next->getTypeInfoDeclaration();
183 TypeInfoDeclaration *TypeDArray::getTypeInfoDeclaration()
185 return new TypeInfoArrayDeclaration(this);
188 TypeInfoDeclaration *TypeSArray::getTypeInfoDeclaration()
190 return new TypeInfoStaticArrayDeclaration(this);
193 TypeInfoDeclaration *TypeAArray::getTypeInfoDeclaration()
195 return new TypeInfoAssociativeArrayDeclaration(this);
198 TypeInfoDeclaration *TypeStruct::getTypeInfoDeclaration()
200 return new TypeInfoStructDeclaration(this);
203 TypeInfoDeclaration *TypeClass::getTypeInfoDeclaration()
205 if (sym->isInterfaceDeclaration())
206 return new TypeInfoInterfaceDeclaration(this);
207 else
208 return new TypeInfoClassDeclaration(this);
211 TypeInfoDeclaration *TypeEnum::getTypeInfoDeclaration()
213 return new TypeInfoEnumDeclaration(this);
216 TypeInfoDeclaration *TypeFunction::getTypeInfoDeclaration()
218 return new TypeInfoFunctionDeclaration(this);
221 TypeInfoDeclaration *TypeDelegate::getTypeInfoDeclaration()
223 return new TypeInfoDelegateDeclaration(this);
226 TypeInfoDeclaration *TypeTuple::getTypeInfoDeclaration()
228 return new TypeInfoTupleDeclaration(this);
232 /****************************************************
235 #if 1
237 void TypeInfoDeclaration::toDt(dt_t **pdt)
239 //printf("TypeInfoDeclaration::toDt() %s\n", toChars());
240 dtxoff(pdt, Type::typeinfo->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo
241 dtdword(pdt, 0); // monitor
244 void TypeInfoConstDeclaration::toDt(dt_t **pdt)
246 //printf("TypeInfoConstDeclaration::toDt() %s\n", toChars());
247 dtxoff(pdt, Type::typeinfoconst->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Const
248 dtdword(pdt, 0); // monitor
249 Type *tm = tinfo->mutableOf();
250 tm = tm->merge();
251 tm->getTypeInfo(NULL);
252 dtxoff(pdt, tm->vtinfo->toSymbol(), 0, TYnptr);
255 void TypeInfoInvariantDeclaration::toDt(dt_t **pdt)
257 //printf("TypeInfoInvariantDeclaration::toDt() %s\n", toChars());
258 dtxoff(pdt, Type::typeinfoinvariant->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Invariant
259 dtdword(pdt, 0); // monitor
260 Type *tm = tinfo->mutableOf();
261 tm = tm->merge();
262 tm->getTypeInfo(NULL);
263 dtxoff(pdt, tm->vtinfo->toSymbol(), 0, TYnptr);
266 void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
268 //printf("TypeInfoTypedefDeclaration::toDt() %s\n", toChars());
270 dtxoff(pdt, Type::typeinfotypedef->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Typedef
271 dtdword(pdt, 0); // monitor
273 assert(tinfo->ty == Ttypedef);
275 TypeTypedef *tc = (TypeTypedef *)tinfo;
276 TypedefDeclaration *sd = tc->sym;
277 //printf("basetype = %s\n", sd->basetype->toChars());
279 /* Put out:
280 * TypeInfo base;
281 * char[] name;
282 * void[] m_init;
285 sd->basetype = sd->basetype->merge();
286 sd->basetype->getTypeInfo(NULL); // generate vtinfo
287 assert(sd->basetype->vtinfo);
288 dtxoff(pdt, sd->basetype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for basetype
290 char *name = sd->toPrettyChars();
291 size_t namelen = strlen(name);
292 dtdword(pdt, namelen);
293 dtabytes(pdt, TYnptr, 0, namelen + 1, name);
295 // void[] init;
296 if (tinfo->isZeroInit() || !sd->init)
297 { // 0 initializer, or the same as the base type
298 dtdword(pdt, 0); // init.length
299 dtdword(pdt, 0); // init.ptr
301 else
303 dtdword(pdt, sd->type->size()); // init.length
304 dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
308 void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
310 //printf("TypeInfoEnumDeclaration::toDt()\n");
311 dtxoff(pdt, Type::typeinfoenum->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Enum
312 dtdword(pdt, 0); // monitor
314 assert(tinfo->ty == Tenum);
316 TypeEnum *tc = (TypeEnum *)tinfo;
317 EnumDeclaration *sd = tc->sym;
319 /* Put out:
320 * TypeInfo base;
321 * char[] name;
322 * void[] m_init;
325 if (sd->memtype)
326 { sd->memtype->getTypeInfo(NULL);
327 dtxoff(pdt, sd->memtype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for enum members
329 else
330 dtdword(pdt, 0);
332 char *name = sd->toPrettyChars();
333 size_t namelen = strlen(name);
334 dtdword(pdt, namelen);
335 dtabytes(pdt, TYnptr, 0, namelen + 1, name);
337 // void[] init;
338 if (!sd->defaultval || tinfo->isZeroInit())
339 { // 0 initializer, or the same as the base type
340 dtdword(pdt, 0); // init.length
341 dtdword(pdt, 0); // init.ptr
343 else
345 dtdword(pdt, sd->type->size()); // init.length
346 dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
350 void TypeInfoPointerDeclaration::toDt(dt_t **pdt)
352 //printf("TypeInfoPointerDeclaration::toDt()\n");
353 dtxoff(pdt, Type::typeinfopointer->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Pointer
354 dtdword(pdt, 0); // monitor
356 assert(tinfo->ty == Tpointer);
358 TypePointer *tc = (TypePointer *)tinfo;
360 tc->next->getTypeInfo(NULL);
361 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for type being pointed to
364 void TypeInfoArrayDeclaration::toDt(dt_t **pdt)
366 //printf("TypeInfoArrayDeclaration::toDt()\n");
367 dtxoff(pdt, Type::typeinfoarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Array
368 dtdword(pdt, 0); // monitor
370 assert(tinfo->ty == Tarray);
372 TypeDArray *tc = (TypeDArray *)tinfo;
374 tc->next->getTypeInfo(NULL);
375 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
378 void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
380 //printf("TypeInfoStaticArrayDeclaration::toDt()\n");
381 dtxoff(pdt, Type::typeinfostaticarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_StaticArray
382 dtdword(pdt, 0); // monitor
384 assert(tinfo->ty == Tsarray);
386 TypeSArray *tc = (TypeSArray *)tinfo;
388 tc->next->getTypeInfo(NULL);
389 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
391 dtdword(pdt, tc->dim->toInteger()); // length
394 void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
396 //printf("TypeInfoAssociativeArrayDeclaration::toDt()\n");
397 dtxoff(pdt, Type::typeinfoassociativearray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_AssociativeArray
398 dtdword(pdt, 0); // monitor
400 assert(tinfo->ty == Taarray);
402 TypeAArray *tc = (TypeAArray *)tinfo;
404 tc->next->getTypeInfo(NULL);
405 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
407 tc->index->getTypeInfo(NULL);
408 dtxoff(pdt, tc->index->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
411 void TypeInfoFunctionDeclaration::toDt(dt_t **pdt)
413 //printf("TypeInfoFunctionDeclaration::toDt()\n");
414 dtxoff(pdt, Type::typeinfofunction->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Function
415 dtdword(pdt, 0); // monitor
417 assert(tinfo->ty == Tfunction);
419 TypeFunction *tc = (TypeFunction *)tinfo;
421 tc->next->getTypeInfo(NULL);
422 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for function return value
425 void TypeInfoDelegateDeclaration::toDt(dt_t **pdt)
427 //printf("TypeInfoDelegateDeclaration::toDt()\n");
428 dtxoff(pdt, Type::typeinfodelegate->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Delegate
429 dtdword(pdt, 0); // monitor
431 assert(tinfo->ty == Tdelegate);
433 TypeDelegate *tc = (TypeDelegate *)tinfo;
435 tc->next->nextOf()->getTypeInfo(NULL);
436 dtxoff(pdt, tc->next->nextOf()->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for delegate return value
439 void TypeInfoStructDeclaration::toDt(dt_t **pdt)
441 //printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars());
443 unsigned offset = Type::typeinfostruct->structsize;
445 dtxoff(pdt, Type::typeinfostruct->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Struct
446 dtdword(pdt, 0); // monitor
448 assert(tinfo->ty == Tstruct);
450 TypeStruct *tc = (TypeStruct *)tinfo;
451 StructDeclaration *sd = tc->sym;
453 /* Put out:
454 * char[] name;
455 * void[] init;
456 * hash_t function(in void*) xtoHash;
457 * int function(in void*, in void*) xopEquals;
458 * int function(in void*, in void*) xopCmp;
459 * string function(const(void)*) xtoString;
460 * uint m_flags;
461 * xgetMembers;
462 * xdtor;
463 * xpostblit;
465 * name[]
468 char *name = sd->toPrettyChars();
469 size_t namelen = strlen(name);
470 dtdword(pdt, namelen);
471 //dtabytes(pdt, TYnptr, 0, namelen + 1, name);
472 dtxoff(pdt, toSymbol(), offset, TYnptr);
473 offset += namelen + 1;
475 // void[] init;
476 dtdword(pdt, sd->structsize); // init.length
477 if (sd->zeroInit)
478 dtdword(pdt, 0); // NULL for 0 initialization
479 else
480 dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
482 FuncDeclaration *fd;
483 FuncDeclaration *fdx;
484 TypeFunction *tf;
485 Type *ta;
486 Dsymbol *s;
488 static TypeFunction *tftohash;
489 static TypeFunction *tftostring;
491 if (!tftohash)
493 Scope sc;
495 tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd);
496 tftohash->mod = MODconst;
497 tftohash = (TypeFunction *)tftohash->semantic(0, &sc);
499 tftostring = new TypeFunction(NULL, Type::tchar->invariantOf()->arrayOf(), 0, LINKd);
500 tftostring = (TypeFunction *)tftostring->semantic(0, &sc);
503 TypeFunction *tfeqptr;
505 Scope sc;
506 Arguments *arguments = new Arguments;
507 Argument *arg = new Argument(STCin, tc->pointerTo(), NULL, NULL);
509 arguments->push(arg);
510 tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
511 tfeqptr->mod = MODconst;
512 tfeqptr = (TypeFunction *)tfeqptr->semantic(0, &sc);
515 #if 0
516 TypeFunction *tfeq;
518 Scope sc;
519 Array *arguments = new Array;
520 Argument *arg = new Argument(In, tc, NULL, NULL);
522 arguments->push(arg);
523 tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd);
524 tfeq = (TypeFunction *)tfeq->semantic(0, &sc);
526 #endif
528 s = search_function(sd, Id::tohash);
529 fdx = s ? s->isFuncDeclaration() : NULL;
530 if (fdx)
531 { fd = fdx->overloadExactMatch(tftohash);
532 if (fd)
533 dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
534 else
535 //fdx->error("must be declared as extern (D) uint toHash()");
536 dtdword(pdt, 0);
538 else
539 dtdword(pdt, 0);
541 s = search_function(sd, Id::eq);
542 fdx = s ? s->isFuncDeclaration() : NULL;
543 for (int i = 0; i < 2; i++)
545 if (fdx)
546 { fd = fdx->overloadExactMatch(tfeqptr);
547 if (fd)
548 dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
549 else
550 //fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars());
551 dtdword(pdt, 0);
553 else
554 dtdword(pdt, 0);
556 s = search_function(sd, Id::cmp);
557 fdx = s ? s->isFuncDeclaration() : NULL;
560 s = search_function(sd, Id::tostring);
561 fdx = s ? s->isFuncDeclaration() : NULL;
562 if (fdx)
563 { fd = fdx->overloadExactMatch(tftostring);
564 if (fd)
565 dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
566 else
567 //fdx->error("must be declared as extern (D) char[] toString()");
568 dtdword(pdt, 0);
570 else
571 dtdword(pdt, 0);
573 // uint m_flags;
574 dti32(pdt, tc->hasPointers(), false);
576 // xgetMembers
577 FuncDeclaration *sgetmembers = sd->findGetMembers();
578 if (sgetmembers)
579 dtxoff(pdt, sgetmembers->toSymbol(), 0, TYnptr);
580 else
581 dtdword(pdt, 0); // xgetMembers
583 // xdtor
584 FuncDeclaration *sdtor = sd->dtor;
585 if (sdtor)
586 dtxoff(pdt, sdtor->toSymbol(), 0, TYnptr);
587 else
588 dtdword(pdt, 0); // xdtor
590 // xpostblit
591 FuncDeclaration *spostblit = sd->postblit;
592 if (spostblit)
593 dtxoff(pdt, spostblit->toSymbol(), 0, TYnptr);
594 else
595 dtdword(pdt, 0); // xpostblit
597 // name[]
598 dtnbytes(pdt, namelen + 1, name);
601 void TypeInfoClassDeclaration::toDt(dt_t **pdt)
603 //printf("TypeInfoClassDeclaration::toDt() %s\n", tinfo->toChars());
604 dtxoff(pdt, Type::typeinfoclass->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoClass
605 dtdword(pdt, 0); // monitor
607 assert(tinfo->ty == Tclass);
609 TypeClass *tc = (TypeClass *)tinfo;
610 Symbol *s;
612 if (!tc->sym->vclassinfo)
613 tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym);
614 s = tc->sym->vclassinfo->toSymbol();
615 dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo
618 void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
620 //printf("TypeInfoInterfaceDeclaration::toDt() %s\n", tinfo->toChars());
621 dtxoff(pdt, Type::typeinfointerface->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
622 dtdword(pdt, 0); // monitor
624 assert(tinfo->ty == Tclass);
626 TypeClass *tc = (TypeClass *)tinfo;
627 Symbol *s;
629 if (!tc->sym->vclassinfo)
630 tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym);
631 s = tc->sym->vclassinfo->toSymbol();
632 dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo
635 void TypeInfoTupleDeclaration::toDt(dt_t **pdt)
637 //printf("TypeInfoTupleDeclaration::toDt() %s\n", tinfo->toChars());
638 dtxoff(pdt, Type::typeinfotypelist->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
639 dtdword(pdt, 0); // monitor
641 assert(tinfo->ty == Ttuple);
643 TypeTuple *tu = (TypeTuple *)tinfo;
645 size_t dim = tu->arguments->dim;
646 dtdword(pdt, dim); // elements.length
648 dt_t *d = NULL;
649 for (size_t i = 0; i < dim; i++)
650 { Argument *arg = (Argument *)tu->arguments->data[i];
651 Expression *e = arg->type->getTypeInfo(NULL);
652 e = e->optimize(WANTvalue);
653 e->toDt(&d);
656 Symbol *s;
657 s = static_sym();
658 s->Sdt = d;
659 outdata(s);
661 dtxoff(pdt, s, 0, TYnptr); // elements.ptr
664 void TypeInfoDeclaration::toObjFile(int multiobj)
666 Symbol *s;
667 unsigned sz;
668 Dsymbol *parent;
670 //printf("TypeInfoDeclaration::toObjFile(%p '%s') protection %d\n", this, toChars(), protection);
672 if (multiobj)
674 obj_append(this);
675 return;
678 s = toSymbol();
679 sz = type->size();
681 parent = this->toParent();
682 s->Sclass = SCcomdat;
683 s->Sfl = FLdata;
685 toDt(&s->Sdt);
687 dt_optimize(s->Sdt);
689 // See if we can convert a comdat to a comdef,
690 // which saves on exe file space.
691 if (s->Sclass == SCcomdat &&
692 s->Sdt->dt == DT_azeros &&
693 s->Sdt->DTnext == NULL)
695 s->Sclass = SCglobal;
696 s->Sdt->dt = DT_common;
699 #if ELFOBJ // Burton
700 if (s->Sdt && s->Sdt->dt == DT_azeros && s->Sdt->DTnext == NULL)
701 s->Sseg = UDATA;
702 else
703 s->Sseg = DATA;
704 #endif /* ELFOBJ */
705 outdata(s);
706 if (isExport())
707 obj_export(s,0);
710 #endif
712 /* ========================================================================= */
714 /* These decide if there's an instance for them already in std.typeinfo,
715 * because then the compiler doesn't need to build one.
718 int Type::builtinTypeInfo()
720 return 0;
723 int TypeBasic::builtinTypeInfo()
725 return mod ? 0 : 1;
728 int TypeDArray::builtinTypeInfo()
730 return !mod && next->isTypeBasic() != NULL && !next->mod;
733 /* ========================================================================= */
735 /***************************************
736 * Create a static array of TypeInfo references
737 * corresponding to an array of Expression's.
738 * Used to supply hidden _arguments[] value for variadic D functions.
741 Expression *createTypeInfoArray(Scope *sc, Expression *exps[], int dim)
743 #if 1
744 /* Get the corresponding TypeInfo_Tuple and
745 * point at its elements[].
748 /* Create the TypeTuple corresponding to the types of args[]
750 Arguments *args = new Arguments;
751 args->setDim(dim);
752 for (size_t i = 0; i < dim; i++)
753 { Argument *arg = new Argument(STCin, exps[i]->type, NULL, NULL);
754 args->data[i] = (void *)arg;
756 TypeTuple *tup = new TypeTuple(args);
757 Expression *e = tup->getTypeInfo(sc);
758 e = e->optimize(WANTvalue);
759 assert(e->op == TOKsymoff); // should be SymOffExp
761 #if BREAKABI
763 * Should just pass a reference to TypeInfo_Tuple instead,
764 * but that would require existing code to be recompiled.
765 * Source compatibility can be maintained by computing _arguments[]
766 * at the start of the called function by offseting into the
767 * TypeInfo_Tuple reference.
770 #else
771 // Advance to elements[] member of TypeInfo_Tuple
772 SymOffExp *se = (SymOffExp *)e;
773 se->offset += PTRSIZE + PTRSIZE;
775 // Set type to TypeInfo[]*
776 se->type = Type::typeinfo->type->arrayOf()->pointerTo();
778 // Indirect to get the _arguments[] value
779 e = new PtrExp(0, se);
780 e->type = se->type->next;
781 #endif
782 return e;
783 #else
784 /* Improvements:
785 * 1) create an array literal instead,
786 * as it would eliminate the extra dereference of loading the
787 * static variable.
790 ArrayInitializer *ai = new ArrayInitializer(0);
791 VarDeclaration *v;
792 Type *t;
793 Expression *e;
794 OutBuffer buf;
795 Identifier *id;
796 char *name;
798 // Generate identifier for _arguments[]
799 buf.writestring("_arguments_");
800 for (int i = 0; i < dim; i++)
801 { t = exps[i]->type;
802 t->toDecoBuffer(&buf);
804 buf.writeByte(0);
805 id = Lexer::idPool((char *)buf.data);
807 #ifdef IN_GCC
808 Module *m = d_gcc_get_output_module();
809 #else
810 Module *m = sc->module;
811 #endif
812 Dsymbol *s = m->symtab->lookup(id);
814 if (s && s->parent == m)
815 { // Use existing one
816 v = s->isVarDeclaration();
817 assert(v);
819 else
820 { // Generate new one
822 for (int i = 0; i < dim; i++)
823 { t = exps[i]->type;
824 e = t->getTypeInfo(sc);
825 ai->addInit(new IntegerExp(i), new ExpInitializer(0, e));
828 t = Type::typeinfo->type->arrayOf();
829 ai->type = t;
830 v = new VarDeclaration(0, t, id, ai);
831 m->members->push(v);
832 m->symtab->insert(v);
833 sc = sc->push();
834 sc->linkage = LINKc;
835 sc->stc = STCstatic | STCcomdat;
836 ai->semantic(sc, t);
837 v->semantic(sc);
838 v->parent = m;
839 sc = sc->pop();
841 e = new VarExp(0, v);
842 e = e->semantic(sc);
843 return e;
844 #endif