mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-03-05 11:53:14 +01:00
[svn r80] Fixed union literals
This commit is contained in:
77
gen/toir.c
77
gen/toir.c
@@ -1667,36 +1667,52 @@ elem* StructLiteralExp::toElem(IRState* p)
|
||||
LOG_SCOPE;
|
||||
elem* e = new elem;
|
||||
|
||||
llvm::Value* sptr = 0;
|
||||
llvm::Value* sptr;
|
||||
const llvm::Type* llt = LLVM_DtoType(type);
|
||||
|
||||
// if there is no lval, this is probably a temporary struct literal. correct?
|
||||
// temporary struct literal
|
||||
if (!p->topexp() || p->topexp()->e2 != this)
|
||||
{
|
||||
sptr = new llvm::AllocaInst(LLVM_DtoType(type),"tmpstructliteral",p->topallocapoint());
|
||||
sptr = new llvm::AllocaInst(llt,"tmpstructliteral",p->topallocapoint());
|
||||
e->mem = sptr;
|
||||
e->type = elem::VAR;
|
||||
}
|
||||
// already has memory
|
||||
else if (p->topexp()->e2 == this)
|
||||
else
|
||||
{
|
||||
assert(p->topexp()->e2 == this);
|
||||
sptr = p->topexp()->v;
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
|
||||
assert(sptr);
|
||||
// num elements in literal
|
||||
unsigned n = elements->dim;
|
||||
|
||||
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
||||
// unions might have different types for each literal
|
||||
if (sd->llvmHasUnions) {
|
||||
// build the type of the literal
|
||||
std::vector<const llvm::Type*> tys;
|
||||
for (unsigned i=0; i<n; ++i) {
|
||||
Expression* vx = (Expression*)elements->data[i];
|
||||
if (!vx) continue;
|
||||
tys.push_back(LLVM_DtoType(vx->type));
|
||||
}
|
||||
const llvm::StructType* t = llvm::StructType::get(tys);
|
||||
if (t != llt) {
|
||||
assert(gTargetData->getTypeSize(t) == gTargetData->getTypeSize(llt));
|
||||
sptr = p->ir->CreateBitCast(sptr, llvm::PointerType::get(t), "tmp");
|
||||
Logger::cout() << "sptr type is now: " << *t << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
if (sd->isUnionDeclaration()) {
|
||||
Logger::println("num elements = %d", elements->dim);
|
||||
//assert(elements->dim == 1);
|
||||
Expression* vx = (Expression*)elements->data[0];
|
||||
assert(vx);
|
||||
// build
|
||||
unsigned j = 0;
|
||||
for (unsigned i=0; i<n; ++i)
|
||||
{
|
||||
Expression* vx = (Expression*)elements->data[i];
|
||||
if (!vx) continue;
|
||||
|
||||
Type* vxtype = LLVM_DtoDType(vx->type);
|
||||
const llvm::Type* llvxty = llvm::PointerType::get(LLVM_DtoType(vxtype));
|
||||
llvm::Value* arrptr = p->ir->CreateBitCast(sptr, llvxty, "tmp");
|
||||
Logger::cout() << "getting index " << j << " of " << *sptr << '\n';
|
||||
llvm::Value* arrptr = LLVM_DtoGEPi(sptr,0,j,"tmp",p->scopebb());
|
||||
|
||||
p->exps.push_back(IRExp(NULL,vx,arrptr));
|
||||
elem* ve = vx->toElem(p);
|
||||
@@ -1705,36 +1721,13 @@ elem* StructLiteralExp::toElem(IRState* p)
|
||||
if (!ve->inplace) {
|
||||
llvm::Value* val = ve->getValue();
|
||||
Logger::cout() << *val << " | " << *arrptr << '\n';
|
||||
|
||||
Type* vxtype = LLVM_DtoDType(vx->type);
|
||||
LLVM_DtoAssign(vxtype, arrptr, val);
|
||||
}
|
||||
delete ve;
|
||||
}
|
||||
else {
|
||||
unsigned n = elements->dim;
|
||||
for (unsigned i=0; i<n; ++i)
|
||||
{
|
||||
llvm::Value* offset = llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false);
|
||||
llvm::Value* arrptr = LLVM_DtoGEP(sptr,zero,offset,"tmp",p->scopebb());
|
||||
|
||||
Expression* vx = (Expression*)elements->data[i];
|
||||
if (vx != 0) {
|
||||
p->exps.push_back(IRExp(NULL,vx,arrptr));
|
||||
elem* ve = vx->toElem(p);
|
||||
p->exps.pop_back();
|
||||
|
||||
if (!ve->inplace) {
|
||||
llvm::Value* val = ve->getValue();
|
||||
Logger::cout() << *val << " | " << *arrptr << '\n';
|
||||
|
||||
Type* vxtype = LLVM_DtoDType(vx->type);
|
||||
LLVM_DtoAssign(vxtype, arrptr, val);
|
||||
}
|
||||
delete ve;
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
e->inplace = true;
|
||||
|
||||
16
test/union4.d
Normal file
16
test/union4.d
Normal file
@@ -0,0 +1,16 @@
|
||||
module union4;
|
||||
|
||||
pragma(LLVM_internal, "notypeinfo")
|
||||
union U {
|
||||
struct { float x,y,z; }
|
||||
float[3] xyz;
|
||||
}
|
||||
|
||||
void main() {
|
||||
const float[3] a = [1f,2,3];
|
||||
U u = U(1,2,3);
|
||||
assert(u.xyz == a);
|
||||
assert(u.x == 1);
|
||||
assert(u.y == 2);
|
||||
assert(u.z == 3);
|
||||
}
|
||||
39
test/union5.d
Normal file
39
test/union5.d
Normal file
@@ -0,0 +1,39 @@
|
||||
module union5;
|
||||
|
||||
pragma(LLVM_internal, "notypeinfo")
|
||||
{
|
||||
union S
|
||||
{
|
||||
T t;
|
||||
U u;
|
||||
uint i;
|
||||
struct {
|
||||
ushort sl,sh;
|
||||
}
|
||||
}
|
||||
|
||||
struct T
|
||||
{
|
||||
int i;
|
||||
}
|
||||
|
||||
struct U
|
||||
{
|
||||
float f;
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
S s;
|
||||
assert(s.t.i == 0);
|
||||
assert(s.u.f == 0);
|
||||
s.t.i = -1;
|
||||
assert(s.i == 0xFFFF_FFFF);
|
||||
float f = 3.1415;
|
||||
s.u.f = f;
|
||||
uint pi = *cast(uint*)&f;
|
||||
assert(s.i == pi);
|
||||
assert(s.sl == (pi&0xFFFF));
|
||||
assert(s.sh == (pi>>>16));
|
||||
}
|
||||
Reference in New Issue
Block a user