Mercurial > projects > ldc
comparison gen/classes.cpp @ 213:7816aafeea3c trunk
[svn r229] Updated the object.d implementation to the latest Tango.
Fixed a bunch of the built-in typeinfos for arrays, they did not inherit TypeInfo_Array.
Applied patch to tango/text/convert/Layout.d by fvbommel, closes #47 .
Cleaned up some type code.
Replaced uses of llvm::Type with LLType (a typedef), same for Value and Constant.
Fixed a few cases where typeinfo for user structs could be emitted multiple times, seems to still be some cases of this :/
author | lindquist |
---|---|
date | Fri, 30 May 2008 19:32:04 +0200 |
parents | 1d6cfdbc97f0 |
children | 0806379a5eca |
comparison
equal
deleted
inserted
replaced
212:4c2689d57ba4 | 213:7816aafeea3c |
---|---|
127 // push state | 127 // push state |
128 gIR->structs.push_back(irstruct); | 128 gIR->structs.push_back(irstruct); |
129 gIR->classes.push_back(cd); | 129 gIR->classes.push_back(cd); |
130 | 130 |
131 // vector holding the field types | 131 // vector holding the field types |
132 std::vector<const llvm::Type*> fieldtypes; | 132 std::vector<const LLType*> fieldtypes; |
133 | 133 |
134 // add vtable | 134 // add vtable |
135 ts->ir.vtblType = new llvm::PATypeHolder(llvm::OpaqueType::get()); | 135 ts->ir.vtblType = new llvm::PATypeHolder(llvm::OpaqueType::get()); |
136 const llvm::Type* vtabty = getPtrToType(ts->ir.vtblType->get()); | 136 const LLType* vtabty = getPtrToType(ts->ir.vtblType->get()); |
137 fieldtypes.push_back(vtabty); | 137 fieldtypes.push_back(vtabty); |
138 | 138 |
139 // add monitor | 139 // add monitor |
140 fieldtypes.push_back(getVoidPtrType()); | 140 fieldtypes.push_back(getVoidPtrType()); |
141 | 141 |
160 else | 160 else |
161 { | 161 { |
162 Logger::println("has fields"); | 162 Logger::println("has fields"); |
163 unsigned prevsize = (unsigned)-1; | 163 unsigned prevsize = (unsigned)-1; |
164 unsigned lastoffset = (unsigned)-1; | 164 unsigned lastoffset = (unsigned)-1; |
165 const llvm::Type* fieldtype = NULL; | 165 const LLType* fieldtype = NULL; |
166 VarDeclaration* fieldinit = NULL; | 166 VarDeclaration* fieldinit = NULL; |
167 size_t fieldpad = 0; | 167 size_t fieldpad = 0; |
168 int idx = 0; | 168 int idx = 0; |
169 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { | 169 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { |
170 // first iteration | 170 // first iteration |
239 IrInterface* iri = *i; | 239 IrInterface* iri = *i; |
240 ClassDeclaration* id = iri->decl; | 240 ClassDeclaration* id = iri->decl; |
241 | 241 |
242 // set vtbl type | 242 // set vtbl type |
243 TypeClass* itc = (TypeClass*)id->type; | 243 TypeClass* itc = (TypeClass*)id->type; |
244 const llvm::Type* ivtblTy = getPtrToType(itc->ir.vtblType->get()); | 244 const LLType* ivtblTy = getPtrToType(itc->ir.vtblType->get()); |
245 fieldtypes.push_back(ivtblTy); | 245 fieldtypes.push_back(ivtblTy); |
246 | 246 |
247 // fix the interface vtable type | 247 // fix the interface vtable type |
248 #if OPAQUE_VTBLS | 248 #if OPAQUE_VTBLS |
249 iri->vtblTy = isaArray(itc->ir.vtblType->get()); | 249 iri->vtblTy = isaArray(itc->ir.vtblType->get()); |
285 // void*[vtbl.dim] | 285 // void*[vtbl.dim] |
286 const llvm::ArrayType* svtbl_ty | 286 const llvm::ArrayType* svtbl_ty |
287 = llvm::ArrayType::get(getVoidPtrType(), cd->vtbl.dim); | 287 = llvm::ArrayType::get(getVoidPtrType(), cd->vtbl.dim); |
288 | 288 |
289 #else | 289 #else |
290 std::vector<const llvm::Type*> sinits_ty; | 290 std::vector<const LLType*> sinits_ty; |
291 | 291 |
292 for (int k=0; k < cd->vtbl.dim; k++) | 292 for (int k=0; k < cd->vtbl.dim; k++) |
293 { | 293 { |
294 Dsymbol* dsym = (Dsymbol*)cd->vtbl.data[k]; | 294 Dsymbol* dsym = (Dsymbol*)cd->vtbl.data[k]; |
295 assert(dsym); | 295 assert(dsym); |
297 | 297 |
298 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { | 298 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { |
299 DtoResolveFunction(fd); | 299 DtoResolveFunction(fd); |
300 //assert(fd->type->ty == Tfunction); | 300 //assert(fd->type->ty == Tfunction); |
301 //TypeFunction* tf = (TypeFunction*)fd->type; | 301 //TypeFunction* tf = (TypeFunction*)fd->type; |
302 //const llvm::Type* fpty = getPtrToType(tf->ir.type->get()); | 302 //const LLType* fpty = getPtrToType(tf->ir.type->get()); |
303 const llvm::FunctionType* vfty = DtoBaseFunctionType(fd); | 303 const llvm::FunctionType* vfty = DtoBaseFunctionType(fd); |
304 const llvm::Type* vfpty = getPtrToType(vfty); | 304 const LLType* vfpty = getPtrToType(vfty); |
305 sinits_ty.push_back(vfpty); | 305 sinits_ty.push_back(vfpty); |
306 } | 306 } |
307 else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) { | 307 else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) { |
308 Logger::println("*** ClassDeclaration in vtable: %s", cd2->toChars()); | 308 Logger::println("*** ClassDeclaration in vtable: %s", cd2->toChars()); |
309 const llvm::Type* cinfoty; | 309 const LLType* cinfoty; |
310 if (cd->isInterfaceDeclaration()) { | 310 if (cd->isInterfaceDeclaration()) { |
311 cinfoty = infoTy; | 311 cinfoty = infoTy; |
312 } | 312 } |
313 else if (cd != ClassDeclaration::classinfo) { | 313 else if (cd != ClassDeclaration::classinfo) { |
314 cinfoty = ClassDeclaration::classinfo->type->ir.type->get(); | 314 cinfoty = ClassDeclaration::classinfo->type->ir.type->get(); |
315 } | 315 } |
316 else { | 316 else { |
317 // this is the ClassInfo class, the type is this type | 317 // this is the ClassInfo class, the type is this type |
318 cinfoty = ts->ir.type->get(); | 318 cinfoty = ts->ir.type->get(); |
319 } | 319 } |
320 const llvm::Type* cty = getPtrToType(cinfoty); | 320 const LLType* cty = getPtrToType(cinfoty); |
321 sinits_ty.push_back(cty); | 321 sinits_ty.push_back(cty); |
322 } | 322 } |
323 else | 323 else |
324 assert(0); | 324 assert(0); |
325 } | 325 } |
418 nam.append(id->mangle()); | 418 nam.append(id->mangle()); |
419 nam.append("6__vtblZ"); | 419 nam.append("6__vtblZ"); |
420 | 420 |
421 assert(iri->vtblTy); | 421 assert(iri->vtblTy); |
422 iri->vtbl = new llvm::GlobalVariable(iri->vtblTy, true, _linkage, 0, nam, gIR->module); | 422 iri->vtbl = new llvm::GlobalVariable(iri->vtblTy, true, _linkage, 0, nam, gIR->module); |
423 llvm::Constant* idxs[2] = {DtoConstUint(0), DtoConstUint(idx)}; | 423 LLConstant* idxs[2] = {DtoConstUint(0), DtoConstUint(idx)}; |
424 iri->info = llvm::ConstantExpr::getGetElementPtr(irstruct->interfaceInfos, idxs, 2); | 424 iri->info = llvm::ConstantExpr::getGetElementPtr(irstruct->interfaceInfos, idxs, 2); |
425 idx++; | 425 idx++; |
426 } | 426 } |
427 | 427 |
428 // init | 428 // init |
475 | 475 |
476 // make sure each offset knows its default initializer | 476 // make sure each offset knows its default initializer |
477 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) | 477 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) |
478 { | 478 { |
479 IrStruct::Offset* so = &i->second; | 479 IrStruct::Offset* so = &i->second; |
480 llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init); | 480 LLConstant* finit = DtoConstFieldInitializer(so->var->type, so->var->init); |
481 so->init = finit; | 481 so->init = finit; |
482 so->var->ir.irField->constInit = finit; | 482 so->var->ir.irField->constInit = finit; |
483 } | 483 } |
484 | 484 |
485 // fill out fieldtypes/inits | 485 // fill out fieldtypes/inits |
486 std::vector<llvm::Constant*> fieldinits; | 486 std::vector<LLConstant*> fieldinits; |
487 | 487 |
488 // first field is always the vtable | 488 // first field is always the vtable |
489 if (cd->isAbstract() || cd->isInterfaceDeclaration()) | 489 if (cd->isAbstract() || cd->isInterfaceDeclaration()) |
490 { | 490 { |
491 const llvm::Type* ptrTy = getPtrToType(ts->ir.vtblType->get()); | 491 const LLType* ptrTy = getPtrToType(ts->ir.vtblType->get()); |
492 fieldinits.push_back(llvm::Constant::getNullValue(ptrTy)); | 492 fieldinits.push_back(llvm::Constant::getNullValue(ptrTy)); |
493 } | 493 } |
494 else | 494 else |
495 { | 495 { |
496 assert(cd->ir.irStruct->vtbl != 0); | 496 assert(cd->ir.irStruct->vtbl != 0); |
501 fieldinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty))); | 501 fieldinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty))); |
502 | 502 |
503 // go through the field inits and build the default initializer | 503 // go through the field inits and build the default initializer |
504 size_t nfi = irstruct->defaultFields.size(); | 504 size_t nfi = irstruct->defaultFields.size(); |
505 for (size_t i=0; i<nfi; ++i) { | 505 for (size_t i=0; i<nfi; ++i) { |
506 llvm::Constant* c; | 506 LLConstant* c; |
507 if (irstruct->defaultFields[i]) { | 507 if (irstruct->defaultFields[i]) { |
508 c = irstruct->defaultFields[i]->ir.irField->constInit; | 508 c = irstruct->defaultFields[i]->ir.irField->constInit; |
509 assert(c); | 509 assert(c); |
510 } | 510 } |
511 else { | 511 else { |
512 const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i+2)); | 512 const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i+2)); |
513 assert(arrty); | 513 assert(arrty); |
514 std::vector<llvm::Constant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false)); | 514 std::vector<LLConstant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false)); |
515 c = llvm::ConstantArray::get(arrty, vals); | 515 c = llvm::ConstantArray::get(arrty, vals); |
516 } | 516 } |
517 fieldinits.push_back(c); | 517 fieldinits.push_back(c); |
518 } | 518 } |
519 | 519 |
550 for(size_t i=0; i<fieldinits.size(); ++i) { | 550 for(size_t i=0; i<fieldinits.size(); ++i) { |
551 Logger::cout() << "i#" << i << " = " << *fieldinits[i]->getType() << '\n'; | 551 Logger::cout() << "i#" << i << " = " << *fieldinits[i]->getType() << '\n'; |
552 } | 552 } |
553 #endif | 553 #endif |
554 | 554 |
555 llvm::Constant* _init = llvm::ConstantStruct::get(structtype, fieldinits); | 555 LLConstant* _init = llvm::ConstantStruct::get(structtype, fieldinits); |
556 assert(_init); | 556 assert(_init); |
557 cd->ir.irStruct->constInit = _init; | 557 cd->ir.irStruct->constInit = _init; |
558 | 558 |
559 // abstract classes have no static vtable | 559 // abstract classes have no static vtable |
560 // neither do interfaces (on their own, the implementing class supplies the vtable) | 560 // neither do interfaces (on their own, the implementing class supplies the vtable) |
561 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) | 561 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) |
562 { | 562 { |
563 // generate vtable initializer | 563 // generate vtable initializer |
564 std::vector<llvm::Constant*> sinits; | 564 std::vector<LLConstant*> sinits; |
565 | 565 |
566 for (int k=0; k < cd->vtbl.dim; k++) | 566 for (int k=0; k < cd->vtbl.dim; k++) |
567 { | 567 { |
568 Dsymbol* dsym = (Dsymbol*)cd->vtbl.data[k]; | 568 Dsymbol* dsym = (Dsymbol*)cd->vtbl.data[k]; |
569 assert(dsym); | 569 assert(dsym); |
570 //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n'; | 570 //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n'; |
571 | 571 |
572 #if OPAQUE_VTBLS | 572 #if OPAQUE_VTBLS |
573 const llvm::Type* targetTy = getVoidPtrType(); | 573 const LLType* targetTy = getVoidPtrType(); |
574 #else | 574 #else |
575 const llvm::Type* targetTy = vtbltype->getElementType(k); | 575 const LLType* targetTy = vtbltype->getElementType(k); |
576 #endif | 576 #endif |
577 | 577 |
578 llvm::Constant* c = NULL; | 578 LLConstant* c = NULL; |
579 // virtual method | 579 // virtual method |
580 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { | 580 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { |
581 DtoForceDeclareDsymbol(fd); | 581 DtoForceDeclareDsymbol(fd); |
582 assert(fd->ir.irFunc->func); | 582 assert(fd->ir.irFunc->func); |
583 c = llvm::cast<llvm::Constant>(fd->ir.irFunc->func); | 583 c = llvm::cast<llvm::Constant>(fd->ir.irFunc->func); |
597 #if OPAQUE_VTBLS | 597 #if OPAQUE_VTBLS |
598 const llvm::ArrayType* svtbl_ty = isaArray(ts->ir.vtblType->get()); | 598 const llvm::ArrayType* svtbl_ty = isaArray(ts->ir.vtblType->get()); |
599 cd->ir.irStruct->constVtbl = llvm::ConstantArray::get(svtbl_ty, sinits); | 599 cd->ir.irStruct->constVtbl = llvm::ConstantArray::get(svtbl_ty, sinits); |
600 #else | 600 #else |
601 const llvm::StructType* svtbl_ty = isaStruct(ts->ir.vtblType->get()); | 601 const llvm::StructType* svtbl_ty = isaStruct(ts->ir.vtblType->get()); |
602 llvm::Constant* cvtblInit = llvm::ConstantStruct::get(svtbl_ty, sinits); | 602 LLConstant* cvtblInit = llvm::ConstantStruct::get(svtbl_ty, sinits); |
603 cd->ir.irStruct->constVtbl = llvm::cast<llvm::ConstantStruct>(cvtblInit); | 603 cd->ir.irStruct->constVtbl = llvm::cast<llvm::ConstantStruct>(cvtblInit); |
604 #endif | 604 #endif |
605 | 605 |
606 // create interface vtable const initalizers | 606 // create interface vtable const initalizers |
607 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) | 607 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) |
618 #else | 618 #else |
619 const llvm::StructType* ivtbl_ty = isaStruct(its->ir.vtblType->get()); | 619 const llvm::StructType* ivtbl_ty = isaStruct(its->ir.vtblType->get()); |
620 #endif | 620 #endif |
621 | 621 |
622 // generate interface info initializer | 622 // generate interface info initializer |
623 std::vector<llvm::Constant*> infoInits; | 623 std::vector<LLConstant*> infoInits; |
624 | 624 |
625 // classinfo | 625 // classinfo |
626 assert(id->ir.irStruct->classInfo); | 626 assert(id->ir.irStruct->classInfo); |
627 llvm::Constant* c = id->ir.irStruct->classInfo; | 627 LLConstant* c = id->ir.irStruct->classInfo; |
628 infoInits.push_back(c); | 628 infoInits.push_back(c); |
629 | 629 |
630 // vtbl | 630 // vtbl |
631 const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); | 631 const LLType* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); |
632 c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty); | 632 c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty); |
633 c = DtoConstSlice(DtoConstSize_t(b->vtbl.dim), c); | 633 c = DtoConstSlice(DtoConstSize_t(b->vtbl.dim), c); |
634 infoInits.push_back(c); | 634 infoInits.push_back(c); |
635 | 635 |
636 // offset | 636 // offset |
640 | 640 |
641 // create interface info initializer constant | 641 // create interface info initializer constant |
642 iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits)); | 642 iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits)); |
643 | 643 |
644 // generate vtable initializer | 644 // generate vtable initializer |
645 std::vector<llvm::Constant*> iinits; | 645 std::vector<LLConstant*> iinits; |
646 | 646 |
647 // add interface info | 647 // add interface info |
648 #if OPAQUE_VTBLS | 648 #if OPAQUE_VTBLS |
649 const llvm::Type* targetTy = getVoidPtrType(); | 649 const LLType* targetTy = getVoidPtrType(); |
650 iinits.push_back(llvm::ConstantExpr::getBitCast(iri->info, targetTy)); | 650 iinits.push_back(llvm::ConstantExpr::getBitCast(iri->info, targetTy)); |
651 #else | 651 #else |
652 iinits.push_back(iri->info); | 652 iinits.push_back(iri->info); |
653 #endif | 653 #endif |
654 | 654 |
659 assert(dsym); | 659 assert(dsym); |
660 FuncDeclaration* fd = dsym->isFuncDeclaration(); | 660 FuncDeclaration* fd = dsym->isFuncDeclaration(); |
661 assert(fd); | 661 assert(fd); |
662 DtoForceDeclareDsymbol(fd); | 662 DtoForceDeclareDsymbol(fd); |
663 assert(fd->ir.irFunc->func); | 663 assert(fd->ir.irFunc->func); |
664 llvm::Constant* c = llvm::cast<llvm::Constant>(fd->ir.irFunc->func); | 664 LLConstant* c = llvm::cast<llvm::Constant>(fd->ir.irFunc->func); |
665 | 665 |
666 #if !OPAQUE_VTBLS | 666 #if !OPAQUE_VTBLS |
667 const llvm::Type* targetTy = iri->vtblTy->getContainedType(k); | 667 const LLType* targetTy = iri->vtblTy->getContainedType(k); |
668 #endif | 668 #endif |
669 | 669 |
670 // we have to bitcast, as the type created in ResolveClass expects a different this type | 670 // we have to bitcast, as the type created in ResolveClass expects a different this type |
671 c = llvm::ConstantExpr::getBitCast(c, targetTy); | 671 c = llvm::ConstantExpr::getBitCast(c, targetTy); |
672 iinits.push_back(c); | 672 iinits.push_back(c); |
673 Logger::cout() << "c: " << *c << '\n'; | 673 Logger::cout() << "c: " << *c << '\n'; |
674 } | 674 } |
675 | 675 |
676 #if OPAQUE_VTBLS | 676 #if OPAQUE_VTBLS |
677 Logger::cout() << "n: " << iinits.size() << " ivtbl_ty: " << *ivtbl_ty << '\n'; | 677 Logger::cout() << "n: " << iinits.size() << " ivtbl_ty: " << *ivtbl_ty << '\n'; |
678 llvm::Constant* civtblInit = llvm::ConstantArray::get(ivtbl_ty, iinits); | 678 LLConstant* civtblInit = llvm::ConstantArray::get(ivtbl_ty, iinits); |
679 iri->vtblInit = llvm::cast<llvm::ConstantArray>(civtblInit); | 679 iri->vtblInit = llvm::cast<llvm::ConstantArray>(civtblInit); |
680 #else | 680 #else |
681 llvm::Constant* civtblInit = llvm::ConstantStruct::get(ivtbl_ty, iinits); | 681 LLConstant* civtblInit = llvm::ConstantStruct::get(ivtbl_ty, iinits); |
682 iri->vtblInit = llvm::cast<llvm::ConstantStruct>(civtblInit); | 682 iri->vtblInit = llvm::cast<llvm::ConstantStruct>(civtblInit); |
683 #endif | 683 #endif |
684 } | 684 } |
685 } | 685 } |
686 // we always generate interfaceinfos as best we can | 686 // we always generate interfaceinfos as best we can |
696 ClassDeclaration* id = iri->decl; | 696 ClassDeclaration* id = iri->decl; |
697 assert(id->type->ty == Tclass); | 697 assert(id->type->ty == Tclass); |
698 TypeClass* its = (TypeClass*)id->type; | 698 TypeClass* its = (TypeClass*)id->type; |
699 | 699 |
700 // generate interface info initializer | 700 // generate interface info initializer |
701 std::vector<llvm::Constant*> infoInits; | 701 std::vector<LLConstant*> infoInits; |
702 | 702 |
703 // classinfo | 703 // classinfo |
704 assert(id->ir.irStruct->classInfo); | 704 assert(id->ir.irStruct->classInfo); |
705 llvm::Constant* c = id->ir.irStruct->classInfo; | 705 LLConstant* c = id->ir.irStruct->classInfo; |
706 infoInits.push_back(c); | 706 infoInits.push_back(c); |
707 | 707 |
708 // vtbl | 708 // vtbl |
709 const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); | 709 const LLType* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); |
710 c = DtoConstSlice(DtoConstSize_t(0), getNullPtr(byteptrptrty)); | 710 c = DtoConstSlice(DtoConstSize_t(0), getNullPtr(byteptrptrty)); |
711 infoInits.push_back(c); | 711 infoInits.push_back(c); |
712 | 712 |
713 // offset | 713 // offset |
714 assert(iri->index >= 0); | 714 assert(iri->index >= 0); |
756 } | 756 } |
757 } | 757 } |
758 | 758 |
759 // always do interface info array when possible | 759 // always do interface info array when possible |
760 IrStruct* irstruct = cd->ir.irStruct; | 760 IrStruct* irstruct = cd->ir.irStruct; |
761 std::vector<llvm::Constant*> infoInits; | 761 std::vector<LLConstant*> infoInits; |
762 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) | 762 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) |
763 { | 763 { |
764 IrInterface* iri = *i; | 764 IrInterface* iri = *i; |
765 infoInits.push_back(iri->infoInit); | 765 infoInits.push_back(iri->infoInit); |
766 } | 766 } |
767 // set initializer | 767 // set initializer |
768 if (!infoInits.empty()) | 768 if (!infoInits.empty()) |
769 { | 769 { |
770 llvm::Constant* arrInit = llvm::ConstantArray::get(irstruct->interfaceInfosTy, infoInits); | 770 LLConstant* arrInit = llvm::ConstantArray::get(irstruct->interfaceInfosTy, infoInits); |
771 irstruct->interfaceInfos->setInitializer(arrInit); | 771 irstruct->interfaceInfos->setInitializer(arrInit); |
772 } | 772 } |
773 else | 773 else |
774 { | 774 { |
775 assert(irstruct->interfaceInfos == NULL); | 775 assert(irstruct->interfaceInfos == NULL); |
786 { | 786 { |
787 // resolve type | 787 // resolve type |
788 DtoForceDeclareDsymbol(tc->sym); | 788 DtoForceDeclareDsymbol(tc->sym); |
789 | 789 |
790 // allocate | 790 // allocate |
791 llvm::Value* mem; | 791 LLValue* mem; |
792 if (newexp->onstack) | 792 if (newexp->onstack) |
793 { | 793 { |
794 mem = new llvm::AllocaInst(DtoType(tc)->getContainedType(0), "newclass_alloca", gIR->topallocapoint()); | 794 mem = new llvm::AllocaInst(DtoType(tc)->getContainedType(0), "newclass_alloca", gIR->topallocapoint()); |
795 } | 795 } |
796 else | 796 else |
797 { | 797 { |
798 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_newclass"); | 798 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_newclass"); |
799 std::vector<llvm::Value*> args; | 799 std::vector<LLValue*> args; |
800 args.push_back(tc->sym->ir.irStruct->classInfo); | 800 args.push_back(tc->sym->ir.irStruct->classInfo); |
801 mem = gIR->ir->CreateCall(fn, args.begin(), args.end(), "newclass_gc_alloc"); | 801 mem = gIR->ir->CreateCall(fn, args.begin(), args.end(), "newclass_gc_alloc"); |
802 mem = DtoBitCast(mem, DtoType(tc), "newclass_gc"); | 802 mem = DtoBitCast(mem, DtoType(tc), "newclass_gc"); |
803 } | 803 } |
804 | 804 |
810 { | 810 { |
811 Logger::println("Resolving outer class"); | 811 Logger::println("Resolving outer class"); |
812 LOG_SCOPE; | 812 LOG_SCOPE; |
813 DValue* thisval = newexp->thisexp->toElem(gIR); | 813 DValue* thisval = newexp->thisexp->toElem(gIR); |
814 size_t idx = 2 + tc->sym->vthis->ir.irField->index; | 814 size_t idx = 2 + tc->sym->vthis->ir.irField->index; |
815 llvm::Value* src = thisval->getRVal(); | 815 LLValue* src = thisval->getRVal(); |
816 llvm::Value* dst = DtoGEPi(mem,0,idx,"tmp"); | 816 LLValue* dst = DtoGEPi(mem,0,idx,"tmp"); |
817 Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n'; | 817 Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n'; |
818 DtoStore(src, dst); | 818 DtoStore(src, dst); |
819 } | 819 } |
820 // set the context for nested classes | 820 // set the context for nested classes |
821 else if (tc->sym->isNested()) | 821 else if (tc->sym->isNested()) |
822 { | 822 { |
823 Logger::println("Resolving nested context"); | 823 Logger::println("Resolving nested context"); |
824 LOG_SCOPE; | 824 LOG_SCOPE; |
825 size_t idx = 2; | 825 size_t idx = 2; |
826 //idx += tc->sym->ir.irStruct->interfaces.size(); | 826 //idx += tc->sym->ir.irStruct->interfaces.size(); |
827 llvm::Value* nest = gIR->func()->decl->ir.irFunc->nestedVar; | 827 LLValue* nest = gIR->func()->decl->ir.irFunc->nestedVar; |
828 if (!nest) | 828 if (!nest) |
829 nest = gIR->func()->decl->ir.irFunc->thisVar; | 829 nest = gIR->func()->decl->ir.irFunc->thisVar; |
830 assert(nest); | 830 assert(nest); |
831 llvm::Value* gep = DtoGEPi(mem,0,idx,"tmp"); | 831 LLValue* gep = DtoGEPi(mem,0,idx,"tmp"); |
832 nest = DtoBitCast(nest, gep->getType()->getContainedType(0)); | 832 nest = DtoBitCast(nest, gep->getType()->getContainedType(0)); |
833 DtoStore(nest, gep); | 833 DtoStore(nest, gep); |
834 } | 834 } |
835 | 835 |
836 // call constructor | 836 // call constructor |
844 return new DImValue(tc, mem, false); | 844 return new DImValue(tc, mem, false); |
845 } | 845 } |
846 | 846 |
847 ////////////////////////////////////////////////////////////////////////////////////////// | 847 ////////////////////////////////////////////////////////////////////////////////////////// |
848 | 848 |
849 void DtoInitClass(TypeClass* tc, llvm::Value* dst) | 849 void DtoInitClass(TypeClass* tc, LLValue* dst) |
850 { | 850 { |
851 size_t presz = 2*getABITypeSize(DtoSize_t()); | 851 size_t presz = 2*getABITypeSize(DtoSize_t()); |
852 uint64_t n = getABITypeSize(tc->ir.type->get()) - presz; | 852 uint64_t n = getABITypeSize(tc->ir.type->get()) - presz; |
853 | 853 |
854 // set vtable field seperately, this might give better optimization | 854 // set vtable field seperately, this might give better optimization |
855 assert(tc->sym->ir.irStruct->vtbl); | 855 assert(tc->sym->ir.irStruct->vtbl); |
856 DtoStore(tc->sym->ir.irStruct->vtbl, DtoGEPi(dst,0,0,"vtbl")); | 856 DtoStore(tc->sym->ir.irStruct->vtbl, DtoGEPi(dst,0,0,"vtbl")); |
857 | 857 |
858 // monitor always defaults to zero | 858 // monitor always defaults to zero |
859 llvm::Value* tmp = DtoGEPi(dst,0,1,"monitor"); | 859 LLValue* tmp = DtoGEPi(dst,0,1,"monitor"); |
860 DtoStore(llvm::Constant::getNullValue(tmp->getType()->getContainedType(0)), tmp); | 860 DtoStore(llvm::Constant::getNullValue(tmp->getType()->getContainedType(0)), tmp); |
861 | 861 |
862 // done? | 862 // done? |
863 if (n == 0) | 863 if (n == 0) |
864 return; | 864 return; |
865 | 865 |
866 // copy the rest from the static initializer | 866 // copy the rest from the static initializer |
867 assert(tc->sym->ir.irStruct->init); | 867 assert(tc->sym->ir.irStruct->init); |
868 assert(dst->getType() == tc->sym->ir.irStruct->init->getType()); | 868 assert(dst->getType() == tc->sym->ir.irStruct->init->getType()); |
869 | 869 |
870 const llvm::Type* arrty = getPtrToType(llvm::Type::Int8Ty); | 870 const LLType* arrty = getPtrToType(llvm::Type::Int8Ty); |
871 | 871 |
872 llvm::Value* dstarr = DtoGEPi(dst,0,2,"tmp"); | 872 LLValue* dstarr = DtoGEPi(dst,0,2,"tmp"); |
873 dstarr = DtoBitCast(dstarr, arrty); | 873 dstarr = DtoBitCast(dstarr, arrty); |
874 | 874 |
875 llvm::Value* srcarr = DtoGEPi(tc->sym->ir.irStruct->init,0,2,"tmp"); | 875 LLValue* srcarr = DtoGEPi(tc->sym->ir.irStruct->init,0,2,"tmp"); |
876 srcarr = DtoBitCast(srcarr, arrty); | 876 srcarr = DtoBitCast(srcarr, arrty); |
877 | 877 |
878 llvm::Function* fn = LLVM_DeclareMemCpy32(); | 878 llvm::Function* fn = LLVM_DeclareMemCpy32(); |
879 std::vector<llvm::Value*> llargs; | 879 std::vector<LLValue*> llargs; |
880 llargs.resize(4); | 880 llargs.resize(4); |
881 llargs[0] = dstarr; | 881 llargs[0] = dstarr; |
882 llargs[1] = srcarr; | 882 llargs[1] = srcarr; |
883 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); | 883 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); |
884 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 884 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
886 llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | 886 llvm::CallInst::Create(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); |
887 } | 887 } |
888 | 888 |
889 ////////////////////////////////////////////////////////////////////////////////////////// | 889 ////////////////////////////////////////////////////////////////////////////////////////// |
890 | 890 |
891 DValue* DtoCallClassCtor(TypeClass* type, CtorDeclaration* ctor, Array* arguments, llvm::Value* mem) | 891 DValue* DtoCallClassCtor(TypeClass* type, CtorDeclaration* ctor, Array* arguments, LLValue* mem) |
892 { | 892 { |
893 Logger::println("Calling constructor"); | 893 Logger::println("Calling constructor"); |
894 LOG_SCOPE; | 894 LOG_SCOPE; |
895 | 895 |
896 assert(ctor); | 896 assert(ctor); |
897 DtoForceDeclareDsymbol(ctor); | 897 DtoForceDeclareDsymbol(ctor); |
898 llvm::Function* fn = ctor->ir.irFunc->func; | 898 llvm::Function* fn = ctor->ir.irFunc->func; |
899 TypeFunction* tf = (TypeFunction*)DtoDType(ctor->type); | 899 TypeFunction* tf = (TypeFunction*)DtoDType(ctor->type); |
900 | 900 |
901 std::vector<llvm::Value*> ctorargs; | 901 std::vector<LLValue*> ctorargs; |
902 ctorargs.push_back(mem); | 902 ctorargs.push_back(mem); |
903 for (size_t i=0; i<arguments->dim; ++i) | 903 for (size_t i=0; i<arguments->dim; ++i) |
904 { | 904 { |
905 Expression* ex = (Expression*)arguments->data[i]; | 905 Expression* ex = (Expression*)arguments->data[i]; |
906 Argument* fnarg = Argument::getNth(tf->parameters, i); | 906 Argument* fnarg = Argument::getNth(tf->parameters, i); |
907 DValue* argval = DtoArgument(fnarg, ex); | 907 DValue* argval = DtoArgument(fnarg, ex); |
908 llvm::Value* a = argval->getRVal(); | 908 LLValue* a = argval->getRVal(); |
909 const llvm::Type* aty = fn->getFunctionType()->getParamType(i+1); | 909 const LLType* aty = fn->getFunctionType()->getParamType(i+1); |
910 if (a->getType() != aty) | 910 if (a->getType() != aty) |
911 a = DtoBitCast(a, aty); | 911 a = DtoBitCast(a, aty); |
912 ctorargs.push_back(a); | 912 ctorargs.push_back(a); |
913 } | 913 } |
914 llvm::CallInst* call = llvm::CallInst::Create(fn, ctorargs.begin(), ctorargs.end(), "tmp", gIR->scopebb()); | 914 llvm::CallInst* call = llvm::CallInst::Create(fn, ctorargs.begin(), ctorargs.end(), "tmp", gIR->scopebb()); |
917 return new DImValue(type, call, false); | 917 return new DImValue(type, call, false); |
918 } | 918 } |
919 | 919 |
920 ////////////////////////////////////////////////////////////////////////////////////////// | 920 ////////////////////////////////////////////////////////////////////////////////////////// |
921 | 921 |
922 void DtoFinalizeClass(llvm::Value* inst) | 922 void DtoFinalizeClass(LLValue* inst) |
923 { | 923 { |
924 // get runtime function | 924 // get runtime function |
925 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_callfinalizer"); | 925 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_callfinalizer"); |
926 // build args | 926 // build args |
927 llvm::SmallVector<llvm::Value*,1> arg; | 927 LLSmallVector<LLValue*,1> arg; |
928 arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp")); | 928 arg.push_back(DtoBitCast(inst, fn->getFunctionType()->getParamType(0), ".tmp")); |
929 // call | 929 // call |
930 llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb()); | 930 llvm::CallInst::Create(fn, arg.begin(), arg.end(), "", gIR->scopebb()); |
931 } | 931 } |
932 | 932 |
937 Logger::println("DtoCastClass(%s, %s)", val->getType()->toChars(), _to->toChars()); | 937 Logger::println("DtoCastClass(%s, %s)", val->getType()->toChars(), _to->toChars()); |
938 LOG_SCOPE; | 938 LOG_SCOPE; |
939 | 939 |
940 Type* to = DtoDType(_to); | 940 Type* to = DtoDType(_to); |
941 if (to->ty == Tpointer) { | 941 if (to->ty == Tpointer) { |
942 const llvm::Type* tolltype = DtoType(_to); | 942 const LLType* tolltype = DtoType(_to); |
943 llvm::Value* rval = DtoBitCast(val->getRVal(), tolltype); | 943 LLValue* rval = DtoBitCast(val->getRVal(), tolltype); |
944 return new DImValue(_to, rval); | 944 return new DImValue(_to, rval); |
945 } | 945 } |
946 | 946 |
947 assert(to->ty == Tclass); | 947 assert(to->ty == Tclass); |
948 TypeClass* tc = (TypeClass*)to; | 948 TypeClass* tc = (TypeClass*)to; |
968 Logger::println("interface cast"); | 968 Logger::println("interface cast"); |
969 return DtoCastInterfaceToObject(val, _to); | 969 return DtoCastInterfaceToObject(val, _to); |
970 } | 970 } |
971 else if (!tc->sym->isInterfaceDeclaration() && tc->sym->isBaseOf(fc->sym,NULL)) { | 971 else if (!tc->sym->isInterfaceDeclaration() && tc->sym->isBaseOf(fc->sym,NULL)) { |
972 Logger::println("static down cast)"); | 972 Logger::println("static down cast)"); |
973 const llvm::Type* tolltype = DtoType(_to); | 973 const LLType* tolltype = DtoType(_to); |
974 llvm::Value* rval = DtoBitCast(val->getRVal(), tolltype); | 974 LLValue* rval = DtoBitCast(val->getRVal(), tolltype); |
975 return new DImValue(_to, rval); | 975 return new DImValue(_to, rval); |
976 } | 976 } |
977 else { | 977 else { |
978 Logger::println("dynamic up cast"); | 978 Logger::println("dynamic up cast"); |
979 return DtoDynamicCastObject(val, _to); | 979 return DtoDynamicCastObject(val, _to); |
992 DtoForceDeclareDsymbol(ClassDeclaration::classinfo); | 992 DtoForceDeclareDsymbol(ClassDeclaration::classinfo); |
993 | 993 |
994 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_dynamic_cast"); | 994 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_dynamic_cast"); |
995 const llvm::FunctionType* funcTy = func->getFunctionType(); | 995 const llvm::FunctionType* funcTy = func->getFunctionType(); |
996 | 996 |
997 std::vector<llvm::Value*> args; | 997 std::vector<LLValue*> args; |
998 | 998 |
999 // Object o | 999 // Object o |
1000 llvm::Value* tmp = val->getRVal(); | 1000 LLValue* tmp = val->getRVal(); |
1001 tmp = DtoBitCast(tmp, funcTy->getParamType(0)); | 1001 tmp = DtoBitCast(tmp, funcTy->getParamType(0)); |
1002 args.push_back(tmp); | 1002 args.push_back(tmp); |
1003 assert(funcTy->getParamType(0) == tmp->getType()); | 1003 assert(funcTy->getParamType(0) == tmp->getType()); |
1004 | 1004 |
1005 // ClassInfo c | 1005 // ClassInfo c |
1012 tmp = DtoBitCast(tmp, funcTy->getParamType(1)); | 1012 tmp = DtoBitCast(tmp, funcTy->getParamType(1)); |
1013 args.push_back(tmp); | 1013 args.push_back(tmp); |
1014 assert(funcTy->getParamType(1) == tmp->getType()); | 1014 assert(funcTy->getParamType(1) == tmp->getType()); |
1015 | 1015 |
1016 // call it | 1016 // call it |
1017 llvm::Value* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "tmp"); | 1017 LLValue* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "tmp"); |
1018 | 1018 |
1019 // cast return value | 1019 // cast return value |
1020 ret = DtoBitCast(ret, DtoType(_to)); | 1020 ret = DtoBitCast(ret, DtoType(_to)); |
1021 | 1021 |
1022 return new DImValue(_to, ret); | 1022 return new DImValue(_to, ret); |
1031 | 1031 |
1032 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_toObject"); | 1032 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_toObject"); |
1033 const llvm::FunctionType* funcTy = func->getFunctionType(); | 1033 const llvm::FunctionType* funcTy = func->getFunctionType(); |
1034 | 1034 |
1035 // void* p | 1035 // void* p |
1036 llvm::Value* tmp = val->getRVal(); | 1036 LLValue* tmp = val->getRVal(); |
1037 tmp = DtoBitCast(tmp, funcTy->getParamType(0)); | 1037 tmp = DtoBitCast(tmp, funcTy->getParamType(0)); |
1038 | 1038 |
1039 // call it | 1039 // call it |
1040 llvm::Value* ret = gIR->ir->CreateCall(func, tmp, "tmp"); | 1040 LLValue* ret = gIR->ir->CreateCall(func, tmp, "tmp"); |
1041 | 1041 |
1042 // cast return value | 1042 // cast return value |
1043 if (to != NULL) | 1043 if (to != NULL) |
1044 ret = DtoBitCast(ret, DtoType(to)); | 1044 ret = DtoBitCast(ret, DtoType(to)); |
1045 else | 1045 else |
1059 DtoForceDeclareDsymbol(ClassDeclaration::classinfo); | 1059 DtoForceDeclareDsymbol(ClassDeclaration::classinfo); |
1060 | 1060 |
1061 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_interface_cast"); | 1061 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_interface_cast"); |
1062 const llvm::FunctionType* funcTy = func->getFunctionType(); | 1062 const llvm::FunctionType* funcTy = func->getFunctionType(); |
1063 | 1063 |
1064 std::vector<llvm::Value*> args; | 1064 std::vector<LLValue*> args; |
1065 | 1065 |
1066 // void* p | 1066 // void* p |
1067 llvm::Value* tmp = val->getRVal(); | 1067 LLValue* tmp = val->getRVal(); |
1068 tmp = DtoBitCast(tmp, funcTy->getParamType(0)); | 1068 tmp = DtoBitCast(tmp, funcTy->getParamType(0)); |
1069 args.push_back(tmp); | 1069 args.push_back(tmp); |
1070 | 1070 |
1071 // ClassInfo c | 1071 // ClassInfo c |
1072 TypeClass* to = (TypeClass*)DtoDType(_to); | 1072 TypeClass* to = (TypeClass*)DtoDType(_to); |
1077 // this could happen in user code as well :/ | 1077 // this could happen in user code as well :/ |
1078 tmp = DtoBitCast(tmp, funcTy->getParamType(1)); | 1078 tmp = DtoBitCast(tmp, funcTy->getParamType(1)); |
1079 args.push_back(tmp); | 1079 args.push_back(tmp); |
1080 | 1080 |
1081 // call it | 1081 // call it |
1082 llvm::Value* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "tmp"); | 1082 LLValue* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "tmp"); |
1083 | 1083 |
1084 // cast return value | 1084 // cast return value |
1085 ret = DtoBitCast(ret, DtoType(_to)); | 1085 ret = DtoBitCast(ret, DtoType(_to)); |
1086 | 1086 |
1087 return new DImValue(_to, ret); | 1087 return new DImValue(_to, ret); |
1125 result.push_back(r); | 1125 result.push_back(r); |
1126 } | 1126 } |
1127 | 1127 |
1128 ////////////////////////////////////////////////////////////////////////////////////////// | 1128 ////////////////////////////////////////////////////////////////////////////////////////// |
1129 | 1129 |
1130 llvm::Value* DtoIndexClass(llvm::Value* ptr, ClassDeclaration* cd, Type* t, unsigned os, std::vector<unsigned>& idxs) | 1130 LLValue* DtoIndexClass(LLValue* ptr, ClassDeclaration* cd, Type* t, unsigned os, std::vector<unsigned>& idxs) |
1131 { | 1131 { |
1132 Logger::println("checking for offset %u type %s:", os, t->toChars()); | 1132 Logger::println("checking for offset %u type %s:", os, t->toChars()); |
1133 LOG_SCOPE; | 1133 LOG_SCOPE; |
1134 | 1134 |
1135 if (idxs.empty()) | 1135 if (idxs.empty()) |
1136 idxs.push_back(0); | 1136 idxs.push_back(0); |
1137 | 1137 |
1138 const llvm::Type* st = DtoType(cd->type); | 1138 const LLType* st = DtoType(cd->type); |
1139 if (ptr->getType() != st) { | 1139 if (ptr->getType() != st) { |
1140 //assert(cd->ir.irStruct->hasUnions); | 1140 //assert(cd->ir.irStruct->hasUnions); |
1141 ptr = gIR->ir->CreateBitCast(ptr, st, "tmp"); | 1141 ptr = gIR->ir->CreateBitCast(ptr, st, "tmp"); |
1142 } | 1142 } |
1143 | 1143 |
1144 const llvm::Type* llt = getPtrToType(DtoType(t)); | 1144 const LLType* llt = getPtrToType(DtoType(t)); |
1145 unsigned dataoffset = 2; | 1145 unsigned dataoffset = 2; |
1146 | 1146 |
1147 IrStruct* irstruct = cd->ir.irStruct; | 1147 IrStruct* irstruct = cd->ir.irStruct; |
1148 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { | 1148 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { |
1149 //for (unsigned i=0; i<cd->fields.dim; ++i) { | 1149 //for (unsigned i=0; i<cd->fields.dim; ++i) { |
1178 ptr = llvm::GetElementPtrInst::Create(ptr, DtoConstUint(vd->ir.irField->indexOffset), "tmp", gIR->scopebb()); | 1178 ptr = llvm::GetElementPtrInst::Create(ptr, DtoConstUint(vd->ir.irField->indexOffset), "tmp", gIR->scopebb()); |
1179 std::vector<unsigned> tmp; | 1179 std::vector<unsigned> tmp; |
1180 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); | 1180 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); |
1181 } | 1181 } |
1182 else { | 1182 else { |
1183 const llvm::Type* sty = getPtrToType(DtoType(vd->type)); | 1183 const LLType* sty = getPtrToType(DtoType(vd->type)); |
1184 if (ptr->getType() != sty) { | 1184 if (ptr->getType() != sty) { |
1185 ptr = gIR->ir->CreateBitCast(ptr, sty, "tmp"); | 1185 ptr = gIR->ir->CreateBitCast(ptr, sty, "tmp"); |
1186 std::vector<unsigned> tmp; | 1186 std::vector<unsigned> tmp; |
1187 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); | 1187 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); |
1188 } | 1188 } |
1201 return llvm::GetElementPtrInst::Create(ptr, DtoConstUint(os / llt_sz), "tmp", gIR->scopebb()); | 1201 return llvm::GetElementPtrInst::Create(ptr, DtoConstUint(os / llt_sz), "tmp", gIR->scopebb()); |
1202 } | 1202 } |
1203 | 1203 |
1204 ////////////////////////////////////////////////////////////////////////////////////////// | 1204 ////////////////////////////////////////////////////////////////////////////////////////// |
1205 | 1205 |
1206 llvm::Value* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl) | 1206 LLValue* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl) |
1207 { | 1207 { |
1208 assert(fdecl->isVirtual());//fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual())); | 1208 assert(fdecl->isVirtual());//fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual())); |
1209 assert(fdecl->vtblIndex > 0); | 1209 assert(fdecl->vtblIndex > 0); |
1210 assert(DtoDType(inst->getType())->ty == Tclass); | 1210 assert(DtoDType(inst->getType())->ty == Tclass); |
1211 | 1211 |
1212 llvm::Value* vthis = inst->getRVal(); | 1212 LLValue* vthis = inst->getRVal(); |
1213 Logger::cout() << "vthis: " << *vthis << '\n'; | 1213 Logger::cout() << "vthis: " << *vthis << '\n'; |
1214 | 1214 |
1215 llvm::Value* funcval; | 1215 LLValue* funcval; |
1216 funcval = DtoGEPi(vthis, 0, 0, "tmp"); | 1216 funcval = DtoGEPi(vthis, 0, 0, "tmp"); |
1217 funcval = DtoLoad(funcval); | 1217 funcval = DtoLoad(funcval); |
1218 funcval = DtoGEPi(funcval, 0, fdecl->vtblIndex, fdecl->toPrettyChars()); | 1218 funcval = DtoGEPi(funcval, 0, fdecl->vtblIndex, fdecl->toPrettyChars()); |
1219 funcval = DtoLoad(funcval); | 1219 funcval = DtoLoad(funcval); |
1220 | 1220 |
1249 if (!cd->isInterfaceDeclaration()) | 1249 if (!cd->isInterfaceDeclaration()) |
1250 gname.append("7__ClassZ"); | 1250 gname.append("7__ClassZ"); |
1251 else | 1251 else |
1252 gname.append("11__InterfaceZ"); | 1252 gname.append("11__InterfaceZ"); |
1253 | 1253 |
1254 const llvm::Type* st = cinfo->type->ir.type->get(); | 1254 const LLType* st = cinfo->type->ir.type->get(); |
1255 | 1255 |
1256 cd->ir.irStruct->classInfo = new llvm::GlobalVariable(st, true, DtoLinkage(cd), NULL, gname, gIR->module); | 1256 cd->ir.irStruct->classInfo = new llvm::GlobalVariable(st, true, DtoLinkage(cd), NULL, gname, gIR->module); |
1257 } | 1257 } |
1258 | 1258 |
1259 static llvm::Constant* build_offti_entry(VarDeclaration* vd) | 1259 static LLConstant* build_offti_entry(VarDeclaration* vd) |
1260 { | 1260 { |
1261 std::vector<const llvm::Type*> types; | 1261 std::vector<const LLType*> types; |
1262 std::vector<llvm::Constant*> inits; | 1262 std::vector<LLConstant*> inits; |
1263 | 1263 |
1264 types.push_back(DtoSize_t()); | 1264 types.push_back(DtoSize_t()); |
1265 | 1265 |
1266 size_t offset = vd->offset; // TODO might not be the true offset | 1266 size_t offset = vd->offset; // TODO might not be the true offset |
1267 // dmd only accounts for the vtable, not classinfo or monitor | 1267 // dmd only accounts for the vtable, not classinfo or monitor |
1272 inits.push_back(DtoConstSize_t(offset)); | 1272 inits.push_back(DtoConstSize_t(offset)); |
1273 | 1273 |
1274 vd->type->getTypeInfo(NULL); | 1274 vd->type->getTypeInfo(NULL); |
1275 assert(vd->type->vtinfo); | 1275 assert(vd->type->vtinfo); |
1276 DtoForceDeclareDsymbol(vd->type->vtinfo); | 1276 DtoForceDeclareDsymbol(vd->type->vtinfo); |
1277 llvm::Constant* c = isaConstant(vd->type->vtinfo->ir.getIrValue()); | 1277 LLConstant* c = isaConstant(vd->type->vtinfo->ir.getIrValue()); |
1278 | 1278 |
1279 const llvm::Type* tiTy = getPtrToType(Type::typeinfo->type->ir.type->get()); | 1279 const LLType* tiTy = getPtrToType(Type::typeinfo->type->ir.type->get()); |
1280 //Logger::cout() << "tiTy = " << *tiTy << '\n'; | 1280 //Logger::cout() << "tiTy = " << *tiTy << '\n'; |
1281 | 1281 |
1282 types.push_back(tiTy); | 1282 types.push_back(tiTy); |
1283 inits.push_back(llvm::ConstantExpr::getBitCast(c, tiTy)); | 1283 inits.push_back(llvm::ConstantExpr::getBitCast(c, tiTy)); |
1284 | 1284 |
1285 const llvm::StructType* sTy = llvm::StructType::get(types); | 1285 const llvm::StructType* sTy = llvm::StructType::get(types); |
1286 return llvm::ConstantStruct::get(sTy, inits); | 1286 return llvm::ConstantStruct::get(sTy, inits); |
1287 } | 1287 } |
1288 | 1288 |
1289 static llvm::Constant* build_offti_array(ClassDeclaration* cd, llvm::Constant* init) | 1289 static LLConstant* build_offti_array(ClassDeclaration* cd, LLConstant* init) |
1290 { | 1290 { |
1291 const llvm::StructType* initTy = isaStruct(init->getType()); | 1291 const llvm::StructType* initTy = isaStruct(init->getType()); |
1292 assert(initTy); | 1292 assert(initTy); |
1293 | 1293 |
1294 std::vector<llvm::Constant*> arrayInits; | 1294 std::vector<LLConstant*> arrayInits; |
1295 for (ClassDeclaration *cd2 = cd; cd2; cd2 = cd2->baseClass) | 1295 for (ClassDeclaration *cd2 = cd; cd2; cd2 = cd2->baseClass) |
1296 { | 1296 { |
1297 if (cd2->members) | 1297 if (cd2->members) |
1298 { | 1298 { |
1299 for (size_t i = 0; i < cd2->members->dim; i++) | 1299 for (size_t i = 0; i < cd2->members->dim; i++) |
1300 { | 1300 { |
1301 Dsymbol *sm = (Dsymbol *)cd2->members->data[i]; | 1301 Dsymbol *sm = (Dsymbol *)cd2->members->data[i]; |
1302 if (VarDeclaration* vd = sm->isVarDeclaration()) // is this enough? | 1302 if (VarDeclaration* vd = sm->isVarDeclaration()) // is this enough? |
1303 { | 1303 { |
1304 llvm::Constant* c = build_offti_entry(vd); | 1304 LLConstant* c = build_offti_entry(vd); |
1305 assert(c); | 1305 assert(c); |
1306 arrayInits.push_back(c); | 1306 arrayInits.push_back(c); |
1307 } | 1307 } |
1308 } | 1308 } |
1309 } | 1309 } |
1310 } | 1310 } |
1311 | 1311 |
1312 size_t ninits = arrayInits.size(); | 1312 size_t ninits = arrayInits.size(); |
1313 llvm::Constant* size = DtoConstSize_t(ninits); | 1313 LLConstant* size = DtoConstSize_t(ninits); |
1314 llvm::Constant* ptr; | 1314 LLConstant* ptr; |
1315 | 1315 |
1316 if (ninits > 0) { | 1316 if (ninits > 0) { |
1317 // OffsetTypeInfo type | 1317 // OffsetTypeInfo type |
1318 std::vector<const llvm::Type*> elemtypes; | 1318 std::vector<const LLType*> elemtypes; |
1319 elemtypes.push_back(DtoSize_t()); | 1319 elemtypes.push_back(DtoSize_t()); |
1320 const llvm::Type* tiTy = getPtrToType(Type::typeinfo->type->ir.type->get()); | 1320 const LLType* tiTy = getPtrToType(Type::typeinfo->type->ir.type->get()); |
1321 elemtypes.push_back(tiTy); | 1321 elemtypes.push_back(tiTy); |
1322 const llvm::StructType* sTy = llvm::StructType::get(elemtypes); | 1322 const llvm::StructType* sTy = llvm::StructType::get(elemtypes); |
1323 | 1323 |
1324 // array type | 1324 // array type |
1325 const llvm::ArrayType* arrTy = llvm::ArrayType::get(sTy, ninits); | 1325 const llvm::ArrayType* arrTy = llvm::ArrayType::get(sTy, ninits); |
1326 llvm::Constant* arrInit = llvm::ConstantArray::get(arrTy, arrayInits); | 1326 LLConstant* arrInit = llvm::ConstantArray::get(arrTy, arrayInits); |
1327 | 1327 |
1328 std::string name(cd->type->vtinfo->toChars()); | 1328 std::string name(cd->type->vtinfo->toChars()); |
1329 name.append("__OffsetTypeInfos"); | 1329 name.append("__OffsetTypeInfos"); |
1330 | 1330 |
1331 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrTy,true,DtoInternalLinkage(cd),arrInit,name,gIR->module); | 1331 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrTy,true,DtoInternalLinkage(cd),arrInit,name,gIR->module); |
1336 } | 1336 } |
1337 | 1337 |
1338 return DtoConstSlice(size, ptr); | 1338 return DtoConstSlice(size, ptr); |
1339 } | 1339 } |
1340 | 1340 |
1341 static llvm::Constant* build_class_dtor(ClassDeclaration* cd) | 1341 static LLConstant* build_class_dtor(ClassDeclaration* cd) |
1342 { | 1342 { |
1343 // construct the function | 1343 // construct the function |
1344 std::vector<const llvm::Type*> paramTypes; | 1344 std::vector<const LLType*> paramTypes; |
1345 paramTypes.push_back(getPtrToType(cd->type->ir.type->get())); | 1345 paramTypes.push_back(getPtrToType(cd->type->ir.type->get())); |
1346 | 1346 |
1347 const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy, paramTypes, false); | 1347 const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy, paramTypes, false); |
1348 | 1348 |
1349 if (cd->dtors.dim == 0) { | 1349 if (cd->dtors.dim == 0) { |
1359 std::string gname("_D"); | 1359 std::string gname("_D"); |
1360 gname.append(cd->mangle()); | 1360 gname.append(cd->mangle()); |
1361 gname.append("12__destructorMFZv"); | 1361 gname.append("12__destructorMFZv"); |
1362 | 1362 |
1363 llvm::Function* func = llvm::Function::Create(fnTy, DtoInternalLinkage(cd), gname, gIR->module); | 1363 llvm::Function* func = llvm::Function::Create(fnTy, DtoInternalLinkage(cd), gname, gIR->module); |
1364 llvm::Value* thisptr = func->arg_begin(); | 1364 LLValue* thisptr = func->arg_begin(); |
1365 thisptr->setName("this"); | 1365 thisptr->setName("this"); |
1366 | 1366 |
1367 llvm::BasicBlock* bb = llvm::BasicBlock::Create("entry", func); | 1367 llvm::BasicBlock* bb = llvm::BasicBlock::Create("entry", func); |
1368 IRBuilder builder(bb); | 1368 IRBuilder builder(bb); |
1369 | 1369 |
1443 assert(cd->ir.irStruct->vtbl); | 1443 assert(cd->ir.irStruct->vtbl); |
1444 assert(cd->ir.irStruct->constVtbl); | 1444 assert(cd->ir.irStruct->constVtbl); |
1445 } | 1445 } |
1446 | 1446 |
1447 // holds the list of initializers for llvm | 1447 // holds the list of initializers for llvm |
1448 std::vector<llvm::Constant*> inits; | 1448 std::vector<LLConstant*> inits; |
1449 | 1449 |
1450 ClassDeclaration* cinfo = ClassDeclaration::classinfo; | 1450 ClassDeclaration* cinfo = ClassDeclaration::classinfo; |
1451 DtoForceConstInitDsymbol(cinfo); | 1451 DtoForceConstInitDsymbol(cinfo); |
1452 assert(cinfo->ir.irStruct->constInit); | 1452 assert(cinfo->ir.irStruct->constInit); |
1453 | 1453 |
1454 llvm::Constant* c; | 1454 LLConstant* c; |
1455 | 1455 |
1456 // own vtable | 1456 // own vtable |
1457 c = cinfo->ir.irStruct->constInit->getOperand(0); | 1457 c = cinfo->ir.irStruct->constInit->getOperand(0); |
1458 assert(c); | 1458 assert(c); |
1459 inits.push_back(c); | 1459 inits.push_back(c); |
1461 // monitor | 1461 // monitor |
1462 c = cinfo->ir.irStruct->constInit->getOperand(1); | 1462 c = cinfo->ir.irStruct->constInit->getOperand(1); |
1463 inits.push_back(c); | 1463 inits.push_back(c); |
1464 | 1464 |
1465 // byte[] init | 1465 // byte[] init |
1466 const llvm::Type* byteptrty = getPtrToType(llvm::Type::Int8Ty); | 1466 const LLType* byteptrty = getPtrToType(llvm::Type::Int8Ty); |
1467 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { | 1467 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { |
1468 c = cinfo->ir.irStruct->constInit->getOperand(2); | 1468 c = cinfo->ir.irStruct->constInit->getOperand(2); |
1469 } | 1469 } |
1470 else { | 1470 else { |
1471 c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->init, byteptrty); | 1471 c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->init, byteptrty); |
1490 // vtbl array | 1490 // vtbl array |
1491 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { | 1491 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { |
1492 c = cinfo->ir.irStruct->constInit->getOperand(4); | 1492 c = cinfo->ir.irStruct->constInit->getOperand(4); |
1493 } | 1493 } |
1494 else { | 1494 else { |
1495 const llvm::Type* byteptrptrty = getPtrToType(byteptrty); | 1495 const LLType* byteptrptrty = getPtrToType(byteptrty); |
1496 assert(!cd->ir.irStruct->vtbl->getType()->isAbstract()); | 1496 assert(!cd->ir.irStruct->vtbl->getType()->isAbstract()); |
1497 c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->vtbl, byteptrptrty); | 1497 c = llvm::ConstantExpr::getBitCast(cd->ir.irStruct->vtbl, byteptrptrty); |
1498 assert(!cd->ir.irStruct->constVtbl->getType()->isAbstract()); | 1498 assert(!cd->ir.irStruct->constVtbl->getType()->isAbstract()); |
1499 size_t vtblsz = 0; | 1499 size_t vtblsz = 0; |
1500 llvm::ConstantArray* constVtblArray = llvm::dyn_cast<llvm::ConstantArray>(cd->ir.irStruct->constVtbl); | 1500 llvm::ConstantArray* constVtblArray = llvm::dyn_cast<llvm::ConstantArray>(cd->ir.irStruct->constVtbl); |
1509 IrStruct* irstruct = cd->ir.irStruct; | 1509 IrStruct* irstruct = cd->ir.irStruct; |
1510 if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos || cd->isAbstract()) { | 1510 if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos || cd->isAbstract()) { |
1511 c = cinfo->ir.irStruct->constInit->getOperand(5); | 1511 c = cinfo->ir.irStruct->constInit->getOperand(5); |
1512 } | 1512 } |
1513 else { | 1513 else { |
1514 const llvm::Type* t = cinfo->ir.irStruct->constInit->getOperand(5)->getType()->getContainedType(1); | 1514 const LLType* t = cinfo->ir.irStruct->constInit->getOperand(5)->getType()->getContainedType(1); |
1515 c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t); | 1515 c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t); |
1516 size_t iisz = irstruct->interfaceInfosTy->getNumElements(); | 1516 size_t iisz = irstruct->interfaceInfosTy->getNumElements(); |
1517 c = DtoConstSlice(DtoConstSize_t(iisz), c); | 1517 c = DtoConstSlice(DtoConstSize_t(iisz), c); |
1518 } | 1518 } |
1519 inits.push_back(c); | 1519 inits.push_back(c); |
1571 | 1571 |
1572 // default constructor | 1572 // default constructor |
1573 if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) { | 1573 if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) { |
1574 DtoForceDeclareDsymbol(cd->defaultCtor); | 1574 DtoForceDeclareDsymbol(cd->defaultCtor); |
1575 c = isaConstant(cd->defaultCtor->ir.irFunc->func); | 1575 c = isaConstant(cd->defaultCtor->ir.irFunc->func); |
1576 const llvm::Type* toTy = cinfo->ir.irStruct->constInit->getOperand(12)->getType(); | 1576 const LLType* toTy = cinfo->ir.irStruct->constInit->getOperand(12)->getType(); |
1577 c = llvm::ConstantExpr::getBitCast(c, toTy); | 1577 c = llvm::ConstantExpr::getBitCast(c, toTy); |
1578 } | 1578 } |
1579 else { | 1579 else { |
1580 c = cinfo->ir.irStruct->constInit->getOperand(12); | 1580 c = cinfo->ir.irStruct->constInit->getOperand(12); |
1581 } | 1581 } |
1587 Logger::cout() << "inits[" << i << "]: " << *inits[i] << '\n'; | 1587 Logger::cout() << "inits[" << i << "]: " << *inits[i] << '\n'; |
1588 }*/ | 1588 }*/ |
1589 | 1589 |
1590 // build the initializer | 1590 // build the initializer |
1591 const llvm::StructType* st = isaStruct(cinfo->ir.irStruct->constInit->getType()); | 1591 const llvm::StructType* st = isaStruct(cinfo->ir.irStruct->constInit->getType()); |
1592 llvm::Constant* finalinit = llvm::ConstantStruct::get(st, inits); | 1592 LLConstant* finalinit = llvm::ConstantStruct::get(st, inits); |
1593 //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n'; | 1593 //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n'; |
1594 | 1594 |
1595 cd->ir.irStruct->constClassInfo = finalinit; | 1595 cd->ir.irStruct->constClassInfo = finalinit; |
1596 cd->ir.irStruct->classInfo->setInitializer(finalinit); | 1596 cd->ir.irStruct->classInfo->setInitializer(finalinit); |
1597 } | 1597 } |