Mercurial > projects > ldc
comparison gen/toir.cpp @ 113:27b9f749d9fe trunk
[svn r117] Initial working implementation of interfaces.
Groundwork for all the different types of class/interface casts laid out.
author | lindquist |
---|---|
date | Sat, 24 Nov 2007 06:33:00 +0100 |
parents | 5ab8e92611f9 |
children | 5880c12dba83 |
comparison
equal
deleted
inserted
replaced
112:368547b1cbe6 | 113:27b9f749d9fe |
---|---|
1228 | 1228 |
1229 DValue* a = e1->toElem(p); | 1229 DValue* a = e1->toElem(p); |
1230 | 1230 |
1231 if (p->topexp() && p->topexp()->e1 == this) { | 1231 if (p->topexp() && p->topexp()->e1 == this) { |
1232 Logger::println("lval PtrExp"); | 1232 Logger::println("lval PtrExp"); |
1233 //if (a->isField()) return a; | |
1234 return new DVarValue(type, a->getRVal(), true); | 1233 return new DVarValue(type, a->getRVal(), true); |
1235 } | 1234 } |
1236 | 1235 |
1236 // this should be deterministic but right now lvalue casts don't propagate lvalueness !?! | |
1237 llvm::Value* lv = a->getRVal(); | 1237 llvm::Value* lv = a->getRVal(); |
1238 llvm::Value* v = lv; | 1238 llvm::Value* v = lv; |
1239 if (DtoCanLoad(v)) | 1239 if (DtoCanLoad(v)) |
1240 v = DtoLoad(v); | 1240 v = DtoLoad(v); |
1241 return new DLRValue(e1->type, lv, type, v); | 1241 return new DLRValue(e1->type, lv, type, v); |
1251 DValue* l = e1->toElem(p); | 1251 DValue* l = e1->toElem(p); |
1252 | 1252 |
1253 Type* t = DtoDType(type); | 1253 Type* t = DtoDType(type); |
1254 Type* e1type = DtoDType(e1->type); | 1254 Type* e1type = DtoDType(e1->type); |
1255 | 1255 |
1256 Logger::print("e1->type=%s\n", e1type->toChars()); | 1256 Logger::print("e1type=%s\n", e1type->toChars()); |
1257 | 1257 |
1258 if (VarDeclaration* vd = var->isVarDeclaration()) { | 1258 if (VarDeclaration* vd = var->isVarDeclaration()) { |
1259 llvm::Value* arrptr; | 1259 llvm::Value* arrptr; |
1260 if (e1type->ty == Tpointer) { | 1260 if (e1type->ty == Tpointer) { |
1261 assert(e1type->next->ty == Tstruct); | 1261 assert(e1type->next->ty == Tstruct); |
1263 Logger::println("Struct member offset:%d", vd->offset); | 1263 Logger::println("Struct member offset:%d", vd->offset); |
1264 llvm::Value* src = l->getRVal(); | 1264 llvm::Value* src = l->getRVal(); |
1265 std::vector<unsigned> vdoffsets; | 1265 std::vector<unsigned> vdoffsets; |
1266 arrptr = DtoIndexStruct(src, ts->sym, vd->type, vd->offset, vdoffsets); | 1266 arrptr = DtoIndexStruct(src, ts->sym, vd->type, vd->offset, vdoffsets); |
1267 } | 1267 } |
1268 else if (e1->type->ty == Tclass) { | 1268 else if (e1type->ty == Tclass) { |
1269 TypeClass* tc = (TypeClass*)e1type; | 1269 TypeClass* tc = (TypeClass*)e1type; |
1270 Logger::println("Class member offset: %d", vd->offset); | 1270 Logger::println("Class member offset: %d", vd->offset); |
1271 std::vector<unsigned> vdoffsets(1,0); | 1271 std::vector<unsigned> vdoffsets(1,0); |
1272 tc->sym->offsetToIndex(vd->type, vd->offset, vdoffsets); | 1272 tc->sym->offsetToIndex(vd->type, vd->offset, vdoffsets); |
1273 llvm::Value* src = l->getRVal(); | 1273 llvm::Value* src = l->getRVal(); |
1280 Logger::cout() << "mem: " << *arrptr << '\n'; | 1280 Logger::cout() << "mem: " << *arrptr << '\n'; |
1281 return new DVarValue(vd, arrptr, true); | 1281 return new DVarValue(vd, arrptr, true); |
1282 } | 1282 } |
1283 else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) | 1283 else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) |
1284 { | 1284 { |
1285 if (fdecl->llvmValue == 0) | 1285 DtoResolveDsymbol(fdecl); |
1286 { | 1286 |
1287 DtoForceDeclareDsymbol(fdecl); | 1287 llvm::Value* funcval; |
1288 } | 1288 llvm::Value* vthis2 = 0; |
1289 | 1289 if (e1type->ty == Tclass) { |
1290 llvm::Value* funcval = fdecl->llvmValue; | 1290 TypeClass* tc = (TypeClass*)e1type; |
1291 if (tc->sym->isInterfaceDeclaration()) { | |
1292 vthis2 = DtoCastInterfaceToObject(l)->getRVal(); | |
1293 } | |
1294 } | |
1291 llvm::Value* vthis = l->getRVal(); | 1295 llvm::Value* vthis = l->getRVal(); |
1292 unsigned cc = (unsigned)-1; | 1296 if (!vthis2) vthis2 = vthis; |
1297 //unsigned cc = (unsigned)-1; | |
1293 | 1298 |
1294 // virtual call | 1299 // virtual call |
1295 if (!fdecl->isFinal() && fdecl->isVirtual()) { | 1300 if (!fdecl->isFinal() && fdecl->isVirtual()) { |
1296 assert(fdecl->vtblIndex > 0); | 1301 assert(fdecl->vtblIndex > 0); |
1297 assert(e1type->ty == Tclass); | 1302 assert(e1type->ty == Tclass); |
1301 Logger::cout() << "vthis: " << *vthis << '\n'; | 1306 Logger::cout() << "vthis: " << *vthis << '\n'; |
1302 funcval = DtoGEP(vthis, zero, zero, "tmp", p->scopebb()); | 1307 funcval = DtoGEP(vthis, zero, zero, "tmp", p->scopebb()); |
1303 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); | 1308 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); |
1304 funcval = DtoGEP(funcval, zero, vtblidx, toChars(), p->scopebb()); | 1309 funcval = DtoGEP(funcval, zero, vtblidx, toChars(), p->scopebb()); |
1305 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); | 1310 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); |
1306 assert(funcval->getType() == fdecl->llvmValue->getType()); | 1311 //assert(funcval->getType() == DtoType(fdecl->type)); |
1307 cc = DtoCallingConv(fdecl->linkage); | 1312 //cc = DtoCallingConv(fdecl->linkage); |
1308 } | 1313 } |
1309 return new DFuncValue(fdecl, funcval, vthis); | 1314 // static call |
1315 else { | |
1316 DtoForceDeclareDsymbol(fdecl); | |
1317 funcval = fdecl->llvmValue; | |
1318 assert(funcval); | |
1319 //assert(funcval->getType() == DtoType(fdecl->type)); | |
1320 } | |
1321 return new DFuncValue(fdecl, funcval, vthis2); | |
1310 } | 1322 } |
1311 else { | 1323 else { |
1312 printf("unknown: %s\n", var->toChars()); | 1324 printf("unknown: %s\n", var->toChars()); |
1313 } | 1325 } |
1314 | 1326 |
1827 LOG_SCOPE; | 1839 LOG_SCOPE; |
1828 | 1840 |
1829 //assert(e1->type->ty != Tclass); | 1841 //assert(e1->type->ty != Tclass); |
1830 | 1842 |
1831 DValue* v = e1->toElem(p); | 1843 DValue* v = e1->toElem(p); |
1832 llvm::Value* val = v->getRVal(); | 1844 const llvm::Type* t = DtoType(v->getType()); |
1833 llvm::Value* ldval = 0; | 1845 llvm::Value* ldval = 0; |
1834 | |
1835 const llvm::Type* t = val->getType(); | |
1836 llvm::Constant* z = llvm::Constant::getNullValue(t); | 1846 llvm::Constant* z = llvm::Constant::getNullValue(t); |
1837 | 1847 |
1838 Type* e1type = DtoDType(e1->type); | 1848 Type* e1type = DtoDType(e1->type); |
1839 | 1849 |
1840 if (e1type->ty == Tpointer) { | 1850 if (e1type->ty == Tpointer) { |
1851 llvm::Value* val = v->getRVal(); | |
1841 Logger::cout() << *z << '\n'; | 1852 Logger::cout() << *z << '\n'; |
1842 Logger::cout() << *val << '\n'; | 1853 Logger::cout() << *val << '\n'; |
1843 new llvm::FreeInst(val, p->scopebb()); | 1854 new llvm::FreeInst(val, p->scopebb()); |
1844 new llvm::StoreInst(z, v->getLVal(), p->scopebb()); | 1855 new llvm::StoreInst(z, v->getLVal(), p->scopebb()); |
1845 } | 1856 } |
1846 else if (e1type->ty == Tclass) { | 1857 else if (e1type->ty == Tclass) { |
1847 TypeClass* tc = (TypeClass*)e1type; | 1858 TypeClass* tc = (TypeClass*)e1type; |
1848 DtoCallClassDtors(tc, val); | 1859 llvm::Value* val = 0; |
1860 if (tc->sym->dtors.dim > 0) { | |
1861 val = v->getRVal(); | |
1862 DtoCallClassDtors(tc, val); | |
1863 } | |
1849 | 1864 |
1850 if (DVarValue* vv = v->isVar()) { | 1865 if (DVarValue* vv = v->isVar()) { |
1851 if (vv->var && !vv->var->onstack) | 1866 if (vv->var && !vv->var->onstack) { |
1867 if (!val) val = v->getRVal(); | |
1852 new llvm::FreeInst(val, p->scopebb()); | 1868 new llvm::FreeInst(val, p->scopebb()); |
1869 } | |
1853 } | 1870 } |
1854 new llvm::StoreInst(z, v->getLVal(), p->scopebb()); | 1871 new llvm::StoreInst(z, v->getLVal(), p->scopebb()); |
1855 } | 1872 } |
1856 else if (e1type->ty == Tarray) { | 1873 else if (e1type->ty == Tarray) { |
1857 // must be on the heap (correct?) | 1874 // must be on the heap (correct?) |
1875 llvm::Value* val = v->getRVal(); | |
1858 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1876 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
1859 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); | 1877 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); |
1860 llvm::Value* ptr = DtoGEP(val,zero,one,"tmp",p->scopebb()); | 1878 llvm::Value* ptr = DtoGEP(val,zero,one,"tmp",p->scopebb()); |
1861 ptr = new llvm::LoadInst(ptr,"tmp",p->scopebb()); | 1879 ptr = new llvm::LoadInst(ptr,"tmp",p->scopebb()); |
1862 new llvm::FreeInst(ptr, p->scopebb()); | 1880 new llvm::FreeInst(ptr, p->scopebb()); |