mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-03 08:30:47 +03:00
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:
parent
3b21ae25be
commit
905ca019dd
11 changed files with 43 additions and 32 deletions
|
@ -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)
|
||||||
|
|
|
@ -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; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
24
gen/toir.cpp
24
gen/toir.cpp
|
@ -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';
|
||||||
|
|
|
@ -48,6 +48,8 @@ IrStruct::IrStruct(Type* t)
|
||||||
classDeclared = false;
|
classDeclared = false;
|
||||||
classDefined = false;
|
classDefined = false;
|
||||||
|
|
||||||
|
packed = false;
|
||||||
|
|
||||||
dwarfComposite = NULL;
|
dwarfComposite = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue