comparison gen/typinf.cpp @ 86:fd32135dca3e trunk

[svn r90] Major updates to the gen directory. Redesigned the 'elem' struct. Much more... !!! Lots of bugfixes. Added support for special foreach on strings. Added std.array, std.utf, std.ctype and std.uni to phobos. Changed all the .c files in the gen dir to .cpp (it *is* C++ after all)
author lindquist
date Sat, 03 Nov 2007 14:44:58 +0100
parents gen/typinf.c@3587401b6eeb
children ccca1c13e13a
comparison
equal deleted inserted replaced
85:f869c636a113 86:fd32135dca3e
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
14 #include "gen/llvm.h"
15
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
30 #include "gen/irstate.h"
31 #include "gen/logger.h"
32 #include "gen/runtime.h"
33 #include "gen/tollvm.h"
34 #include "gen/arrays.h"
35
36 /*******************************************
37 * Get a canonicalized form of the TypeInfo for use with the internal
38 * runtime library routines. Canonicalized in that static arrays are
39 * represented as dynamic arrays, enums are represented by their
40 * underlying type, etc. This reduces the number of TypeInfo's needed,
41 * so we can use the custom internal ones more.
42 */
43
44 Expression *Type::getInternalTypeInfo(Scope *sc)
45 { TypeInfoDeclaration *tid;
46 Expression *e;
47 Type *t;
48 static TypeInfoDeclaration *internalTI[TMAX];
49
50 //printf("Type::getInternalTypeInfo() %s\n", toChars());
51 t = toBasetype();
52 switch (t->ty)
53 {
54 case Tsarray:
55 t = t->next->arrayOf(); // convert to corresponding dynamic array type
56 break;
57
58 case Tclass:
59 if (((TypeClass *)t)->sym->isInterfaceDeclaration())
60 break;
61 goto Linternal;
62
63 case Tarray:
64 if (t->next->ty != Tclass)
65 break;
66 goto Linternal;
67
68 case Tfunction:
69 case Tdelegate:
70 case Tpointer:
71 Linternal:
72 tid = internalTI[t->ty];
73 if (!tid)
74 { tid = new TypeInfoDeclaration(t, 1);
75 internalTI[t->ty] = tid;
76 }
77 e = new VarExp(0, tid);
78 //e = e->addressOf(sc);
79 e->type = tid->type; // do this so we don't get redundant dereference
80 return e;
81
82 default:
83 break;
84 }
85 //printf("\tcalling getTypeInfo() %s\n", t->toChars());
86 return t->getTypeInfo(sc);
87 }
88
89
90 /****************************************************
91 * Get the exact TypeInfo.
92 */
93
94 Expression *Type::getTypeInfo(Scope *sc)
95 {
96 Expression *e;
97 Type *t;
98
99 //printf("Type::getTypeInfo() %p, %s\n", this, toChars());
100 t = merge(); // do this since not all Type's are merge'd
101 if (!t->vtinfo)
102 { t->vtinfo = t->getTypeInfoDeclaration();
103 assert(t->vtinfo);
104
105 /* If this has a custom implementation in std/typeinfo, then
106 * do not generate a COMDAT for it.
107 */
108 if (!t->builtinTypeInfo())
109 { // Generate COMDAT
110 if (sc) // if in semantic() pass
111 { // Find module that will go all the way to an object file
112 Module *m = sc->module->importedFrom;
113 m->members->push(t->vtinfo);
114 }
115 else // if in obj generation pass
116 {
117 t->vtinfo->toObjFile();
118 }
119 }
120 }
121 e = new VarExp(0, t->vtinfo);
122 //e = e->addressOf(sc);
123 e->type = t->vtinfo->type; // do this so we don't get redundant dereference
124 return e;
125 }
126
127 enum RET TypeFunction::retStyle()
128 {
129 return RETstack;
130 }
131
132 TypeInfoDeclaration *Type::getTypeInfoDeclaration()
133 {
134 //printf("Type::getTypeInfoDeclaration() %s\n", toChars());
135 return new TypeInfoDeclaration(this, 0);
136 }
137
138 TypeInfoDeclaration *TypeTypedef::getTypeInfoDeclaration()
139 {
140 return new TypeInfoTypedefDeclaration(this);
141 }
142
143 TypeInfoDeclaration *TypePointer::getTypeInfoDeclaration()
144 {
145 return new TypeInfoPointerDeclaration(this);
146 }
147
148 TypeInfoDeclaration *TypeDArray::getTypeInfoDeclaration()
149 {
150 return new TypeInfoArrayDeclaration(this);
151 }
152
153 TypeInfoDeclaration *TypeSArray::getTypeInfoDeclaration()
154 {
155 return new TypeInfoStaticArrayDeclaration(this);
156 }
157
158 TypeInfoDeclaration *TypeAArray::getTypeInfoDeclaration()
159 {
160 return new TypeInfoAssociativeArrayDeclaration(this);
161 }
162
163 TypeInfoDeclaration *TypeStruct::getTypeInfoDeclaration()
164 {
165 return new TypeInfoStructDeclaration(this);
166 }
167
168 TypeInfoDeclaration *TypeClass::getTypeInfoDeclaration()
169 {
170 if (sym->isInterfaceDeclaration())
171 return new TypeInfoInterfaceDeclaration(this);
172 else
173 return new TypeInfoClassDeclaration(this);
174 }
175
176 TypeInfoDeclaration *TypeEnum::getTypeInfoDeclaration()
177 {
178 return new TypeInfoEnumDeclaration(this);
179 }
180
181 TypeInfoDeclaration *TypeFunction::getTypeInfoDeclaration()
182 {
183 return new TypeInfoFunctionDeclaration(this);
184 }
185
186 TypeInfoDeclaration *TypeDelegate::getTypeInfoDeclaration()
187 {
188 return new TypeInfoDelegateDeclaration(this);
189 }
190
191 TypeInfoDeclaration *TypeTuple::getTypeInfoDeclaration()
192 {
193 return new TypeInfoTupleDeclaration(this);
194 }
195
196
197 /* ========================================================================= */
198
199 /* These decide if there's an instance for them already in std.typeinfo,
200 * because then the compiler doesn't need to build one.
201 */
202
203 int Type::builtinTypeInfo()
204 {
205 return 0;
206 }
207
208 int TypeBasic::builtinTypeInfo()
209 {
210 return 1;
211 }
212
213 int TypeDArray::builtinTypeInfo()
214 {
215 return next->isTypeBasic() != NULL;
216 }
217
218 /* ========================================================================= */
219
220 /***************************************
221 * Create a static array of TypeInfo references
222 * corresponding to an array of Expression's.
223 * Used to supply hidden _arguments[] value for variadic D functions.
224 */
225
226 Expression *createTypeInfoArray(Scope *sc, Expression *exps[], int dim)
227 {
228 assert(0);
229 return NULL;
230 }
231
232 /* ========================================================================= */
233
234 //////////////////////////////////////////////////////////////////////////////
235 // MAGIC PLACE
236 //////////////////////////////////////////////////////////////////////////////
237
238 void TypeInfoDeclaration::toObjFile()
239 {
240 if (llvmTouched) return;
241 else llvmTouched = true;
242
243 Logger::println("TypeInfoDeclaration::toObjFile()");
244 LOG_SCOPE;
245
246 Logger::println("type = '%s'", tinfo->toChars());
247 Logger::println("typeinfo mangle: %s", mangle());
248
249 // this is a declaration of a builtin __initZ var
250 if (tinfo->builtinTypeInfo()) {
251 llvmValue = LLVM_D_GetRuntimeGlobal(gIR->module, mangle());
252 assert(llvmValue);
253 Logger::cout() << "Got typeinfo var:" << '\n' << *llvmValue << '\n';
254 }
255 // custom typedef
256 else {
257 toDt(NULL);
258 }
259 }
260
261 /* ========================================================================= */
262
263 void TypeInfoDeclaration::toDt(dt_t **pdt)
264 {
265 assert(0 && "TypeInfoDeclaration");
266 }
267
268 /* ========================================================================= */
269
270 void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
271 {
272 Logger::println("TypeInfoTypedefDeclaration::toDt() %s", toChars());
273 LOG_SCOPE;
274
275 ClassDeclaration* base = Type::typeinfotypedef;
276 base->toObjFile();
277
278 llvm::Constant* initZ = base->llvmInitZ;
279 assert(initZ);
280 const llvm::StructType* stype = llvm::cast<llvm::StructType>(initZ->getType());
281
282 std::vector<llvm::Constant*> sinits;
283 sinits.push_back(initZ->getOperand(0));
284
285 assert(tinfo->ty == Ttypedef);
286 TypeTypedef *tc = (TypeTypedef *)tinfo;
287 TypedefDeclaration *sd = tc->sym;
288
289 // TypeInfo base
290 //const llvm::PointerType* basept = llvm::cast<llvm::PointerType>(initZ->getOperand(1)->getType());
291 //sinits.push_back(llvm::ConstantPointerNull::get(basept));
292 Logger::println("generating base typeinfo");
293 //sd->basetype = sd->basetype->merge();
294 sd->basetype->getTypeInfo(NULL); // generate vtinfo
295 assert(sd->basetype->vtinfo);
296 if (!sd->basetype->vtinfo->llvmValue)
297 sd->basetype->vtinfo->toObjFile();
298 assert(llvm::isa<llvm::Constant>(sd->basetype->vtinfo->llvmValue));
299 llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->basetype->vtinfo->llvmValue);
300 castbase = llvm::ConstantExpr::getBitCast(castbase, initZ->getOperand(1)->getType());
301 sinits.push_back(castbase);
302
303 // char[] name
304 char *name = sd->toPrettyChars();
305 sinits.push_back(DtoConstString(name));
306 assert(sinits.back()->getType() == initZ->getOperand(2)->getType());
307
308 // void[] init
309 const llvm::PointerType* initpt = llvm::PointerType::get(llvm::Type::Int8Ty);
310 if (tinfo->isZeroInit() || !sd->init) // 0 initializer, or the same as the base type
311 {
312 sinits.push_back(DtoConstSlice(DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt)));
313 }
314 else
315 {
316 llvm::Constant* ci = DtoConstInitializer(sd->basetype, sd->init);
317 std::string ciname(sd->mangle());
318 ciname.append("__init");
319 llvm::GlobalVariable* civar = new llvm::GlobalVariable(DtoType(sd->basetype),true,llvm::GlobalValue::InternalLinkage,ci,ciname,gIR->module);
320 llvm::Constant* cicast = llvm::ConstantExpr::getBitCast(civar, initpt);
321 size_t cisize = gTargetData->getTypeSize(DtoType(sd->basetype));
322 sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast));
323 }
324
325 // create the symbol
326 llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
327 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,tiInit,toChars(),gIR->module);
328
329 llvmValue = gvar;
330 }
331
332 /* ========================================================================= */
333
334 void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
335 {
336 Logger::println("TypeInfoTypedefDeclaration::toDt() %s", toChars());
337 LOG_SCOPE;
338
339 ClassDeclaration* base = Type::typeinfoenum;
340 base->toObjFile();
341
342 llvm::Constant* initZ = base->llvmInitZ;
343 assert(initZ);
344 const llvm::StructType* stype = llvm::cast<llvm::StructType>(initZ->getType());
345
346 std::vector<llvm::Constant*> sinits;
347 sinits.push_back(initZ->getOperand(0));
348
349 assert(tinfo->ty == Tenum);
350 TypeEnum *tc = (TypeEnum *)tinfo;
351 EnumDeclaration *sd = tc->sym;
352
353 // TypeInfo base
354 //const llvm::PointerType* basept = llvm::cast<llvm::PointerType>(initZ->getOperand(1)->getType());
355 //sinits.push_back(llvm::ConstantPointerNull::get(basept));
356 Logger::println("generating base typeinfo");
357 //sd->basetype = sd->basetype->merge();
358 sd->memtype->getTypeInfo(NULL); // generate vtinfo
359 assert(sd->memtype->vtinfo);
360 if (!sd->memtype->vtinfo->llvmValue)
361 sd->memtype->vtinfo->toObjFile();
362 assert(llvm::isa<llvm::Constant>(sd->memtype->vtinfo->llvmValue));
363 llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->memtype->vtinfo->llvmValue);
364 castbase = llvm::ConstantExpr::getBitCast(castbase, initZ->getOperand(1)->getType());
365 sinits.push_back(castbase);
366
367 // char[] name
368 char *name = sd->toPrettyChars();
369 sinits.push_back(DtoConstString(name));
370 assert(sinits.back()->getType() == initZ->getOperand(2)->getType());
371
372 // void[] init
373 const llvm::PointerType* initpt = llvm::PointerType::get(llvm::Type::Int8Ty);
374 if (tinfo->isZeroInit() || !sd->defaultval) // 0 initializer, or the same as the base type
375 {
376 sinits.push_back(DtoConstSlice(DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt)));
377 }
378 else
379 {
380 const llvm::Type* memty = DtoType(sd->memtype);
381 llvm::Constant* ci = llvm::ConstantInt::get(memty, sd->defaultval, !sd->memtype->isunsigned());
382 std::string ciname(sd->mangle());
383 ciname.append("__init");
384 llvm::GlobalVariable* civar = new llvm::GlobalVariable(memty,true,llvm::GlobalValue::InternalLinkage,ci,ciname,gIR->module);
385 llvm::Constant* cicast = llvm::ConstantExpr::getBitCast(civar, initpt);
386 size_t cisize = gTargetData->getTypeSize(memty);
387 sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast));
388 }
389
390 // create the symbol
391 llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
392 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,tiInit,toChars(),gIR->module);
393
394 llvmValue = gvar;
395 }
396
397 /* ========================================================================= */
398
399 static llvm::Constant* LLVM_D_Create_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid, ClassDeclaration* cd)
400 {
401 ClassDeclaration* base = cd;
402 base->toObjFile();
403
404 llvm::Constant* initZ = base->llvmInitZ;
405 assert(initZ);
406 const llvm::StructType* stype = llvm::cast<llvm::StructType>(initZ->getType());
407
408 std::vector<llvm::Constant*> sinits;
409 sinits.push_back(initZ->getOperand(0));
410
411 // TypeInfo base
412 Logger::println("generating base typeinfo");
413 basetype->getTypeInfo(NULL);
414 assert(basetype->vtinfo);
415 if (!basetype->vtinfo->llvmValue)
416 basetype->vtinfo->toObjFile();
417 assert(llvm::isa<llvm::Constant>(basetype->vtinfo->llvmValue));
418 llvm::Constant* castbase = llvm::cast<llvm::Constant>(basetype->vtinfo->llvmValue);
419 castbase = llvm::ConstantExpr::getBitCast(castbase, initZ->getOperand(1)->getType());
420 sinits.push_back(castbase);
421
422 // create the symbol
423 llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
424 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,tiInit,tid->toChars(),gIR->module);
425
426 tid->llvmValue = gvar;
427 }
428
429 /* ========================================================================= */
430
431 void TypeInfoPointerDeclaration::toDt(dt_t **pdt)
432 {
433 Logger::println("TypeInfoPointerDeclaration::toDt() %s", toChars());
434 LOG_SCOPE;
435
436 assert(tinfo->ty == Tpointer);
437 TypePointer *tc = (TypePointer *)tinfo;
438
439 LLVM_D_Create_TypeInfoBase(tc->next, this, Type::typeinfopointer);
440 }
441
442 /* ========================================================================= */
443
444 void TypeInfoArrayDeclaration::toDt(dt_t **pdt)
445 {
446 Logger::println("TypeInfoArrayDeclaration::toDt() %s", toChars());
447 LOG_SCOPE;
448
449 assert(tinfo->ty == Tarray);
450 TypeDArray *tc = (TypeDArray *)tinfo;
451
452 LLVM_D_Create_TypeInfoBase(tc->next, this, Type::typeinfoarray);
453 }
454
455 /* ========================================================================= */
456
457 void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
458 {
459 assert(0 && "TypeInfoStaticArrayDeclaration");
460
461 /*
462 //printf("TypeInfoStaticArrayDeclaration::toDt()\n");
463 dtxoff(pdt, Type::typeinfostaticarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_StaticArray
464 dtdword(pdt, 0); // monitor
465
466 assert(tinfo->ty == Tsarray);
467
468 TypeSArray *tc = (TypeSArray *)tinfo;
469
470 tc->next->getTypeInfo(NULL);
471 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
472
473 dtdword(pdt, tc->dim->toInteger()); // length
474 */
475 }
476
477 /* ========================================================================= */
478
479 void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
480 {
481 assert(0 && "TypeInfoAssociativeArrayDeclaration");
482
483 /*
484 //printf("TypeInfoAssociativeArrayDeclaration::toDt()\n");
485 dtxoff(pdt, Type::typeinfoassociativearray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_AssociativeArray
486 dtdword(pdt, 0); // monitor
487
488 assert(tinfo->ty == Taarray);
489
490 TypeAArray *tc = (TypeAArray *)tinfo;
491
492 tc->next->getTypeInfo(NULL);
493 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
494
495 tc->index->getTypeInfo(NULL);
496 dtxoff(pdt, tc->index->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
497 */
498 }
499
500 /* ========================================================================= */
501
502 void TypeInfoFunctionDeclaration::toDt(dt_t **pdt)
503 {
504 Logger::println("TypeInfoFunctionDeclaration::toDt() %s", toChars());
505 LOG_SCOPE;
506
507 assert(tinfo->ty == Tfunction);
508 TypeFunction *tc = (TypeFunction *)tinfo;
509
510 LLVM_D_Create_TypeInfoBase(tc->next, this, Type::typeinfofunction);
511 }
512
513 /* ========================================================================= */
514
515 void TypeInfoDelegateDeclaration::toDt(dt_t **pdt)
516 {
517 Logger::println("TypeInfoDelegateDeclaration::toDt() %s", toChars());
518 LOG_SCOPE;
519
520 assert(tinfo->ty == Tdelegate);
521 TypeDelegate *tc = (TypeDelegate *)tinfo;
522
523 LLVM_D_Create_TypeInfoBase(tc->next->next, this, Type::typeinfodelegate);
524 }
525
526 /* ========================================================================= */
527
528 void TypeInfoStructDeclaration::toDt(dt_t **pdt)
529 {
530 Logger::println("TypeInfoStructDeclaration::toDt() %s", toChars());
531 LOG_SCOPE;
532
533 assert(tinfo->ty == Tstruct);
534 TypeStruct *tc = (TypeStruct *)tinfo;
535 StructDeclaration *sd = tc->sym;
536
537 ClassDeclaration* base = Type::typeinfostruct;
538 base->toObjFile();
539
540 const llvm::StructType* stype = llvm::cast<llvm::StructType>(base->llvmType);
541
542 std::vector<llvm::Constant*> sinits;
543 sinits.push_back(base->llvmVtbl);
544
545 // char[] name
546 char *name = sd->toPrettyChars();
547 sinits.push_back(DtoConstString(name));
548 Logger::println("************** A");
549 assert(sinits.back()->getType() == stype->getElementType(1));
550
551 // void[] init
552 const llvm::PointerType* initpt = llvm::PointerType::get(llvm::Type::Int8Ty);
553 if (sd->zeroInit) // 0 initializer, or the same as the base type
554 {
555 sinits.push_back(DtoConstSlice(DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt)));
556 }
557 else
558 {
559 assert(sd->llvmInitZ);
560 size_t cisize = gTargetData->getTypeSize(tc->llvmType);
561 llvm::Constant* cicast = llvm::ConstantExpr::getBitCast(tc->llvmInit, initpt);
562 sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast));
563 }
564
565 // toX functions ground work
566 FuncDeclaration *fd;
567 FuncDeclaration *fdx;
568 TypeFunction *tf;
569 Type *ta;
570 Dsymbol *s;
571
572 static TypeFunction *tftohash;
573 static TypeFunction *tftostring;
574
575 if (!tftohash)
576 {
577 Scope sc;
578
579 tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd);
580 tftohash = (TypeFunction *)tftohash->semantic(0, &sc);
581
582 tftostring = new TypeFunction(NULL, Type::tchar->arrayOf(), 0, LINKd);
583 tftostring = (TypeFunction *)tftostring->semantic(0, &sc);
584 }
585
586 TypeFunction *tfeqptr;
587 {
588 Scope sc;
589 Arguments *arguments = new Arguments;
590 Argument *arg = new Argument(STCin, tc->pointerTo(), NULL, NULL);
591
592 arguments->push(arg);
593 tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
594 tfeqptr = (TypeFunction *)tfeqptr->semantic(0, &sc);
595 }
596
597 #if 0
598 TypeFunction *tfeq;
599 {
600 Scope sc;
601 Array *arguments = new Array;
602 Argument *arg = new Argument(In, tc, NULL, NULL);
603
604 arguments->push(arg);
605 tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd);
606 tfeq = (TypeFunction *)tfeq->semantic(0, &sc);
607 }
608 #endif
609
610 Logger::println("************** B");
611 const llvm::PointerType* ptty = llvm::cast<llvm::PointerType>(stype->getElementType(3));
612
613 s = search_function(sd, Id::tohash);
614 fdx = s ? s->isFuncDeclaration() : NULL;
615 if (fdx)
616 {
617 fd = fdx->overloadExactMatch(tftohash);
618 if (fd) {
619 assert(fd->llvmValue != 0);
620 llvm::Constant* c = llvm::cast_or_null<llvm::Constant>(fd->llvmValue);
621 assert(c);
622 c = llvm::ConstantExpr::getBitCast(c, ptty);
623 sinits.push_back(c);
624 }
625 else {
626 //fdx->error("must be declared as extern (D) uint toHash()");
627 sinits.push_back(llvm::ConstantPointerNull::get(ptty));
628 }
629 }
630 else {
631 sinits.push_back(llvm::ConstantPointerNull::get(ptty));
632 }
633
634 s = search_function(sd, Id::eq);
635 fdx = s ? s->isFuncDeclaration() : NULL;
636 for (int i = 0; i < 2; i++)
637 {
638 Logger::println("************** C %d", i);
639 ptty = llvm::cast<llvm::PointerType>(stype->getElementType(4+i));
640 if (fdx)
641 {
642 fd = fdx->overloadExactMatch(tfeqptr);
643 if (fd) {
644 assert(fd->llvmValue != 0);
645 llvm::Constant* c = llvm::cast_or_null<llvm::Constant>(fd->llvmValue);
646 assert(c);
647 c = llvm::ConstantExpr::getBitCast(c, ptty);
648 sinits.push_back(c);
649 }
650 else {
651 //fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars());
652 sinits.push_back(llvm::ConstantPointerNull::get(ptty));
653 }
654 }
655 else {
656 sinits.push_back(llvm::ConstantPointerNull::get(ptty));
657 }
658
659 s = search_function(sd, Id::cmp);
660 fdx = s ? s->isFuncDeclaration() : NULL;
661 }
662
663 Logger::println("************** D");
664 ptty = llvm::cast<llvm::PointerType>(stype->getElementType(6));
665 s = search_function(sd, Id::tostring);
666 fdx = s ? s->isFuncDeclaration() : NULL;
667 if (fdx)
668 {
669 fd = fdx->overloadExactMatch(tftostring);
670 if (fd) {
671 assert(fd->llvmValue != 0);
672 llvm::Constant* c = llvm::cast_or_null<llvm::Constant>(fd->llvmValue);
673 assert(c);
674 c = llvm::ConstantExpr::getBitCast(c, ptty);
675 sinits.push_back(c);
676 }
677 else {
678 //fdx->error("must be declared as extern (D) char[] toString()");
679 sinits.push_back(llvm::ConstantPointerNull::get(ptty));
680 }
681 }
682 else {
683 sinits.push_back(llvm::ConstantPointerNull::get(ptty));
684 }
685
686 // uint m_flags;
687 sinits.push_back(DtoConstUint(tc->hasPointers()));
688
689 // create the symbol
690 llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
691 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,tiInit,toChars(),gIR->module);
692
693 llvmValue = gvar;
694 }
695
696 /* ========================================================================= */
697
698 void TypeInfoClassDeclaration::toDt(dt_t **pdt)
699 {
700 assert(0 && "TypeInfoClassDeclaration");
701
702 /*
703 //printf("TypeInfoClassDeclaration::toDt() %s\n", tinfo->toChars());
704 dtxoff(pdt, Type::typeinfoclass->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoClass
705 dtdword(pdt, 0); // monitor
706
707 assert(tinfo->ty == Tclass);
708
709 TypeClass *tc = (TypeClass *)tinfo;
710 Symbol *s;
711
712 if (!tc->sym->vclassinfo)
713 tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym);
714 s = tc->sym->vclassinfo->toSymbol();
715 dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo
716 */
717 }
718
719 /* ========================================================================= */
720
721 void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
722 {
723 assert(0 && "TypeInfoInterfaceDeclaration");
724
725 /*
726 //printf("TypeInfoInterfaceDeclaration::toDt() %s\n", tinfo->toChars());
727 dtxoff(pdt, Type::typeinfointerface->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
728 dtdword(pdt, 0); // monitor
729
730 assert(tinfo->ty == Tclass);
731
732 TypeClass *tc = (TypeClass *)tinfo;
733 Symbol *s;
734
735 if (!tc->sym->vclassinfo)
736 tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym);
737 s = tc->sym->vclassinfo->toSymbol();
738 dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo
739 */
740 }
741
742 /* ========================================================================= */
743
744 void TypeInfoTupleDeclaration::toDt(dt_t **pdt)
745 {
746 assert(0 && "TypeInfoTupleDeclaration");
747
748 /*
749 //printf("TypeInfoTupleDeclaration::toDt() %s\n", tinfo->toChars());
750 dtxoff(pdt, Type::typeinfotypelist->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
751 dtdword(pdt, 0); // monitor
752
753 assert(tinfo->ty == Ttuple);
754
755 TypeTuple *tu = (TypeTuple *)tinfo;
756
757 size_t dim = tu->arguments->dim;
758 dtdword(pdt, dim); // elements.length
759
760 dt_t *d = NULL;
761 for (size_t i = 0; i < dim; i++)
762 { Argument *arg = (Argument *)tu->arguments->data[i];
763 Expression *e = arg->type->getTypeInfo(NULL);
764 e = e->optimize(WANTvalue);
765 e->toDt(&d);
766 }
767
768 Symbol *s;
769 s = static_sym();
770 s->Sdt = d;
771 outdata(s);
772
773 dtxoff(pdt, s, 0, TYnptr); // elements.ptr
774 */
775 }