[svn r28] * Fixed accessing aggregate fields. it was still not quite right. hopefully is now :)

This commit is contained in:
Tomas Lindquist Olsen
2007-10-04 10:13:21 +02:00
parent 53038b0f5e
commit 24c3e2649a
5 changed files with 47 additions and 24 deletions

View File

@@ -99,7 +99,7 @@ struct AggregateDeclaration : ScopeDsymbol
llvm::Type* llvmType;
llvm::Value* llvmVtbl;
llvm::Constant* llvmInitZ;
virtual void offsetToIndex(unsigned os, std::vector<unsigned>& result); // converts a DMD field offsets to LLVM struct index vector
virtual void offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& 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<unsigned>& result);
virtual void offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result);
ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; }
};

View File

@@ -462,7 +462,7 @@ elem* AddExp::toElem(IRState* p)
TypeStruct* ts = (TypeStruct*)e1->type->next;
std::vector<unsigned> 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<unsigned> 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 {

View File

@@ -471,7 +471,7 @@ llvm::Constant* LLVM_DtoStructInitializer(StructInitializer* si)
Logger::println("vars[%d] = %s", i, vd->toChars());
std::vector<unsigned> idxs;
si->ad->offsetToIndex(vd->offset, idxs);
si->ad->offsetToIndex(vd->type, vd->offset, idxs);
assert(idxs.size() == 1);
unsigned idx = idxs[0];

View File

@@ -143,28 +143,24 @@ void Declaration::toObjFile()
/* ================================================================== */
/// Returns the LLVM style index from a DMD style offset
void AggregateDeclaration::offsetToIndex(unsigned os, std::vector<unsigned>& result)
void AggregateDeclaration::offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& 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; i<fields.dim; ++i) {
VarDeclaration* vd = (VarDeclaration*)fields.data[i];
//Logger::println("found %u", vd->offset);
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<unsigned>& result)
void ClassDeclaration::offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result)
{
unsigned idx = 0;
unsigned r = LLVM_ClassOffsetToIndex(this, os, idx);

26
test/structs4.d Normal file
View File

@@ -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);}
}