From 553d5518b374730145f38689ee222762436eca8c Mon Sep 17 00:00:00 2001 From: Alexey Prokhin Date: Sat, 8 Jan 2011 13:01:54 +0300 Subject: [PATCH] Implemented casting of a global variable to a pointer in an initializer. Implemented adding to a pointer in an initializer --- dmd/expression.h | 4 ++++ dmd2/expression.h | 2 ++ gen/toir.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/dmd/expression.h b/dmd/expression.h index 6af35e5d..4469b011 100644 --- a/dmd/expression.h +++ b/dmd/expression.h @@ -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 }; diff --git a/dmd2/expression.h b/dmd2/expression.h index 357bfc67..00929142 100644 --- a/dmd2/expression.h +++ b/dmd2/expression.h @@ -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 }; diff --git a/gen/toir.cpp b/gen/toir.cpp index a58039a8..627ceaa0 100644 --- a/gen/toir.cpp +++ b/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);