Fixed #53 — Assertion !isaStruct(t)

This commit is contained in:
Alexey Prokhin
2012-01-09 16:31:26 +04:00
parent dbb6528c95
commit 9889067420
5 changed files with 60 additions and 29 deletions

View File

@@ -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);
} }
} }

View File

@@ -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) {

View File

@@ -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();

View File

@@ -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");

View File

@@ -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
{ {