Mercurial > projects > ldc
comparison gen/classes.cpp @ 114:5880c12dba83 trunk
[svn r118] Fixed dynamic casts.
Fixed a few interface bugs.
author | lindquist |
---|---|
date | Sun, 25 Nov 2007 00:19:13 +0100 |
parents | 27b9f749d9fe |
children | 5ba6d286c941 |
comparison
equal
deleted
inserted
replaced
113:27b9f749d9fe | 114:5880c12dba83 |
---|---|
126 if (!ts->llvmType) | 126 if (!ts->llvmType) |
127 ts->llvmType = new llvm::PATypeHolder(structtype); | 127 ts->llvmType = new llvm::PATypeHolder(structtype); |
128 else | 128 else |
129 *ts->llvmType = structtype; | 129 *ts->llvmType = structtype; |
130 | 130 |
131 if (cd->parent->isModule()) { | 131 if (cd->isNested()) { |
132 assert(0 && "nested classes not implemented"); | |
133 } | |
134 else { | |
132 gIR->module->addTypeName(cd->mangle(), ts->llvmType->get()); | 135 gIR->module->addTypeName(cd->mangle(), ts->llvmType->get()); |
133 } | |
134 else { | |
135 assert(0 && "class parent is not a module"); | |
136 } | 136 } |
137 | 137 |
138 // build interface info type | 138 // build interface info type |
139 std::vector<const llvm::Type*> infoTypes; | 139 std::vector<const llvm::Type*> infoTypes; |
140 // ClassInfo classinfo | 140 // ClassInfo classinfo |
590 } | 590 } |
591 } | 591 } |
592 | 592 |
593 ////////////////////////////////////////////////////////////////////////////////////////// | 593 ////////////////////////////////////////////////////////////////////////////////////////// |
594 | 594 |
595 DValue* DtoCastObjectToInterface(DValue* val, Type* _to) | 595 DValue* DtoCastClass(DValue* val, Type* _to) |
596 { | |
597 Type* to = DtoDType(_to); | |
598 if (to->ty == Tpointer) { | |
599 const llvm::Type* tolltype = DtoType(_to); | |
600 llvm::Value* rval = DtoBitCast(val->getRVal(), tolltype); | |
601 return new DImValue(_to, rval); | |
602 } | |
603 | |
604 assert(to->ty == Tclass); | |
605 TypeClass* tc = (TypeClass*)to; | |
606 | |
607 Type* from = DtoDType(val->getType()); | |
608 TypeClass* fc = (TypeClass*)from; | |
609 | |
610 if (tc->sym->isInterfaceDeclaration()) { | |
611 assert(!fc->sym->isInterfaceDeclaration()); | |
612 return DtoDynamicCastObject(val, _to); | |
613 } | |
614 else { | |
615 int poffset; | |
616 if (fc->sym->isInterfaceDeclaration()) { | |
617 return DtoCastInterfaceToObject(val, _to); | |
618 } | |
619 else if (tc->sym->isBaseOf(fc->sym,NULL)) { | |
620 const llvm::Type* tolltype = DtoType(_to); | |
621 llvm::Value* rval = DtoBitCast(val->getRVal(), tolltype); | |
622 return new DImValue(_to, rval); | |
623 } | |
624 else { | |
625 return DtoDynamicCastObject(val, _to); | |
626 } | |
627 } | |
628 } | |
629 | |
630 ////////////////////////////////////////////////////////////////////////////////////////// | |
631 | |
632 DValue* DtoDynamicCastObject(DValue* val, Type* _to) | |
596 { | 633 { |
597 // call: | 634 // call: |
598 // Object _d_dynamic_cast(Object o, ClassInfo c) | 635 // Object _d_dynamic_cast(Object o, ClassInfo c) |
636 | |
637 DtoForceDeclareDsymbol(ClassDeclaration::object); | |
638 DtoForceDeclareDsymbol(ClassDeclaration::classinfo); | |
599 | 639 |
600 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_dynamic_cast"); | 640 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_dynamic_cast"); |
601 const llvm::FunctionType* funcTy = func->getFunctionType(); | 641 const llvm::FunctionType* funcTy = func->getFunctionType(); |
602 | 642 |
603 std::vector<llvm::Value*> args; | 643 std::vector<llvm::Value*> args; |
604 | 644 |
605 // Object o | 645 // Object o |
606 llvm::Value* tmp = val->getRVal(); | 646 llvm::Value* tmp = val->getRVal(); |
607 tmp = DtoBitCast(tmp, funcTy->getParamType(0)); | 647 tmp = DtoBitCast(tmp, funcTy->getParamType(0)); |
608 args.push_back(tmp); | 648 args.push_back(tmp); |
649 assert(funcTy->getParamType(0) == tmp->getType()); | |
609 | 650 |
610 // ClassInfo c | 651 // ClassInfo c |
611 TypeClass* to = (TypeClass*)DtoDType(_to); | 652 TypeClass* to = (TypeClass*)DtoDType(_to); |
612 DtoForceDeclareDsymbol(to->sym); | 653 DtoForceDeclareDsymbol(to->sym); |
613 assert(to->sym->llvmClass); | 654 assert(to->sym->llvmClass); |
614 args.push_back(to->sym->llvmClass); | 655 tmp = to->sym->llvmClass; |
656 // unfortunately this is needed as the implementation of object differs somehow from the declaration | |
657 // this could happen in user code as well :/ | |
658 tmp = DtoBitCast(tmp, funcTy->getParamType(1)); | |
659 args.push_back(tmp); | |
660 assert(funcTy->getParamType(1) == tmp->getType()); | |
615 | 661 |
616 // call it | 662 // call it |
617 llvm::Value* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "tmp"); | 663 llvm::Value* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "tmp"); |
664 | |
665 // cast return value | |
618 ret = DtoBitCast(ret, DtoType(_to)); | 666 ret = DtoBitCast(ret, DtoType(_to)); |
667 | |
619 return new DImValue(_to, ret); | 668 return new DImValue(_to, ret); |
620 } | 669 } |
621 | 670 |
622 ////////////////////////////////////////////////////////////////////////////////////////// | 671 ////////////////////////////////////////////////////////////////////////////////////////// |
623 | 672 |
624 DValue* DtoCastInterfaceToObject(DValue* val) | 673 DValue* DtoCastInterfaceToObject(DValue* val, Type* to) |
625 { | 674 { |
626 // call: | 675 // call: |
627 // Object _d_toObject(void* p) | 676 // Object _d_toObject(void* p) |
628 | 677 |
629 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_toObject"); | 678 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_toObject"); |
633 llvm::Value* tmp = val->getRVal(); | 682 llvm::Value* tmp = val->getRVal(); |
634 tmp = DtoBitCast(tmp, funcTy->getParamType(0)); | 683 tmp = DtoBitCast(tmp, funcTy->getParamType(0)); |
635 | 684 |
636 // call it | 685 // call it |
637 llvm::Value* ret = gIR->ir->CreateCall(func, tmp, "tmp"); | 686 llvm::Value* ret = gIR->ir->CreateCall(func, tmp, "tmp"); |
638 return new DImValue(ClassDeclaration::object->type, ret); | 687 |
688 // cast return value | |
689 if (to != NULL) | |
690 ret = DtoBitCast(ret, DtoType(to)); | |
691 else | |
692 to = ClassDeclaration::object->type; | |
693 | |
694 return new DImValue(to, ret); | |
639 } | 695 } |
640 | 696 |
641 ////////////////////////////////////////////////////////////////////////////////////////// | 697 ////////////////////////////////////////////////////////////////////////////////////////// |
642 | 698 |
643 void DtoDeclareClassInfo(ClassDeclaration* cd) | 699 void DtoDeclareClassInfo(ClassDeclaration* cd) |