comparison gen/classes.cpp @ 486:a34078905d01

Added pragma(llvmdc, "string") for misc per-module compiler configuration, currently "string" can only be "verbose" which forces -vv for module it appears in. Reimplemented support for nested functions/class using a new approach. Added error on taking address of intrinsic. Fixed problems with the ->syntaxCopy of TypeFunction delegate exp. Removed DtoDType and replaced all uses with ->toBasetype() instead. Removed unused inplace stuff. Fixed a bunch of issues in the runtime unittests, not complete yet. Added mini tests.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Sun, 10 Aug 2008 08:37:38 +0200
parents 672eb4893b55
children 577211114d6d
comparison
equal deleted inserted replaced
485:50f6e2337a6b 486:a34078905d01
784 } 784 }
785 } 785 }
786 786
787 ////////////////////////////////////////////////////////////////////////////////////////// 787 //////////////////////////////////////////////////////////////////////////////////////////
788 788
789 DValue* DtoNewClass(TypeClass* tc, NewExp* newexp) 789 DValue* DtoNewClass(Loc loc, TypeClass* tc, NewExp* newexp)
790 { 790 {
791 // resolve type 791 // resolve type
792 DtoForceDeclareDsymbol(tc->sym); 792 DtoForceDeclareDsymbol(tc->sym);
793 793
794 // allocate 794 // allocate
827 LLValue* dst = DtoGEPi(mem,0,idx,"tmp"); 827 LLValue* dst = DtoGEPi(mem,0,idx,"tmp");
828 Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n'; 828 Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n';
829 DtoStore(src, dst); 829 DtoStore(src, dst);
830 } 830 }
831 // set the context for nested classes 831 // set the context for nested classes
832 else if (tc->sym->isNested()) 832 else if (tc->sym->isNested() && tc->sym->vthis)
833 { 833 {
834 Logger::println("Resolving nested context"); 834 Logger::println("Resolving nested context");
835 LOG_SCOPE; 835 LOG_SCOPE;
836 836
837 // get context
838 LLValue* nest = DtoNestedContext(loc, tc->sym);
839
840 // store into right location
837 size_t idx = 2 + tc->sym->vthis->ir.irField->index; 841 size_t idx = 2 + tc->sym->vthis->ir.irField->index;
838 LLValue* gep = DtoGEPi(mem,0,idx,"tmp"); 842 LLValue* gep = DtoGEPi(mem,0,idx,"tmp");
839 843 DtoStore(DtoBitCast(nest, gep->getType()->getContainedType(0)), gep);
840 // this value might be zero if it was not necessary to generate it ...
841 LLValue* nest = gIR->func()->nestedVar;
842 // ... then revert to the this ptr if there is one
843 if (!nest)
844 nest = gIR->func()->thisVar;
845 // ... or just use zero, since it must be unused.
846 if (!nest)
847 nest = llvm::Constant::getNullValue(gep->getType()->getContainedType(0));
848 else
849 nest = DtoBitCast(nest, gep->getType()->getContainedType(0));
850 DtoStore(nest, gep);
851 } 844 }
852 845
853 // call constructor 846 // call constructor
854 if (newexp->member) 847 if (newexp->member)
855 { 848 {
858 DFuncValue dfn(newexp->member, newexp->member->ir.irFunc->func, mem); 851 DFuncValue dfn(newexp->member, newexp->member->ir.irFunc->func, mem);
859 return DtoCallFunction(newexp->loc, tc, &dfn, newexp->arguments); 852 return DtoCallFunction(newexp->loc, tc, &dfn, newexp->arguments);
860 } 853 }
861 854
862 // return default constructed class 855 // return default constructed class
863 return new DImValue(tc, mem, false); 856 return new DImValue(tc, mem);
864 } 857 }
865 858
866 ////////////////////////////////////////////////////////////////////////////////////////// 859 //////////////////////////////////////////////////////////////////////////////////////////
867 860
868 void DtoInitClass(TypeClass* tc, LLValue* dst) 861 void DtoInitClass(TypeClass* tc, LLValue* dst)
910 DValue* DtoCastClass(DValue* val, Type* _to) 903 DValue* DtoCastClass(DValue* val, Type* _to)
911 { 904 {
912 Logger::println("DtoCastClass(%s, %s)", val->getType()->toChars(), _to->toChars()); 905 Logger::println("DtoCastClass(%s, %s)", val->getType()->toChars(), _to->toChars());
913 LOG_SCOPE; 906 LOG_SCOPE;
914 907
915 Type* to = DtoDType(_to); 908 Type* to = _to->toBasetype();
916 if (to->ty == Tpointer) { 909 if (to->ty == Tpointer) {
917 const LLType* tolltype = DtoType(_to); 910 const LLType* tolltype = DtoType(_to);
918 LLValue* rval = DtoBitCast(val->getRVal(), tolltype); 911 LLValue* rval = DtoBitCast(val->getRVal(), tolltype);
919 return new DImValue(_to, rval); 912 return new DImValue(_to, rval);
920 } 913 }
921 914
922 assert(to->ty == Tclass); 915 assert(to->ty == Tclass);
923 TypeClass* tc = (TypeClass*)to; 916 TypeClass* tc = (TypeClass*)to;
924 917
925 Type* from = DtoDType(val->getType()); 918 Type* from = val->getType()->toBasetype();
926 TypeClass* fc = (TypeClass*)from; 919 TypeClass* fc = (TypeClass*)from;
927 920
928 if (tc->sym->isInterfaceDeclaration()) { 921 if (tc->sym->isInterfaceDeclaration()) {
929 Logger::println("to interface"); 922 Logger::println("to interface");
930 if (fc->sym->isInterfaceDeclaration()) { 923 if (fc->sym->isInterfaceDeclaration()) {
975 LLValue* obj = val->getRVal(); 968 LLValue* obj = val->getRVal();
976 obj = DtoBitCast(obj, funcTy->getParamType(0)); 969 obj = DtoBitCast(obj, funcTy->getParamType(0));
977 assert(funcTy->getParamType(0) == obj->getType()); 970 assert(funcTy->getParamType(0) == obj->getType());
978 971
979 // ClassInfo c 972 // ClassInfo c
980 TypeClass* to = (TypeClass*)DtoDType(_to); 973 TypeClass* to = (TypeClass*)_to->toBasetype();
981 DtoForceDeclareDsymbol(to->sym); 974 DtoForceDeclareDsymbol(to->sym);
982 assert(to->sym->ir.irStruct->classInfo); 975 assert(to->sym->ir.irStruct->classInfo);
983 LLValue* cinfo = to->sym->ir.irStruct->classInfo; 976 LLValue* cinfo = to->sym->ir.irStruct->classInfo;
984 // unfortunately this is needed as the implementation of object differs somehow from the declaration 977 // unfortunately this is needed as the implementation of object differs somehow from the declaration
985 // this could happen in user code as well :/ 978 // this could happen in user code as well :/
1039 // void* p 1032 // void* p
1040 LLValue* ptr = val->getRVal(); 1033 LLValue* ptr = val->getRVal();
1041 ptr = DtoBitCast(ptr, funcTy->getParamType(0)); 1034 ptr = DtoBitCast(ptr, funcTy->getParamType(0));
1042 1035
1043 // ClassInfo c 1036 // ClassInfo c
1044 TypeClass* to = (TypeClass*)DtoDType(_to); 1037 TypeClass* to = (TypeClass*)_to->toBasetype();
1045 DtoForceDeclareDsymbol(to->sym); 1038 DtoForceDeclareDsymbol(to->sym);
1046 assert(to->sym->ir.irStruct->classInfo); 1039 assert(to->sym->ir.irStruct->classInfo);
1047 LLValue* cinfo = to->sym->ir.irStruct->classInfo; 1040 LLValue* cinfo = to->sym->ir.irStruct->classInfo;
1048 // unfortunately this is needed as the implementation of object differs somehow from the declaration 1041 // unfortunately this is needed as the implementation of object differs somehow from the declaration
1049 // this could happen in user code as well :/ 1042 // this could happen in user code as well :/
1114 1107
1115 IrStruct* irstruct = cd->ir.irStruct; 1108 IrStruct* irstruct = cd->ir.irStruct;
1116 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { 1109 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
1117 VarDeclaration* vd = i->second.var; 1110 VarDeclaration* vd = i->second.var;
1118 assert(vd); 1111 assert(vd);
1119 Type* vdtype = DtoDType(vd->type); 1112 Type* vdtype = vd->type->toBasetype();
1120 //Logger::println("found %u type %s", vd->offset, vdtype->toChars()); 1113 //Logger::println("found %u type %s", vd->offset, vdtype->toChars());
1121 assert(vd->ir.irField->index >= 0); 1114 assert(vd->ir.irField->index >= 0);
1122 if (os == vd->offset && vdtype->toBasetype() == t->toBasetype()) { 1115 if (os == vd->offset && vdtype->toBasetype() == t->toBasetype()) {
1123 Logger::println("found %s %s", vdtype->toChars(), vd->toChars()); 1116 Logger::println("found %s %s", vdtype->toChars(), vd->toChars());
1124 idxs.push_back(vd->ir.irField->index + dataoffset); 1117 idxs.push_back(vd->ir.irField->index + dataoffset);
1171 1164
1172 LLValue* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl) 1165 LLValue* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl)
1173 { 1166 {
1174 assert(fdecl->isVirtual());//fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual())); 1167 assert(fdecl->isVirtual());//fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual()));
1175 assert(fdecl->vtblIndex > 0); 1168 assert(fdecl->vtblIndex > 0);
1176 assert(DtoDType(inst->getType())->ty == Tclass); 1169 assert(inst->getType()->toBasetype()->ty == Tclass);
1177 1170
1178 LLValue* vthis = inst->getRVal(); 1171 LLValue* vthis = inst->getRVal();
1179 Logger::cout() << "vthis: " << *vthis << '\n'; 1172 Logger::cout() << "vthis: " << *vthis << '\n';
1180 1173
1181 LLValue* funcval; 1174 LLValue* funcval;