changeset 23:77e3d1ddae3f trunk

[svn r27] * Fixed bug in aggregate field lookup. * Fixed structs with no fields. * Added support for NegExp as in -x.
author lindquist
date Thu, 04 Oct 2007 09:24:15 +0200
parents a6360e68134a
children 25bb577878e8
files gen/toir.c gen/toobj.c lphobos/std/stdio.d test/bug1.d test/neg.d
diffstat 5 files changed, 67 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/gen/toir.c	Thu Oct 04 07:35:02 2007 +0200
+++ b/gen/toir.c	Thu Oct 04 09:24:15 2007 +0200
@@ -448,7 +448,7 @@
 
 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 @@
     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 @@
     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* 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(NotExp);
 //STUB(ComExp);
-STUB(NegExp);
+//STUB(NegExp);
 //STUB(PtrExp);
 //STUB(AddrExp);
 //STUB(SliceExp);
--- a/gen/toobj.c	Thu Oct 04 07:35:02 2007 +0200
+++ b/gen/toobj.c	Thu Oct 04 09:24:15 2007 +0200
@@ -145,10 +145,17 @@
 /// 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 @@
                 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 @@
         }
     }
 
+    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;}
--- a/lphobos/std/stdio.d	Thu Oct 04 07:35:02 2007 +0200
+++ b/lphobos/std/stdio.d	Thu Oct 04 09:24:15 2007 +0200
@@ -9,7 +9,7 @@
   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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/bug1.d	Thu Oct 04 09:24:15 2007 +0200
@@ -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); }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/neg.d	Thu Oct 04 09:24:15 2007 +0200
@@ -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);
+}