+
+ private void generate_accesspath(CodeWriter cr, VarDescriptor right, VarDescriptor newright, Updates u) {
+ Vector dotvector=new Vector();
+ Expr ptr=u.getRightExpr();
+ VarExpr rightve=new VarExpr(right);
+ right.td=ReservedTypeDescriptor.INT;
+
+ while(true) {
+ /* Does something other than a dereference? */
+ dotvector.add(ptr);
+ if (ptr instanceof DotExpr)
+ ptr=((DotExpr)ptr).left;
+ else if (ptr instanceof CastExpr)
+ ptr=((CastExpr)ptr).getExpr();
+ if (ptr instanceof VarExpr) {
+ /* Finished constructing vector */
+ break;
+ }
+ }
+ ArrayAnalysis.AccessPath ap=u.getAccessPath();
+ VarDescriptor init=VarDescriptor.makeNew("init");
+ if (ap.isSet()) {
+ cr.addDeclaration("int", init.getSafeSymbol());
+ cr.outputline(init.getSafeSymbol()+"= SimpleHashfirstkey("+ap.getSet().getSafeSymbol()+"_hash);");
+ init.td=ap.getSet().getType();
+ } else {
+ init=ap.getVar();
+ }
+ Expr newexpr=new VarExpr(init);
+ int apindex=0;
+ for(int i=dotvector.size()-1;i>=0;i--) {
+ Expr e=(Expr)dotvector.get(i);
+ if (e instanceof CastExpr) {
+ newexpr.td=e.td;
+ newexpr=new CastExpr(((CastExpr)e).getType(),newexpr);
+ } else if (e instanceof DotExpr) {
+ DotExpr de=(DotExpr)e;
+ if (de.getField() instanceof ArrayDescriptor) {
+ DotExpr de2=new DotExpr(newexpr,de.field,new IntegerLiteralExpr(0));
+ de2.fd=de.fd;
+ de2.fieldtype=de.fieldtype;
+ de2.td=de.td;
+ OpExpr offset=new OpExpr(Opcode.SUB,rightve,de2);
+ OpExpr index=new OpExpr(Opcode.DIV,offset,de.fieldtype.getSizeExpr());
+ if (u.getRightPos()==apindex) {
+ index.generate(cr,newright);
+ return;
+ } else {
+ DotExpr de3=new DotExpr(newexpr,de.field,index);
+ de3.fd=de.fd;
+ de3.td=de.td;
+ de3.fieldtype=de.fieldtype;
+ newexpr=de3;
+ }
+ } else {
+ DotExpr de2=new DotExpr(newexpr,de.field,null);
+ de2.fd=de.fd;
+ de2.fieldtype=de.fieldtype;
+ de2.td=de.td;
+ newexpr=de2;
+ }
+ apindex++;
+ } else throw new Error();
+ }
+ throw new Error();
+ }
+