Mercurial > projects > ldc
comparison gen/toir.cpp @ 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 | 69a5e4a6fc0f |
children | bb4a81e68ddb |
comparison
equal
deleted
inserted
replaced
818:e8f8cafcaa62 | 819:446263a8a30d |
---|---|
894 return new DImValue(type, DtoBitCast(v->getLVal(), DtoType(type))); | 894 return new DImValue(type, DtoBitCast(v->getLVal(), DtoType(type))); |
895 } | 895 } |
896 | 896 |
897 LLConstant* AddrExp::toConstElem(IRState* p) | 897 LLConstant* AddrExp::toConstElem(IRState* p) |
898 { | 898 { |
899 assert(e1->op == TOKvar); | 899 // FIXME: this should probably be generalized more so we don't |
900 VarExp* vexp = (VarExp*)e1; | 900 // need to have a case for each thing we can take the address of |
901 | 901 |
902 if (vexp->var->needThis()) | 902 // address of global variable |
903 { | 903 if (e1->op == TOKvar) |
904 error("need 'this' to access %s", vexp->var->toChars()); | 904 { |
905 fatal(); | 905 VarExp* vexp = (VarExp*)e1; |
906 } | 906 |
907 | 907 // make sure 'this' isn't needed |
908 // global variable | 908 if (vexp->var->needThis()) |
909 if (VarDeclaration* vd = vexp->var->isVarDeclaration()) | 909 { |
910 { | 910 error("need 'this' to access %s", vexp->var->toChars()); |
911 LLConstant* llc = llvm::dyn_cast<LLConstant>(vd->ir.getIrValue()); | 911 fatal(); |
912 assert(llc); | 912 } |
913 return llc; | 913 |
914 } | 914 // global variable |
915 // static function | 915 if (VarDeclaration* vd = vexp->var->isVarDeclaration()) |
916 else if (FuncDeclaration* fd = vexp->var->isFuncDeclaration()) | 916 { |
917 { | 917 LLConstant* llc = llvm::dyn_cast<LLConstant>(vd->ir.getIrValue()); |
918 IrFunction* irfunc = fd->ir.irFunc; | 918 assert(llc); |
919 assert(irfunc); | 919 return llc; |
920 return irfunc->func; | 920 } |
921 // static function | |
922 else if (FuncDeclaration* fd = vexp->var->isFuncDeclaration()) | |
923 { | |
924 IrFunction* irfunc = fd->ir.irFunc; | |
925 assert(irfunc); | |
926 return irfunc->func; | |
927 } | |
928 // something else | |
929 else | |
930 { | |
931 // fail | |
932 goto Lerr; | |
933 } | |
934 } | |
935 // address of indexExp | |
936 else if (e1->op == TOKindex) | |
937 { | |
938 IndexExp* iexp = (IndexExp*)e1; | |
939 | |
940 // indexee must be global static array var | |
941 assert(iexp->e1->op == TOKvar); | |
942 VarExp* vexp = (VarExp*)iexp->e1; | |
943 VarDeclaration* vd = vexp->var->isVarDeclaration(); | |
944 assert(vd); | |
945 assert(vd->type->toBasetype()->ty == Tsarray); | |
946 assert(vd->ir.irGlobal); | |
947 | |
948 // get index | |
949 LLConstant* index = iexp->e2->toConstElem(p); | |
950 assert(index->getType() == DtoSize_t()); | |
951 | |
952 // gep | |
953 LLConstant* idxs[2] = { DtoConstSize_t(0), index }; | |
954 LLConstant* gep = llvm::ConstantExpr::getGetElementPtr(isaConstant(vd->ir.irGlobal->value), idxs, 2); | |
955 | |
956 // bitcast to requested type | |
957 assert(type->toBasetype()->ty == Tpointer); | |
958 return DtoBitCast(gep, DtoType(type)); | |
921 } | 959 } |
922 // not yet supported | 960 // not yet supported |
923 else | 961 else |
924 { | 962 { |
963 Lerr: | |
925 error("constant expression '%s' not yet implemented", toChars()); | 964 error("constant expression '%s' not yet implemented", toChars()); |
926 fatal(); | 965 fatal(); |
927 } | 966 } |
928 } | 967 } |
929 | 968 |