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