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 }