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;