diff gen/tollvm.c @ 9:dafae18f9c08 trunk

[svn r13] * Updated for LLVM 2.1 * Class v-tables are now typesafe * Code cleanups
author lindquist
date Mon, 01 Oct 2007 21:19:53 +0200
parents 5e69b77a5c51
children d3ee9efe20e2
line wrap: on
line diff
--- a/gen/tollvm.c	Thu Sep 27 06:03:06 2007 +0200
+++ b/gen/tollvm.c	Mon Oct 01 21:19:53 2007 +0200
@@ -208,7 +208,7 @@
     TypeFunction* f = (TypeFunction*)fdecl->type;
     assert(f != 0);
 
-    // has already been pulled in by a reference to (
+    // type has already been resolved
     if (f->llvmType != 0) {
         return llvm::cast<llvm::FunctionType>(f->llvmType);
     }
@@ -247,10 +247,17 @@
         paramvec.push_back(rettype);
     }
 
-    if (fdecl->needThis() && fdecl->vthis) {
-        Logger::print("this is: %s\n", fdecl->vthis->type->toChars());
-        paramvec.push_back(LLVM_DtoType(fdecl->vthis->type));
-        usesthis = true;
+    if (fdecl->needThis()) {
+        if (AggregateDeclaration* ad = fdecl->isMember()) {
+            Logger::print("isMember = this is: %s\n", ad->type->toChars());
+            const llvm::Type* thisty = LLVM_DtoType(ad->type);
+            if (llvm::isa<llvm::StructType>(thisty))
+                thisty = llvm::PointerType::get(thisty);
+            paramvec.push_back(thisty);
+            usesthis = true;
+        }
+        else
+        assert(0);
     }
 
     size_t n = Argument::dim(f->parameters);
@@ -295,6 +302,8 @@
     llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg);
 
     f->llvmType = functype;
+    f->llvmRetInPtr = retinptr;
+    f->llvmUsesThis = usesthis;
     return functype;
 }
 
@@ -837,3 +846,74 @@
     Logger::cout() << '\n';
     return new llvm::GetElementPtrInst(ptr, dst.begin(), dst.end(), var, bb);
 }
+
+llvm::Function* LLVM_DtoDeclareFunction(FuncDeclaration* fdecl)
+{
+    if (fdecl->llvmValue != 0) {
+        return llvm::cast<llvm::Function>(fdecl->llvmValue);
+    }
+
+    static int fdi = 0;
+    Logger::print("FuncDeclaration::toObjFile(%d,%s): %s\n", fdi++, fdecl->needThis()?"this":"static",fdecl->toChars());
+    LOG_SCOPE;
+
+    if (fdecl->llvmInternal == LLVMintrinsic && fdecl->fbody) {
+        error("intrinsics cannot have function bodies");
+        fatal();
+    }
+
+    // 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);
+
+    // mangled name
+    char* mangled_name = (fdecl->llvmInternal == LLVMintrinsic) ? fdecl->llvmInternal1 : fdecl->mangle();
+
+    // make the function
+    llvm::Function* func = gIR->module->getFunction(mangled_name);
+    if (func == 0) {
+        func = new llvm::Function(functype,LLVM_DtoLinkage(fdecl->protection, fdecl->storage_class),mangled_name,gIR->module);
+    }
+
+    if (fdecl->llvmInternal != LLVMintrinsic)
+        func->setCallingConv(LLVM_DtoCallingConv(f->linkage));
+
+    fdecl->llvmValue = func;
+    f->llvmType = functype;
+
+    if (fdecl->isMain()) {
+        gIR->mainFunc = func;
+    }
+
+    // name parameters
+    llvm::Function::arg_iterator iarg = func->arg_begin();
+    int k = 0;
+    if (f->llvmRetInPtr) {
+        iarg->setName("retval");
+        f->llvmRetArg = iarg;
+        ++iarg;
+    }
+    if (f->llvmUsesThis) {
+        iarg->setName("this");
+        ++iarg;
+    }
+    for (; iarg != func->arg_end(); ++iarg)
+    {
+        Argument* arg = Argument::getNth(f->parameters, k++);
+        assert(arg != 0);
+        //arg->llvmValue = iarg;
+        //printf("identifier: '%s' %p\n", arg->ident->toChars(), arg->ident);
+        if (arg->ident != 0) {
+            if (arg->vardecl) {
+                arg->vardecl->llvmValue = iarg;
+            }
+            iarg->setName(arg->ident->toChars());
+        }
+        else {
+            iarg->setName("unnamed");
+        }
+    }
+
+    return func;
+}