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