mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-27 10:03:13 +01:00
Fixed #53 — Assertion !isaStruct(t)
This commit is contained in:
@@ -597,17 +597,15 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
|||||||
{
|
{
|
||||||
if (fdecl->parameters && fdecl->parameters->dim > k)
|
if (fdecl->parameters && fdecl->parameters->dim > k)
|
||||||
{
|
{
|
||||||
Dsymbol* argsym;
|
int paramIndex = f->fty.reverseParams ? fdecl->parameters->dim-k-1 : k;
|
||||||
if (f->fty.reverseParams)
|
Dsymbol* argsym = (Dsymbol*)fdecl->parameters->data[paramIndex];
|
||||||
argsym = (Dsymbol*)fdecl->parameters->data[fdecl->parameters->dim-k-1];
|
|
||||||
else
|
|
||||||
argsym = (Dsymbol*)fdecl->parameters->data[k];
|
|
||||||
|
|
||||||
VarDeclaration* argvd = argsym->isVarDeclaration();
|
VarDeclaration* argvd = argsym->isVarDeclaration();
|
||||||
assert(argvd);
|
assert(argvd);
|
||||||
assert(!argvd->ir.irLocal);
|
assert(!argvd->ir.irLocal);
|
||||||
argvd->ir.irLocal = new IrLocal(argvd);
|
argvd->ir.irParam = new IrParameter(argvd);
|
||||||
argvd->ir.irLocal->value = iarg;
|
argvd->ir.irParam->value = iarg;
|
||||||
|
argvd->ir.irParam->arg = f->fty.args[paramIndex];
|
||||||
|
|
||||||
str = argvd->ident->toChars();
|
str = argvd->ident->toChars();
|
||||||
str.append("_arg");
|
str.append("_arg");
|
||||||
@@ -720,9 +718,10 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
|||||||
irfunction->thisArg = thismem;
|
irfunction->thisArg = thismem;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(!fd->vthis->ir.irLocal);
|
assert(!fd->vthis->ir.irParam);
|
||||||
fd->vthis->ir.irLocal = new IrLocal(fd->vthis);
|
fd->vthis->ir.irParam = new IrParameter(fd->vthis);
|
||||||
fd->vthis->ir.irLocal->value = thismem;
|
fd->vthis->ir.irParam->value = thismem;
|
||||||
|
fd->vthis->ir.irParam->arg = f->fty.arg_this;
|
||||||
|
|
||||||
DtoDwarfLocalVariable(thismem, fd->vthis);
|
DtoDwarfLocalVariable(thismem, fd->vthis);
|
||||||
|
|
||||||
@@ -755,8 +754,8 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
|||||||
VarDeclaration* vd = argsym->isVarDeclaration();
|
VarDeclaration* vd = argsym->isVarDeclaration();
|
||||||
assert(vd);
|
assert(vd);
|
||||||
|
|
||||||
IrLocal* irloc = vd->ir.irLocal;
|
IrParameter* irparam = vd->ir.irParam;
|
||||||
assert(irloc);
|
assert(irparam);
|
||||||
|
|
||||||
#if DMDV1
|
#if DMDV1
|
||||||
if (vd->nestedref)
|
if (vd->nestedref)
|
||||||
@@ -767,26 +766,26 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
|||||||
|
|
||||||
bool refout = vd->storage_class & (STCref | STCout);
|
bool refout = vd->storage_class & (STCref | STCout);
|
||||||
bool lazy = vd->storage_class & STClazy;
|
bool lazy = vd->storage_class & STClazy;
|
||||||
if (!refout && (!f->fty.args[i]->byref || lazy))
|
if (!refout && (!irparam->arg->byref || lazy))
|
||||||
{
|
{
|
||||||
// alloca a stack slot for this first class value arg
|
// alloca a stack slot for this first class value arg
|
||||||
LLType* argt;
|
LLType* argt;
|
||||||
if (lazy)
|
if (lazy)
|
||||||
argt = irloc->value->getType();
|
argt = irparam->value->getType();
|
||||||
else
|
else
|
||||||
argt = DtoType(vd->type);
|
argt = DtoType(vd->type);
|
||||||
LLValue* mem = DtoRawAlloca(argt, 0, vd->ident->toChars());
|
LLValue* mem = DtoRawAlloca(argt, 0, vd->ident->toChars());
|
||||||
|
|
||||||
// let the abi transform the argument back first
|
// let the abi transform the argument back first
|
||||||
DImValue arg_dval(vd->type, irloc->value);
|
DImValue arg_dval(vd->type, irparam->value);
|
||||||
f->fty.getParam(vd->type, i, &arg_dval, mem);
|
f->fty.getParam(vd->type, i, &arg_dval, mem);
|
||||||
|
|
||||||
// set the arg var value to the alloca
|
// set the arg var value to the alloca
|
||||||
irloc->value = mem;
|
irparam->value = mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (global.params.symdebug && !(isaArgument(irloc->value) && isaArgument(irloc->value)->hasByValAttr()) && !refout)
|
if (global.params.symdebug && !(isaArgument(irparam->value) && isaArgument(irparam->value)->hasByValAttr()) && !refout)
|
||||||
DtoDwarfLocalVariable(irloc->value, vd);
|
DtoDwarfLocalVariable(irparam->value, vd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -461,20 +461,31 @@ static void DtoCreateNestedContextType(FuncDeclaration* fd) {
|
|||||||
vd->ir.irLocal->nestedIndex = types.size();
|
vd->ir.irLocal->nestedIndex = types.size();
|
||||||
vd->ir.irLocal->nestedDepth = depth;
|
vd->ir.irLocal->nestedDepth = depth;
|
||||||
if (vd->isParameter()) {
|
if (vd->isParameter()) {
|
||||||
// Parameters already have storage associated with them (to handle byref etc.),
|
// Parameters will have storage associated with them (to handle byref etc.),
|
||||||
// so handle those cases specially by storing a pointer instead of a value.
|
// so handle those cases specially by storing a pointer instead of a value.
|
||||||
assert(vd->ir.irLocal->value);
|
assert(vd->ir.irParam->value);
|
||||||
LLValue* value = vd->ir.irLocal->value;
|
LLValue* value = vd->ir.irParam->value;
|
||||||
LLType* type = value->getType();
|
LLType* type = value->getType();
|
||||||
if (llvm::isa<llvm::AllocaInst>(llvm::GetUnderlyingObject(value)))
|
bool refout = vd->storage_class & (STCref | STCout);
|
||||||
|
bool lazy = vd->storage_class & STClazy;
|
||||||
|
if (!refout && (!vd->ir.irParam->arg->byref || lazy)) {
|
||||||
// This will be copied to the nesting frame.
|
// This will be copied to the nesting frame.
|
||||||
type = type->getContainedType(0);
|
if (lazy)
|
||||||
|
type = type->getContainedType(0);
|
||||||
|
else
|
||||||
|
type = DtoType(vd->type);
|
||||||
|
vd->ir.irParam->byref = false;
|
||||||
|
} else {
|
||||||
|
vd->ir.irParam->byref = true;
|
||||||
|
}
|
||||||
types.push_back(type);
|
types.push_back(type);
|
||||||
} else if (vd->isRef() || vd->isOut()) {
|
} else if (vd->isRef() || vd->isOut()) {
|
||||||
// Foreach variables can also be by reference, for instance.
|
// Foreach variables can also be by reference, for instance.
|
||||||
types.push_back(DtoType(vd->type->pointerTo()));
|
types.push_back(DtoType(vd->type->pointerTo()));
|
||||||
|
vd->ir.irLocal->byref = true;
|
||||||
} else {
|
} else {
|
||||||
types.push_back(DtoType(vd->type));
|
types.push_back(DtoType(vd->type));
|
||||||
|
vd->ir.irLocal->byref = false;
|
||||||
}
|
}
|
||||||
if (Logger::enabled()) {
|
if (Logger::enabled()) {
|
||||||
Logger::println("Nested var: %s", vd->toChars());
|
Logger::println("Nested var: %s", vd->toChars());
|
||||||
@@ -669,30 +680,30 @@ void DtoCreateNestedContext(FuncDeclaration* fd) {
|
|||||||
// The parameter value is an alloca'd stack slot.
|
// The parameter value is an alloca'd stack slot.
|
||||||
// Copy to the nesting frame and leave the alloca for
|
// Copy to the nesting frame and leave the alloca for
|
||||||
// the optimizers to clean up.
|
// the optimizers to clean up.
|
||||||
|
assert(!vd->ir.irLocal->byref);
|
||||||
DtoStore(DtoLoad(value), gep);
|
DtoStore(DtoLoad(value), gep);
|
||||||
gep->takeName(value);
|
gep->takeName(value);
|
||||||
vd->ir.irLocal->value = gep;
|
vd->ir.irLocal->value = gep;
|
||||||
vd->ir.irLocal->byref = false;
|
|
||||||
} else {
|
} else {
|
||||||
Logger::println("Adding pointer to nested frame");
|
Logger::println("Adding pointer to nested frame");
|
||||||
// The parameter value is something else, such as a
|
// The parameter value is something else, such as a
|
||||||
// passed-in pointer (for 'ref' or 'out' parameters) or
|
// passed-in pointer (for 'ref' or 'out' parameters) or
|
||||||
// a pointer arg with byval attribute.
|
// a pointer arg with byval attribute.
|
||||||
// Store the address into the frame and set the byref flag.
|
// Store the address into the frame.
|
||||||
|
assert(vd->ir.irLocal->byref);
|
||||||
storeVariable(vd, gep);
|
storeVariable(vd, gep);
|
||||||
vd->ir.irLocal->byref = true;
|
|
||||||
}
|
}
|
||||||
} else if (vd->isRef() || vd->isOut()) {
|
} else if (vd->isRef() || vd->isOut()) {
|
||||||
// This slot is initialized in DtoNestedInit, to handle things like byref foreach variables
|
// This slot is initialized in DtoNestedInit, to handle things like byref foreach variables
|
||||||
// which move around in memory.
|
// which move around in memory.
|
||||||
vd->ir.irLocal->byref = true;
|
assert(vd->ir.irLocal->byref);
|
||||||
} else {
|
} else {
|
||||||
Logger::println("nested var: %s", vd->toChars());
|
Logger::println("nested var: %s", vd->toChars());
|
||||||
if (vd->ir.irLocal->value)
|
if (vd->ir.irLocal->value)
|
||||||
Logger::cout() << "Pre-existing value: " << *vd->ir.irLocal->value << '\n';
|
Logger::cout() << "Pre-existing value: " << *vd->ir.irLocal->value << '\n';
|
||||||
assert(!vd->ir.irLocal->value);
|
assert(!vd->ir.irLocal->value);
|
||||||
vd->ir.irLocal->value = gep;
|
vd->ir.irLocal->value = gep;
|
||||||
vd->ir.irLocal->byref = false;
|
assert(!vd->ir.irLocal->byref);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (global.params.symdebug) {
|
if (global.params.symdebug) {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ struct IrFunction;
|
|||||||
struct IrStruct;
|
struct IrStruct;
|
||||||
struct IrGlobal;
|
struct IrGlobal;
|
||||||
struct IrLocal;
|
struct IrLocal;
|
||||||
|
struct IrParameter;
|
||||||
struct IrField;
|
struct IrField;
|
||||||
struct IrVar;
|
struct IrVar;
|
||||||
struct Dsymbol;
|
struct Dsymbol;
|
||||||
@@ -43,7 +44,10 @@ struct IrDsymbol
|
|||||||
IrFunction* irFunc;
|
IrFunction* irFunc;
|
||||||
|
|
||||||
IrGlobal* irGlobal;
|
IrGlobal* irGlobal;
|
||||||
IrLocal* irLocal;
|
union {
|
||||||
|
IrLocal* irLocal;
|
||||||
|
IrParameter *irParam;
|
||||||
|
};
|
||||||
IrField* irField;
|
IrField* irField;
|
||||||
IrVar* getIrVar();
|
IrVar* getIrVar();
|
||||||
llvm::Value*& getIrValue();
|
llvm::Value*& getIrValue();
|
||||||
|
|||||||
@@ -38,6 +38,14 @@ IrLocal::IrLocal(VarDeclaration* v) : IrVar(v)
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
IrParameter::IrParameter(VarDeclaration* v) : IrLocal(v), arg(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
IrField::IrField(VarDeclaration* v) : IrVar(v)
|
IrField::IrField(VarDeclaration* v) : IrVar(v)
|
||||||
{
|
{
|
||||||
assert(V->ir.irField == NULL && "field for this variable already exists");
|
assert(V->ir.irField == NULL && "field for this variable already exists");
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
#include "ir/ir.h"
|
#include "ir/ir.h"
|
||||||
#include "llvm/Type.h"
|
#include "llvm/Type.h"
|
||||||
|
|
||||||
|
struct IrFuncTyArg;
|
||||||
|
|
||||||
struct IrVar : IrBase
|
struct IrVar : IrBase
|
||||||
{
|
{
|
||||||
IrVar(VarDeclaration* var);
|
IrVar(VarDeclaration* var);
|
||||||
@@ -31,6 +33,13 @@ struct IrLocal : IrVar
|
|||||||
int nestedIndex;
|
int nestedIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// represents a function parameter
|
||||||
|
struct IrParameter : IrLocal
|
||||||
|
{
|
||||||
|
IrParameter(VarDeclaration* v);
|
||||||
|
IrFuncTyArg *arg;
|
||||||
|
};
|
||||||
|
|
||||||
// represents an aggregate field variable
|
// represents an aggregate field variable
|
||||||
struct IrField : IrVar
|
struct IrField : IrVar
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user