mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-02-27 17:13:20 +01:00
Implemented casting of a global variable to a pointer in an initializer. Implemented adding to a pointer in an initializer
This commit is contained in:
@@ -1065,6 +1065,7 @@ struct CallExp : UnaExp
|
||||
Expression *inlineScan(InlineScanState *iss);
|
||||
|
||||
#if IN_LLVM
|
||||
void cacheLvalue(IRState* p);
|
||||
DValue* toElem(IRState* irs);
|
||||
#endif
|
||||
};
|
||||
@@ -1333,6 +1334,7 @@ struct CommaExp : BinExp
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
void cacheLvalue(IRState* p);
|
||||
DValue* toElem(IRState* irs);
|
||||
#endif
|
||||
};
|
||||
@@ -1468,6 +1470,7 @@ struct AddExp : BinExp
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
llvm::Constant* toConstElem(IRState* p);
|
||||
DValue* toElem(IRState* irs);
|
||||
#endif
|
||||
};
|
||||
@@ -1490,6 +1493,7 @@ struct MinExp : BinExp
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
llvm::Constant* toConstElem(IRState* p);
|
||||
DValue* toElem(IRState* irs);
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1567,6 +1567,7 @@ struct AddExp : BinExp
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
llvm::Constant *toConstElem(IRState* p);
|
||||
DValue* toElem(IRState* irs);
|
||||
#endif
|
||||
};
|
||||
@@ -1589,6 +1590,7 @@ struct MinExp : BinExp
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
llvm::Constant *toConstElem(IRState* p);
|
||||
DValue* toElem(IRState* irs);
|
||||
#endif
|
||||
};
|
||||
|
||||
60
gen/toir.cpp
60
gen/toir.cpp
@@ -644,6 +644,23 @@ static void errorOnIllegalArrayOp(Expression* base, Expression* e1, Expression*
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LLConstant* AddExp::toConstElem(IRState* p)
|
||||
{
|
||||
// add to pointer
|
||||
if (e1->type->ty == Tpointer && e2->type->isintegral()) {
|
||||
LLConstant *ptr = e1->toConstElem(p);
|
||||
LLConstant *index = e2->toConstElem(p);
|
||||
ptr = llvm::ConstantExpr::getGetElementPtr(ptr, &index, 1);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
error("expression '%s' is not a constant", toChars());
|
||||
fatal();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* AddExp::toElem(IRState* p)
|
||||
{
|
||||
Logger::print("AddExp::toElem: %s @ %s\n", toChars(), type->toChars());
|
||||
@@ -680,6 +697,23 @@ DValue* AddExp::toElem(IRState* p)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LLConstant* MinExp::toConstElem(IRState* p)
|
||||
{
|
||||
if (e1->type->ty == Tpointer && e2->type->isintegral()) {
|
||||
LLConstant *ptr = e1->toConstElem(p);
|
||||
LLConstant *index = e2->toConstElem(p);
|
||||
index = llvm::ConstantExpr::getNeg(index);
|
||||
ptr = llvm::ConstantExpr::getGetElementPtr(ptr, &index, 1);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
error("expression '%s' is not a constant", toChars());
|
||||
fatal();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DValue* MinExp::toElem(IRState* p)
|
||||
{
|
||||
Logger::print("MinExp::toElem: %s @ %s\n", toChars(), type->toChars());
|
||||
@@ -917,12 +951,30 @@ LLConstant* CastExp::toConstElem(IRState* p)
|
||||
else if (tb->ty == Tpointer && e1->type->toBasetype()->ty == Tpointer) {
|
||||
res = llvm::ConstantExpr::getBitCast(e1->toConstElem(p), lltype);
|
||||
}
|
||||
// global variable to pointer
|
||||
else if (tb->ty == Tpointer && e1->op == TOKvar) {
|
||||
VarDeclaration *vd = ((VarExp*)e1)->var->isVarDeclaration();
|
||||
assert(vd);
|
||||
vd->codegen(Type::sir);
|
||||
LLConstant *value = vd->ir.irGlobal ? isaConstant(vd->ir.irGlobal->value) : 0;
|
||||
if (!value)
|
||||
goto Lerr;
|
||||
Type *type = vd->type->toBasetype();
|
||||
if (type->ty == Tarray || type->ty == Tdelegate) {
|
||||
LLConstant* idxs[2] = { DtoConstSize_t(0), DtoConstSize_t(1) };
|
||||
value = llvm::ConstantExpr::getGetElementPtr(value, idxs, 2);
|
||||
}
|
||||
return DtoBitCast(value, DtoType(tb));
|
||||
}
|
||||
else {
|
||||
error("can not cast %s to %s at compile time", e1->type->toChars(), type->toChars());
|
||||
return e1->toConstElem(p);
|
||||
goto Lerr;
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
Lerr:
|
||||
error("can not cast %s to %s at compile time", e1->type->toChars(), type->toChars());
|
||||
return e1->toConstElem(p);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1038,7 +1090,9 @@ LLConstant* AddrExp::toConstElem(IRState* p)
|
||||
|
||||
// gep
|
||||
LLConstant* idxs[2] = { DtoConstSize_t(0), index };
|
||||
LLConstant* gep = llvm::ConstantExpr::getGetElementPtr(isaConstant(vd->ir.irGlobal->value), idxs, 2);
|
||||
LLConstant *val = isaConstant(vd->ir.irGlobal->value);
|
||||
val = DtoBitCast(val, DtoType(vd->type->pointerTo()));
|
||||
LLConstant* gep = llvm::ConstantExpr::getGetElementPtr(val, idxs, 2);
|
||||
|
||||
// bitcast to requested type
|
||||
assert(type->toBasetype()->ty == Tpointer);
|
||||
|
||||
Reference in New Issue
Block a user