mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-11 13:26:08 +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;
|
||||
val = llvmValue;
|
||||
rval = 0;
|
||||
lval = lvalue;
|
||||
type = var->type;
|
||||
type = t;
|
||||
}
|
||||
|
||||
DVarValue::DVarValue(Type* t, LLValue* lv, LLValue* rv)
|
||||
|
|
|
@ -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; }
|
||||
};
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ struct DUnionIdx
|
|||
class DUnion
|
||||
{
|
||||
std::vector<DUnionField> fields;
|
||||
bool ispacked;
|
||||
public:
|
||||
DUnion();
|
||||
LLConstant* getConst(std::vector<DUnionIdx>& in);
|
||||
|
|
|
@ -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;
|
||||
|
|
24
gen/toir.cpp
24
gen/toir.cpp
|
@ -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';
|
||||
|
|
|
@ -48,6 +48,8 @@ IrStruct::IrStruct(Type* t)
|
|||
classDeclared = false;
|
||||
classDefined = false;
|
||||
|
||||
packed = false;
|
||||
|
||||
dwarfComposite = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -81,6 +81,8 @@ public:
|
|||
bool classDeclared;
|
||||
bool classDefined;
|
||||
|
||||
bool packed; // true for: align(1) struct S { ... }
|
||||
|
||||
LLGlobalVariable* dwarfComposite;
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue