Added type param to DVarValue as DMD sometimes overrides the type of the VarDeclaration.

Added support for align(1)/packed structs, other alignments are still ignored.
Fixed some problems with accessing lazy arguments.
This commit is contained in:
Tomas Lindquist Olsen 2008-07-30 10:12:55 +02:00
parent 3b21ae25be
commit 905ca019dd
11 changed files with 43 additions and 32 deletions

View file

@ -10,13 +10,13 @@
/////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////
DVarValue::DVarValue(VarDeclaration* vd, LLValue* llvmValue, bool lvalue)
DVarValue::DVarValue(Type* t, VarDeclaration* vd, LLValue* llvmValue, bool lvalue)
{
var = vd;
val = llvmValue;
rval = 0;
lval = lvalue;
type = var->type;
type = t;
}
DVarValue::DVarValue(Type* t, LLValue* lv, LLValue* rv)

View file

@ -111,8 +111,8 @@ struct DVarValue : DValue
LLValue* rval;
bool lval;
DVarValue(VarDeclaration* vd, LLValue* llvmValue, bool lvalue);
DVarValue(Type* vd, LLValue* lv, LLValue* rv);
DVarValue(Type* t, VarDeclaration* vd, LLValue* llvmValue, bool lvalue);
DVarValue(Type* t, LLValue* lv, LLValue* rv);
DVarValue(Type* t, LLValue* llvmValue, bool lvalue);
virtual bool isLVal() { return val && lval; }
@ -133,7 +133,7 @@ struct DFieldValue : DVarValue
// this d-value
struct DThisValue : DVarValue
{
DThisValue(VarDeclaration* vd, LLValue* llvmValue) : DVarValue(vd, llvmValue, true) {}
DThisValue(Type* t, VarDeclaration* vd, LLValue* llvmValue) : DVarValue(t, vd, llvmValue, true) {}
virtual DThisValue* isThis() { return this; }
};

View file

@ -22,8 +22,8 @@
const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, bool ismain)
{
assert(type->ty == Tfunction);
TypeFunction* f = (TypeFunction*)type;
assert(f != 0);
if (type->ir.type != NULL) {
return llvm::cast<llvm::FunctionType>(type->ir.type->get());

View file

@ -1264,7 +1264,7 @@ DValue* DtoDeclarationExp(Dsymbol* declaration)
DValue* ie = DtoInitializer(vd->init);
}
return new DVarValue(vd, vd->ir.getIrValue(), true);
return new DVarValue(vd->type, vd, vd->ir.getIrValue(), true);
}
// struct declaration
else if (StructDeclaration* s = declaration->isStructDeclaration())

View file

@ -106,7 +106,7 @@ LLValue* DtoBoolean(Loc& loc, DValue* dval);
unsigned DtoCallingConv(LINK l);
///
TypeFunction* DtoTypeFunction(Type* type);
TypeFunction* DtoTypeFunction(DValue* fnval);
///
DValue* DtoVaArg(Loc& loc, Type* type, Expression* valistArg);

View file

@ -124,10 +124,14 @@ void DtoResolveStruct(StructDeclaration* sd)
TypeStruct* ts = (TypeStruct*)DtoDType(sd->type);
bool ispacked = (ts->alignsize() == 1);
IrStruct* irstruct = new IrStruct(ts);
sd->ir.irStruct = irstruct;
gIR->structs.push_back(irstruct);
irstruct->packed = ispacked;
// fields
Array* arr = &sd->fields;
for (int k=0; k < arr->dim; k++) {
@ -170,7 +174,7 @@ void DtoResolveStruct(StructDeclaration* sd)
{
Logger::println("has no fields");
fieldtypes.push_back(LLType::Int8Ty);
structtype = llvm::StructType::get(fieldtypes);
structtype = llvm::StructType::get(fieldtypes, ispacked);
}
else
{
@ -239,7 +243,7 @@ void DtoResolveStruct(StructDeclaration* sd)
}
Logger::println("creating struct type");
structtype = llvm::StructType::get(fieldtypes);
structtype = llvm::StructType::get(fieldtypes, ispacked);
}
// refine abstract types for stuff like: struct S{S* next;}
@ -329,7 +333,7 @@ void DtoConstInitStruct(StructDeclaration* sd)
}
// generate the union mapper
sd->ir.irStruct->dunion = new DUnion; // uses gIR->topstruct()
sd->ir.irStruct->dunion = new DUnion(); // uses gIR->topstruct()
// always generate the constant initalizer
if (!sd->zeroInit) {
@ -445,6 +449,8 @@ DUnion::DUnion()
}
}
ispacked = topstruct->packed;
/*{
LOG_SCOPE;
Logger::println("******** DUnion BEGIN");
@ -533,7 +539,7 @@ LLConstant* DUnion::getConst(std::vector<DUnionIdx>& in)
for (size_t i=0; i<nout; ++i)
tys.push_back(out[i]->getType());
const llvm::StructType* st = llvm::StructType::get(tys);
const llvm::StructType* st = llvm::StructType::get(tys, ispacked);
return llvm::ConstantStruct::get(st, out);
}

View file

@ -66,6 +66,7 @@ struct DUnionIdx
class DUnion
{
std::vector<DUnionField> fields;
bool ispacked;
public:
DUnion();
LLConstant* getConst(std::vector<DUnionIdx>& in);

View file

@ -13,20 +13,21 @@
//////////////////////////////////////////////////////////////////////////////////////////
TypeFunction* DtoTypeFunction(Type* type)
TypeFunction* DtoTypeFunction(DValue* fnval)
{
TypeFunction* tf = 0;
type = type->toBasetype();
Type* type = fnval->getType()->toBasetype();
if (type->ty == Tfunction)
{
tf = (TypeFunction*)type;
return (TypeFunction*)type;
}
else if (type->ty == Tdelegate)
{
assert(type->next->ty == Tfunction);
tf = (TypeFunction*)type->next;
return (TypeFunction*)type->next;
}
return tf;
assert(0 && "cant get TypeFunction* from non lazy/function/delegate");
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////
@ -192,8 +193,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
bool va_intrinsic = (dfnval && dfnval->func && (dfnval->func->llvmInternal == LLVMva_intrinsic));
// get function type info
TypeFunction* tf = DtoTypeFunction(calleeType);
assert(tf);
TypeFunction* tf = DtoTypeFunction(fnval);
// misc
bool retinptr = tf->llvmRetInPtr;

View file

@ -65,7 +65,7 @@ DValue* VarExp::toElem(IRState* p)
Logger::println("Id::_arguments");
LLValue* v = p->func()->_arguments;
assert(v);
return new DVarValue(vd, v, true);
return new DVarValue(type, vd, v, true);
}
// _argptr
else if (vd->ident == Id::_argptr)
@ -73,7 +73,7 @@ DValue* VarExp::toElem(IRState* p)
Logger::println("Id::_argptr");
LLValue* v = p->func()->_argptr;
assert(v);
return new DVarValue(vd, v, true);
return new DVarValue(type, vd, v, true);
}
// _dollar
else if (vd->ident == Id::dollar)
@ -81,7 +81,7 @@ DValue* VarExp::toElem(IRState* p)
Logger::println("Id::dollar");
assert(!p->arrays.empty());
LLValue* tmp = DtoArrayLen(p->arrays.back());
return new DVarValue(vd, tmp, false);
return new DVarValue(type, vd, tmp, false);
}
// typeinfo
else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration())
@ -95,7 +95,7 @@ DValue* VarExp::toElem(IRState* p)
m = p->ir->CreateBitCast(tid->ir.getIrValue(), vartype, "tmp");
else
m = tid->ir.getIrValue();
return new DVarValue(vd, m, true);
return new DVarValue(type, vd, m, true);
}
// classinfo
else if (ClassInfoDeclaration* cid = vd->isClassInfoDeclaration())
@ -103,12 +103,12 @@ DValue* VarExp::toElem(IRState* p)
Logger::println("ClassInfoDeclaration: %s", cid->cd->toChars());
DtoForceDeclareDsymbol(cid->cd);
assert(cid->cd->ir.irStruct->classInfo);
return new DVarValue(vd, cid->cd->ir.irStruct->classInfo, true);
return new DVarValue(type, vd, cid->cd->ir.irStruct->classInfo, true);
}
// nested variable
else if (vd->nestedref) {
Logger::println("nested variable");
return new DVarValue(vd, DtoNestedVariable(vd), true);
return new DVarValue(type, vd, DtoNestedVariable(vd), true);
}
// function parameter
else if (vd->isParameter()) {
@ -116,10 +116,10 @@ DValue* VarExp::toElem(IRState* p)
FuncDeclaration* fd = vd->toParent2()->isFuncDeclaration();
if (fd && fd != p->func()->decl) {
Logger::println("nested parameter");
return new DVarValue(vd, DtoNestedVariable(vd), true);
return new DVarValue(type, vd, DtoNestedVariable(vd), true);
}
else if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa<llvm::AllocaInst>(vd->ir.getIrValue())) {
return new DVarValue(vd, vd->ir.getIrValue(), true);
return new DVarValue(type, vd, vd->ir.getIrValue(), true);
}
else if (llvm::isa<llvm::Argument>(vd->ir.getIrValue())) {
return new DImValue(type, vd->ir.getIrValue());
@ -137,7 +137,7 @@ DValue* VarExp::toElem(IRState* p)
Logger::cout() << "unresolved global had type: " << *DtoType(vd->type) << '\n';
fatal();
}
return new DVarValue(vd, vd->ir.getIrValue(), true);
return new DVarValue(type, vd, vd->ir.getIrValue(), true);
}
}
else if (FuncDeclaration* fdecl = var->isFuncDeclaration())
@ -897,7 +897,7 @@ DValue* DotVarExp::toElem(IRState* p)
assert(0);
//Logger::cout() << "mem: " << *arrptr << '\n';
return new DVarValue(vd, arrptr, true);
return new DVarValue(type, vd, arrptr, true);
}
else if (FuncDeclaration* fdecl = var->isFuncDeclaration())
{
@ -977,7 +977,7 @@ DValue* ThisExp::toElem(IRState* p)
const LLType* t = DtoType(type);
if (v->getType() != t)
v = DtoBitCast(v, t);
return new DThisValue(vd, v);
return new DThisValue(type, vd, v);
}
// anything we're not yet handling ?
@ -2122,7 +2122,7 @@ DValue* StructLiteralExp::toElem(IRState* p)
if (!vx) continue;
tys.push_back(DtoType(vx->type));
}
const LLStructType* t = LLStructType::get(tys);
const LLStructType* t = LLStructType::get(tys, sd->ir.irStruct->packed);
if (t != llt) {
if (getABITypeSize(t) != getABITypeSize(llt)) {
Logger::cout() << "got size " << getABITypeSize(t) << ", expected " << getABITypeSize(llt) << '\n';

View file

@ -48,6 +48,8 @@ IrStruct::IrStruct(Type* t)
classDeclared = false;
classDefined = false;
packed = false;
dwarfComposite = NULL;
}

View file

@ -81,6 +81,8 @@ public:
bool classDeclared;
bool classDefined;
bool packed; // true for: align(1) struct S { ... }
LLGlobalVariable* dwarfComposite;
};