Mercurial > projects > ldc
comparison gen/toir.c @ 76:9e1bd80a7e98 trunk
[svn r80] Fixed union literals
author | lindquist |
---|---|
date | Wed, 31 Oct 2007 07:24:02 +0100 |
parents | b706170e24a9 |
children | 714057ff2dbb |
comparison
equal
deleted
inserted
replaced
75:ab8f5ec40a14 | 76:9e1bd80a7e98 |
---|---|
1665 { | 1665 { |
1666 Logger::print("StructLiteralExp::toElem: %s | %s\n", toChars(), type->toChars()); | 1666 Logger::print("StructLiteralExp::toElem: %s | %s\n", toChars(), type->toChars()); |
1667 LOG_SCOPE; | 1667 LOG_SCOPE; |
1668 elem* e = new elem; | 1668 elem* e = new elem; |
1669 | 1669 |
1670 llvm::Value* sptr = 0; | 1670 llvm::Value* sptr; |
1671 | 1671 const llvm::Type* llt = LLVM_DtoType(type); |
1672 // if there is no lval, this is probably a temporary struct literal. correct? | 1672 |
1673 // temporary struct literal | |
1673 if (!p->topexp() || p->topexp()->e2 != this) | 1674 if (!p->topexp() || p->topexp()->e2 != this) |
1674 { | 1675 { |
1675 sptr = new llvm::AllocaInst(LLVM_DtoType(type),"tmpstructliteral",p->topallocapoint()); | 1676 sptr = new llvm::AllocaInst(llt,"tmpstructliteral",p->topallocapoint()); |
1676 e->mem = sptr; | 1677 e->mem = sptr; |
1677 e->type = elem::VAR; | 1678 e->type = elem::VAR; |
1678 } | 1679 } |
1679 // already has memory | 1680 // already has memory |
1680 else if (p->topexp()->e2 == this) | 1681 else |
1681 { | 1682 { |
1683 assert(p->topexp()->e2 == this); | |
1682 sptr = p->topexp()->v; | 1684 sptr = p->topexp()->v; |
1683 } | 1685 } |
1684 else | 1686 |
1685 assert(0); | 1687 // num elements in literal |
1686 | 1688 unsigned n = elements->dim; |
1687 assert(sptr); | 1689 |
1688 | 1690 // unions might have different types for each literal |
1689 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1691 if (sd->llvmHasUnions) { |
1690 | 1692 // build the type of the literal |
1691 if (sd->isUnionDeclaration()) { | 1693 std::vector<const llvm::Type*> tys; |
1692 Logger::println("num elements = %d", elements->dim); | 1694 for (unsigned i=0; i<n; ++i) { |
1693 //assert(elements->dim == 1); | 1695 Expression* vx = (Expression*)elements->data[i]; |
1694 Expression* vx = (Expression*)elements->data[0]; | 1696 if (!vx) continue; |
1695 assert(vx); | 1697 tys.push_back(LLVM_DtoType(vx->type)); |
1696 | 1698 } |
1697 Type* vxtype = LLVM_DtoDType(vx->type); | 1699 const llvm::StructType* t = llvm::StructType::get(tys); |
1698 const llvm::Type* llvxty = llvm::PointerType::get(LLVM_DtoType(vxtype)); | 1700 if (t != llt) { |
1699 llvm::Value* arrptr = p->ir->CreateBitCast(sptr, llvxty, "tmp"); | 1701 assert(gTargetData->getTypeSize(t) == gTargetData->getTypeSize(llt)); |
1702 sptr = p->ir->CreateBitCast(sptr, llvm::PointerType::get(t), "tmp"); | |
1703 Logger::cout() << "sptr type is now: " << *t << '\n'; | |
1704 } | |
1705 } | |
1706 | |
1707 // build | |
1708 unsigned j = 0; | |
1709 for (unsigned i=0; i<n; ++i) | |
1710 { | |
1711 Expression* vx = (Expression*)elements->data[i]; | |
1712 if (!vx) continue; | |
1713 | |
1714 Logger::cout() << "getting index " << j << " of " << *sptr << '\n'; | |
1715 llvm::Value* arrptr = LLVM_DtoGEPi(sptr,0,j,"tmp",p->scopebb()); | |
1700 | 1716 |
1701 p->exps.push_back(IRExp(NULL,vx,arrptr)); | 1717 p->exps.push_back(IRExp(NULL,vx,arrptr)); |
1702 elem* ve = vx->toElem(p); | 1718 elem* ve = vx->toElem(p); |
1703 p->exps.pop_back(); | 1719 p->exps.pop_back(); |
1704 | 1720 |
1705 if (!ve->inplace) { | 1721 if (!ve->inplace) { |
1706 llvm::Value* val = ve->getValue(); | 1722 llvm::Value* val = ve->getValue(); |
1707 Logger::cout() << *val << " | " << *arrptr << '\n'; | 1723 Logger::cout() << *val << " | " << *arrptr << '\n'; |
1724 | |
1725 Type* vxtype = LLVM_DtoDType(vx->type); | |
1708 LLVM_DtoAssign(vxtype, arrptr, val); | 1726 LLVM_DtoAssign(vxtype, arrptr, val); |
1709 } | 1727 } |
1710 delete ve; | 1728 delete ve; |
1711 } | 1729 |
1712 else { | 1730 j++; |
1713 unsigned n = elements->dim; | |
1714 for (unsigned i=0; i<n; ++i) | |
1715 { | |
1716 llvm::Value* offset = llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false); | |
1717 llvm::Value* arrptr = LLVM_DtoGEP(sptr,zero,offset,"tmp",p->scopebb()); | |
1718 | |
1719 Expression* vx = (Expression*)elements->data[i]; | |
1720 if (vx != 0) { | |
1721 p->exps.push_back(IRExp(NULL,vx,arrptr)); | |
1722 elem* ve = vx->toElem(p); | |
1723 p->exps.pop_back(); | |
1724 | |
1725 if (!ve->inplace) { | |
1726 llvm::Value* val = ve->getValue(); | |
1727 Logger::cout() << *val << " | " << *arrptr << '\n'; | |
1728 | |
1729 Type* vxtype = LLVM_DtoDType(vx->type); | |
1730 LLVM_DtoAssign(vxtype, arrptr, val); | |
1731 } | |
1732 delete ve; | |
1733 } | |
1734 else { | |
1735 assert(0); | |
1736 } | |
1737 } | |
1738 } | 1731 } |
1739 | 1732 |
1740 e->inplace = true; | 1733 e->inplace = true; |
1741 | 1734 |
1742 return e; | 1735 return e; |