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:
Alexey Prokhin
2011-01-08 13:01:54 +03:00
parent e01aed4327
commit 553d5518b3
3 changed files with 63 additions and 3 deletions

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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);