From 24c3e2649a6ffe62f7a76aeb75abc8d3747af618 Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Thu, 4 Oct 2007 10:13:21 +0200 Subject: [PATCH] [svn r28] * Fixed accessing aggregate fields. it was still not quite right. hopefully is now :) --- dmd/aggregate.h | 4 ++-- gen/toir.c | 13 +++++++------ gen/tollvm.c | 2 +- gen/toobj.c | 26 +++++++++++--------------- test/structs4.d | 26 ++++++++++++++++++++++++++ 5 files changed, 47 insertions(+), 24 deletions(-) create mode 100644 test/structs4.d diff --git a/dmd/aggregate.h b/dmd/aggregate.h index 58475d63..9d70e194 100644 --- a/dmd/aggregate.h +++ b/dmd/aggregate.h @@ -99,7 +99,7 @@ struct AggregateDeclaration : ScopeDsymbol llvm::Type* llvmType; llvm::Value* llvmVtbl; llvm::Constant* llvmInitZ; - virtual void offsetToIndex(unsigned os, std::vector& result); // converts a DMD field offsets to LLVM struct index vector + virtual void offsetToIndex(Type* t, unsigned os, std::vector& result); // converts a DMD field offsets to LLVM struct index vector AggregateDeclaration *isAggregateDeclaration() { return this; } }; @@ -234,7 +234,7 @@ struct ClassDeclaration : AggregateDeclaration Symbol *vtblsym; - virtual void offsetToIndex(unsigned os, std::vector& result); + virtual void offsetToIndex(Type* t, unsigned os, std::vector& result); ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; } }; diff --git a/gen/toir.c b/gen/toir.c index bab6749c..7f18d5ec 100644 --- a/gen/toir.c +++ b/gen/toir.c @@ -462,7 +462,7 @@ elem* AddExp::toElem(IRState* p) TypeStruct* ts = (TypeStruct*)e1->type->next; std::vector offsets(1,0); - ts->sym->offsetToIndex(cofs->getZExtValue(), offsets); + ts->sym->offsetToIndex(type->next, cofs->getZExtValue(), offsets); e->mem = LLVM_DtoGEP(l->getValue(), offsets, "tmp", p->scopebb()); e->type = elem::VAR; e->field = true; @@ -1154,7 +1154,7 @@ elem* SymOffExp::toElem(IRState* p) TypeStruct* vdt = (TypeStruct*)vd->type; e = new elem; std::vector dst(1,0); - vdt->sym->offsetToIndex(offset, dst); + vdt->sym->offsetToIndex(type->next, offset, dst); llvm::Value* ptr = vd->llvmValue; assert(ptr); e->mem = LLVM_DtoGEP(ptr,dst,"tmp",p->scopebb()); @@ -1242,14 +1242,14 @@ elem* DotVarExp::toElem(IRState* p) if (e1->type->ty == Tpointer) { assert(e1->type->next->ty == Tstruct); TypeStruct* ts = (TypeStruct*)e1->type->next; - ts->sym->offsetToIndex(vd->offset, vdoffsets); + ts->sym->offsetToIndex(vd->type, vd->offset, vdoffsets); Logger::println("Struct member offset:%d", vd->offset); src = l->val ? l->val : l->mem; } else if (e1->type->ty == Tclass) { TypeClass* tc = (TypeClass*)e1->type; Logger::println("Class member offset: %d", vd->offset); - tc->sym->offsetToIndex(vd->offset, vdoffsets); + tc->sym->offsetToIndex(vd->type, vd->offset, vdoffsets); src = l->getValue(); } assert(vdoffsets.size() != 1); @@ -1376,8 +1376,9 @@ elem* StructLiteralExp::toElem(IRState* p) Expression* vx = (Expression*)elements->data[i]; if (vx != 0) { elem* ve = vx->toElem(p); - //Logger::cout() << *ve->val << " | " << *arrptr << '\n'; - new llvm::StoreInst(ve->getValue(), arrptr, p->scopebb()); + llvm::Value* val = ve->getValue(); + Logger::cout() << *val << " | " << *arrptr << '\n'; + new llvm::StoreInst(val, arrptr, p->scopebb()); delete ve; } else { diff --git a/gen/tollvm.c b/gen/tollvm.c index b85ca897..2719b30a 100644 --- a/gen/tollvm.c +++ b/gen/tollvm.c @@ -471,7 +471,7 @@ llvm::Constant* LLVM_DtoStructInitializer(StructInitializer* si) Logger::println("vars[%d] = %s", i, vd->toChars()); std::vector idxs; - si->ad->offsetToIndex(vd->offset, idxs); + si->ad->offsetToIndex(vd->type, vd->offset, idxs); assert(idxs.size() == 1); unsigned idx = idxs[0]; diff --git a/gen/toobj.c b/gen/toobj.c index b9f057ac..d684d7b0 100644 --- a/gen/toobj.c +++ b/gen/toobj.c @@ -143,28 +143,24 @@ void Declaration::toObjFile() /* ================================================================== */ /// Returns the LLVM style index from a DMD style offset -void AggregateDeclaration::offsetToIndex(unsigned os, std::vector& result) +void AggregateDeclaration::offsetToIndex(Type* t, unsigned os, std::vector& result) { - //Logger::println("checking for offset %u :", os); + Logger::println("checking for offset %u type %s:", os, t->toChars()); LOG_SCOPE; - unsigned vos = 0; for (unsigned i=0; ioffset); - if (os == vd->offset) { + Logger::println("found %u type %s", vd->offset, vd->type->toChars()); + if (os == vd->offset && vd->type == t) { result.push_back(i); return; } - else if (vd->type->ty == Tstruct) { - if (vos + vd->type->size() > os) { - TypeStruct* ts = (TypeStruct*)vd->type; - StructDeclaration* sd = ts->sym; - result.push_back(i); - sd->offsetToIndex(os - vos, result); - return; - } + else if (vd->type->ty == Tstruct && (vd->offset + vd->type->size()) > os) { + TypeStruct* ts = (TypeStruct*)vd->type; + StructDeclaration* sd = ts->sym; + result.push_back(i); + sd->offsetToIndex(t, os - vd->offset, result); + return; } - vos += vd->offset; } assert(0 && "Offset not found in any aggregate field"); } @@ -194,7 +190,7 @@ static unsigned LLVM_ClassOffsetToIndex(ClassDeclaration* cd, unsigned os, unsig /// Returns the LLVM style index from a DMD style offset /// Handles class inheritance -void ClassDeclaration::offsetToIndex(unsigned os, std::vector& result) +void ClassDeclaration::offsetToIndex(Type* t, unsigned os, std::vector& result) { unsigned idx = 0; unsigned r = LLVM_ClassOffsetToIndex(this, os, idx); diff --git a/test/structs4.d b/test/structs4.d new file mode 100644 index 00000000..88d1cea8 --- /dev/null +++ b/test/structs4.d @@ -0,0 +1,26 @@ +module structs4; + +struct S{ + int a; + T t; +} + +struct T{ + int b; + U u; +} + +struct U{ + int c; +} + +void main() +{ + S s; + s.a = 3; + s.t = T.init; + s.t.b = 4; + s.t.u = U.init; + s.t.u.c = 5; + {assert(s.t.u.c == 5);} +}