comparison gen/tollvm.c @ 77:714057ff2dbb trunk

[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
author lindquist
date Wed, 31 Oct 2007 09:34:18 +0100
parents b706170e24a9
children 2332006e1fa4
comparison
equal deleted inserted replaced
76:9e1bd80a7e98 77:714057ff2dbb
1385 llargs[2] = nbytes; 1385 llargs[2] = nbytes;
1386 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); 1386 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
1387 1387
1388 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); 1388 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
1389 } 1389 }
1390
1391 //////////////////////////////////////////////////////////////////////////////////////////
1392
1393 llvm::Value* LLVM_DtoIndexStruct(llvm::Value* ptr, StructDeclaration* sd, Type* t, unsigned os, std::vector<unsigned>& idxs)
1394 {
1395 Logger::println("checking for offset %u type %s:", os, t->toChars());
1396 LOG_SCOPE;
1397
1398 if (idxs.empty())
1399 idxs.push_back(0);
1400
1401 const llvm::Type* llt = llvm::PointerType::get(LLVM_DtoType(t));
1402
1403 for (unsigned i=0; i<sd->fields.dim; ++i) {
1404 VarDeclaration* vd = (VarDeclaration*)sd->fields.data[i];
1405 Type* vdtype = LLVM_DtoDType(vd->type);
1406 Logger::println("found %u type %s", vd->offset, vdtype->toChars());
1407 assert(vd->llvmFieldIndex >= 0);
1408 if (os == vd->offset && vdtype == t) {
1409 idxs.push_back(vd->llvmFieldIndex);
1410 ptr = LLVM_DtoGEP(ptr, idxs, "tmp");
1411 if (ptr->getType() != llt)
1412 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
1413 if (vd->llvmFieldIndexOffset)
1414 ptr = new llvm::GetElementPtrInst(ptr, LLVM_DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb());
1415 return ptr;
1416 }
1417 else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) {
1418 TypeStruct* ts = (TypeStruct*)vdtype;
1419 StructDeclaration* ssd = ts->sym;
1420 idxs.push_back(vd->llvmFieldIndex);
1421 if (vd->llvmFieldIndexOffset) {
1422 Logger::println("has union field offset");
1423 ptr = LLVM_DtoGEP(ptr, idxs, "tmp");
1424 if (ptr->getType() != llt)
1425 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
1426 ptr = new llvm::GetElementPtrInst(ptr, LLVM_DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb());
1427 std::vector<unsigned> tmp;
1428 return LLVM_DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp);
1429 }
1430 else {
1431 const llvm::Type* sty = llvm::PointerType::get(LLVM_DtoType(vd->type));
1432 if (ptr->getType() != sty) {
1433 ptr = gIR->ir->CreateBitCast(ptr, sty, "tmp");
1434 std::vector<unsigned> tmp;
1435 return LLVM_DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp);
1436 }
1437 else {
1438 return LLVM_DtoIndexStruct(ptr, ssd, t, os-vd->offset, idxs);
1439 }
1440 }
1441 }
1442 }
1443
1444 size_t llt_sz = gTargetData->getTypeSize(llt->getContainedType(0));
1445 assert(os % llt_sz == 0);
1446 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
1447 return new llvm::GetElementPtrInst(ptr, LLVM_DtoConstUint(os / llt_sz), "tmp", gIR->scopebb());
1448 }