Cleanup/comments in DtoFunction type (NFC)

This commit is contained in:
David Nadlinger 2015-08-22 19:14:43 +02:00
parent ef431836b0
commit 83dc8859cb

View file

@ -67,55 +67,53 @@ llvm::FunctionType* DtoFunctionType(Type* type, IrFuncTy &irFty, Type* thistype,
// of the argument types refer to this type. // of the argument types refer to this type.
IrFuncTy newIrFty; IrFuncTy newIrFty;
// llvm idx counter // The index of the next argument on the LLVM level.
size_t lidx = 0; unsigned nextLLArgIdx = 0;
// main needs a little special handling
if (isMain) if (isMain)
{ {
// _Dmain always returns i32, no matter what the type in the D main() is.
newIrFty.ret = new IrFuncTyArg(Type::tint32, false); newIrFty.ret = new IrFuncTyArg(Type::tint32, false);
} }
// sane return value
else else
{ {
Type* rt = f->next; Type* rt = f->next;
const bool byref = f->isref && rt->toBasetype()->ty != Tvoid; const bool byref = f->isref && rt->toBasetype()->ty != Tvoid;
AttrBuilder attrBuilder; AttrBuilder attrBuilder;
// sret return
if (abi->returnInArg(f)) if (abi->returnInArg(f))
{ {
// sret return
newIrFty.arg_sret = new IrFuncTyArg(rt, true, newIrFty.arg_sret = new IrFuncTyArg(rt, true,
AttrBuilder().add(LDC_ATTRIBUTE(StructRet)).add(LDC_ATTRIBUTE(NoAlias))); AttrBuilder().add(LDC_ATTRIBUTE(StructRet)).add(LDC_ATTRIBUTE(NoAlias)));
rt = Type::tvoid; rt = Type::tvoid;
lidx++; ++nextLLArgIdx;
} }
// sext/zext return
else else
{ {
// sext/zext return
attrBuilder.add(DtoShouldExtend(byref ? rt->pointerTo() : rt)); attrBuilder.add(DtoShouldExtend(byref ? rt->pointerTo() : rt));
} }
newIrFty.ret = new IrFuncTyArg(rt, byref, attrBuilder); newIrFty.ret = new IrFuncTyArg(rt, byref, attrBuilder);
} }
lidx++; ++nextLLArgIdx;
// member functions
if (thistype) if (thistype)
{ {
// Add the this pointer for member functions
AttrBuilder attrBuilder; AttrBuilder attrBuilder;
#if LDC_LLVM_VER >= 303 #if LDC_LLVM_VER >= 303
if (isCtor) if (isCtor)
attrBuilder.add(LDC_ATTRIBUTE(Returned)); attrBuilder.add(LDC_ATTRIBUTE(Returned));
#endif #endif
newIrFty.arg_this = new IrFuncTyArg(thistype, thistype->toBasetype()->ty == Tstruct, attrBuilder); newIrFty.arg_this = new IrFuncTyArg(thistype, thistype->toBasetype()->ty == Tstruct, attrBuilder);
lidx++; ++nextLLArgIdx;
} }
// and nested functions
else if (nesttype) else if (nesttype)
{ {
// Add the context pointer for nested functions
newIrFty.arg_nest = new IrFuncTyArg(nesttype, false); newIrFty.arg_nest = new IrFuncTyArg(nesttype, false);
lidx++; ++nextLLArgIdx;
} }
// vararg functions are special too // vararg functions are special too
@ -129,7 +127,7 @@ llvm::FunctionType* DtoFunctionType(Type* type, IrFuncTy &irFty, Type* thistype,
{ {
// _arguments // _arguments
newIrFty.arg_arguments = new IrFuncTyArg(Type::dtypeinfo->type->arrayOf(), false); newIrFty.arg_arguments = new IrFuncTyArg(Type::dtypeinfo->type->arrayOf(), false);
lidx++; ++nextLLArgIdx;
} }
} }
@ -137,51 +135,49 @@ llvm::FunctionType* DtoFunctionType(Type* type, IrFuncTy &irFty, Type* thistype,
} }
// if this _Dmain() doesn't have an argument, we force it to have one // if this _Dmain() doesn't have an argument, we force it to have one
int nargs = Parameter::dim(f->parameters); size_t nargs = Parameter::dim(f->parameters);
if (isMain && nargs == 0) if (isMain && nargs == 0)
{ {
Type* mainargs = Type::tchar->arrayOf()->arrayOf(); Type* mainargs = Type::tchar->arrayOf()->arrayOf();
newIrFty.args.push_back(new IrFuncTyArg(mainargs, false)); newIrFty.args.push_back(new IrFuncTyArg(mainargs, false));
lidx++; ++nextLLArgIdx;
} }
// add explicit parameters
else for (int i = 0; i < nargs; i++) for (size_t i = 0; i < nargs; ++i)
{ {
// get argument
Parameter* arg = Parameter::getNth(f->parameters, i); Parameter* arg = Parameter::getNth(f->parameters, i);
// reference semantics? ref, out and d1 static arrays are // Whether the parameter is passed by LLVM value or as a pointer to the
bool byref = arg->storageClass & (STCref|STCout); // alloca/….
bool passPointer = arg->storageClass & (STCref | STCout);
Type* argtype = arg->type; Type* loweredDType = arg->type;
AttrBuilder attrBuilder; AttrBuilder attrBuilder;
// handle lazy args
if (arg->storageClass & STClazy) if (arg->storageClass & STClazy)
{ {
// Lazy arguments are lowered to delegates.
Logger::println("lazy param"); Logger::println("lazy param");
TypeFunction *ltf = new TypeFunction(NULL, arg->type, 0, LINKd); TypeFunction *ltf = new TypeFunction(NULL, arg->type, 0, LINKd);
TypeDelegate *ltd = new TypeDelegate(ltf); TypeDelegate *ltd = new TypeDelegate(ltf);
argtype = ltd; loweredDType = ltd;
} }
else if (!byref) else if (!passPointer)
{ {
// byval if (abi->passByVal(loweredDType))
if (abi->passByVal(argtype))
{ {
attrBuilder.add(LDC_ATTRIBUTE(ByVal)); attrBuilder.add(LDC_ATTRIBUTE(ByVal));
// set byref, because byval requires a pointed LLVM type // byval parameters are also passed as an address
byref = true; passPointer = true;
} }
// sext/zext
else else
{ {
attrBuilder.add(DtoShouldExtend(argtype)); // Add sext/zext as needed.
attrBuilder.add(DtoShouldExtend(loweredDType));
} }
} }
newIrFty.args.push_back(new IrFuncTyArg(argtype, byref, attrBuilder)); newIrFty.args.push_back(new IrFuncTyArg(loweredDType, passPointer, attrBuilder));
lidx++; ++nextLLArgIdx;
} }
// let the abi rewrite the types as necesary // let the abi rewrite the types as necesary
@ -190,26 +186,26 @@ llvm::FunctionType* DtoFunctionType(Type* type, IrFuncTy &irFty, Type* thistype,
// Now we can modify irFty safely. // Now we can modify irFty safely.
irFty = llvm_move(newIrFty); irFty = llvm_move(newIrFty);
// build the function type // Finally build the actual LLVM function type.
std::vector<LLType*> argtypes; std::vector<LLType*> argtypes;
argtypes.reserve(lidx); argtypes.reserve(nextLLArgIdx);
if (irFty.arg_sret) argtypes.push_back(irFty.arg_sret->ltype); if (irFty.arg_sret) argtypes.push_back(irFty.arg_sret->ltype);
if (irFty.arg_this) argtypes.push_back(irFty.arg_this->ltype); if (irFty.arg_this) argtypes.push_back(irFty.arg_this->ltype);
if (irFty.arg_nest) argtypes.push_back(irFty.arg_nest->ltype); if (irFty.arg_nest) argtypes.push_back(irFty.arg_nest->ltype);
if (irFty.arg_arguments) argtypes.push_back(irFty.arg_arguments->ltype); if (irFty.arg_arguments) argtypes.push_back(irFty.arg_arguments->ltype);
size_t beg = argtypes.size(); const size_t firstExplicitArg = argtypes.size();
size_t nargs2 = irFty.args.size(); const size_t numExplicitArgs = irFty.args.size();
for (size_t i = 0; i < nargs2; i++) for (size_t i = 0; i < numExplicitArgs; i++)
{ {
argtypes.push_back(irFty.args[i]->ltype); argtypes.push_back(irFty.args[i]->ltype);
} }
// reverse params? // reverse params?
if (irFty.reverseParams && nargs2 > 1) if (irFty.reverseParams && numExplicitArgs > 1)
{ {
std::reverse(argtypes.begin() + beg, argtypes.end()); std::reverse(argtypes.begin() + firstExplicitArg, argtypes.end());
} }
irFty.funcType = LLFunctionType::get(irFty.ret->ltype, argtypes, irFty.c_vararg); irFty.funcType = LLFunctionType::get(irFty.ret->ltype, argtypes, irFty.c_vararg);