root/trunk/src/typinf.c

Revision 769, 25.4 kB (checked in by walter, 1 year ago)

belatedly merge in changes from changeset 717

  • Property svn:eol-style set to native
Line 
1 // Compiler implementation of the D programming language
2 // Copyright (c) 1999-2010 by Digital Mars
3 // All Rights Reserved
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.
9
10 #include <stdio.h>
11 #include <assert.h>
12
13 //#include "mem.h"
14
15 #include "mars.h"
16 #include "module.h"
17 #include "mtype.h"
18 #include "scope.h"
19 #include "init.h"
20 #include "expression.h"
21 #include "attrib.h"
22 #include "declaration.h"
23 #include "template.h"
24 #include "id.h"
25 #include "enum.h"
26 #include "import.h"
27 #include "aggregate.h"
28
29 #ifndef TARGET_NET
30 #include "rmem.h"
31 #include "cc.h"
32 #include "global.h"
33 #include "oper.h"
34 #include "code.h"
35 #include "type.h"
36 #include "dt.h"
37 #include "cgcv.h"
38 #include "outbuf.h"
39 #include "irstate.h"
40 #endif
41
42 extern Symbol *static_sym();
43
44 /*******************************************
45  * Get a canonicalized form of the TypeInfo for use with the internal
46  * runtime library routines. Canonicalized in that static arrays are
47  * represented as dynamic arrays, enums are represented by their
48  * underlying type, etc. This reduces the number of TypeInfo's needed,
49  * so we can use the custom internal ones more.
50  */
51
52 Expression *Type::getInternalTypeInfo(Scope *sc)
53 {   TypeInfoDeclaration *tid;
54     Expression *e;
55     Type *t;
56     static TypeInfoDeclaration *internalTI[TMAX];
57
58     //printf("Type::getInternalTypeInfo() %s\n", toChars());
59     t = toBasetype();
60     switch (t->ty)
61     {
62         case Tsarray:
63 #if 0
64             // convert to corresponding dynamic array type
65             t = t->nextOf()->mutableOf()->arrayOf();
66 #endif
67             break;
68
69         case Tclass:
70             if (((TypeClass *)t)->sym->isInterfaceDeclaration())
71                 break;
72             goto Linternal;
73
74         case Tarray:
75             // convert to corresponding dynamic array type
76             t = t->nextOf()->mutableOf()->arrayOf();
77             if (t->nextOf()->ty != Tclass)
78                 break;
79             goto Linternal;
80
81         case Tfunction:
82         case Tdelegate:
83         case Tpointer:
84         Linternal:
85             tid = internalTI[t->ty];
86             if (!tid)
87             {   tid = new TypeInfoDeclaration(t, 1);
88                 internalTI[t->ty] = tid;
89             }
90             e = new VarExp(0, tid);
91             e = e->addressOf(sc);
92             e->type = tid->type;        // do this so we don't get redundant dereference
93             return e;
94
95         default:
96             break;
97     }
98     //printf("\tcalling getTypeInfo() %s\n", t->toChars());
99     return t->getTypeInfo(sc);
100 }
101
102
103 /****************************************************
104  * Get the exact TypeInfo.
105  */
106
107 Expression *Type::getTypeInfo(Scope *sc)
108 {
109     //printf("Type::getTypeInfo() %p, %s\n", this, toChars());
110     if (!Type::typeinfo)
111     {
112         error(0, "TypeInfo not found. object.d may be incorrectly installed or corrupt, compile with -v switch");
113         fatal();
114     }
115
116     Type *t = merge2(); // do this since not all Type's are merge'd
117     if (!t->vtinfo)
118     {
119 #if DMDV2
120         if (t->isShared())      // does both 'shared' and 'shared const'
121             t->vtinfo = new TypeInfoSharedDeclaration(t);
122         else if (t->isConst())
123             t->vtinfo = new TypeInfoConstDeclaration(t);
124         else if (t->isImmutable())
125             t->vtinfo = new TypeInfoInvariantDeclaration(t);
126         else if (t->isWild())
127             t->vtinfo = new TypeInfoWildDeclaration(t);
128         else
129 #endif
130             t->vtinfo = t->getTypeInfoDeclaration();
131         assert(t->vtinfo);
132         vtinfo = t->vtinfo;
133
134         /* If this has a custom implementation in std/typeinfo, then
135          * do not generate a COMDAT for it.
136          */
137         if (!t->builtinTypeInfo())
138         {   // Generate COMDAT
139             if (sc)                     // if in semantic() pass
140             {   // Find module that will go all the way to an object file
141                 Module *m = sc->module->importedFrom;
142                 m->members->push(t->vtinfo);
143             }
144             else                        // if in obj generation pass
145             {
146                 t->vtinfo->toObjFile(global.params.multiobj);
147             }
148         }
149     }
150     if (!vtinfo)
151         vtinfo = t->vtinfo;     // Types aren't merged, but we can share the vtinfo's
152     Expression *e = new VarExp(0, t->vtinfo);
153     e = e->addressOf(sc);
154     e->type = t->vtinfo->type;          // do this so we don't get redundant dereference
155     return e;
156 }
157
158 TypeInfoDeclaration *Type::getTypeInfoDeclaration()
159 {
160     //printf("Type::getTypeInfoDeclaration() %s\n", toChars());
161     return new TypeInfoDeclaration(this, 0);
162 }
163
164 TypeInfoDeclaration *TypeTypedef::getTypeInfoDeclaration()
165 {
166     return new TypeInfoTypedefDeclaration(this);
167 }
168
169 TypeInfoDeclaration *TypePointer::getTypeInfoDeclaration()
170 {
171     return new TypeInfoPointerDeclaration(this);
172 }
173
174 TypeInfoDeclaration *TypeDArray::getTypeInfoDeclaration()
175 {
176     return new TypeInfoArrayDeclaration(this);
177 }
178
179 TypeInfoDeclaration *TypeSArray::getTypeInfoDeclaration()
180 {
181     return new TypeInfoStaticArrayDeclaration(this);
182 }
183
184 TypeInfoDeclaration *TypeAArray::getTypeInfoDeclaration()
185 {
186     return new TypeInfoAssociativeArrayDeclaration(this);
187 }
188
189 TypeInfoDeclaration *TypeStruct::getTypeInfoDeclaration()
190 {
191     return new TypeInfoStructDeclaration(this);
192 }
193
194 TypeInfoDeclaration *TypeClass::getTypeInfoDeclaration()
195 {
196     if (sym->isInterfaceDeclaration())
197         return new TypeInfoInterfaceDeclaration(this);
198     else
199         return new TypeInfoClassDeclaration(this);
200 }
201
202 TypeInfoDeclaration *TypeEnum::getTypeInfoDeclaration()
203 {
204     return new TypeInfoEnumDeclaration(this);
205 }
206
207 TypeInfoDeclaration *TypeFunction::getTypeInfoDeclaration()
208 {
209     return new TypeInfoFunctionDeclaration(this);
210 }
211
212 TypeInfoDeclaration *TypeDelegate::getTypeInfoDeclaration()
213 {
214     return new TypeInfoDelegateDeclaration(this);
215 }
216
217 TypeInfoDeclaration *TypeTuple::getTypeInfoDeclaration()
218 {
219     return new TypeInfoTupleDeclaration(this);
220 }
221
222 #ifndef TARGET_NET
223 /****************************************************
224  */
225
226 #if 1
227
228 void TypeInfoDeclaration::toDt(dt_t **pdt)
229 {
230     //printf("TypeInfoDeclaration::toDt() %s\n", toChars());
231     dtxoff(pdt, Type::typeinfo->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo
232     dtsize_t(pdt, 0);                        // monitor
233 }
234
235 #if DMDV2
236 void TypeInfoConstDeclaration::toDt(dt_t **pdt)
237 {
238     //printf("TypeInfoConstDeclaration::toDt() %s\n", toChars());
239     dtxoff(pdt, Type::typeinfoconst->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Const
240     dtsize_t(pdt, 0);                        // monitor
241     Type *tm = tinfo->mutableOf();
242     tm = tm->merge();
243     tm->getTypeInfo(NULL);
244     dtxoff(pdt, tm->vtinfo->toSymbol(), 0, TYnptr);
245 }
246
247 void TypeInfoInvariantDeclaration::toDt(dt_t **pdt)
248 {
249     //printf("TypeInfoInvariantDeclaration::toDt() %s\n", toChars());
250     dtxoff(pdt, Type::typeinfoinvariant->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Invariant
251     dtsize_t(pdt, 0);                        // monitor
252     Type *tm = tinfo->mutableOf();
253     tm = tm->merge();
254     tm->getTypeInfo(NULL);
255     dtxoff(pdt, tm->vtinfo->toSymbol(), 0, TYnptr);
256 }
257
258 void TypeInfoSharedDeclaration::toDt(dt_t **pdt)
259 {
260     //printf("TypeInfoSharedDeclaration::toDt() %s\n", toChars());
261     dtxoff(pdt, Type::typeinfoshared->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Shared
262     dtsize_t(pdt, 0);                        // monitor
263     Type *tm = tinfo->unSharedOf();
264     tm = tm->merge();
265     tm->getTypeInfo(NULL);
266     dtxoff(pdt, tm->vtinfo->toSymbol(), 0, TYnptr);
267 }
268
269 void TypeInfoWildDeclaration::toDt(dt_t **pdt)
270 {
271     //printf("TypeInfoWildDeclaration::toDt() %s\n", toChars());
272     dtxoff(pdt, Type::typeinfowild->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Wild
273     dtsize_t(pdt, 0);                        // monitor
274     Type *tm = tinfo->mutableOf();
275     tm = tm->merge();
276     tm->getTypeInfo(NULL);
277     dtxoff(pdt, tm->vtinfo->toSymbol(), 0, TYnptr);
278 }
279
280 #endif
281
282 void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
283 {
284     //printf("TypeInfoTypedefDeclaration::toDt() %s\n", toChars());
285
286     dtxoff(pdt, Type::typeinfotypedef->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Typedef
287     dtsize_t(pdt, 0);                        // monitor
288
289     assert(tinfo->ty == Ttypedef);
290
291     TypeTypedef *tc = (TypeTypedef *)tinfo;
292     TypedefDeclaration *sd = tc->sym;
293     //printf("basetype = %s\n", sd->basetype->toChars());
294
295     /* Put out:
296      *  TypeInfo base;
297      *  char[] name;
298      *  void[] m_init;
299      */
300
301     sd->basetype = sd->basetype->merge();
302     sd->basetype->getTypeInfo(NULL);            // generate vtinfo
303     assert(sd->basetype->vtinfo);
304     dtxoff(pdt, sd->basetype->vtinfo->toSymbol(), 0, TYnptr);   // TypeInfo for basetype
305
306     const char *name = sd->toPrettyChars();
307     size_t namelen = strlen(name);
308     dtsize_t(pdt, namelen);
309     dtabytes(pdt, TYnptr, 0, namelen + 1, name);
310
311     // void[] init;
312     if (tinfo->isZeroInit() || !sd->init)
313     {   // 0 initializer, or the same as the base type
314         dtsize_t(pdt, 0);        // init.length
315         dtsize_t(pdt, 0);        // init.ptr
316     }
317     else
318     {
319         dtsize_t(pdt, sd->type->size()); // init.length
320         dtxoff(pdt, sd->toInitializer(), 0, TYnptr);    // init.ptr
321     }
322 }
323
324 void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
325 {
326     //printf("TypeInfoEnumDeclaration::toDt()\n");
327     dtxoff(pdt, Type::typeinfoenum->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Enum
328     dtsize_t(pdt, 0);                        // monitor
329
330     assert(tinfo->ty == Tenum);
331
332     TypeEnum *tc = (TypeEnum *)tinfo;
333     EnumDeclaration *sd = tc->sym;
334
335     /* Put out:
336      *  TypeInfo base;
337      *  char[] name;
338      *  void[] m_init;
339      */
340
341     if (sd->memtype)
342     {   sd->memtype->getTypeInfo(NULL);
343         dtxoff(pdt, sd->memtype->vtinfo->toSymbol(), 0, TYnptr);        // TypeInfo for enum members
344     }
345     else
346         dtsize_t(pdt, 0);
347
348     const char *name = sd->toPrettyChars();
349     size_t namelen = strlen(name);
350     dtsize_t(pdt, namelen);
351     dtabytes(pdt, TYnptr, 0, namelen + 1, name);
352
353     // void[] init;
354     if (!sd->defaultval || tinfo->isZeroInit())
355     {   // 0 initializer, or the same as the base type
356         dtsize_t(pdt, 0);        // init.length
357         dtsize_t(pdt, 0);        // init.ptr
358     }
359     else
360     {
361         dtsize_t(pdt, sd->type->size()); // init.length
362         dtxoff(pdt, sd->toInitializer(), 0, TYnptr);    // init.ptr
363     }
364 }
365
366 void TypeInfoPointerDeclaration::toDt(dt_t **pdt)
367 {
368     //printf("TypeInfoPointerDeclaration::toDt()\n");
369     dtxoff(pdt, Type::typeinfopointer->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Pointer
370     dtsize_t(pdt, 0);                        // monitor
371
372     assert(tinfo->ty == Tpointer);
373
374     TypePointer *tc = (TypePointer *)tinfo;
375
376     tc->next->getTypeInfo(NULL);
377     dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for type being pointed to
378 }
379
380 void TypeInfoArrayDeclaration::toDt(dt_t **pdt)
381 {
382     //printf("TypeInfoArrayDeclaration::toDt()\n");
383     dtxoff(pdt, Type::typeinfoarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Array
384     dtsize_t(pdt, 0);                        // monitor
385
386     assert(tinfo->ty == Tarray);
387
388     TypeDArray *tc = (TypeDArray *)tinfo;
389
390     tc->next->getTypeInfo(NULL);
391     dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
392 }
393
394 void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
395 {
396     //printf("TypeInfoStaticArrayDeclaration::toDt()\n");
397     dtxoff(pdt, Type::typeinfostaticarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_StaticArray
398     dtsize_t(pdt, 0);                        // monitor
399
400     assert(tinfo->ty == Tsarray);
401
402     TypeSArray *tc = (TypeSArray *)tinfo;
403
404     tc->next->getTypeInfo(NULL);
405     dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
406
407     dtsize_t(pdt, tc->dim->toInteger());         // length
408 }
409
410 void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
411 {
412     //printf("TypeInfoAssociativeArrayDeclaration::toDt()\n");
413     dtxoff(pdt, Type::typeinfoassociativearray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_AssociativeArray
414     dtsize_t(pdt, 0);                        // monitor
415
416     assert(tinfo->ty == Taarray);
417
418     TypeAArray *tc = (TypeAArray *)tinfo;
419
420     tc->next->getTypeInfo(NULL);
421     dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
422
423     tc->index->getTypeInfo(NULL);
424     dtxoff(pdt, tc->index->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
425
426 #if DMDV2
427     tc->getImpl()->type->getTypeInfo(NULL);
428     dtxoff(pdt, tc->getImpl()->type->vtinfo->toSymbol(), 0, TYnptr);    // impl
429 #endif
430 }
431
432 void TypeInfoFunctionDeclaration::toDt(dt_t **pdt)
433 {
434     //printf("TypeInfoFunctionDeclaration::toDt()\n");
435     dtxoff(pdt, Type::typeinfofunction->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Function
436     dtsize_t(pdt, 0);                        // monitor
437
438     assert(tinfo->ty == Tfunction);
439
440     TypeFunction *tc = (TypeFunction *)tinfo;
441
442     tc->next->getTypeInfo(NULL);
443     dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for function return value
444 }
445
446 void TypeInfoDelegateDeclaration::toDt(dt_t **pdt)
447 {
448     //printf("TypeInfoDelegateDeclaration::toDt()\n");
449     dtxoff(pdt, Type::typeinfodelegate->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Delegate
450     dtsize_t(pdt, 0);                        // monitor
451
452     assert(tinfo->ty == Tdelegate);
453
454     TypeDelegate *tc = (TypeDelegate *)tinfo;
455
456     tc->next->nextOf()->getTypeInfo(NULL);
457     dtxoff(pdt, tc->next->nextOf()->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for delegate return value
458 }
459
460 void TypeInfoStructDeclaration::toDt(dt_t **pdt)
461 {
462     //printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars());
463
464     unsigned offset = Type::typeinfostruct->structsize;
465
466     dtxoff(pdt, Type::typeinfostruct->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Struct
467     dtsize_t(pdt, 0);                        // monitor
468
469     assert(tinfo->ty == Tstruct);
470
471     TypeStruct *tc = (TypeStruct *)tinfo;
472     StructDeclaration *sd = tc->sym;
473
474     /* Put out:
475      *  char[] name;
476      *  void[] init;
477      *  hash_t function(in void*) xtoHash;
478      *  bool function(in void*, in void*) xopEquals;
479      *  int function(in void*, in void*) xopCmp;
480      *  string function(const(void)*) xtoString;
481      *  uint m_flags;
482      *  xgetMembers;
483      *  xdtor;
484      *  xpostblit;
485      *  uint m_align;
486      *  version (X86_64)
487      *      TypeInfo m_arg1;
488      *      TypeInfo m_arg2;
489      *
490      *  name[]
491      */
492
493     const char *name = sd->toPrettyChars();
494     size_t namelen = strlen(name);
495     dtsize_t(pdt, namelen);
496     //dtabytes(pdt, TYnptr, 0, namelen + 1, name);
497     dtxoff(pdt, toSymbol(), offset, TYnptr);
498     offset += namelen + 1;
499
500     // void[] init;
501     dtsize_t(pdt, sd->structsize);       // init.length
502     if (sd->zeroInit)
503         dtsize_t(pdt, 0);                // NULL for 0 initialization
504     else
505         dtxoff(pdt, sd->toInitializer(), 0, TYnptr);    // init.ptr
506
507     FuncDeclaration *fd;
508     FuncDeclaration *fdx;
509     TypeFunction *tf;
510     Type *ta;
511     Dsymbol *s;
512
513     static TypeFunction *tftohash;
514     static TypeFunction *tftostring;
515
516     if (!tftohash)
517     {
518         Scope sc;
519
520         tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd);
521         tftohash->mod = MODconst;
522         tftohash = (TypeFunction *)tftohash->semantic(0, &sc);
523
524         tftostring = new TypeFunction(NULL, Type::tchar->invariantOf()->arrayOf(), 0, LINKd);
525         tftostring = (TypeFunction *)tftostring->semantic(0, &sc);
526     }
527
528     TypeFunction *tfcmpptr;
529     {
530         Scope sc;
531         Parameters *arguments = new Parameters;
532 #if STRUCTTHISREF
533         // arg type is ref const T
534         Parameter *arg = new Parameter(STCref, tc->constOf(), NULL, NULL);
535 #else
536         // arg type is const T*
537         Parameter *arg = new Parameter(STCin, tc->pointerTo(), NULL, NULL);
538 #endif
539
540         arguments->push(arg);
541         tfcmpptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
542         tfcmpptr->mod = MODconst;
543         tfcmpptr = (TypeFunction *)tfcmpptr->semantic(0, &sc);
544     }
545
546     s = search_function(sd, Id::tohash);
547     fdx = s ? s->isFuncDeclaration() : NULL;
548     if (fdx)
549     {   fd = fdx->overloadExactMatch(tftohash);
550         if (fd)
551             dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
552         else
553             //fdx->error("must be declared as extern (D) uint toHash()");
554             dtsize_t(pdt, 0);
555     }
556     else
557         dtsize_t(pdt, 0);
558
559     if (sd->eq)
560         dtxoff(pdt, sd->eq->toSymbol(), 0, TYnptr);
561     else
562         dtsize_t(pdt, 0);
563
564     s = search_function(sd, Id::cmp);
565     fdx = s ? s->isFuncDeclaration() : NULL;
566     if (fdx)
567     {
568         //printf("test1 %s, %s, %s\n", fdx->toChars(), fdx->type->toChars(), tfeqptr->toChars());
569         fd = fdx->overloadExactMatch(tfcmpptr);
570         if (fd)
571         {   dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
572             //printf("test2\n");
573         }
574         else
575             //fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars());
576             dtsize_t(pdt, 0);
577     }
578     else
579         dtsize_t(pdt, 0);
580
581     s = search_function(sd, Id::tostring);
582     fdx = s ? s->isFuncDeclaration() : NULL;
583     if (fdx)
584     {   fd = fdx->overloadExactMatch(tftostring);
585         if (fd)
586             dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
587         else
588             //fdx->error("must be declared as extern (D) char[] toString()");
589             dtsize_t(pdt, 0);
590     }
591     else
592         dtsize_t(pdt, 0);
593
594     // uint m_flags;
595     dtsize_t(pdt, tc->hasPointers());
596
597 #if DMDV2
598     // xgetMembers
599     FuncDeclaration *sgetmembers = sd->findGetMembers();
600     if (sgetmembers)
601         dtxoff(pdt, sgetmembers->toSymbol(), 0, TYnptr);
602     else
603         dtsize_t(pdt, 0);                        // xgetMembers
604
605     // xdtor
606     FuncDeclaration *sdtor = sd->dtor;
607     if (sdtor)
608         dtxoff(pdt, sdtor->toSymbol(), 0, TYnptr);
609     else
610         dtsize_t(pdt, 0);                        // xdtor
611
612     // xpostblit
613     FuncDeclaration *spostblit = sd->postblit;
614     if (spostblit)
615         dtxoff(pdt, spostblit->toSymbol(), 0, TYnptr);
616     else
617         dtsize_t(pdt, 0);                        // xpostblit
618 #endif
619
620     // uint m_align;
621     dtsize_t(pdt, tc->alignsize());
622
623     if (global.params.isX86_64)
624     {
625         TypeTuple *tup = tc->toArgTypes();
626         assert(tup->arguments->dim <= 2);
627         for (int i = 0; i < 2; i++)
628         {
629             if (i < tup->arguments->dim)
630             {
631                 Type *targ = ((Parameter *)tup->arguments->data[i])->type;
632                 targ = targ->merge();
633                 targ->getTypeInfo(NULL);
634                 dtxoff(pdt, targ->vtinfo->toSymbol(), 0, TYnptr);       // m_argi
635             }
636             else
637                 dtsize_t(pdt, 0);                    // m_argi
638         }
639     }
640
641     // name[]
642     dtnbytes(pdt, namelen + 1, name);
643 }
644
645 void TypeInfoClassDeclaration::toDt(dt_t **pdt)
646 {
647     //printf("TypeInfoClassDeclaration::toDt() %s\n", tinfo->toChars());
648 #if DMDV1
649     dtxoff(pdt, Type::typeinfoclass->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoClass
650     dtsize_t(pdt, 0);                        // monitor
651
652     assert(tinfo->ty == Tclass);
653
654     TypeClass *tc = (TypeClass *)tinfo;
655     Symbol *s;
656
657     if (!tc->sym->vclassinfo)
658         tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym);
659     s = tc->sym->vclassinfo->toSymbol();
660     dtxoff(pdt, s, 0, TYnptr);          // ClassInfo for tinfo
661 #else
662     assert(0);
663 #endif
664 }
665
666 void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
667 {
668     //printf("TypeInfoInterfaceDeclaration::toDt() %s\n", tinfo->toChars());
669     dtxoff(pdt, Type::typeinfointerface->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
670     dtsize_t(pdt, 0);                        // monitor
671
672     assert(tinfo->ty == Tclass);
673
674     TypeClass *tc = (TypeClass *)tinfo;
675     Symbol *s;
676
677     if (!tc->sym->vclassinfo)
678 #if DMDV1
679         tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym);
680 #else
681         tc->sym->vclassinfo = new TypeInfoClassDeclaration(tc);
682 #endif
683     s = tc->sym->vclassinfo->toSymbol();
684     dtxoff(pdt, s, 0, TYnptr);          // ClassInfo for tinfo
685 }
686
687 void TypeInfoTupleDeclaration::toDt(dt_t **pdt)
688 {
689     //printf("TypeInfoTupleDeclaration::toDt() %s\n", tinfo->toChars());
690     dtxoff(pdt, Type::typeinfotypelist->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
691     dtsize_t(pdt, 0);                        // monitor
692
693     assert(tinfo->ty == Ttuple);
694
695     TypeTuple *tu = (TypeTuple *)tinfo;
696
697     size_t dim = tu->arguments->dim;
698     dtsize_t(pdt, dim);                      // elements.length
699
700     dt_t *d = NULL;
701     for (size_t i = 0; i < dim; i++)
702     {   Parameter *arg = (Parameter *)tu->arguments->data[i];
703         Expression *e = arg->type->getTypeInfo(NULL);
704         e = e->optimize(WANTvalue);
705         e->toDt(&d);
706     }
707
708     Symbol *s;
709     s = static_sym();
710     s->Sdt = d;
711     outdata(s);
712
713     dtxoff(pdt, s, 0, TYnptr);              // elements.ptr
714 }
715
716 void TypeInfoDeclaration::toObjFile(int multiobj)
717 {
718     Symbol *s;
719     unsigned sz;
720     Dsymbol *parent;
721
722     //printf("TypeInfoDeclaration::toObjFile(%p '%s') protection %d\n", this, toChars(), protection);
723
724     if (multiobj)
725     {
726         obj_append(this);
727         return;
728     }
729
730     s = toSymbol();
731     sz = type->size();
732
733     parent = this->toParent();
734     s->Sclass = SCcomdat;
735     s->Sfl = FLdata;
736
737     toDt(&s->Sdt);
738
739     dt_optimize(s->Sdt);
740
741     // See if we can convert a comdat to a comdef,
742     // which saves on exe file space.
743     if (s->Sclass == SCcomdat &&
744         s->Sdt->dt == DT_azeros &&
745         s->Sdt->DTnext == NULL)
746     {
747         s->Sclass = SCglobal;
748         s->Sdt->dt = DT_common;
749     }
750
751 #if ELFOBJ || MACHOBJ // Burton
752     if (s->Sdt && s->Sdt->dt == DT_azeros && s->Sdt->DTnext == NULL)
753         s->Sseg = UDATA;
754     else
755         s->Sseg = DATA;
756 #endif
757     outdata(s);
758     if (isExport())
759         obj_export(s,0);
760 }
761
762 #endif
763 #endif // TARGET_NET
764
765 /* ========================================================================= */
766
767 /* These decide if there's an instance for them already in std.typeinfo,
768  * because then the compiler doesn't need to build one.
769  */
770
771 int Type::builtinTypeInfo()
772 {
773     return 0;
774 }
775
776 int TypeBasic::builtinTypeInfo()
777 {
778 #if DMDV2
779     return mod ? 0 : 1;
780 #else
781     return 1;
782 #endif
783 }
784
785 int TypeDArray::builtinTypeInfo()
786 {
787 #if DMDV2
788     return !mod && (next->isTypeBasic() != NULL && !next->mod ||
789         // strings are so common, make them builtin
790         next->ty == Tchar && next->mod == MODimmutable);
791 #else
792     return next->isTypeBasic() != NULL;
793 #endif
794 }
795
796 int TypeClass::builtinTypeInfo()
797 {
798     /* This is statically put out with the ClassInfo, so
799      * claim it is built in so it isn't regenerated by each module.
800      */
801 #if DMDV2
802     return mod ? 0 : 1;
803 #else
804     return 1;
805 #endif
806 }
807
808 /* ========================================================================= */
809
810 /***************************************
811  * Create a static array of TypeInfo references
812  * corresponding to an array of Expression's.
813  * Used to supply hidden _arguments[] value for variadic D functions.
814  */
815
816 Expression *createTypeInfoArray(Scope *sc, Expression *exps[], int dim)
817 {
818 #if 1
819     /* Get the corresponding TypeInfo_Tuple and
820      * point at its elements[].
821      */
822
823     /* Create the TypeTuple corresponding to the types of args[]
824      */
825     Parameters *args = new Parameters;
826     args->setDim(dim);
827     for (size_t i = 0; i < dim; i++)
828     {   Parameter *arg = new Parameter(STCin, exps[i]->type, NULL, NULL);
829         args->data[i] = (void *)arg;
830     }
831     TypeTuple *tup = new TypeTuple(args);
832     Expression *e = tup->getTypeInfo(sc);
833     e = e->optimize(WANTvalue);
834     assert(e->op == TOKsymoff);         // should be SymOffExp
835
836 #if BREAKABI
837     /*
838      * Should just pass a reference to TypeInfo_Tuple instead,
839      * but that would require existing code to be recompiled.
840      * Source compatibility can be maintained by computing _arguments[]
841      * at the start of the called function by offseting into the
842      * TypeInfo_Tuple reference.
843      */
844
845 #else
846     // Advance to elements[] member of TypeInfo_Tuple
847     SymOffExp *se = (SymOffExp *)e;
848     se->offset += PTRSIZE + PTRSIZE;
849
850     // Set type to TypeInfo[]*
851     se->type = Type::typeinfo->type->arrayOf()->pointerTo();
852
853     // Indirect to get the _arguments[] value
854     e = new PtrExp(0, se);
855     e->type = se->type->next;
856 #endif
857     return e;
858 #else
859     /* Improvements:
860      * 1) create an array literal instead,
861      * as it would eliminate the extra dereference of loading the
862      * static variable.
863      */
864
865     ArrayInitializer *ai = new ArrayInitializer(0);
866     VarDeclaration *v;
867     Type *t;
868     Expression *e;
869     OutBuffer buf;
870     Identifier *id;
871     char *name;
872
873     // Generate identifier for _arguments[]
874     buf.writestring("_arguments_");
875     for (int i = 0; i < dim; i++)
876     {   t = exps[i]->type;
877         t->toDecoBuffer(&buf);
878     }
879     buf.writeByte(0);
880     id = Lexer::idPool((char *)buf.data);
881
882     Module *m = sc->module;
883     Dsymbol *s = m->symtab->lookup(id);
884
885     if (s && s->parent == m)
886     {   // Use existing one
887         v = s->isVarDeclaration();
888         assert(v);
889     }
890     else
891     {   // Generate new one
892
893         for (int i = 0; i < dim; i++)
894         {   t = exps[i]->type;
895             e = t->getTypeInfo(sc);
896             ai->addInit(new IntegerExp(i), new ExpInitializer(0, e));
897         }
898
899         t = Type::typeinfo->type->arrayOf();
900         ai->type = t;
901         v = new VarDeclaration(0, t, id, ai);
902         m->members->push(v);
903         m->symtabInsert(v);
904         sc = sc->push();
905         sc->linkage = LINKc;
906         sc->stc = STCstatic | STCcomdat;
907         ai->semantic(sc, t);
908         v->semantic(sc);
909         v->parent = m;
910         sc = sc->pop();
911     }
912     e = new VarExp(0, v);
913     e = e->semantic(sc);
914     return e;
915 #endif
916 }
Note: See TracBrowser for help on using the browser.