Mercurial > projects > ldc
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; +}