diff gen/tollvm.c @ 11:d3ee9efe20e2 trunk

[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing. * Now 50/51 tests compile. * Added a simple runalltests.d scripts that should be run with 'gdmd -run runalltests.d' - LLVMDC will not compile it yet.
author lindquist
date Tue, 02 Oct 2007 05:10:18 +0200
parents dafae18f9c08
children c05ef76f1c20
line wrap: on
line diff
--- a/gen/tollvm.c	Mon Oct 01 23:32:29 2007 +0200
+++ b/gen/tollvm.c	Tue Oct 02 05:10:18 2007 +0200
@@ -159,7 +159,7 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-llvm::FunctionType* LLVM_DtoFunctionType(Type* t, const llvm::Type* thisparam)
+const llvm::FunctionType* LLVM_DtoFunctionType(Type* t, const llvm::Type* thisparam)
 {
     TypeFunction* f = (TypeFunction*)t;
 
@@ -203,7 +203,7 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-llvm::FunctionType* LLVM_DtoFunctionType(FuncDeclaration* fdecl)
+const llvm::FunctionType* LLVM_DtoFunctionType(FuncDeclaration* fdecl)
 {
     TypeFunction* f = (TypeFunction*)fdecl->type;
     assert(f != 0);
@@ -309,7 +309,7 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-llvm::StructType* LLVM_DtoDelegateType(Type* t)
+const llvm::StructType* LLVM_DtoDelegateType(Type* t)
 {
     const llvm::Type* i8ptr = llvm::PointerType::get(llvm::Type::Int8Ty);
     const llvm::Type* func = LLVM_DtoFunctionType(t->next, i8ptr);
@@ -323,7 +323,7 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-llvm::Type* LLVM_DtoStructType(Type* t)
+const llvm::Type* LLVM_DtoStructType(Type* t)
 {
     assert(0);
     std::vector<const llvm::Type*> types;
@@ -763,26 +763,40 @@
 
 void LLVM_DtoInitClass(TypeClass* tc, llvm::Value* dst)
 {
-    assert(tc->llvmInit);
-    assert(dst->getType() == tc->llvmInit->getType());
     assert(gIR);
 
     assert(tc->llvmType);
-    uint64_t n = gTargetData->getTypeSize(tc->llvmType);
-    llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
+    uint64_t size_t_size = gTargetData->getTypeSize(LLVM_DtoSize_t());
+    uint64_t n = gTargetData->getTypeSize(tc->llvmType) - size_t_size;
 
-    llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
-    llvm::Value* srcarr = new llvm::BitCastInst(tc->llvmInit,arrty,"tmp",gIR->scopebb());
+    // set vtable field
+    llvm::Value* vtblvar = LLVM_DtoGEPi(dst,0,0,"tmp",gIR->scopebb());
+    assert(tc->sym->llvmVtbl);
+    new llvm::StoreInst(tc->sym->llvmVtbl, vtblvar, gIR->scopebb());
+
+    // copy the static initializer
+    if (n > 0) {
+        assert(tc->llvmInit);
+        assert(dst->getType() == tc->llvmInit->getType());
+
+        llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
 
-    llvm::Function* fn = LLVM_DeclareMemCpy32();
-    std::vector<llvm::Value*> llargs;
-    llargs.resize(4);
-    llargs[0] = dstarr;
-    llargs[1] = srcarr;
-    llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
-    llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
+        llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
+        dstarr = LLVM_DtoGEPi(dstarr,size_t_size,"tmp",gIR->scopebb());
+
+        llvm::Value* srcarr = new llvm::BitCastInst(tc->llvmInit,arrty,"tmp",gIR->scopebb());
+        srcarr = LLVM_DtoGEPi(srcarr,size_t_size,"tmp",gIR->scopebb());
 
-    new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
+        llvm::Function* fn = LLVM_DeclareMemCpy32();
+        std::vector<llvm::Value*> llargs;
+        llargs.resize(4);
+        llargs[0] = dstarr;
+        llargs[1] = srcarr;
+        llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
+        llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
+
+        new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
+    }
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -825,14 +839,19 @@
     return _init;
 }
 
+//////////////////////////////////////////////////////////////////////////////////////////
+
 llvm::Value* LLVM_DtoGEP(llvm::Value* ptr, llvm::Value* i0, llvm::Value* i1, const std::string& var, llvm::BasicBlock* bb)
 {
     std::vector<llvm::Value*> v(2);
     v[0] = i0;
     v[1] = i1;
+    Logger::cout() << "DtoGEP: " << *ptr << '\n';
     return new llvm::GetElementPtrInst(ptr, v.begin(), v.end(), var, bb);
 }
 
+//////////////////////////////////////////////////////////////////////////////////////////
+
 llvm::Value* LLVM_DtoGEP(llvm::Value* ptr, const std::vector<unsigned>& src, const std::string& var, llvm::BasicBlock* bb)
 {
     size_t n = src.size();
@@ -847,9 +866,32 @@
     return new llvm::GetElementPtrInst(ptr, dst.begin(), dst.end(), var, bb);
 }
 
+//////////////////////////////////////////////////////////////////////////////////////////
+
+llvm::Value* LLVM_DtoGEPi(llvm::Value* ptr, unsigned i, const std::string& var, llvm::BasicBlock* bb)
+{
+    return new llvm::GetElementPtrInst(ptr, llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false), var, bb);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
+llvm::Value* LLVM_DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std::string& var, llvm::BasicBlock* bb)
+{
+    std::vector<llvm::Value*> v(2);
+    v[0] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i0, false);
+    v[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i1, false);
+    return new llvm::GetElementPtrInst(ptr, v.begin(), v.end(), var, bb);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
 llvm::Function* LLVM_DtoDeclareFunction(FuncDeclaration* fdecl)
 {
+    TypeFunction* f = (TypeFunction*)fdecl->type;
+    assert(f != 0);
+
     if (fdecl->llvmValue != 0) {
+        assert(llvm::isa<llvm::Function>(fdecl->llvmValue));
         return llvm::cast<llvm::Function>(fdecl->llvmValue);
     }
 
@@ -863,9 +905,7 @@
     }
 
     // construct function
-    TypeFunction* f = (TypeFunction*)fdecl->type;
-    assert(f != 0);
-    llvm::FunctionType* functype = (f->llvmType == 0) ? LLVM_DtoFunctionType(fdecl) : llvm::cast<llvm::FunctionType>(f->llvmType);
+    const llvm::FunctionType* functype = (f->llvmType == 0) ? LLVM_DtoFunctionType(fdecl) : llvm::cast<llvm::FunctionType>(f->llvmType);
 
     // mangled name
     char* mangled_name = (fdecl->llvmInternal == LLVMintrinsic) ? fdecl->llvmInternal1 : fdecl->mangle();
@@ -881,6 +921,7 @@
 
     fdecl->llvmValue = func;
     f->llvmType = functype;
+    assert(llvm::isa<llvm::FunctionType>(f->llvmType));
 
     if (fdecl->isMain()) {
         gIR->mainFunc = func;