Mercurial > projects > ldc
changeset 819:446263a8a30d
Fixed taking address of global static array element as constant expression.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Tue, 02 Dec 2008 01:07:22 +0100 |
parents | e8f8cafcaa62 |
children | bb4a81e68ddb |
files | gen/toir.cpp tests/mini/const2.d |
diffstat | 2 files changed, 65 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/gen/toir.cpp Mon Dec 01 20:26:32 2008 +0100 +++ b/gen/toir.cpp Tue Dec 02 01:07:22 2008 +0100 @@ -896,32 +896,71 @@ LLConstant* AddrExp::toConstElem(IRState* p) { - assert(e1->op == TOKvar); - VarExp* vexp = (VarExp*)e1; - - if (vexp->var->needThis()) + // FIXME: this should probably be generalized more so we don't + // need to have a case for each thing we can take the address of + + // address of global variable + if (e1->op == TOKvar) { - error("need 'this' to access %s", vexp->var->toChars()); - fatal(); + VarExp* vexp = (VarExp*)e1; + + // make sure 'this' isn't needed + if (vexp->var->needThis()) + { + error("need 'this' to access %s", vexp->var->toChars()); + fatal(); + } + + // global variable + if (VarDeclaration* vd = vexp->var->isVarDeclaration()) + { + LLConstant* llc = llvm::dyn_cast<LLConstant>(vd->ir.getIrValue()); + assert(llc); + return llc; + } + // static function + else if (FuncDeclaration* fd = vexp->var->isFuncDeclaration()) + { + IrFunction* irfunc = fd->ir.irFunc; + assert(irfunc); + return irfunc->func; + } + // something else + else + { + // fail + goto Lerr; + } } - - // global variable - if (VarDeclaration* vd = vexp->var->isVarDeclaration()) + // address of indexExp + else if (e1->op == TOKindex) { - LLConstant* llc = llvm::dyn_cast<LLConstant>(vd->ir.getIrValue()); - assert(llc); - return llc; - } - // static function - else if (FuncDeclaration* fd = vexp->var->isFuncDeclaration()) - { - IrFunction* irfunc = fd->ir.irFunc; - assert(irfunc); - return irfunc->func; + IndexExp* iexp = (IndexExp*)e1; + + // indexee must be global static array var + assert(iexp->e1->op == TOKvar); + VarExp* vexp = (VarExp*)iexp->e1; + VarDeclaration* vd = vexp->var->isVarDeclaration(); + assert(vd); + assert(vd->type->toBasetype()->ty == Tsarray); + assert(vd->ir.irGlobal); + + // get index + LLConstant* index = iexp->e2->toConstElem(p); + assert(index->getType() == DtoSize_t()); + + // gep + LLConstant* idxs[2] = { DtoConstSize_t(0), index }; + LLConstant* gep = llvm::ConstantExpr::getGetElementPtr(isaConstant(vd->ir.irGlobal->value), idxs, 2); + + // bitcast to requested type + assert(type->toBasetype()->ty == Tpointer); + return DtoBitCast(gep, DtoType(type)); } // not yet supported else { + Lerr: error("constant expression '%s' not yet implemented", toChars()); fatal(); }