# HG changeset patch # User Anders Halager # Date 1208810832 -7200 # Node ID 1a7a308f75b213204658e2ef111d0fc33a68e3fa # Parent 52eb0eb92e911bcaba830074e822ad3d9a58790e 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) diff -r 52eb0eb92e91 -r 1a7a308f75b2 gen/LLVMGen.d --- 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; diff -r 52eb0eb92e91 -r 1a7a308f75b2 sema/DType.d --- 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 diff -r 52eb0eb92e91 -r 1a7a308f75b2 sema/Declarations.d --- 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; } } diff -r 52eb0eb92e91 -r 1a7a308f75b2 tests/code/struct_1.d --- /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; +} diff -r 52eb0eb92e91 -r 1a7a308f75b2 tests/code/struct_2.d --- /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; +} diff -r 52eb0eb92e91 -r 1a7a308f75b2 tests/code/struct_3.d --- /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; +} diff -r 52eb0eb92e91 -r 1a7a308f75b2 tests/code/struct_4.d --- /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; +} diff -r 52eb0eb92e91 -r 1a7a308f75b2 tests/run.d --- 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); }