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());