[svn r27] * Fixed bug in aggregate field lookup.

* Fixed structs with no fields.
* Added support for NegExp as in -x.
This commit is contained in:
Tomas Lindquist Olsen
2007-10-04 09:24:15 +02:00
parent 0ba16ebb39
commit 53038b0f5e
5 changed files with 67 additions and 9 deletions

View File

@@ -448,7 +448,7 @@ elem* AssignExp::toElem(IRState* p)
elem* AddExp::toElem(IRState* p)
{
Logger::print("AddExp::toElem: %s\n", toChars());
Logger::print("AddExp::toElem: %s | %s\n", toChars(), type->toChars());
LOG_SCOPE;
elem* e = new elem;
elem* l = e1->toElem(p);
@@ -457,7 +457,6 @@ elem* AddExp::toElem(IRState* p)
if (e1->type != e2->type) {
if (e1->type->ty == Tpointer && e1->type->next->ty == Tstruct) {
//assert(l->field);
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
assert(r->type == elem::CONST);
llvm::ConstantInt* cofs = llvm::cast<llvm::ConstantInt>(r->val);
@@ -1150,6 +1149,7 @@ elem* SymOffExp::toElem(IRState* p)
if (VarDeclaration* vd = var->isVarDeclaration())
{
Logger::println("VarDeclaration");
assert(vd->llvmValue);
if (vd->type->ty == Tstruct && !(type->ty == Tpointer && type->next == vd->type)) {
TypeStruct* vdt = (TypeStruct*)vd->type;
e = new elem;
@@ -2245,6 +2245,37 @@ elem* ComExp::toElem(IRState* p)
//////////////////////////////////////////////////////////////////////////////////////////
elem* NegExp::toElem(IRState* p)
{
Logger::print("NegExp::toElem: %s | %s\n", toChars(), type->toChars());
LOG_SCOPE;
elem* e = new elem;
elem* l = e1->toElem(p);
llvm::Value* val = l->getValue();
delete l;
llvm::Value* zero = 0;
if (type->isintegral())
zero = llvm::ConstantInt::get(val->getType(), 0, true);
else if (type->isfloating()) {
if (type->ty == Tfloat32)
zero = llvm::ConstantFP::get(val->getType(), float(0));
else if (type->ty == Tfloat64 || type->ty == Tfloat80)
zero = llvm::ConstantFP::get(val->getType(), double(0));
else
assert(0);
}
else
assert(0);
e->val = llvm::BinaryOperator::createSub(zero,val,"tmp",p->scopebb());
e->type = elem::VAL;
return e;
}
//////////////////////////////////////////////////////////////////////////////////////////
#define STUB(x) elem *x::toElem(IRState * p) {error("Exp type "#x" not implemented: %s", toChars()); fatal(); return 0; }
//STUB(IdentityExp);
//STUB(CondExp);
@@ -2304,7 +2335,7 @@ STUB(BoolExp);
//STUB(NotExp);
//STUB(ComExp);
STUB(NegExp);
//STUB(NegExp);
//STUB(PtrExp);
//STUB(AddrExp);
//STUB(SliceExp);

View File

@@ -145,10 +145,17 @@ void Declaration::toObjFile()
/// Returns the LLVM style index from a DMD style offset
void AggregateDeclaration::offsetToIndex(unsigned os, std::vector<unsigned>& result)
{
//Logger::println("checking for offset %u :", os);
LOG_SCOPE;
unsigned vos = 0;
for (unsigned i=0; i<fields.dim; ++i) {
VarDeclaration* vd = (VarDeclaration*)fields.data[i];
if (vd->type->ty == Tstruct) {
//Logger::println("found %u", vd->offset);
if (os == vd->offset) {
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;
@@ -157,10 +164,6 @@ void AggregateDeclaration::offsetToIndex(unsigned os, std::vector<unsigned>& res
return;
}
}
else if (os == vd->offset) {
result.push_back(i);
return;
}
vos += vd->offset;
}
assert(0 && "Offset not found in any aggregate field");
@@ -235,6 +238,12 @@ void StructDeclaration::toObjFile()
}
}
if (gIR->topstruct().fields.empty())
{
gIR->topstruct().fields.push_back(llvm::Type::Int8Ty);
gIR->topstruct().inits.push_back(llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false));
}
llvm::StructType* structtype = llvm::StructType::get(gIR->topstruct().fields);
// refine abstract types for stuff like: struct S{S* next;}

View File

@@ -9,7 +9,7 @@ void _writef(T)(T t) {
static if(isArray!(T)) {
_writef('[');
if (t.length) _writef(t[0]);
for (int i=1; i<t.lengthi; ++i) { _writef(','); _writef(t[i]); }
for (int i=1; i<t.length; ++i) { _writef(','); _writef(t[i]); }
_writef(']');
} else
static if(is(T==int)) printf("%i", t); else

5
test/bug1.d Normal file
View File

@@ -0,0 +1,5 @@
module bug1;
struct Foo { Foo opSub(ref Foo b) { return Foo(); } }
struct Bar { Foo whee; }
void test(ref Bar moo) { Foo nngh; auto plonk = nngh - moo.whee; }
void main() { Bar bar; test(bar); }

13
test/neg.d Normal file
View File

@@ -0,0 +1,13 @@
module neg;
void main()
{
int i = 32;
long l = 55;
float f = 23;
double d = 4;
assert(-i == -32);
assert(-l == -55);
assert(-f == -23);
assert(-d == -4);
}