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; var = vd;
val = llvmValue; val = llvmValue;
rval = 0; rval = 0;
lval = lvalue; lval = lvalue;
type = var->type; type = t;
} }
DVarValue::DVarValue(Type* t, LLValue* lv, LLValue* rv) DVarValue::DVarValue(Type* t, LLValue* lv, LLValue* rv)

View file

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

View file

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

View file

@ -1264,7 +1264,7 @@ DValue* DtoDeclarationExp(Dsymbol* declaration)
DValue* ie = DtoInitializer(vd->init); 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 // struct declaration
else if (StructDeclaration* s = declaration->isStructDeclaration()) else if (StructDeclaration* s = declaration->isStructDeclaration())

View file

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

View file

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

View file

@ -66,6 +66,7 @@ struct DUnionIdx
class DUnion class DUnion
{ {
std::vector<DUnionField> fields; std::vector<DUnionField> fields;
bool ispacked;
public: public:
DUnion(); DUnion();
LLConstant* getConst(std::vector<DUnionIdx>& in); 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 = fnval->getType()->toBasetype();
type = type->toBasetype();
if (type->ty == Tfunction) if (type->ty == Tfunction)
{ {
tf = (TypeFunction*)type; return (TypeFunction*)type;
} }
else if (type->ty == Tdelegate) else if (type->ty == Tdelegate)
{ {
assert(type->next->ty == Tfunction); 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)); bool va_intrinsic = (dfnval && dfnval->func && (dfnval->func->llvmInternal == LLVMva_intrinsic));
// get function type info // get function type info
TypeFunction* tf = DtoTypeFunction(calleeType); TypeFunction* tf = DtoTypeFunction(fnval);
assert(tf);
// misc // misc
bool retinptr = tf->llvmRetInPtr; bool retinptr = tf->llvmRetInPtr;

View file

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

View file

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

View file

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