mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-04-29 22:50:53 +03:00
Eliminate the need for TypeFunction::funcdecl
This commit is contained in:
parent
ca82589e25
commit
b819975c84
22 changed files with 187 additions and 160 deletions
|
@ -915,7 +915,7 @@ struct FuncDeclaration : Declaration
|
|||
virtual FuncDeclaration *toAliasFunc() { return this; }
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC stuff
|
||||
IrFuncTy irFty;
|
||||
|
||||
/// Codegen traversal
|
||||
void codegen(Ir* ir);
|
||||
|
|
|
@ -744,8 +744,7 @@ struct TypeFunction : TypeNext
|
|||
Expression *defaultInit(Loc loc);
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
IrFuncTy fty;
|
||||
IrFuncTy irFty;
|
||||
|
||||
FuncDeclaration* funcdecl;
|
||||
#endif
|
||||
|
@ -778,6 +777,10 @@ struct TypeDelegate : TypeNext
|
|||
#if IN_DMD
|
||||
type *toCtype();
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
IrFuncTy irFty;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct TypeQualified : Type
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//===-- abi-ppc64.cpp -----------------------------------------------------===//
|
||||
//
|
||||
// LDC – the LLVM D compiler
|
||||
// LDC ? the LLVM D compiler
|
||||
//
|
||||
// This file is distributed under the BSD-style LDC license. See the LICENSE
|
||||
// file for details.
|
||||
|
@ -63,7 +63,7 @@ struct PPC64TargetABI : TargetABI {
|
|||
{
|
||||
}
|
||||
|
||||
void rewriteFunctionType(TypeFunction* tf)
|
||||
void rewriteFunctionType(TypeFunction* tf, IrFuncTy &fty)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
|
@ -97,7 +97,7 @@ struct Win64TargetABI : TargetABI
|
|||
|
||||
bool passByVal(Type* t);
|
||||
|
||||
void rewriteFunctionType(TypeFunction* tf);
|
||||
void rewriteFunctionType(TypeFunction* tf, IrFuncTy &fty);
|
||||
};
|
||||
|
||||
|
||||
|
@ -153,9 +153,8 @@ bool Win64TargetABI::passByVal(Type* t)
|
|||
return (t->ty == Tstruct || t->ty == Tsarray) && !canRewriteAsInt(t);
|
||||
}
|
||||
|
||||
void Win64TargetABI::rewriteFunctionType(TypeFunction* tf)
|
||||
void Win64TargetABI::rewriteFunctionType(TypeFunction* tf, IrFuncTy &fty)
|
||||
{
|
||||
IrFuncTy& fty = tf->fty;
|
||||
Type* rt = fty.ret->type->toBasetype();
|
||||
|
||||
// RETURN VALUE
|
||||
|
|
|
@ -376,7 +376,7 @@ struct X86_64TargetABI : TargetABI {
|
|||
|
||||
bool passByVal(Type* t);
|
||||
|
||||
void rewriteFunctionType(TypeFunction* tf);
|
||||
void rewriteFunctionType(TypeFunction* tf, IrFuncTy &fty);
|
||||
|
||||
void doneWithFunctionType() {
|
||||
funcTypeStack.pop_back();
|
||||
|
@ -539,8 +539,7 @@ void X86_64TargetABI::fixup(IrFuncTyArg& arg) {
|
|||
}
|
||||
}
|
||||
|
||||
void X86_64TargetABI::rewriteFunctionType(TypeFunction* tf) {
|
||||
IrFuncTy& fty = tf->fty;
|
||||
void X86_64TargetABI::rewriteFunctionType(TypeFunction* tf, IrFuncTy &fty) {
|
||||
Type* rt = fty.ret->type->toBasetype();
|
||||
|
||||
if (tf->linkage == LINKd) {
|
||||
|
|
|
@ -92,9 +92,8 @@ struct X86TargetABI : TargetABI
|
|||
return t->toBasetype()->ty == Tstruct || t->toBasetype()->ty == Tsarray;
|
||||
}
|
||||
|
||||
void rewriteFunctionType(TypeFunction* tf)
|
||||
void rewriteFunctionType(TypeFunction* tf, IrFuncTy &fty)
|
||||
{
|
||||
IrFuncTy& fty = tf->fty;
|
||||
Type* rt = fty.ret->type->toBasetype();
|
||||
|
||||
// extern(D)
|
||||
|
|
|
@ -74,7 +74,7 @@ struct UnknownTargetABI : TargetABI
|
|||
return t->toBasetype()->ty == Tstruct;
|
||||
}
|
||||
|
||||
void rewriteFunctionType(TypeFunction* t)
|
||||
void rewriteFunctionType(TypeFunction* t, IrFuncTy &fty)
|
||||
{
|
||||
// why?
|
||||
}
|
||||
|
@ -135,12 +135,10 @@ struct IntrinsicABI : TargetABI
|
|||
}
|
||||
}
|
||||
|
||||
void rewriteFunctionType(TypeFunction* tf)
|
||||
void rewriteFunctionType(TypeFunction* tf, IrFuncTy &fty)
|
||||
{
|
||||
assert(tf->linkage == LINKintrinsic);
|
||||
|
||||
IrFuncTy& fty = tf->fty;
|
||||
|
||||
if (!fty.arg_sret) {
|
||||
Type* rt = fty.ret->type->toBasetype();
|
||||
if (rt->ty == Tstruct) {
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
struct Type;
|
||||
struct TypeFunction;
|
||||
struct IrFuncTy;
|
||||
struct IrFuncTyArg;
|
||||
class DValue;
|
||||
|
||||
|
@ -88,7 +89,7 @@ struct TargetABI
|
|||
virtual bool passByVal(Type* t) = 0;
|
||||
|
||||
/// Called to give ABI the chance to rewrite the types
|
||||
virtual void rewriteFunctionType(TypeFunction* t) = 0;
|
||||
virtual void rewriteFunctionType(TypeFunction* t, IrFuncTy &fty) = 0;
|
||||
|
||||
/// Called if resolution of new function type is done
|
||||
virtual void doneWithFunctionType() {}
|
||||
|
|
|
@ -538,7 +538,7 @@ LLValue* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl, char* n
|
|||
Logger::cout() << "funcval: " << *funcval << '\n';
|
||||
|
||||
// cast to final funcptr type
|
||||
funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type)));
|
||||
funcval = DtoBitCast(funcval, getPtrToType(DtoFunctionType(fdecl)));
|
||||
|
||||
// postpone naming until after casting to get the name in call instructions
|
||||
funcval->setName(name);
|
||||
|
|
|
@ -101,6 +101,10 @@ LLValue* DSliceValue::getRVal()
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DFuncValue::DFuncValue(Type *t, FuncDeclaration* fd, llvm::Value* v, llvm::Value* vt)
|
||||
: DValue(t), func(fd), val(v), vthis(vt)
|
||||
{}
|
||||
|
||||
DFuncValue::DFuncValue(FuncDeclaration* fd, LLValue* v, LLValue* vt)
|
||||
: DValue(fd->type), func(fd), val(v), vthis(vt)
|
||||
{}
|
||||
|
|
|
@ -152,6 +152,7 @@ public:
|
|||
class DFuncValue : public DValue
|
||||
{
|
||||
public:
|
||||
DFuncValue(Type *t, FuncDeclaration* fd, llvm::Value* v, llvm::Value* vt = 0);
|
||||
DFuncValue(FuncDeclaration* fd, llvm::Value* v, llvm::Value* vt = 0);
|
||||
|
||||
virtual llvm::Value* getRVal();
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
using namespace llvm::Attribute;
|
||||
#endif
|
||||
|
||||
llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype, bool ismain)
|
||||
llvm::FunctionType* DtoFunctionType(Type* type, IrFuncTy &irFty, Type* thistype, Type* nesttype, bool ismain)
|
||||
{
|
||||
if (Logger::enabled())
|
||||
Logger::println("DtoFunctionType(%s)", type->toChars());
|
||||
|
@ -54,9 +54,9 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
|
|||
// Tell the ABI we're resolving a new function type
|
||||
abi->newFunctionType(f);
|
||||
|
||||
// Do not modify f->fty yet; this function may be called recursively if any
|
||||
// Do not modify irFty yet; this function may be called recursively if any
|
||||
// of the argument types refer to this type.
|
||||
IrFuncTy fty;
|
||||
IrFuncTy newIrFty;
|
||||
|
||||
// llvm idx counter
|
||||
size_t lidx = 0;
|
||||
|
@ -64,7 +64,7 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
|
|||
// main needs a little special handling
|
||||
if (ismain)
|
||||
{
|
||||
fty.ret = new IrFuncTyArg(Type::tint32, false);
|
||||
newIrFty.ret = new IrFuncTyArg(Type::tint32, false);
|
||||
}
|
||||
// sane return value
|
||||
else
|
||||
|
@ -81,11 +81,11 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
|
|||
{
|
||||
#if LDC_LLVM_VER >= 302
|
||||
#if LDC_LLVM_VER >= 303
|
||||
fty.arg_sret = new IrFuncTyArg(rt, true,
|
||||
newIrFty.arg_sret = new IrFuncTyArg(rt, true,
|
||||
llvm::AttrBuilder().addAttribute(llvm::Attribute::StructRet)
|
||||
.addAttribute(llvm::Attribute::NoAlias)
|
||||
#else
|
||||
fty.arg_sret = new IrFuncTyArg(rt, true, llvm::Attributes::get(gIR->context(),
|
||||
newIrFty.arg_sret = new IrFuncTyArg(rt, true, llvm::Attributes::get(gIR->context(),
|
||||
llvm::AttrBuilder().addAttribute(llvm::Attributes::StructRet)
|
||||
.addAttribute(llvm::Attributes::NoAlias)
|
||||
#endif
|
||||
|
@ -94,7 +94,7 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
|
|||
#endif
|
||||
);
|
||||
#else
|
||||
fty.arg_sret = new IrFuncTyArg(rt, true, StructRet | NoAlias
|
||||
newIrFty.arg_sret = new IrFuncTyArg(rt, true, StructRet | NoAlias
|
||||
);
|
||||
#endif
|
||||
rt = Type::tvoid;
|
||||
|
@ -121,7 +121,7 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
|
|||
#elif LDC_LLVM_VER == 302
|
||||
llvm::Attributes a = llvm::Attributes::get(gIR->context(), attrBuilder);
|
||||
#endif
|
||||
fty.ret = new IrFuncTyArg(rt, f->isref, a);
|
||||
newIrFty.ret = new IrFuncTyArg(rt, f->isref, a);
|
||||
}
|
||||
lidx++;
|
||||
|
||||
|
@ -133,7 +133,7 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
|
|||
if (f->funcdecl && f->funcdecl->isCtorDeclaration())
|
||||
attrBuilder.addAttribute(llvm::Attribute::Returned);
|
||||
#endif
|
||||
fty.arg_this = new IrFuncTyArg(thistype, thistype->toBasetype()->ty == Tstruct
|
||||
newIrFty.arg_this = new IrFuncTyArg(thistype, thistype->toBasetype()->ty == Tstruct
|
||||
#if LDC_LLVM_VER >= 303
|
||||
, attrBuilder
|
||||
#endif
|
||||
|
@ -144,7 +144,7 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
|
|||
// and nested functions
|
||||
else if (nesttype)
|
||||
{
|
||||
fty.arg_nest = new IrFuncTyArg(nesttype, false);
|
||||
newIrFty.arg_nest = new IrFuncTyArg(nesttype, false);
|
||||
lidx++;
|
||||
}
|
||||
|
||||
|
@ -158,19 +158,19 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
|
|||
if (f->varargs == 1)
|
||||
{
|
||||
// _arguments
|
||||
fty.arg_arguments = new IrFuncTyArg(Type::typeinfo->type->arrayOf(), false);
|
||||
newIrFty.arg_arguments = new IrFuncTyArg(Type::typeinfo->type->arrayOf(), false);
|
||||
lidx++;
|
||||
// _argptr
|
||||
#if LDC_LLVM_VER >= 303
|
||||
fty.arg_argptr = new IrFuncTyArg(Type::tvoid->pointerTo(), false,
|
||||
newIrFty.arg_argptr = new IrFuncTyArg(Type::tvoid->pointerTo(), false,
|
||||
llvm::AttrBuilder().addAttribute(llvm::Attribute::NoAlias)
|
||||
.addAttribute(llvm::Attribute::NoCapture));
|
||||
#elif LDC_LLVM_VER == 302
|
||||
fty.arg_argptr = new IrFuncTyArg(Type::tvoid->pointerTo(), false,
|
||||
newIrFty.arg_argptr = new IrFuncTyArg(Type::tvoid->pointerTo(), false,
|
||||
llvm::Attributes::get(gIR->context(), llvm::AttrBuilder().addAttribute(llvm::Attributes::NoAlias)
|
||||
.addAttribute(llvm::Attributes::NoCapture)));
|
||||
#else
|
||||
fty.arg_argptr = new IrFuncTyArg(Type::tvoid->pointerTo(), false, NoAlias | NoCapture);
|
||||
newIrFty.arg_argptr = new IrFuncTyArg(Type::tvoid->pointerTo(), false, NoAlias | NoCapture);
|
||||
#endif
|
||||
lidx++;
|
||||
}
|
||||
|
@ -179,7 +179,7 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
|
|||
{
|
||||
// Default to C-style varargs for non-extern(D) variadic functions.
|
||||
// This seems to be what DMD does.
|
||||
fty.c_vararg = true;
|
||||
newIrFty.c_vararg = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,7 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
|
|||
if (ismain && nargs == 0)
|
||||
{
|
||||
Type* mainargs = Type::tchar->arrayOf()->arrayOf();
|
||||
fty.args.push_back(new IrFuncTyArg(mainargs, false));
|
||||
newIrFty.args.push_back(new IrFuncTyArg(mainargs, false));
|
||||
lidx++;
|
||||
}
|
||||
// add explicit parameters
|
||||
|
@ -247,15 +247,15 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
|
|||
#elif LDC_LLVM_VER == 302
|
||||
llvm::Attributes a = llvm::Attributes::get(gIR->context(), attrBuilder);
|
||||
#endif
|
||||
fty.args.push_back(new IrFuncTyArg(argtype, byref, a));
|
||||
newIrFty.args.push_back(new IrFuncTyArg(argtype, byref, a));
|
||||
lidx++;
|
||||
}
|
||||
|
||||
// Now we can modify f->fty safely.
|
||||
f->fty = fty;
|
||||
// Now we can modify irFty safely.
|
||||
irFty = newIrFty;
|
||||
|
||||
// let the abi rewrite the types as necesary
|
||||
abi->rewriteFunctionType(f);
|
||||
abi->rewriteFunctionType(f, irFty);
|
||||
|
||||
// Tell the ABI we're done with this function type
|
||||
abi->doneWithFunctionType();
|
||||
|
@ -264,26 +264,26 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
|
|||
std::vector<LLType*> argtypes;
|
||||
argtypes.reserve(lidx);
|
||||
|
||||
if (f->fty.arg_sret) argtypes.push_back(f->fty.arg_sret->ltype);
|
||||
if (f->fty.arg_this) argtypes.push_back(f->fty.arg_this->ltype);
|
||||
if (f->fty.arg_nest) argtypes.push_back(f->fty.arg_nest->ltype);
|
||||
if (f->fty.arg_arguments) argtypes.push_back(f->fty.arg_arguments->ltype);
|
||||
if (f->fty.arg_argptr) argtypes.push_back(f->fty.arg_argptr->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_nest) argtypes.push_back(irFty.arg_nest->ltype);
|
||||
if (irFty.arg_arguments) argtypes.push_back(irFty.arg_arguments->ltype);
|
||||
if (irFty.arg_argptr) argtypes.push_back(irFty.arg_argptr->ltype);
|
||||
|
||||
size_t beg = argtypes.size();
|
||||
size_t nargs2 = f->fty.args.size();
|
||||
size_t nargs2 = irFty.args.size();
|
||||
for (size_t i = 0; i < nargs2; i++)
|
||||
{
|
||||
argtypes.push_back(f->fty.args[i]->ltype);
|
||||
argtypes.push_back(irFty.args[i]->ltype);
|
||||
}
|
||||
|
||||
// reverse params?
|
||||
if (f->fty.reverseParams && nargs2 > 1)
|
||||
if (irFty.reverseParams && nargs2 > 1)
|
||||
{
|
||||
std::reverse(argtypes.begin() + beg, argtypes.end());
|
||||
}
|
||||
|
||||
LLFunctionType* functype = LLFunctionType::get(f->fty.ret->ltype, argtypes, f->fty.c_vararg);
|
||||
LLFunctionType* functype = LLFunctionType::get(irFty.ret->ltype, argtypes, irFty.c_vararg);
|
||||
|
||||
Logger::cout() << "Final function type: " << *functype << "\n";
|
||||
|
||||
|
@ -377,26 +377,26 @@ LLFunction* DtoInlineIRFunction(FuncDeclaration* fdecl)
|
|||
|
||||
static llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl)
|
||||
{
|
||||
TypeFunction* f = static_cast<TypeFunction*>(fdecl->type);
|
||||
LLFunctionType* fty = 0;
|
||||
IrFuncTy &irFty = fdecl->irFty;
|
||||
LLFunctionType* type = 0;
|
||||
|
||||
// create new ir funcTy
|
||||
f->fty.reset();
|
||||
f->fty.ret = new IrFuncTyArg(Type::tvoid, false);
|
||||
irFty.reset();
|
||||
irFty.ret = new IrFuncTyArg(Type::tvoid, false);
|
||||
|
||||
f->fty.args.push_back(new IrFuncTyArg(Type::tvoid->pointerTo(), false));
|
||||
irFty.args.push_back(new IrFuncTyArg(Type::tvoid->pointerTo(), false));
|
||||
|
||||
if (fdecl->llvmInternal == LLVMva_start)
|
||||
fty = GET_INTRINSIC_DECL(vastart)->getFunctionType();
|
||||
type = GET_INTRINSIC_DECL(vastart)->getFunctionType();
|
||||
else if (fdecl->llvmInternal == LLVMva_copy) {
|
||||
fty = GET_INTRINSIC_DECL(vacopy)->getFunctionType();
|
||||
f->fty.args.push_back(new IrFuncTyArg(Type::tvoid->pointerTo(), false));
|
||||
type = GET_INTRINSIC_DECL(vacopy)->getFunctionType();
|
||||
irFty.args.push_back(new IrFuncTyArg(Type::tvoid->pointerTo(), false));
|
||||
}
|
||||
else if (fdecl->llvmInternal == LLVMva_end)
|
||||
fty = GET_INTRINSIC_DECL(vaend)->getFunctionType();
|
||||
assert(fty);
|
||||
type = GET_INTRINSIC_DECL(vaend)->getFunctionType();
|
||||
assert(type);
|
||||
|
||||
return fty;
|
||||
return type;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -434,7 +434,7 @@ llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl)
|
|||
dnest = Type::tvoid->pointerTo();
|
||||
}
|
||||
|
||||
LLFunctionType* functype = DtoFunctionType(fdecl->type, dthis, dnest, fdecl->isMain());
|
||||
LLFunctionType* functype = DtoFunctionType(fdecl->type, fdecl->irFty, dthis, dnest, fdecl->isMain());
|
||||
|
||||
return functype;
|
||||
}
|
||||
|
@ -551,6 +551,7 @@ void DtoResolveFunction(FuncDeclaration* fdecl)
|
|||
#if LDC_LLVM_VER >= 303
|
||||
static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclaration* fdecl)
|
||||
{
|
||||
IrFuncTy &irFty = fdecl->irFty;
|
||||
llvm::AttributeSet old = func->getAttributes();
|
||||
llvm::AttributeSet existingAttrs[] = { old.getFnAttributes(), old.getRetAttributes() };
|
||||
llvm::AttributeSet newAttrs = llvm::AttributeSet::get(gIR->context(), existingAttrs);
|
||||
|
@ -559,9 +560,9 @@ static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclarati
|
|||
|
||||
// handle implicit args
|
||||
#define ADD_PA(X) \
|
||||
if (f->fty.X) { \
|
||||
if (f->fty.X->attrs.hasAttributes()) { \
|
||||
llvm::AttributeSet a = llvm::AttributeSet::get(gIR->context(), idx, f->fty.X->attrs); \
|
||||
if (irFty.X) { \
|
||||
if (irFty.X->attrs.hasAttributes()) { \
|
||||
llvm::AttributeSet a = llvm::AttributeSet::get(gIR->context(), idx, irFty.X->attrs); \
|
||||
newAttrs = newAttrs.addAttributes(gIR->context(), idx, a); \
|
||||
} \
|
||||
idx++; \
|
||||
|
@ -583,10 +584,10 @@ static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclarati
|
|||
Parameter* fnarg = Parameter::getNth(f->parameters, k);
|
||||
assert(fnarg);
|
||||
|
||||
llvm::AttrBuilder a = f->fty.args[k]->attrs;
|
||||
llvm::AttrBuilder a = irFty.args[k]->attrs;
|
||||
if (a.hasAttributes())
|
||||
{
|
||||
unsigned i = idx + (f->fty.reverseParams ? n-k-1 : k);
|
||||
unsigned i = idx + (irFty.reverseParams ? n-k-1 : k);
|
||||
llvm::AttributeSet as = llvm::AttributeSet::get(gIR->context(), i, a);
|
||||
newAttrs = newAttrs.addAttributes(gIR->context(), i, as);
|
||||
}
|
||||
|
@ -598,15 +599,16 @@ static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclarati
|
|||
#else
|
||||
static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclaration* fdecl)
|
||||
{
|
||||
IrFuncTy &irFty = fdecl->irFty;
|
||||
LLSmallVector<llvm::AttributeWithIndex, 9> attrs;
|
||||
|
||||
int idx = 0;
|
||||
|
||||
// handle implicit args
|
||||
#define ADD_PA(X) \
|
||||
if (f->fty.X) { \
|
||||
if (HAS_ATTRIBUTES(f->fty.X->attrs)) { \
|
||||
attrs.push_back(llvm::AttributeWithIndex::get(idx, f->fty.X->attrs)); \
|
||||
if (irFty.X) { \
|
||||
if (HAS_ATTRIBUTES(irFty.X->attrs)) { \
|
||||
attrs.push_back(llvm::AttributeWithIndex::get(idx, irFty.X->attrs)); \
|
||||
} \
|
||||
idx++; \
|
||||
}
|
||||
|
@ -633,11 +635,11 @@ static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclarati
|
|||
Parameter* fnarg = Parameter::getNth(f->parameters, k);
|
||||
assert(fnarg);
|
||||
|
||||
attrptr[k] = f->fty.args[k]->attrs;
|
||||
attrptr[k] = irFty.args[k]->attrs;
|
||||
}
|
||||
|
||||
// reverse params?
|
||||
if (f->fty.reverseParams)
|
||||
if (irFty.reverseParams)
|
||||
{
|
||||
std::reverse(attrptr.begin(), attrptr.end());
|
||||
}
|
||||
|
@ -712,6 +714,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
|||
Type* t = fdecl->type->toBasetype();
|
||||
TypeFunction* f = static_cast<TypeFunction*>(t);
|
||||
|
||||
IrFuncTy &irFty = fdecl->irFty;
|
||||
bool declareOnly = !mustDefineSymbol(fdecl);
|
||||
|
||||
if (fdecl->llvmInternal == LLVMva_start)
|
||||
|
@ -835,13 +838,13 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
|||
// name parameters
|
||||
llvm::Function::arg_iterator iarg = func->arg_begin();
|
||||
|
||||
if (f->fty.arg_sret) {
|
||||
if (irFty.arg_sret) {
|
||||
iarg->setName(".sret_arg");
|
||||
fdecl->ir.irFunc->retArg = iarg;
|
||||
++iarg;
|
||||
}
|
||||
|
||||
if (f->fty.arg_this) {
|
||||
if (irFty.arg_this) {
|
||||
iarg->setName(".this_arg");
|
||||
fdecl->ir.irFunc->thisArg = iarg;
|
||||
|
||||
|
@ -855,21 +858,21 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
|||
IrParameter* p = new IrParameter(v);
|
||||
p->isVthis = true;
|
||||
p->value = iarg;
|
||||
p->arg = f->fty.arg_this;
|
||||
p->arg = irFty.arg_this;
|
||||
|
||||
v->ir.irParam = p;
|
||||
}
|
||||
|
||||
++iarg;
|
||||
}
|
||||
else if (f->fty.arg_nest) {
|
||||
else if (irFty.arg_nest) {
|
||||
iarg->setName(".nest_arg");
|
||||
fdecl->ir.irFunc->nestArg = iarg;
|
||||
assert(fdecl->ir.irFunc->nestArg);
|
||||
++iarg;
|
||||
}
|
||||
|
||||
if (f->fty.arg_argptr) {
|
||||
if (irFty.arg_argptr) {
|
||||
iarg->setName("._arguments");
|
||||
fdecl->ir.irFunc->_arguments = iarg;
|
||||
++iarg;
|
||||
|
@ -884,7 +887,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
|||
{
|
||||
if (fdecl->parameters && fdecl->parameters->dim > k)
|
||||
{
|
||||
int paramIndex = f->fty.reverseParams ? fdecl->parameters->dim-k-1 : k;
|
||||
int paramIndex = irFty.reverseParams ? fdecl->parameters->dim-k-1 : k;
|
||||
Dsymbol* argsym = static_cast<Dsymbol*>(fdecl->parameters->data[paramIndex]);
|
||||
|
||||
VarDeclaration* argvd = argsym->isVarDeclaration();
|
||||
|
@ -892,7 +895,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
|||
assert(!argvd->ir.irLocal);
|
||||
argvd->ir.irParam = new IrParameter(argvd);
|
||||
argvd->ir.irParam->value = iarg;
|
||||
argvd->ir.irParam->arg = f->fty.args[paramIndex];
|
||||
argvd->ir.irParam->arg = irFty.args[paramIndex];
|
||||
|
||||
str = argvd->ident->toChars();
|
||||
str.append("_arg");
|
||||
|
@ -940,6 +943,8 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
|||
return;
|
||||
}
|
||||
|
||||
IrFuncTy &irFty = fd->irFty;
|
||||
|
||||
// debug info
|
||||
fd->ir.irFunc->diSubprogram = gIR->DBuilder.EmitSubProgram(fd);
|
||||
|
||||
|
@ -1006,13 +1011,13 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
|||
}
|
||||
|
||||
// give the 'this' argument storage and debug info
|
||||
if (f->fty.arg_this)
|
||||
if (irFty.arg_this)
|
||||
{
|
||||
LLValue* thisvar = irfunction->thisArg;
|
||||
assert(thisvar);
|
||||
|
||||
LLValue* thismem = thisvar;
|
||||
if (!f->fty.arg_this->byref)
|
||||
if (!irFty.arg_this->byref)
|
||||
{
|
||||
thismem = DtoRawAlloca(thisvar->getType(), 0, "this"); // FIXME: align?
|
||||
DtoStore(thisvar, thismem);
|
||||
|
@ -1026,7 +1031,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
|||
}
|
||||
|
||||
// give the 'nestArg' storage
|
||||
if (f->fty.arg_nest)
|
||||
if (irFty.arg_nest)
|
||||
{
|
||||
LLValue *nestArg = irfunction->nestArg;
|
||||
LLValue *val = DtoRawAlloca(nestArg->getType(), 0, "nestedFrame");
|
||||
|
@ -1038,7 +1043,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
|||
// and debug info
|
||||
if (fd->parameters)
|
||||
{
|
||||
size_t n = f->fty.args.size();
|
||||
size_t n = irFty.args.size();
|
||||
assert(n == fd->parameters->dim);
|
||||
for (size_t i=0; i < n; ++i)
|
||||
{
|
||||
|
@ -1063,7 +1068,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
|||
|
||||
// let the abi transform the argument back first
|
||||
DImValue arg_dval(vd->type, irparam->value);
|
||||
f->fty.getParam(vd->type, i, &arg_dval, mem);
|
||||
irFty.getParam(vd->type, i, &arg_dval, mem);
|
||||
|
||||
// set the arg var value to the alloca
|
||||
irparam->value = mem;
|
||||
|
|
|
@ -20,6 +20,7 @@ class DValue;
|
|||
struct Expression;
|
||||
struct FuncDeclaration;
|
||||
struct IRAsmBlock;
|
||||
struct IrFuncTy;
|
||||
struct Parameter;
|
||||
struct Type;
|
||||
namespace llvm
|
||||
|
@ -28,7 +29,7 @@ namespace llvm
|
|||
class Value;
|
||||
}
|
||||
|
||||
llvm::FunctionType* DtoFunctionType(Type* t, Type* thistype, Type* nesttype, bool ismain = false);
|
||||
llvm::FunctionType* DtoFunctionType(Type* t, IrFuncTy &irFty, Type* thistype, Type* nesttype, bool ismain = false);
|
||||
llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl);
|
||||
|
||||
llvm::FunctionType* DtoBaseFunctionType(FuncDeclaration* fdecl);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "gen/runtime.h"
|
||||
#include "gen/tollvm.h"
|
||||
#include "gen/typeinf.h"
|
||||
#include "gen/abi.h"
|
||||
#include "ir/irmodule.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
|
@ -1060,7 +1061,11 @@ void DtoVarDeclaration(VarDeclaration* vd)
|
|||
if (ae->e2->op == TOKcall) {
|
||||
CallExp *ce = static_cast<CallExp *>(ae->e2);
|
||||
TypeFunction *tf = static_cast<TypeFunction *>(ce->e1->type->toBasetype());
|
||||
if (tf->ty == Tfunction && tf->fty.arg_sret) {
|
||||
if (tf->ty == Tfunction && tf->linkage != LINKintrinsic) {
|
||||
gABI->newFunctionType(tf);
|
||||
bool retInArg = gABI->returnInArg(tf);
|
||||
gABI->doneWithFunctionType();
|
||||
if (retInArg) {
|
||||
LLValue* const val = ce->toElem(gIR)->getLVal();
|
||||
if (isSpecialRefVar(vd))
|
||||
{
|
||||
|
@ -1077,6 +1082,7 @@ void DtoVarDeclaration(VarDeclaration* vd)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Type* type = isSpecialRefVar(vd) ? vd->type->pointerTo() : vd->type;
|
||||
|
||||
|
|
|
@ -185,6 +185,8 @@ void tokToIcmpPred(TOK op, bool isUnsigned, llvm::ICmpInst::Predicate* outPred,
|
|||
// gen/tocall.cpp stuff below
|
||||
////////////////////////////////////////////
|
||||
|
||||
///
|
||||
IrFuncTy &DtoIrTypeFunction(DValue* fnval);
|
||||
///
|
||||
TypeFunction* DtoTypeFunction(DValue* fnval);
|
||||
|
||||
|
|
|
@ -925,12 +925,12 @@ static void LLVM_D_BuildRuntimeModule()
|
|||
M
|
||||
);
|
||||
gABI->newFunctionType(dty);
|
||||
gABI->rewriteFunctionType(dty);
|
||||
gABI->rewriteFunctionType(dty, dty->irFty);
|
||||
gABI->doneWithFunctionType();
|
||||
#if LDC_LLVM_VER < 303
|
||||
fn->addAttribute(1, dty->fty.args[0]->attrs);
|
||||
fn->addAttribute(1, dty->irFty.args[0]->attrs);
|
||||
#else
|
||||
fn->addAttributes(1, llvm::AttributeSet::get(gIR->context(), 1, dty->fty.args[0]->attrs));
|
||||
fn->addAttributes(1, llvm::AttributeSet::get(gIR->context(), 1, dty->irFty.args[0]->attrs));
|
||||
#endif
|
||||
fn->setCallingConv(gABI->callingConv(LINKd));
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ void ReturnStatement::toIR(IRState* p)
|
|||
dval = ae->toElemDtor(p);
|
||||
}
|
||||
// do abi specific transformations on the return value
|
||||
v = p->func()->type->fty.putRet(exp->type, dval);
|
||||
v = p->func()->decl->irFty.putRet(exp->type, dval);
|
||||
}
|
||||
|
||||
if (Logger::enabled())
|
||||
|
|
|
@ -23,6 +23,23 @@
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrFuncTy &DtoIrTypeFunction(DValue* fnval)
|
||||
{
|
||||
if (DFuncValue* dfnval = fnval->isFunc())
|
||||
{
|
||||
if (dfnval->func)
|
||||
return dfnval->func->irFty;
|
||||
}
|
||||
|
||||
Type* type = stripModifiers(fnval->getType()->toBasetype());
|
||||
if (type->ty == Tfunction)
|
||||
return static_cast<TypeFunction*>(type)->irFty;
|
||||
else if (type->ty == Tdelegate)
|
||||
return static_cast<TypeDelegate*>(type)->irFty;
|
||||
|
||||
llvm_unreachable("Cannot get IrFuncTy from non lazy/function/delegate");
|
||||
}
|
||||
|
||||
TypeFunction* DtoTypeFunction(DValue* fnval)
|
||||
{
|
||||
Type* type = fnval->getType()->toBasetype();
|
||||
|
@ -113,7 +130,7 @@ LLFunctionType* DtoExtractFunctionType(LLType* type)
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static LLValue *fixArgument(DValue *argval, TypeFunction* tf, LLType *callableArgType, size_t argIndex)
|
||||
static LLValue *fixArgument(DValue *argval, IrFuncTy &irFty, LLType *callableArgType, size_t argIndex)
|
||||
{
|
||||
#if 0
|
||||
if (Logger::enabled()) {
|
||||
|
@ -123,7 +140,7 @@ static LLValue *fixArgument(DValue *argval, TypeFunction* tf, LLType *callableAr
|
|||
#endif
|
||||
|
||||
// give the ABI a say
|
||||
LLValue* arg = tf->fty.putParam(argval->getType(), argIndex, argval);
|
||||
LLValue* arg = irFty.putParam(argval->getType(), argIndex, argval);
|
||||
|
||||
#if 0
|
||||
if (Logger::enabled()) {
|
||||
|
@ -189,8 +206,8 @@ void DtoBuildDVarArgList(std::vector<LLValue*>& args,
|
|||
#else
|
||||
std::vector<llvm::AttributeWithIndex> &attrs,
|
||||
#endif
|
||||
TypeFunction* tf, Expressions* arguments,
|
||||
size_t argidx,
|
||||
TypeFunction* tf, IrFuncTy &irFty,
|
||||
Expressions* arguments, size_t argidx,
|
||||
LLFunctionType* callableTy)
|
||||
{
|
||||
Logger::println("doing d-style variadic arguments");
|
||||
|
@ -284,14 +301,14 @@ void DtoBuildDVarArgList(std::vector<LLValue*>& args,
|
|||
|
||||
// specify arguments
|
||||
args.push_back(DtoLoad(typeinfoarrayparam));
|
||||
if (HAS_ATTRIBUTES(tf->fty.arg_arguments->attrs)) {
|
||||
addToAttributes(attrs, argidx, tf->fty.arg_arguments->attrs);
|
||||
if (HAS_ATTRIBUTES(irFty.arg_arguments->attrs)) {
|
||||
addToAttributes(attrs, argidx, irFty.arg_arguments->attrs);
|
||||
}
|
||||
++argidx;
|
||||
|
||||
args.push_back(gIR->ir->CreateBitCast(mem, getPtrToType(LLType::getInt8Ty(gIR->context())), "tmp"));
|
||||
if (HAS_ATTRIBUTES(tf->fty.arg_argptr->attrs)) {
|
||||
addToAttributes(attrs, argidx, tf->fty.arg_argptr->attrs);
|
||||
if (HAS_ATTRIBUTES(irFty.arg_argptr->attrs)) {
|
||||
addToAttributes(attrs, argidx, irFty.arg_argptr->attrs);
|
||||
}
|
||||
|
||||
// pass non variadic args
|
||||
|
@ -299,11 +316,11 @@ void DtoBuildDVarArgList(std::vector<LLValue*>& args,
|
|||
{
|
||||
Parameter* fnarg = Parameter::getNth(tf->parameters, i);
|
||||
DValue* argval = DtoArgument(fnarg, static_cast<Expression*>(arguments->data[i]));
|
||||
args.push_back(fixArgument(argval, tf, callableTy->getParamType(argidx++), i));
|
||||
args.push_back(fixArgument(argval, irFty, callableTy->getParamType(argidx++), i));
|
||||
|
||||
if (HAS_ATTRIBUTES(tf->fty.args[i]->attrs))
|
||||
if (HAS_ATTRIBUTES(irFty.args[i]->attrs))
|
||||
{
|
||||
addToAttributes(attrs, argidx, tf->fty.args[i]->attrs);
|
||||
addToAttributes(attrs, argidx, irFty.args[i]->attrs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -332,13 +349,14 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
|
|||
bool va_intrinsic = (dfnval && dfnval->func && dfnval->func->isVaIntrinsic());
|
||||
|
||||
// get function type info
|
||||
IrFuncTy &irFty = DtoIrTypeFunction(fnval);
|
||||
TypeFunction* tf = DtoTypeFunction(fnval);
|
||||
|
||||
// misc
|
||||
bool retinptr = tf->fty.arg_sret;
|
||||
bool thiscall = tf->fty.arg_this;
|
||||
bool retinptr = irFty.arg_sret;
|
||||
bool thiscall = irFty.arg_this;
|
||||
bool delegatecall = (calleeType->toBasetype()->ty == Tdelegate);
|
||||
bool nestedcall = tf->fty.arg_nest;
|
||||
bool nestedcall = irFty.arg_nest;
|
||||
bool dvarargs = (tf->linkage == LINKd && tf->varargs == 1);
|
||||
|
||||
llvm::CallingConv::ID callconv = gABI->callingConv(tf->linkage);
|
||||
|
@ -366,14 +384,14 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
|
|||
#endif
|
||||
|
||||
// return attrs
|
||||
if (HAS_ATTRIBUTES(tf->fty.ret->attrs))
|
||||
if (HAS_ATTRIBUTES(irFty.ret->attrs))
|
||||
{
|
||||
addToAttributes(attrs, 0, tf->fty.ret->attrs);
|
||||
addToAttributes(attrs, 0, irFty.ret->attrs);
|
||||
}
|
||||
|
||||
// handle implicit arguments
|
||||
std::vector<LLValue*> args;
|
||||
args.reserve(tf->fty.args.size());
|
||||
args.reserve(irFty.args.size());
|
||||
|
||||
// return in hidden ptr is first
|
||||
if (retinptr)
|
||||
|
@ -385,7 +403,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
|
|||
// add attrs for hidden ptr
|
||||
#if LDC_LLVM_VER >= 303
|
||||
const unsigned Index = 1;
|
||||
llvm::AttrBuilder builder(tf->fty.arg_sret->attrs);
|
||||
llvm::AttrBuilder builder(irFty.arg_sret->attrs);
|
||||
assert((builder.contains(llvm::Attribute::StructRet) || builder.contains(llvm::Attribute::InReg))
|
||||
&& "Sret arg not sret or inreg?");
|
||||
llvm::AttributeSet as = llvm::AttributeSet::get(gIR->context(), Index, builder);
|
||||
|
@ -393,7 +411,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
|
|||
#else
|
||||
llvm::AttributeWithIndex Attr;
|
||||
Attr.Index = 1;
|
||||
Attr.Attrs = tf->fty.arg_sret->attrs;
|
||||
Attr.Attrs = irFty.arg_sret->attrs;
|
||||
#if LDC_LLVM_VER == 302
|
||||
assert((Attr.Attrs.hasAttribute(llvm::Attributes::StructRet) || Attr.Attrs.hasAttribute(llvm::Attributes::InReg))
|
||||
&& "Sret arg not sret or inreg?");
|
||||
|
@ -461,13 +479,13 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
|
|||
}
|
||||
|
||||
// add attributes for context argument
|
||||
if (tf->fty.arg_this && HAS_ATTRIBUTES(tf->fty.arg_this->attrs))
|
||||
if (irFty.arg_this && HAS_ATTRIBUTES(irFty.arg_this->attrs))
|
||||
{
|
||||
addToAttributes(attrs, retinptr ? 2 : 1, tf->fty.arg_this->attrs);
|
||||
addToAttributes(attrs, retinptr ? 2 : 1, irFty.arg_this->attrs);
|
||||
}
|
||||
else if (tf->fty.arg_nest && HAS_ATTRIBUTES(tf->fty.arg_nest->attrs))
|
||||
else if (irFty.arg_nest && HAS_ATTRIBUTES(irFty.arg_nest->attrs))
|
||||
{
|
||||
addToAttributes(attrs, retinptr ? 2 : 1, tf->fty.arg_nest->attrs);
|
||||
addToAttributes(attrs, retinptr ? 2 : 1, irFty.arg_nest->attrs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -490,7 +508,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
|
|||
// d style varargs needs a few more hidden arguments as well as special passing
|
||||
else if (dvarargs)
|
||||
{
|
||||
DtoBuildDVarArgList(args, attrs, tf, arguments, argiter-argbegin+1, callableTy);
|
||||
DtoBuildDVarArgList(args, attrs, tf, irFty, arguments, argiter-argbegin+1, callableTy);
|
||||
}
|
||||
|
||||
// otherwise we're looking at a normal function call
|
||||
|
@ -543,20 +561,20 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
|
|||
{
|
||||
DValue* argval = argvals.at(i);
|
||||
|
||||
int j = tf->fty.reverseParams ? beg + n - i - 1 : beg + i;
|
||||
LLValue *arg = fixArgument(argval, tf, callableTy->getParamType(j), i);
|
||||
int j = irFty.reverseParams ? beg + n - i - 1 : beg + i;
|
||||
LLValue *arg = fixArgument(argval, irFty, callableTy->getParamType(j), i);
|
||||
args.push_back(arg);
|
||||
|
||||
#if LDC_LLVM_VER >= 303
|
||||
addToAttributes(attrs, beg + 1 + (tf->fty.reverseParams ? n-i-1: i), tf->fty.args[i]->attrs);
|
||||
addToAttributes(attrs, beg + 1 + (irFty.reverseParams ? n-i-1: i), irFty.args[i]->attrs);
|
||||
#else
|
||||
attrptr[i] = tf->fty.args[i]->attrs;
|
||||
attrptr[i] = irFty.args[i]->attrs;
|
||||
#endif
|
||||
++argiter;
|
||||
}
|
||||
|
||||
// reverse the relevant params as well as the param attrs
|
||||
if (tf->fty.reverseParams)
|
||||
if (irFty.reverseParams)
|
||||
{
|
||||
std::reverse(args.begin() + beg, args.end());
|
||||
#if LDC_LLVM_VER < 303
|
||||
|
@ -623,7 +641,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
|
|||
{
|
||||
// do abi specific return value fixups
|
||||
DImValue dretval(tf->next, retllval);
|
||||
retllval = tf->fty.getRet(tf->next, &dretval);
|
||||
retllval = irFty.getRet(tf->next, &dretval);
|
||||
}
|
||||
|
||||
// Hack around LDC assuming structs and static arrays are in memory:
|
||||
|
|
|
@ -1465,7 +1465,11 @@ DValue* PtrExp::toElem(IRState* p)
|
|||
if (type->toBasetype()->ty == Tfunction)
|
||||
{
|
||||
assert(!cachedLvalue);
|
||||
return new DImValue(type, e1->toElem(p)->getRVal());
|
||||
DValue *dv = e1->toElem(p);
|
||||
if (DFuncValue *dfv = dv->isFunc())
|
||||
return new DFuncValue(type, dfv->func, dfv->getRVal());
|
||||
else
|
||||
return new DImValue(type, dv->getRVal());
|
||||
}
|
||||
|
||||
// get the rvalue and return it as an lvalue
|
||||
|
@ -2798,7 +2802,7 @@ DValue* FuncExp::toElem(IRState* p)
|
|||
return new DImValue(type, DtoAggrPair(cval, castfptr, ".func"));
|
||||
|
||||
} else {
|
||||
return new DImValue(type, fd->ir.irFunc->func);
|
||||
return new DFuncValue(type, fd, fd->ir.irFunc->func);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "gen/arrays.h"
|
||||
#include "gen/metadata.h"
|
||||
#include "gen/runtime.h"
|
||||
#include "gen/functions.h"
|
||||
|
||||
#include "ir/iraggr.h"
|
||||
#include "ir/irtypeclass.h"
|
||||
|
@ -177,7 +178,7 @@ LLConstant * IrAggr::getVtblInit()
|
|||
|
||||
if (cd->isAbstract() || (fd->isAbstract() && !fd->fbody))
|
||||
{
|
||||
c = getNullValue(DtoType(fd->type->pointerTo()));
|
||||
c = getNullValue(getPtrToType(DtoFunctionType(fd)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -329,8 +330,7 @@ llvm::GlobalVariable * IrAggr::getInterfaceVtbl(BaseClass * b, bool new_instance
|
|||
// the function, we place into the vtable a small wrapper, called thunk,
|
||||
// that casts 'this' to the object and then pass it to the real function.
|
||||
if (b->base->isCPPinterface()) {
|
||||
TypeFunction *f = (TypeFunction*)fd->type->toBasetype();
|
||||
assert(f->fty.arg_this);
|
||||
assert(fd->irFty.arg_this);
|
||||
|
||||
// create the thunk function
|
||||
OutBuffer name;
|
||||
|
@ -352,7 +352,7 @@ llvm::GlobalVariable * IrAggr::getInterfaceVtbl(BaseClass * b, bool new_instance
|
|||
args.push_back(iarg);
|
||||
|
||||
// cast 'this' to Object
|
||||
LLValue* &thisArg = args[(f->fty.arg_sret == 0) ? 0 : 1];
|
||||
LLValue* &thisArg = args[(fd->irFty.arg_sret == 0) ? 0 : 1];
|
||||
LLType* thisType = thisArg->getType();
|
||||
thisArg = DtoBitCast(thisArg, getVoidPtrType());
|
||||
thisArg = DtoGEP1(thisArg, DtoConstInt(-b->offset));
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "gen/tollvm.h"
|
||||
#include "gen/utils.h"
|
||||
#include "gen/llvmhelpers.h"
|
||||
#include "gen/functions.h"
|
||||
#include "ir/irtypeclass.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -346,7 +347,7 @@ std::vector<llvm::Type*> IrTypeClass::buildVtblType(Type* first, Array* vtbl_arr
|
|||
continue;
|
||||
}
|
||||
|
||||
types.push_back(DtoType(fd->type->pointerTo()));
|
||||
types.push_back(getPtrToType(DtoFunctionType(fd)));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -30,14 +30,8 @@ IrTypeFunction* IrTypeFunction::get(Type* dt, Type* nestedContextOverride)
|
|||
assert(!dt->irtype);
|
||||
assert(dt->ty == Tfunction);
|
||||
|
||||
// We can't get cycles here, but we can end up building the type as part of
|
||||
// a class vtbl, ...
|
||||
llvm::Type* lt;
|
||||
TypeFunction* tf = static_cast<TypeFunction*>(dt);
|
||||
if (tf->funcdecl)
|
||||
lt = DtoFunctionType(tf->funcdecl);
|
||||
else
|
||||
lt = DtoFunctionType(tf, NULL, nestedContextOverride);
|
||||
llvm::Type* lt = DtoFunctionType(tf, tf->irFty, NULL, nestedContextOverride);
|
||||
|
||||
if (!dt->irtype)
|
||||
dt->irtype = new IrTypeFunction(dt, lt);
|
||||
|
@ -51,29 +45,21 @@ IrTypeDelegate::IrTypeDelegate(Type * dt, LLType* lt)
|
|||
{
|
||||
}
|
||||
|
||||
IrTypeDelegate* IrTypeDelegate::get(Type* dt)
|
||||
IrTypeDelegate* IrTypeDelegate::get(Type* t)
|
||||
{
|
||||
assert(!dt->irtype);
|
||||
assert(dt->ty == Tdelegate);
|
||||
assert(!t->irtype);
|
||||
assert(t->ty == Tdelegate);
|
||||
assert(t->nextOf()->ty == Tfunction);
|
||||
|
||||
TypeDelegate *dt = (TypeDelegate*)t;
|
||||
|
||||
// We can't get cycles here, but we could end up building the type as part
|
||||
// of a class vtbl, ...
|
||||
if (!dt->nextOf()->irtype)
|
||||
{
|
||||
// Build the underlying function type. Be sure to set irtype here, so
|
||||
// the nested context arg doesn't disappear if DtoType is ever called
|
||||
// on dt->nextOf().
|
||||
IrTypeFunction::get(dt->nextOf(), Type::tvoid->pointerTo());
|
||||
}
|
||||
if (!dt->irtype)
|
||||
{
|
||||
assert(static_cast<TypeFunction*>(dt->nextOf())->fty.arg_nest &&
|
||||
"Underlying function type should have nested context arg, "
|
||||
"picked up random pre-existing type?"
|
||||
);
|
||||
TypeFunction* tf = static_cast<TypeFunction*>(dt->nextOf());
|
||||
llvm::Type* ltf = DtoFunctionType(tf, dt->irFty, NULL, Type::tvoid->pointerTo());
|
||||
|
||||
llvm::Type *types[] = { getVoidPtrType(),
|
||||
getPtrToType(dt->nextOf()->irtype->getLLType()) };
|
||||
getPtrToType(ltf) };
|
||||
LLStructType* lt = LLStructType::get(gIR->context(), types, false);
|
||||
dt->irtype = new IrTypeDelegate(dt, lt);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue