Mercurial > projects > ldc
annotate gen/typinf.c @ 52:0c77619e803b trunk
[svn r56] Initial support for TypeInfo.
Enums not work.
Several other bugfixes.
author | lindquist |
---|---|
date | Tue, 23 Oct 2007 05:55:12 +0200 |
parents | e116aa1488e6 |
children | 28e99b04a132 |
rev | line source |
---|---|
1 | 1 |
2 | |
3 // Copyright (c) 1999-2004 by Digital Mars | |
4 // All Rights Reserved | |
5 // written by Walter Bright | |
6 // 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. | |
10 | |
11 #include <cstdio> | |
12 #include <cassert> | |
13 | |
52 | 14 #include "gen/llvm.h" |
15 | |
1 | 16 #include "mars.h" |
17 #include "module.h" | |
18 #include "mtype.h" | |
19 #include "scope.h" | |
20 #include "init.h" | |
21 #include "expression.h" | |
22 #include "attrib.h" | |
23 #include "declaration.h" | |
24 #include "template.h" | |
25 #include "id.h" | |
26 #include "enum.h" | |
27 #include "import.h" | |
28 #include "aggregate.h" | |
29 | |
52 | 30 #include "gen/irstate.h" |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
31 #include "gen/logger.h" |
52 | 32 #include "gen/runtime.h" |
1 | 33 |
34 /******************************************* | |
35 * Get a canonicalized form of the TypeInfo for use with the internal | |
36 * runtime library routines. Canonicalized in that static arrays are | |
37 * represented as dynamic arrays, enums are represented by their | |
38 * underlying type, etc. This reduces the number of TypeInfo's needed, | |
39 * so we can use the custom internal ones more. | |
40 */ | |
41 | |
42 Expression *Type::getInternalTypeInfo(Scope *sc) | |
43 { TypeInfoDeclaration *tid; | |
44 Expression *e; | |
45 Type *t; | |
46 static TypeInfoDeclaration *internalTI[TMAX]; | |
47 | |
48 //printf("Type::getInternalTypeInfo() %s\n", toChars()); | |
49 t = toBasetype(); | |
50 switch (t->ty) | |
51 { | |
52 case Tsarray: | |
53 t = t->next->arrayOf(); // convert to corresponding dynamic array type | |
54 break; | |
55 | |
56 case Tclass: | |
57 if (((TypeClass *)t)->sym->isInterfaceDeclaration()) | |
58 break; | |
59 goto Linternal; | |
60 | |
61 case Tarray: | |
62 if (t->next->ty != Tclass) | |
63 break; | |
64 goto Linternal; | |
65 | |
66 case Tfunction: | |
67 case Tdelegate: | |
68 case Tpointer: | |
69 Linternal: | |
70 tid = internalTI[t->ty]; | |
71 if (!tid) | |
72 { tid = new TypeInfoDeclaration(t, 1); | |
73 internalTI[t->ty] = tid; | |
74 } | |
75 e = new VarExp(0, tid); | |
52 | 76 //e = e->addressOf(sc); |
1 | 77 e->type = tid->type; // do this so we don't get redundant dereference |
78 return e; | |
79 | |
80 default: | |
81 break; | |
82 } | |
83 //printf("\tcalling getTypeInfo() %s\n", t->toChars()); | |
84 return t->getTypeInfo(sc); | |
85 } | |
86 | |
87 | |
88 /**************************************************** | |
89 * Get the exact TypeInfo. | |
90 */ | |
91 | |
92 Expression *Type::getTypeInfo(Scope *sc) | |
93 { | |
94 Expression *e; | |
95 Type *t; | |
96 | |
97 //printf("Type::getTypeInfo() %p, %s\n", this, toChars()); | |
98 t = merge(); // do this since not all Type's are merge'd | |
99 if (!t->vtinfo) | |
100 { t->vtinfo = t->getTypeInfoDeclaration(); | |
101 assert(t->vtinfo); | |
102 | |
103 /* If this has a custom implementation in std/typeinfo, then | |
104 * do not generate a COMDAT for it. | |
105 */ | |
106 if (!t->builtinTypeInfo()) | |
107 { // Generate COMDAT | |
108 if (sc) // if in semantic() pass | |
109 { // Find module that will go all the way to an object file | |
110 Module *m = sc->module->importedFrom; | |
111 m->members->push(t->vtinfo); | |
112 } | |
113 else // if in obj generation pass | |
114 { | |
115 t->vtinfo->toObjFile(); | |
116 } | |
117 } | |
118 } | |
119 e = new VarExp(0, t->vtinfo); | |
120 //e = e->addressOf(sc); | |
121 e->type = t->vtinfo->type; // do this so we don't get redundant dereference | |
122 return e; | |
123 } | |
124 | |
52 | 125 enum RET TypeFunction::retStyle() |
126 { | |
127 return RETstack; | |
128 } | |
1 | 129 |
130 TypeInfoDeclaration *Type::getTypeInfoDeclaration() | |
131 { | |
132 //printf("Type::getTypeInfoDeclaration() %s\n", toChars()); | |
133 return new TypeInfoDeclaration(this, 0); | |
134 } | |
135 | |
52 | 136 TypeInfoDeclaration *TypeTypedef::getTypeInfoDeclaration() |
1 | 137 { |
52 | 138 return new TypeInfoTypedefDeclaration(this); |
1 | 139 } |
140 | |
52 | 141 TypeInfoDeclaration *TypePointer::getTypeInfoDeclaration() |
142 { | |
143 return new TypeInfoPointerDeclaration(this); | |
144 } | |
1 | 145 |
146 TypeInfoDeclaration *TypeDArray::getTypeInfoDeclaration() | |
147 { | |
148 return new TypeInfoArrayDeclaration(this); | |
149 } | |
150 | |
151 TypeInfoDeclaration *TypeSArray::getTypeInfoDeclaration() | |
152 { | |
153 return new TypeInfoStaticArrayDeclaration(this); | |
154 } | |
155 | |
156 TypeInfoDeclaration *TypeAArray::getTypeInfoDeclaration() | |
157 { | |
158 return new TypeInfoAssociativeArrayDeclaration(this); | |
159 } | |
160 | |
52 | 161 TypeInfoDeclaration *TypeStruct::getTypeInfoDeclaration() |
162 { | |
163 return new TypeInfoStructDeclaration(this); | |
164 } | |
1 | 165 |
166 TypeInfoDeclaration *TypeClass::getTypeInfoDeclaration() | |
167 { | |
168 if (sym->isInterfaceDeclaration()) | |
169 return new TypeInfoInterfaceDeclaration(this); | |
170 else | |
171 return new TypeInfoClassDeclaration(this); | |
172 } | |
173 | |
174 TypeInfoDeclaration *TypeEnum::getTypeInfoDeclaration() | |
175 { | |
176 return new TypeInfoEnumDeclaration(this); | |
177 } | |
178 | |
179 TypeInfoDeclaration *TypeFunction::getTypeInfoDeclaration() | |
180 { | |
181 return new TypeInfoFunctionDeclaration(this); | |
182 } | |
183 | |
184 TypeInfoDeclaration *TypeDelegate::getTypeInfoDeclaration() | |
185 { | |
186 return new TypeInfoDelegateDeclaration(this); | |
187 } | |
188 | |
189 TypeInfoDeclaration *TypeTuple::getTypeInfoDeclaration() | |
190 { | |
191 return new TypeInfoTupleDeclaration(this); | |
192 } | |
193 | |
194 | |
195 /* ========================================================================= */ | |
196 | |
197 /* These decide if there's an instance for them already in std.typeinfo, | |
198 * because then the compiler doesn't need to build one. | |
199 */ | |
200 | |
201 int Type::builtinTypeInfo() | |
202 { | |
203 return 0; | |
204 } | |
205 | |
206 int TypeBasic::builtinTypeInfo() | |
207 { | |
208 return 1; | |
209 } | |
210 | |
211 int TypeDArray::builtinTypeInfo() | |
212 { | |
52 | 213 return next->isTypeBasic() != NULL; |
1 | 214 } |
215 | |
216 /* ========================================================================= */ | |
217 | |
218 /*************************************** | |
219 * Create a static array of TypeInfo references | |
220 * corresponding to an array of Expression's. | |
221 * Used to supply hidden _arguments[] value for variadic D functions. | |
222 */ | |
223 | |
224 Expression *createTypeInfoArray(Scope *sc, Expression *args[], int dim) | |
225 { | |
226 assert(0); | |
227 return 0; | |
228 } | |
229 | |
52 | 230 /* ========================================================================= */ |
231 | |
232 ////////////////////////////////////////////////////////////////////////////// | |
233 // MAGIC PLACE | |
234 ////////////////////////////////////////////////////////////////////////////// | |
235 | |
236 void TypeInfoDeclaration::toObjFile() | |
237 { | |
238 Logger::println("TypeInfoDeclaration::toObjFile()"); | |
239 LOG_SCOPE; | |
240 Logger::println("type = '%s'", tinfo->toChars()); | |
241 | |
242 if (llvmTouched) return; | |
243 else llvmTouched = true; | |
244 | |
245 Logger::println("Getting typeinfo var: %s", mangle()); | |
246 llvmValue = LLVM_D_GetRuntimeGlobal(gIR->module, mangle()); | |
247 assert(llvmValue); | |
248 Logger::cout() << "Got:" << '\n' << *llvmValue << '\n'; | |
249 } | |
250 | |
251 /* ========================================================================= */ | |
252 | |
253 void TypeInfoDeclaration::toDt(dt_t **pdt) | |
254 { | |
255 assert(0 && "TypeInfoDeclaration"); | |
256 } | |
257 | |
258 void TypeInfoTypedefDeclaration::toDt(dt_t **pdt) | |
259 { | |
260 assert(0 && "TypeInfoTypedefDeclaration"); | |
261 } | |
262 | |
263 void TypeInfoEnumDeclaration::toDt(dt_t **pdt) | |
264 { | |
265 assert(0 && "TypeInfoEnumDeclaration"); | |
266 } | |
267 | |
268 void TypeInfoPointerDeclaration::toDt(dt_t **pdt) | |
269 { | |
270 assert(0 && "TypeInfoPointerDeclaration"); | |
271 } | |
272 | |
273 void TypeInfoArrayDeclaration::toDt(dt_t **pdt) | |
274 { | |
275 assert(0 && "TypeInfoArrayDeclaration"); | |
276 } | |
277 | |
278 void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt) | |
279 { | |
280 assert(0 && "TypeInfoStaticArrayDeclaration"); | |
281 } | |
282 | |
283 void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt) | |
284 { | |
285 assert(0 && "TypeInfoAssociativeArrayDeclaration"); | |
286 } | |
287 | |
288 void TypeInfoFunctionDeclaration::toDt(dt_t **pdt) | |
289 { | |
290 assert(0 && "TypeInfoFunctionDeclaration"); | |
291 } | |
292 | |
293 void TypeInfoDelegateDeclaration::toDt(dt_t **pdt) | |
294 { | |
295 assert(0 && "TypeInfoDelegateDeclaration"); | |
296 } | |
297 | |
298 void TypeInfoStructDeclaration::toDt(dt_t **pdt) | |
299 { | |
300 assert(0 && "TypeInfoStructDeclaration"); | |
301 } | |
302 | |
303 void TypeInfoClassDeclaration::toDt(dt_t **pdt) | |
304 { | |
305 assert(0 && "TypeInfoClassDeclaration"); | |
306 } | |
307 | |
308 void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt) | |
309 { | |
310 assert(0 && "TypeInfoInterfaceDeclaration"); | |
311 } | |
312 | |
313 void TypeInfoTupleDeclaration::toDt(dt_t **pdt) | |
314 { | |
315 assert(0 && "TypeInfoTupleDeclaration"); | |
316 } | |
317 | |
318 // original dmdfe toDt code for reference | |
319 | |
320 #if 0 | |
321 | |
322 void TypeInfoDeclaration::toDt(dt_t **pdt) | |
323 { | |
324 //printf("TypeInfoDeclaration::toDt() %s\n", toChars()); | |
325 dtxoff(pdt, Type::typeinfo->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo | |
326 dtdword(pdt, 0); // monitor | |
327 } | |
328 | |
329 void TypeInfoTypedefDeclaration::toDt(dt_t **pdt) | |
330 { | |
331 //printf("TypeInfoTypedefDeclaration::toDt() %s\n", toChars()); | |
332 | |
333 dtxoff(pdt, Type::typeinfotypedef->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Typedef | |
334 dtdword(pdt, 0); // monitor | |
335 | |
336 assert(tinfo->ty == Ttypedef); | |
337 | |
338 TypeTypedef *tc = (TypeTypedef *)tinfo; | |
339 TypedefDeclaration *sd = tc->sym; | |
340 //printf("basetype = %s\n", sd->basetype->toChars()); | |
341 | |
342 /* Put out: | |
343 * TypeInfo base; | |
344 * char[] name; | |
345 * void[] m_init; | |
346 */ | |
347 | |
348 sd->basetype = sd->basetype->merge(); | |
349 sd->basetype->getTypeInfo(NULL); // generate vtinfo | |
350 assert(sd->basetype->vtinfo); | |
351 dtxoff(pdt, sd->basetype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for basetype | |
352 | |
353 char *name = sd->toPrettyChars(); | |
354 size_t namelen = strlen(name); | |
355 dtdword(pdt, namelen); | |
356 dtabytes(pdt, TYnptr, 0, namelen + 1, name); | |
357 | |
358 // void[] init; | |
359 if (tinfo->isZeroInit() || !sd->init) | |
360 { // 0 initializer, or the same as the base type | |
361 dtdword(pdt, 0); // init.length | |
362 dtdword(pdt, 0); // init.ptr | |
363 } | |
364 else | |
365 { | |
366 dtdword(pdt, sd->type->size()); // init.length | |
367 dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr | |
368 } | |
369 } | |
370 | |
371 void TypeInfoEnumDeclaration::toDt(dt_t **pdt) | |
372 { | |
373 //printf("TypeInfoEnumDeclaration::toDt()\n"); | |
374 dtxoff(pdt, Type::typeinfoenum->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Enum | |
375 dtdword(pdt, 0); // monitor | |
376 | |
377 assert(tinfo->ty == Tenum); | |
378 | |
379 TypeEnum *tc = (TypeEnum *)tinfo; | |
380 EnumDeclaration *sd = tc->sym; | |
381 | |
382 /* Put out: | |
383 * TypeInfo base; | |
384 * char[] name; | |
385 * void[] m_init; | |
386 */ | |
387 | |
388 sd->memtype->getTypeInfo(NULL); | |
389 dtxoff(pdt, sd->memtype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for enum members | |
390 | |
391 char *name = sd->toPrettyChars(); | |
392 size_t namelen = strlen(name); | |
393 dtdword(pdt, namelen); | |
394 dtabytes(pdt, TYnptr, 0, namelen + 1, name); | |
395 | |
396 // void[] init; | |
397 if (tinfo->isZeroInit() || !sd->defaultval) | |
398 { // 0 initializer, or the same as the base type | |
399 dtdword(pdt, 0); // init.length | |
400 dtdword(pdt, 0); // init.ptr | |
401 } | |
402 else | |
403 { | |
404 dtdword(pdt, sd->type->size()); // init.length | |
405 dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr | |
406 } | |
407 } | |
408 | |
409 void TypeInfoPointerDeclaration::toDt(dt_t **pdt) | |
410 { | |
411 //printf("TypeInfoPointerDeclaration::toDt()\n"); | |
412 dtxoff(pdt, Type::typeinfopointer->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Pointer | |
413 dtdword(pdt, 0); // monitor | |
414 | |
415 assert(tinfo->ty == Tpointer); | |
416 | |
417 TypePointer *tc = (TypePointer *)tinfo; | |
418 | |
419 tc->next->getTypeInfo(NULL); | |
420 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for type being pointed to | |
421 } | |
422 | |
423 void TypeInfoArrayDeclaration::toDt(dt_t **pdt) | |
424 { | |
425 //printf("TypeInfoArrayDeclaration::toDt()\n"); | |
426 dtxoff(pdt, Type::typeinfoarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Array | |
427 dtdword(pdt, 0); // monitor | |
428 | |
429 assert(tinfo->ty == Tarray); | |
430 | |
431 TypeDArray *tc = (TypeDArray *)tinfo; | |
432 | |
433 tc->next->getTypeInfo(NULL); | |
434 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type | |
435 } | |
436 | |
437 void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt) | |
438 { | |
439 //printf("TypeInfoStaticArrayDeclaration::toDt()\n"); | |
440 dtxoff(pdt, Type::typeinfostaticarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_StaticArray | |
441 dtdword(pdt, 0); // monitor | |
442 | |
443 assert(tinfo->ty == Tsarray); | |
444 | |
445 TypeSArray *tc = (TypeSArray *)tinfo; | |
446 | |
447 tc->next->getTypeInfo(NULL); | |
448 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type | |
449 | |
450 dtdword(pdt, tc->dim->toInteger()); // length | |
451 } | |
452 | |
453 void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt) | |
454 { | |
455 //printf("TypeInfoAssociativeArrayDeclaration::toDt()\n"); | |
456 dtxoff(pdt, Type::typeinfoassociativearray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_AssociativeArray | |
457 dtdword(pdt, 0); // monitor | |
458 | |
459 assert(tinfo->ty == Taarray); | |
460 | |
461 TypeAArray *tc = (TypeAArray *)tinfo; | |
462 | |
463 tc->next->getTypeInfo(NULL); | |
464 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type | |
465 | |
466 tc->index->getTypeInfo(NULL); | |
467 dtxoff(pdt, tc->index->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type | |
468 } | |
469 | |
470 void TypeInfoFunctionDeclaration::toDt(dt_t **pdt) | |
471 { | |
472 //printf("TypeInfoFunctionDeclaration::toDt()\n"); | |
473 dtxoff(pdt, Type::typeinfofunction->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Function | |
474 dtdword(pdt, 0); // monitor | |
475 | |
476 assert(tinfo->ty == Tfunction); | |
477 | |
478 TypeFunction *tc = (TypeFunction *)tinfo; | |
479 | |
480 tc->next->getTypeInfo(NULL); | |
481 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for function return value | |
482 } | |
483 | |
484 void TypeInfoDelegateDeclaration::toDt(dt_t **pdt) | |
485 { | |
486 //printf("TypeInfoDelegateDeclaration::toDt()\n"); | |
487 dtxoff(pdt, Type::typeinfodelegate->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Delegate | |
488 dtdword(pdt, 0); // monitor | |
489 | |
490 assert(tinfo->ty == Tdelegate); | |
491 | |
492 TypeDelegate *tc = (TypeDelegate *)tinfo; | |
493 | |
494 tc->next->next->getTypeInfo(NULL); | |
495 dtxoff(pdt, tc->next->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for delegate return value | |
496 } | |
497 | |
498 void TypeInfoStructDeclaration::toDt(dt_t **pdt) | |
499 { | |
500 //printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars()); | |
501 | |
502 unsigned offset = Type::typeinfostruct->structsize; | |
503 | |
504 dtxoff(pdt, Type::typeinfostruct->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Struct | |
505 dtdword(pdt, 0); // monitor | |
506 | |
507 assert(tinfo->ty == Tstruct); | |
508 | |
509 TypeStruct *tc = (TypeStruct *)tinfo; | |
510 StructDeclaration *sd = tc->sym; | |
511 | |
512 /* Put out: | |
513 * char[] name; | |
514 * void[] init; | |
515 * hash_t function(void*) xtoHash; | |
516 * int function(void*,void*) xopEquals; | |
517 * int function(void*,void*) xopCmp; | |
518 * char[] function(void*) xtoString; | |
519 * uint m_flags; | |
520 * | |
521 * name[] | |
522 */ | |
523 | |
524 char *name = sd->toPrettyChars(); | |
525 size_t namelen = strlen(name); | |
526 dtdword(pdt, namelen); | |
527 //dtabytes(pdt, TYnptr, 0, namelen + 1, name); | |
528 dtxoff(pdt, toSymbol(), offset, TYnptr); | |
529 offset += namelen + 1; | |
530 | |
531 // void[] init; | |
532 dtdword(pdt, sd->structsize); // init.length | |
533 if (sd->zeroInit) | |
534 dtdword(pdt, 0); // NULL for 0 initialization | |
535 else | |
536 dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr | |
537 | |
538 FuncDeclaration *fd; | |
539 FuncDeclaration *fdx; | |
540 TypeFunction *tf; | |
541 Type *ta; | |
542 Dsymbol *s; | |
543 | |
544 static TypeFunction *tftohash; | |
545 static TypeFunction *tftostring; | |
546 | |
547 if (!tftohash) | |
548 { | |
549 Scope sc; | |
550 | |
551 tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd); | |
552 tftohash = (TypeFunction *)tftohash->semantic(0, &sc); | |
553 | |
554 tftostring = new TypeFunction(NULL, Type::tchar->arrayOf(), 0, LINKd); | |
555 tftostring = (TypeFunction *)tftostring->semantic(0, &sc); | |
556 } | |
557 | |
558 TypeFunction *tfeqptr; | |
559 { | |
560 Scope sc; | |
561 Arguments *arguments = new Arguments; | |
562 Argument *arg = new Argument(STCin, tc->pointerTo(), NULL, NULL); | |
563 | |
564 arguments->push(arg); | |
565 tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd); | |
566 tfeqptr = (TypeFunction *)tfeqptr->semantic(0, &sc); | |
567 } | |
568 | |
569 #if 0 | |
570 TypeFunction *tfeq; | |
571 { | |
572 Scope sc; | |
573 Array *arguments = new Array; | |
574 Argument *arg = new Argument(In, tc, NULL, NULL); | |
575 | |
576 arguments->push(arg); | |
577 tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd); | |
578 tfeq = (TypeFunction *)tfeq->semantic(0, &sc); | |
579 } | |
580 #endif | |
581 | |
582 s = search_function(sd, Id::tohash); | |
583 fdx = s ? s->isFuncDeclaration() : NULL; | |
584 if (fdx) | |
585 { fd = fdx->overloadExactMatch(tftohash); | |
586 if (fd) | |
587 dtxoff(pdt, fd->toSymbol(), 0, TYnptr); | |
588 else | |
589 //fdx->error("must be declared as extern (D) uint toHash()"); | |
590 dtdword(pdt, 0); | |
591 } | |
592 else | |
593 dtdword(pdt, 0); | |
594 | |
595 s = search_function(sd, Id::eq); | |
596 fdx = s ? s->isFuncDeclaration() : NULL; | |
597 for (int i = 0; i < 2; i++) | |
598 { | |
599 if (fdx) | |
600 { fd = fdx->overloadExactMatch(tfeqptr); | |
601 if (fd) | |
602 dtxoff(pdt, fd->toSymbol(), 0, TYnptr); | |
603 else | |
604 //fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars()); | |
605 dtdword(pdt, 0); | |
606 } | |
607 else | |
608 dtdword(pdt, 0); | |
609 | |
610 s = search_function(sd, Id::cmp); | |
611 fdx = s ? s->isFuncDeclaration() : NULL; | |
612 } | |
613 | |
614 s = search_function(sd, Id::tostring); | |
615 fdx = s ? s->isFuncDeclaration() : NULL; | |
616 if (fdx) | |
617 { fd = fdx->overloadExactMatch(tftostring); | |
618 if (fd) | |
619 dtxoff(pdt, fd->toSymbol(), 0, TYnptr); | |
620 else | |
621 //fdx->error("must be declared as extern (D) char[] toString()"); | |
622 dtdword(pdt, 0); | |
623 } | |
624 else | |
625 dtdword(pdt, 0); | |
626 | |
627 // uint m_flags; | |
628 dtdword(pdt, tc->hasPointers()); | |
629 | |
630 // name[] | |
631 dtnbytes(pdt, namelen + 1, name); | |
632 } | |
633 | |
634 void TypeInfoClassDeclaration::toDt(dt_t **pdt) | |
635 { | |
636 //printf("TypeInfoClassDeclaration::toDt() %s\n", tinfo->toChars()); | |
637 dtxoff(pdt, Type::typeinfoclass->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoClass | |
638 dtdword(pdt, 0); // monitor | |
639 | |
640 assert(tinfo->ty == Tclass); | |
641 | |
642 TypeClass *tc = (TypeClass *)tinfo; | |
643 Symbol *s; | |
644 | |
645 if (!tc->sym->vclassinfo) | |
646 tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym); | |
647 s = tc->sym->vclassinfo->toSymbol(); | |
648 dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo | |
649 } | |
650 | |
651 void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt) | |
652 { | |
653 //printf("TypeInfoInterfaceDeclaration::toDt() %s\n", tinfo->toChars()); | |
654 dtxoff(pdt, Type::typeinfointerface->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface | |
655 dtdword(pdt, 0); // monitor | |
656 | |
657 assert(tinfo->ty == Tclass); | |
658 | |
659 TypeClass *tc = (TypeClass *)tinfo; | |
660 Symbol *s; | |
661 | |
662 if (!tc->sym->vclassinfo) | |
663 tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym); | |
664 s = tc->sym->vclassinfo->toSymbol(); | |
665 dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo | |
666 } | |
667 | |
668 void TypeInfoTupleDeclaration::toDt(dt_t **pdt) | |
669 { | |
670 //printf("TypeInfoTupleDeclaration::toDt() %s\n", tinfo->toChars()); | |
671 dtxoff(pdt, Type::typeinfotypelist->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface | |
672 dtdword(pdt, 0); // monitor | |
673 | |
674 assert(tinfo->ty == Ttuple); | |
675 | |
676 TypeTuple *tu = (TypeTuple *)tinfo; | |
677 | |
678 size_t dim = tu->arguments->dim; | |
679 dtdword(pdt, dim); // elements.length | |
680 | |
681 dt_t *d = NULL; | |
682 for (size_t i = 0; i < dim; i++) | |
683 { Argument *arg = (Argument *)tu->arguments->data[i]; | |
684 Expression *e = arg->type->getTypeInfo(NULL); | |
685 e = e->optimize(WANTvalue); | |
686 e->toDt(&d); | |
687 } | |
688 | |
689 Symbol *s; | |
690 s = static_sym(); | |
691 s->Sdt = d; | |
692 outdata(s); | |
693 | |
694 dtxoff(pdt, s, 0, TYnptr); // elements.ptr | |
695 } | |
696 | |
697 void TypeInfoDeclaration::toObjFile() | |
698 { | |
699 Symbol *s; | |
700 unsigned sz; | |
701 Dsymbol *parent; | |
702 | |
703 //printf("TypeInfoDeclaration::toObjFile(%p '%s') protection %d\n", this, toChars(), protection); | |
704 | |
705 s = toSymbol(); | |
706 sz = type->size(); | |
707 | |
708 parent = this->toParent(); | |
709 s->Sclass = SCcomdat; | |
710 s->Sfl = FLdata; | |
711 | |
712 toDt(&s->Sdt); | |
713 | |
714 dt_optimize(s->Sdt); | |
715 | |
716 // See if we can convert a comdat to a comdef, | |
717 // which saves on exe file space. | |
718 if (s->Sclass == SCcomdat && | |
719 s->Sdt->dt == DT_azeros && | |
720 s->Sdt->DTnext == NULL) | |
721 { | |
722 s->Sclass = SCglobal; | |
723 s->Sdt->dt = DT_common; | |
724 } | |
725 | |
726 #if ELFOBJ // Burton | |
727 if (s->Sdt && s->Sdt->dt == DT_azeros && s->Sdt->DTnext == NULL) | |
728 s->Sseg = UDATA; | |
729 else | |
730 s->Sseg = DATA; | |
731 #endif /* ELFOBJ */ | |
732 outdata(s); | |
733 if (isExport()) | |
734 obj_export(s,0); | |
735 } | |
736 | |
737 #endif |