Mercurial > projects > ldc
comparison gen/classes.cpp @ 121:9c79b61fb638 trunk
[svn r125] Renamed/moved a few backend member inside DMD structures for consistency.
Unit tests are now implemented.
author | lindquist |
---|---|
date | Tue, 27 Nov 2007 03:09:36 +0100 |
parents | 56a21f3e5d3e |
children | 7f9a0a58394b |
comparison
equal
deleted
inserted
replaced
120:5ce8ab11e75a | 121:9c79b61fb638 |
---|---|
303 std::string initname("_D"); | 303 std::string initname("_D"); |
304 initname.append(cd->mangle()); | 304 initname.append(cd->mangle()); |
305 initname.append("6__initZ"); | 305 initname.append("6__initZ"); |
306 | 306 |
307 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module); | 307 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module); |
308 ts->llvmInit = initvar; | 308 cd->llvmInit = initvar; |
309 } | 309 } |
310 | 310 |
311 gIR->classes.pop_back(); | 311 gIR->classes.pop_back(); |
312 gIR->structs.pop_back(); | 312 gIR->structs.pop_back(); |
313 | 313 |
392 } | 392 } |
393 #endif | 393 #endif |
394 | 394 |
395 llvm::Constant* _init = llvm::ConstantStruct::get(structtype, fieldinits); | 395 llvm::Constant* _init = llvm::ConstantStruct::get(structtype, fieldinits); |
396 assert(_init); | 396 assert(_init); |
397 cd->llvmInitZ = _init; | 397 cd->llvmConstInit = _init; |
398 | 398 |
399 // generate vtable initializer | 399 // generate vtable initializer |
400 std::vector<llvm::Constant*> sinits; | 400 std::vector<llvm::Constant*> sinits; |
401 | 401 |
402 for (int k=0; k < cd->vtbl.dim; k++) | 402 for (int k=0; k < cd->vtbl.dim; k++) |
522 | 522 |
523 bool def = false; | 523 bool def = false; |
524 if (cd->parent->isModule() && cd->getModule() == gIR->dmodule) { | 524 if (cd->parent->isModule() && cd->getModule() == gIR->dmodule) { |
525 // interfaces don't have initializers | 525 // interfaces don't have initializers |
526 if (!cd->isInterfaceDeclaration()) { | 526 if (!cd->isInterfaceDeclaration()) { |
527 ts->llvmInit->setInitializer(cd->llvmInitZ); | 527 cd->llvmInit->setInitializer(cd->llvmConstInit); |
528 cd->llvmVtbl->setInitializer(cd->llvmConstVtbl); | 528 cd->llvmVtbl->setInitializer(cd->llvmConstVtbl); |
529 | 529 |
530 // initialize interface vtables | 530 // initialize interface vtables |
531 IRStruct* irstruct = cd->llvmIRStruct; | 531 IRStruct* irstruct = cd->llvmIRStruct; |
532 std::vector<llvm::Constant*> infoInits; | 532 std::vector<llvm::Constant*> infoInits; |
577 assert(tc->sym->llvmVtbl); | 577 assert(tc->sym->llvmVtbl); |
578 new llvm::StoreInst(tc->sym->llvmVtbl, vtblvar, gIR->scopebb()); | 578 new llvm::StoreInst(tc->sym->llvmVtbl, vtblvar, gIR->scopebb()); |
579 | 579 |
580 // copy the static initializer | 580 // copy the static initializer |
581 if (n > 0) { | 581 if (n > 0) { |
582 assert(tc->llvmInit); | 582 assert(tc->sym->llvmInit); |
583 assert(dst->getType() == tc->llvmInit->getType()); | 583 assert(dst->getType() == tc->sym->llvmInit->getType()); |
584 | 584 |
585 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty); | 585 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty); |
586 | 586 |
587 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb()); | 587 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb()); |
588 dstarr = DtoGEPi(dstarr,size_t_size,"tmp",gIR->scopebb()); | 588 dstarr = DtoGEPi(dstarr,size_t_size,"tmp",gIR->scopebb()); |
589 | 589 |
590 llvm::Value* srcarr = new llvm::BitCastInst(tc->llvmInit,arrty,"tmp",gIR->scopebb()); | 590 llvm::Value* srcarr = new llvm::BitCastInst(tc->sym->llvmInit,arrty,"tmp",gIR->scopebb()); |
591 srcarr = DtoGEPi(srcarr,size_t_size,"tmp",gIR->scopebb()); | 591 srcarr = DtoGEPi(srcarr,size_t_size,"tmp",gIR->scopebb()); |
592 | 592 |
593 llvm::Function* fn = LLVM_DeclareMemCpy32(); | 593 llvm::Function* fn = LLVM_DeclareMemCpy32(); |
594 std::vector<llvm::Value*> llargs; | 594 std::vector<llvm::Value*> llargs; |
595 llargs.resize(4); | 595 llargs.resize(4); |
910 assert(cd->type->ty == Tclass); | 910 assert(cd->type->ty == Tclass); |
911 assert(cd->llvmClass); | 911 assert(cd->llvmClass); |
912 | 912 |
913 TypeClass* cdty = (TypeClass*)cd->type; | 913 TypeClass* cdty = (TypeClass*)cd->type; |
914 if (!cd->isInterfaceDeclaration()) { | 914 if (!cd->isInterfaceDeclaration()) { |
915 assert(cd->llvmInitZ); | 915 assert(cd->llvmInit); |
916 assert(cd->llvmConstInit); | |
916 assert(cd->llvmVtbl); | 917 assert(cd->llvmVtbl); |
917 assert(cd->llvmConstVtbl); | 918 assert(cd->llvmConstVtbl); |
918 assert(cdty->llvmInit); | |
919 } | 919 } |
920 | 920 |
921 // holds the list of initializers for llvm | 921 // holds the list of initializers for llvm |
922 std::vector<llvm::Constant*> inits; | 922 std::vector<llvm::Constant*> inits; |
923 | 923 |
924 ClassDeclaration* cinfo = ClassDeclaration::classinfo; | 924 ClassDeclaration* cinfo = ClassDeclaration::classinfo; |
925 DtoForceConstInitDsymbol(cinfo); | 925 DtoForceConstInitDsymbol(cinfo); |
926 assert(cinfo->llvmInitZ); | 926 assert(cinfo->llvmConstInit); |
927 | 927 |
928 llvm::Constant* c; | 928 llvm::Constant* c; |
929 | 929 |
930 // own vtable | 930 // own vtable |
931 c = cinfo->llvmInitZ->getOperand(0); | 931 c = cinfo->llvmConstInit->getOperand(0); |
932 assert(c); | 932 assert(c); |
933 inits.push_back(c); | 933 inits.push_back(c); |
934 | 934 |
935 // monitor | 935 // monitor |
936 c = cinfo->llvmInitZ->getOperand(1); | 936 c = cinfo->llvmConstInit->getOperand(1); |
937 inits.push_back(c); | 937 inits.push_back(c); |
938 | 938 |
939 // byte[] init | 939 // byte[] init |
940 const llvm::Type* byteptrty = llvm::PointerType::get(llvm::Type::Int8Ty); | 940 const llvm::Type* byteptrty = llvm::PointerType::get(llvm::Type::Int8Ty); |
941 if (cd->isInterfaceDeclaration()) { | 941 if (cd->isInterfaceDeclaration()) { |
942 c = cinfo->llvmInitZ->getOperand(2); | 942 c = cinfo->llvmConstInit->getOperand(2); |
943 } | 943 } |
944 else { | 944 else { |
945 c = llvm::ConstantExpr::getBitCast(cdty->llvmInit, byteptrty); | 945 c = llvm::ConstantExpr::getBitCast(cd->llvmInit, byteptrty); |
946 assert(!cd->llvmInitZ->getType()->isAbstract()); | 946 assert(!cd->llvmConstInit->getType()->isAbstract()); |
947 size_t initsz = gTargetData->getTypeSize(cd->llvmInitZ->getType()); | 947 size_t initsz = gTargetData->getTypeSize(cd->llvmConstInit->getType()); |
948 c = DtoConstSlice(DtoConstSize_t(initsz), c); | 948 c = DtoConstSlice(DtoConstSize_t(initsz), c); |
949 } | 949 } |
950 inits.push_back(c); | 950 inits.push_back(c); |
951 | 951 |
952 // class name | 952 // class name |
961 c = DtoConstString(name); | 961 c = DtoConstString(name); |
962 inits.push_back(c); | 962 inits.push_back(c); |
963 | 963 |
964 // vtbl array | 964 // vtbl array |
965 if (cd->isInterfaceDeclaration()) { | 965 if (cd->isInterfaceDeclaration()) { |
966 c = cinfo->llvmInitZ->getOperand(4); | 966 c = cinfo->llvmConstInit->getOperand(4); |
967 } | 967 } |
968 else { | 968 else { |
969 const llvm::Type* byteptrptrty = llvm::PointerType::get(byteptrty); | 969 const llvm::Type* byteptrptrty = llvm::PointerType::get(byteptrty); |
970 assert(!cd->llvmVtbl->getType()->isAbstract()); | 970 assert(!cd->llvmVtbl->getType()->isAbstract()); |
971 c = llvm::ConstantExpr::getBitCast(cd->llvmVtbl, byteptrptrty); | 971 c = llvm::ConstantExpr::getBitCast(cd->llvmVtbl, byteptrptrty); |
976 inits.push_back(c); | 976 inits.push_back(c); |
977 | 977 |
978 // interfaces array | 978 // interfaces array |
979 IRStruct* irstruct = cd->llvmIRStruct; | 979 IRStruct* irstruct = cd->llvmIRStruct; |
980 if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos) { | 980 if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos) { |
981 c = cinfo->llvmInitZ->getOperand(5); | 981 c = cinfo->llvmConstInit->getOperand(5); |
982 } | 982 } |
983 else { | 983 else { |
984 const llvm::Type* t = cinfo->llvmInitZ->getOperand(5)->getType()->getContainedType(1); | 984 const llvm::Type* t = cinfo->llvmConstInit->getOperand(5)->getType()->getContainedType(1); |
985 c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t); | 985 c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t); |
986 size_t iisz = irstruct->interfaceInfosTy->getNumElements(); | 986 size_t iisz = irstruct->interfaceInfosTy->getNumElements(); |
987 c = DtoConstSlice(DtoConstSize_t(iisz), c); | 987 c = DtoConstSlice(DtoConstSize_t(iisz), c); |
988 } | 988 } |
989 inits.push_back(c); | 989 inits.push_back(c); |
995 assert(c); | 995 assert(c); |
996 inits.push_back(c); | 996 inits.push_back(c); |
997 } | 997 } |
998 else { | 998 else { |
999 // null | 999 // null |
1000 c = cinfo->llvmInitZ->getOperand(6); | 1000 c = cinfo->llvmConstInit->getOperand(6); |
1001 inits.push_back(c); | 1001 inits.push_back(c); |
1002 } | 1002 } |
1003 | 1003 |
1004 // destructor | 1004 // destructor |
1005 if (cd->isInterfaceDeclaration()) { | 1005 if (cd->isInterfaceDeclaration()) { |
1006 c = cinfo->llvmInitZ->getOperand(7); | 1006 c = cinfo->llvmConstInit->getOperand(7); |
1007 } | 1007 } |
1008 else { | 1008 else { |
1009 c = build_class_dtor(cd); | 1009 c = build_class_dtor(cd); |
1010 } | 1010 } |
1011 inits.push_back(c); | 1011 inits.push_back(c); |
1012 | 1012 |
1013 // invariant | 1013 // invariant |
1014 // TODO | 1014 // TODO |
1015 c = cinfo->llvmInitZ->getOperand(8); | 1015 c = cinfo->llvmConstInit->getOperand(8); |
1016 inits.push_back(c); | 1016 inits.push_back(c); |
1017 | 1017 |
1018 // uint flags | 1018 // uint flags |
1019 if (cd->isInterfaceDeclaration()) { | 1019 if (cd->isInterfaceDeclaration()) { |
1020 c = cinfo->llvmInitZ->getOperand(9); | 1020 c = cinfo->llvmConstInit->getOperand(9); |
1021 } | 1021 } |
1022 else { | 1022 else { |
1023 uint flags = build_classinfo_flags(cd); | 1023 uint flags = build_classinfo_flags(cd); |
1024 c = DtoConstUint(flags); | 1024 c = DtoConstUint(flags); |
1025 } | 1025 } |
1026 inits.push_back(c); | 1026 inits.push_back(c); |
1027 | 1027 |
1028 // allocator | 1028 // allocator |
1029 // TODO | 1029 // TODO |
1030 c = cinfo->llvmInitZ->getOperand(10); | 1030 c = cinfo->llvmConstInit->getOperand(10); |
1031 inits.push_back(c); | 1031 inits.push_back(c); |
1032 | 1032 |
1033 // offset typeinfo | 1033 // offset typeinfo |
1034 if (cd->isInterfaceDeclaration()) { | 1034 if (cd->isInterfaceDeclaration()) { |
1035 c = cinfo->llvmInitZ->getOperand(11); | 1035 c = cinfo->llvmConstInit->getOperand(11); |
1036 } | 1036 } |
1037 else { | 1037 else { |
1038 c = build_offti_array(cd, cinfo->llvmInitZ->getOperand(11)); | 1038 c = build_offti_array(cd, cinfo->llvmConstInit->getOperand(11)); |
1039 } | 1039 } |
1040 inits.push_back(c); | 1040 inits.push_back(c); |
1041 | 1041 |
1042 // default constructor | 1042 // default constructor |
1043 if (cd->defaultCtor && !cd->isInterfaceDeclaration()) { | 1043 if (cd->defaultCtor && !cd->isInterfaceDeclaration()) { |
1044 DtoForceDeclareDsymbol(cd->defaultCtor); | 1044 DtoForceDeclareDsymbol(cd->defaultCtor); |
1045 c = isaConstant(cd->defaultCtor->llvmValue); | 1045 c = isaConstant(cd->defaultCtor->llvmValue); |
1046 const llvm::Type* toTy = cinfo->llvmInitZ->getOperand(12)->getType(); | 1046 const llvm::Type* toTy = cinfo->llvmConstInit->getOperand(12)->getType(); |
1047 c = llvm::ConstantExpr::getBitCast(c, toTy); | 1047 c = llvm::ConstantExpr::getBitCast(c, toTy); |
1048 } | 1048 } |
1049 else { | 1049 else { |
1050 c = cinfo->llvmInitZ->getOperand(12); | 1050 c = cinfo->llvmConstInit->getOperand(12); |
1051 } | 1051 } |
1052 inits.push_back(c); | 1052 inits.push_back(c); |
1053 | 1053 |
1054 /*size_t n = inits.size(); | 1054 /*size_t n = inits.size(); |
1055 for (size_t i=0; i<n; ++i) | 1055 for (size_t i=0; i<n; ++i) |
1056 { | 1056 { |
1057 Logger::cout() << "inits[" << i << "]: " << *inits[i] << '\n'; | 1057 Logger::cout() << "inits[" << i << "]: " << *inits[i] << '\n'; |
1058 }*/ | 1058 }*/ |
1059 | 1059 |
1060 // build the initializer | 1060 // build the initializer |
1061 const llvm::StructType* st = isaStruct(cinfo->llvmInitZ->getType()); | 1061 const llvm::StructType* st = isaStruct(cinfo->llvmConstInit->getType()); |
1062 llvm::Constant* finalinit = llvm::ConstantStruct::get(st, inits); | 1062 llvm::Constant* finalinit = llvm::ConstantStruct::get(st, inits); |
1063 //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n'; | 1063 //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n'; |
1064 | 1064 |
1065 cd->llvmClassZ = finalinit; | 1065 cd->llvmConstClass = finalinit; |
1066 cd->llvmClass->setInitializer(finalinit); | 1066 cd->llvmClass->setInitializer(finalinit); |
1067 } | 1067 } |