Mercurial > projects > ldc
diff gen/tocall.cpp @ 347:6057fdf797d8 trunk
[svn r368] Fixed custom class allocators with arbitrary user arguments. Closes #25
Removed some dead code.
Started on a more generalised approach to call misc. D functions.
author | lindquist |
---|---|
date | Sun, 13 Jul 2008 20:49:10 +0200 |
parents | |
children | ac1fcc138e42 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gen/tocall.cpp Sun Jul 13 20:49:10 2008 +0200 @@ -0,0 +1,61 @@ +#include "gen/llvm.h" + +#include "mtype.h" +#include "declaration.h" + +#include "gen/tollvm.h" +#include "gen/llvmhelpers.h" +#include "gen/irstate.h" +#include "gen/dvalue.h" +#include "gen/functions.h" + +#include "gen/logger.h" + +////////////////////////////////////////////////////////////////////////////////////////// + +DValue* DtoCallDFunc(FuncDeclaration* fdecl, Array* arguments, TypeClass* type, LLValue* thismem) +{ + Logger::println("Calling function: %s", fdecl->toPrettyChars()); + LOG_SCOPE; + + assert(fdecl); + DtoForceDeclareDsymbol(fdecl); + llvm::Function* fn = fdecl->ir.irFunc->func; + TypeFunction* tf = (TypeFunction*)DtoDType(fdecl->type); + + llvm::PAListPtr palist; + + int thisOffset = 0; + if (type || thismem) + { + assert(type && thismem); + thisOffset = 1; + } + + std::vector<LLValue*> args; + if (thisOffset) + args.push_back(thismem); + for (size_t i=0; i<arguments->dim; ++i) + { + Expression* ex = (Expression*)arguments->data[i]; + Argument* fnarg = Argument::getNth(tf->parameters, i); + DValue* argval = DtoArgument(fnarg, ex); + LLValue* a = argval->getRVal(); + const LLType* aty = fn->getFunctionType()->getParamType(i+thisOffset); + if (a->getType() != aty) + { + Logger::cout() << "expected: " << *aty << '\n'; + Logger::cout() << "got: " << *a->getType() << '\n'; + a = DtoBitCast(a, aty); + } + args.push_back(a); + if (fnarg && fnarg->llvmByVal) + palist = palist.addAttr(i+thisOffset+1, llvm::ParamAttr::ByVal); // return,this,args... + } + + CallOrInvoke* call = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), "tmp"); + call->setCallingConv(DtoCallingConv(LINKd)); + call->setParamAttrs(palist); + + return new DImValue(type, call->get(), false); +}