changeset 39:1a7a308f75b2 new_gen

Added some struct tests, and implemented a wrong struct assignment It assumes 8 bytes for all struct, we have no DType available at that point Slight improvement to an error message (Member access to unknown members)
author Anders Halager <halager@gmail.com>
date Mon, 21 Apr 2008 22:47:12 +0200
parents 52eb0eb92e91
children 9fb190ad81a4
files gen/LLVMGen.d sema/DType.d sema/Declarations.d tests/code/struct_1.d tests/code/struct_2.d tests/code/struct_3.d tests/code/struct_4.d tests/run.d
diffstat 8 files changed, 107 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/gen/LLVMGen.d	Sun Apr 20 23:53:42 2008 +0200
+++ b/gen/LLVMGen.d	Mon Apr 21 22:47:12 2008 +0200
@@ -60,23 +60,25 @@
         m = new Module("main_module");
         scope(exit) m.dispose();
 
-
         table.enterScope;
 
+        BytePtr = PointerType.Get(Type.Int8);
+        auto temp = FunctionType.Get(Type.Void, [BytePtr, BytePtr, Type.Int32, Type.Int32]);
+        llvm_memcpy = m.addFunction(temp, "llvm.memcpy.i32");
         auto registerFunc =
             (FuncDecl fd)
             {
                 Type[] param_types;
                 foreach (p; fd.funcArgs)
                 {
-                    if(cast(DStruct)p.env.find(p.identifier).type)
+                    DType t = p.env.find(p.identifier).type;
+                    if(cast(DStruct)t)
                     {
-                        Type pointer = PointerType.Get(p.env.find(p.identifier).type.llvm());
+                        Type pointer = PointerType.Get(t.llvm());
                         param_types ~= pointer;
                     }
-                        
                     else
-                        param_types ~= p.env.find(p.identifier).type.llvm();
+                        param_types ~= t.llvm();
                 }
                 auto ret_t = fd.env.find(fd.identifier).type.llvm();
                 auto func_t = FunctionType.Get(ret_t, param_types);
@@ -469,6 +471,11 @@
 
                         Value val = b.buildGEP(v, vals, sym.id.get~"."~child.get);
                         return val;
+
+                    default:
+                        Value val = genExpression(exp);
+                        auto AI = b.buildAlloca(val.type, ".s");
+                        return b.buildStore(val, AI);
                 }
             default:
                 Value val = genExpression(exp);
@@ -478,18 +485,37 @@
         assert(0, "Reached end of switch in getPointer");
         return null;
     }
+
     private Value buildAssign(Exp target, Exp exp)
     {
         Value t = getPointer(target);
         Value v = genExpression(exp);
 
-        auto a = (cast(PointerType)(t.type));
+        auto a = cast(PointerType)t.type;
 
         assert(a, "Assing to type have to be of type PointerType");
 
-        if (v.type != a.elementType)
+        Type value_type = v.type;
+        if (auto value_ptr = cast(PointerType)v.type)
         {
-            IntegerType v_t = cast(IntegerType) v.type;
+            value_type = value_ptr.elementType;
+
+            if (a.elementType is value_type && cast(StructType)value_type)
+            {
+                // bitcast "from" to i8*
+                Value from = b.buildBitCast(v, BytePtr, ".copy_from");
+                // bitcast "to" to i8*
+                Value to = b.buildBitCast(t, BytePtr, ".copy_to");
+                // call llvm.memcpy.i32( "from", "to", type_size, alignment (32 in clang) );
+                b.buildCall(llvm_memcpy, [from, to, ConstantInt.GetS(Type.Int32, 8), ConstantInt.GetS(Type.Int32, 32)], null);
+                // return "to"
+                return t;
+            }
+        }
+
+        if (value_type != a.elementType)
+        {
+            IntegerType v_t = cast(IntegerType) value_type;
             IntegerType i_t = cast(IntegerType) a.elementType;
             if (v_t is null || i_t is null)
                 throw error(__LINE__, PE.NoImplicitConversion)
@@ -514,6 +540,8 @@
     // llvm stuff
     Module m;
     Builder b;
+    Function llvm_memcpy;
+    Type BytePtr;
 
     FuncDecl[char[]] functions;
 
--- a/sema/DType.d	Sun Apr 20 23:53:42 2008 +0200
+++ b/sema/DType.d	Mon Apr 21 22:47:12 2008 +0200
@@ -54,6 +54,7 @@
     char[] name() { return id; }
     Location getLoc() { return loc; }
     LLVM.Type llvm() { return llvmType; }
+    int byteSize() { return 0; }
 
     static DInteger
         Bool,
@@ -89,6 +90,8 @@
         llvmType = LLVM.IntegerType.Get(bits);
     }
 
+    override int byteSize() { return bits / 8; }
+
     int bits;
     bool unsigned;
 }
@@ -100,19 +103,25 @@
         super(id, actual);
     }
 
+    int byteSize() { return bytes_total; }
+
     void setMembers(DType[char[]] members)
     {
         this.members = members;
 
         LLVM.Type[] types;
 
-        foreach( type ; members)
+        foreach (type; members)
+        {
             types ~= type.llvm;
+            bytes_total += type.byteSize();
+        }
 
         this.llvmType = LLVM.StructType.Get(types);
 
     }
     DType[char[]] members;
+    private int bytes_total;
 }
 
 class DFunction : DType
--- a/sema/Declarations.d	Sun Apr 20 23:53:42 2008 +0200
+++ b/sema/Declarations.d	Mon Apr 21 22:47:12 2008 +0200
@@ -53,12 +53,15 @@
                 auto target = cast(Identifier)m.target;
                 auto child = m.child;
                 auto st = cast(DStruct)(target.env.find(target).type);
-                if((child.get in st.members) == null)
-                    throw error(__LINE__, "Undefined member in %0 with type %1")
+                if((child.get in st.members) is null)
+                    throw error(__LINE__, "%0 %1 has no member %2")
+                        .arg(st.name)
                         .arg(target.get)
-                        .arg(st.name)
-                        .loc(target.token.location)
-                        .loc(child.token.location);
+                        .arg(child.get)
+                        .tok(child.token);
+                break;
+            case ExpType.MemberLookup:
+                break;
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/code/struct_1.d	Mon Apr 21 22:47:12 2008 +0200
@@ -0,0 +1,9 @@
+
+struct S
+{
+}
+
+void main()
+{
+    S s;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/code/struct_2.d	Mon Apr 21 22:47:12 2008 +0200
@@ -0,0 +1,13 @@
+
+struct S
+{
+    int a;
+    int b;
+}
+
+void main()
+{
+    S s;
+    s.a = 2;
+    s.b = s.a;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/code/struct_3.d	Mon Apr 21 22:47:12 2008 +0200
@@ -0,0 +1,11 @@
+
+struct S
+{
+    int a;
+}
+
+void main()
+{
+    S s;
+    S s2 = s;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/code/struct_4.d	Mon Apr 21 22:47:12 2008 +0200
@@ -0,0 +1,18 @@
+
+struct A
+{
+    int a;
+}
+
+struct B
+{
+    int b;
+    A a;
+}
+
+void main()
+{
+    B b;
+    b.a.a = 1;
+    b.b = 2;
+}
--- a/tests/run.d	Sun Apr 20 23:53:42 2008 +0200
+++ b/tests/run.d	Mon Apr 21 22:47:12 2008 +0200
@@ -101,6 +101,7 @@
         process.execute;
         auto result = process.wait;
 
+        /*
         if(result.status == 0)
         {
             auto llvm_process = new Process("llvm-as");
@@ -109,6 +110,7 @@
             llvm_process.stdin.close();
             result = llvm_process.wait;
         }
+        */
 
         return resultOf(result.status, mode);
     }