From 53038b0f5ed039b9d20457cbe10fcd639a0f6ae2 Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Thu, 4 Oct 2007 09:24:15 +0200 Subject: [PATCH] [svn r27] * Fixed bug in aggregate field lookup. * Fixed structs with no fields. * Added support for NegExp as in -x. --- gen/toir.c | 37 ++++++++++++++++++++++++++++++++++--- gen/toobj.c | 19 ++++++++++++++----- lphobos/std/stdio.d | 2 +- test/bug1.d | 5 +++++ test/neg.d | 13 +++++++++++++ 5 files changed, 67 insertions(+), 9 deletions(-) create mode 100644 test/bug1.d create mode 100644 test/neg.d diff --git a/gen/toir.c b/gen/toir.c index 0b9091af..bab6749c 100644 --- a/gen/toir.c +++ b/gen/toir.c @@ -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(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); diff --git a/gen/toobj.c b/gen/toobj.c index b9c72979..b9f057ac 100644 --- a/gen/toobj.c +++ b/gen/toobj.c @@ -145,10 +145,17 @@ void Declaration::toObjFile() /// Returns the LLVM style index from a DMD style offset void AggregateDeclaration::offsetToIndex(unsigned os, std::vector& result) { + //Logger::println("checking for offset %u :", os); + LOG_SCOPE; unsigned vos = 0; for (unsigned i=0; itype->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& 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;} diff --git a/lphobos/std/stdio.d b/lphobos/std/stdio.d index 2e3ddfb0..77243209 100644 --- a/lphobos/std/stdio.d +++ b/lphobos/std/stdio.d @@ -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