changeset 435:74101be2a553

Added type param to DVarValue as DMD sometimes overrides the type of the VarDeclaration. Added support for align(1)/packed structs, other alignments are still ignored. Fixed some problems with accessing lazy arguments.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Wed, 30 Jul 2008 10:12:55 +0200
parents b5f55f471e0b
children 657d37df25b0
files gen/dvalue.cpp gen/dvalue.h gen/functions.cpp gen/llvmhelpers.cpp gen/llvmhelpers.h gen/structs.cpp gen/structs.h gen/tocall.cpp gen/toir.cpp ir/irstruct.cpp ir/irstruct.h
diffstat 11 files changed, 43 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/gen/dvalue.cpp	Wed Jul 30 09:21:06 2008 +0200
+++ b/gen/dvalue.cpp	Wed Jul 30 10:12:55 2008 +0200
@@ -10,13 +10,13 @@
 /////////////////////////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////
 
-DVarValue::DVarValue(VarDeclaration* vd, LLValue* llvmValue, bool lvalue)
+DVarValue::DVarValue(Type* t, VarDeclaration* vd, LLValue* llvmValue, bool lvalue)
 {
     var = vd;
     val = llvmValue;
     rval = 0;
     lval = lvalue;
-    type = var->type;
+    type = t;
 }
 
 DVarValue::DVarValue(Type* t, LLValue* lv, LLValue* rv)
--- a/gen/dvalue.h	Wed Jul 30 09:21:06 2008 +0200
+++ b/gen/dvalue.h	Wed Jul 30 10:12:55 2008 +0200
@@ -111,8 +111,8 @@
     LLValue* rval;
     bool lval;
 
-    DVarValue(VarDeclaration* vd, LLValue* llvmValue, bool lvalue);
-    DVarValue(Type* vd, LLValue* lv, LLValue* rv);
+    DVarValue(Type* t, VarDeclaration* vd, LLValue* llvmValue, bool lvalue);
+    DVarValue(Type* t, LLValue* lv, LLValue* rv);
     DVarValue(Type* t, LLValue* llvmValue, bool lvalue);
 
     virtual bool isLVal() { return val && lval; }
@@ -133,7 +133,7 @@
 // this d-value
 struct DThisValue : DVarValue
 {
-    DThisValue(VarDeclaration* vd, LLValue* llvmValue) : DVarValue(vd, llvmValue, true) {}
+    DThisValue(Type* t, VarDeclaration* vd, LLValue* llvmValue) : DVarValue(t, vd, llvmValue, true) {}
     virtual DThisValue* isThis() { return this; }
 };
 
--- a/gen/functions.cpp	Wed Jul 30 09:21:06 2008 +0200
+++ b/gen/functions.cpp	Wed Jul 30 10:12:55 2008 +0200
@@ -22,8 +22,8 @@
 
 const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, bool ismain)
 {
+    assert(type->ty == Tfunction);
     TypeFunction* f = (TypeFunction*)type;
-    assert(f != 0);
 
     if (type->ir.type != NULL) {
         return llvm::cast<llvm::FunctionType>(type->ir.type->get());
--- a/gen/llvmhelpers.cpp	Wed Jul 30 09:21:06 2008 +0200
+++ b/gen/llvmhelpers.cpp	Wed Jul 30 10:12:55 2008 +0200
@@ -1264,7 +1264,7 @@
             DValue* ie = DtoInitializer(vd->init);
         }
 
-        return new DVarValue(vd, vd->ir.getIrValue(), true);
+        return new DVarValue(vd->type, vd, vd->ir.getIrValue(), true);
     }
     // struct declaration
     else if (StructDeclaration* s = declaration->isStructDeclaration())
--- a/gen/llvmhelpers.h	Wed Jul 30 09:21:06 2008 +0200
+++ b/gen/llvmhelpers.h	Wed Jul 30 10:12:55 2008 +0200
@@ -106,7 +106,7 @@
 unsigned DtoCallingConv(LINK l);
 
 ///
-TypeFunction* DtoTypeFunction(Type* type);
+TypeFunction* DtoTypeFunction(DValue* fnval);
 
 ///
 DValue* DtoVaArg(Loc& loc, Type* type, Expression* valistArg);
--- a/gen/structs.cpp	Wed Jul 30 09:21:06 2008 +0200
+++ b/gen/structs.cpp	Wed Jul 30 10:12:55 2008 +0200
@@ -124,10 +124,14 @@
 
     TypeStruct* ts = (TypeStruct*)DtoDType(sd->type);
 
+    bool ispacked = (ts->alignsize() == 1);
+
     IrStruct* irstruct = new IrStruct(ts);
     sd->ir.irStruct = irstruct;
     gIR->structs.push_back(irstruct);
 
+    irstruct->packed = ispacked;
+
     // fields
     Array* arr = &sd->fields;
     for (int k=0; k < arr->dim; k++) {
@@ -170,7 +174,7 @@
     {
         Logger::println("has no fields");
         fieldtypes.push_back(LLType::Int8Ty);
-        structtype = llvm::StructType::get(fieldtypes);
+        structtype = llvm::StructType::get(fieldtypes, ispacked);
     }
     else
     {
@@ -239,7 +243,7 @@
         }
 
         Logger::println("creating struct type");
-        structtype = llvm::StructType::get(fieldtypes);
+        structtype = llvm::StructType::get(fieldtypes, ispacked);
     }
 
     // refine abstract types for stuff like: struct S{S* next;}
@@ -329,7 +333,7 @@
     }
 
     // generate the union mapper
-    sd->ir.irStruct->dunion = new DUnion; // uses gIR->topstruct()
+    sd->ir.irStruct->dunion = new DUnion(); // uses gIR->topstruct()
 
     // always generate the constant initalizer
     if (!sd->zeroInit) {
@@ -445,6 +449,8 @@
         }
     }
 
+    ispacked = topstruct->packed;
+
     /*{
         LOG_SCOPE;
         Logger::println("******** DUnion BEGIN");
@@ -533,7 +539,7 @@
     for (size_t i=0; i<nout; ++i)
         tys.push_back(out[i]->getType());
 
-    const llvm::StructType* st = llvm::StructType::get(tys);
+    const llvm::StructType* st = llvm::StructType::get(tys, ispacked);
     return llvm::ConstantStruct::get(st, out);
 }
 
--- a/gen/structs.h	Wed Jul 30 09:21:06 2008 +0200
+++ b/gen/structs.h	Wed Jul 30 10:12:55 2008 +0200
@@ -66,6 +66,7 @@
 class DUnion
 {
     std::vector<DUnionField> fields;
+    bool ispacked;
 public:
     DUnion();
     LLConstant* getConst(std::vector<DUnionIdx>& in);
--- a/gen/tocall.cpp	Wed Jul 30 09:21:06 2008 +0200
+++ b/gen/tocall.cpp	Wed Jul 30 10:12:55 2008 +0200
@@ -13,20 +13,21 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-TypeFunction* DtoTypeFunction(Type* type)
+TypeFunction* DtoTypeFunction(DValue* fnval)
 {
-    TypeFunction* tf = 0;
-    type = type->toBasetype();
+    Type* type = fnval->getType()->toBasetype();
     if (type->ty == Tfunction)
     {
-         tf = (TypeFunction*)type;
+         return (TypeFunction*)type;
     }
     else if (type->ty == Tdelegate)
     {
         assert(type->next->ty == Tfunction);
-        tf = (TypeFunction*)type->next;
+        return (TypeFunction*)type->next;
     }
-    return tf;
+
+    assert(0 && "cant get TypeFunction* from non lazy/function/delegate");
+    return 0;
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -192,8 +193,7 @@
     bool va_intrinsic = (dfnval && dfnval->func && (dfnval->func->llvmInternal == LLVMva_intrinsic));
 
     // get function type info
-    TypeFunction* tf = DtoTypeFunction(calleeType);
-    assert(tf);
+    TypeFunction* tf = DtoTypeFunction(fnval);
 
     // misc
     bool retinptr = tf->llvmRetInPtr;
--- a/gen/toir.cpp	Wed Jul 30 09:21:06 2008 +0200
+++ b/gen/toir.cpp	Wed Jul 30 10:12:55 2008 +0200
@@ -65,7 +65,7 @@
             Logger::println("Id::_arguments");
             LLValue* v = p->func()->_arguments;
             assert(v);
-            return new DVarValue(vd, v, true);
+            return new DVarValue(type, vd, v, true);
         }
         // _argptr
         else if (vd->ident == Id::_argptr)
@@ -73,7 +73,7 @@
             Logger::println("Id::_argptr");
             LLValue* v = p->func()->_argptr;
             assert(v);
-            return new DVarValue(vd, v, true);
+            return new DVarValue(type, vd, v, true);
         }
         // _dollar
         else if (vd->ident == Id::dollar)
@@ -81,7 +81,7 @@
             Logger::println("Id::dollar");
             assert(!p->arrays.empty());
             LLValue* tmp = DtoArrayLen(p->arrays.back());
-            return new DVarValue(vd, tmp, false);
+            return new DVarValue(type, vd, tmp, false);
         }
         // typeinfo
         else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration())
@@ -95,7 +95,7 @@
                 m = p->ir->CreateBitCast(tid->ir.getIrValue(), vartype, "tmp");
             else
                 m = tid->ir.getIrValue();
-            return new DVarValue(vd, m, true);
+            return new DVarValue(type, vd, m, true);
         }
         // classinfo
         else if (ClassInfoDeclaration* cid = vd->isClassInfoDeclaration())
@@ -103,12 +103,12 @@
             Logger::println("ClassInfoDeclaration: %s", cid->cd->toChars());
             DtoForceDeclareDsymbol(cid->cd);
             assert(cid->cd->ir.irStruct->classInfo);
-            return new DVarValue(vd, cid->cd->ir.irStruct->classInfo, true);
+            return new DVarValue(type, vd, cid->cd->ir.irStruct->classInfo, true);
         }
         // nested variable
         else if (vd->nestedref) {
             Logger::println("nested variable");
-            return new DVarValue(vd, DtoNestedVariable(vd), true);
+            return new DVarValue(type, vd, DtoNestedVariable(vd), true);
         }
         // function parameter
         else if (vd->isParameter()) {
@@ -116,10 +116,10 @@
             FuncDeclaration* fd = vd->toParent2()->isFuncDeclaration();
             if (fd && fd != p->func()->decl) {
                 Logger::println("nested parameter");
-                return new DVarValue(vd, DtoNestedVariable(vd), true);
+                return new DVarValue(type, vd, DtoNestedVariable(vd), true);
             }
             else if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa<llvm::AllocaInst>(vd->ir.getIrValue())) {
-                return new DVarValue(vd, vd->ir.getIrValue(), true);
+                return new DVarValue(type, vd, vd->ir.getIrValue(), true);
             }
             else if (llvm::isa<llvm::Argument>(vd->ir.getIrValue())) {
                 return new DImValue(type, vd->ir.getIrValue());
@@ -137,7 +137,7 @@
                 Logger::cout() << "unresolved global had type: " << *DtoType(vd->type) << '\n';
                 fatal();
             }
-            return new DVarValue(vd, vd->ir.getIrValue(), true);
+            return new DVarValue(type, vd, vd->ir.getIrValue(), true);
         }
     }
     else if (FuncDeclaration* fdecl = var->isFuncDeclaration())
@@ -897,7 +897,7 @@
             assert(0);
 
         //Logger::cout() << "mem: " << *arrptr << '\n';
-        return new DVarValue(vd, arrptr, true);
+        return new DVarValue(type, vd, arrptr, true);
     }
     else if (FuncDeclaration* fdecl = var->isFuncDeclaration())
     {
@@ -977,7 +977,7 @@
         const LLType* t = DtoType(type);
         if (v->getType() != t)
             v = DtoBitCast(v, t);
-        return new DThisValue(vd, v);
+        return new DThisValue(type, vd, v);
     }
 
     // anything we're not yet handling ?
@@ -2122,7 +2122,7 @@
             if (!vx) continue;
             tys.push_back(DtoType(vx->type));
         }
-        const LLStructType* t = LLStructType::get(tys);
+        const LLStructType* t = LLStructType::get(tys, sd->ir.irStruct->packed);
         if (t != llt) {
             if (getABITypeSize(t) != getABITypeSize(llt)) {
                 Logger::cout() << "got size " << getABITypeSize(t) << ", expected " << getABITypeSize(llt) << '\n';
--- a/ir/irstruct.cpp	Wed Jul 30 09:21:06 2008 +0200
+++ b/ir/irstruct.cpp	Wed Jul 30 10:12:55 2008 +0200
@@ -48,6 +48,8 @@
     classDeclared = false;
     classDefined = false;
 
+    packed = false;
+
     dwarfComposite = NULL;
 }
 
--- a/ir/irstruct.h	Wed Jul 30 09:21:06 2008 +0200
+++ b/ir/irstruct.h	Wed Jul 30 10:12:55 2008 +0200
@@ -81,6 +81,8 @@
     bool classDeclared;
     bool classDefined;
 
+    bool packed; // true for: align(1) struct S { ... }
+
     LLGlobalVariable* dwarfComposite;
 };