Mercurial > projects > ldc
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; |