mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-19 06:13:14 +01:00
[svn r28] * Fixed accessing aggregate fields. it was still not quite right. hopefully is now :)
This commit is contained in:
@@ -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; }
|
||||
};
|
||||
|
||||
13
gen/toir.c
13
gen/toir.c
@@ -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 {
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
26
gen/toobj.c
26
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<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
26
test/structs4.d
Normal 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);}
|
||||
}
|
||||
Reference in New Issue
Block a user