Classification makeClassification(ConstMap cm, MustParamOracle mpo, HCodeElement hce, Temp t) { if (cm.isConst(hce, t)) // constant value? return new Classification(cm.constMap(hce, t)); if (mpo.isMustParam(t)) // must be a parameter? return new Classification(mpo.whichMustParam(t)); return new Classification(); // no info }
/** Find fields which are *not* subclass-final. */ private Set findBadFields(HCodeFactory hcf, ClassHierarchy ch) { Set badFields = new HashSet(); // for each callable method... for (Iterator it = ch.callableMethods().iterator(); it.hasNext(); ) { HMethod hm = (HMethod) it.next(); HCode hc = hcf.convert(hm); if (hc == null) continue; // xxx: native methods may write fields! // construct a must-param oracle for constructors. MustParamOracle mpo = isConstructor(hm) ? new MustParamOracle(hc) : null; // examine this method for writes HClass thisClass = hc.getMethod().getDeclaringClass(); for (Iterator it2 = hc.getElementsI(); it2.hasNext(); ) { Quad q = (Quad) it2.next(); if (q instanceof SET) { SET qq = (SET) q; // ignore writes of static fields. if (qq.isStatic()) continue; // if this is a constructor, than it may write only // to fields of 'this' if (isConstructor(hm) && mpo.isMustParam(qq.objectref()) && mpo.whichMustParam(qq.objectref()) == 0) continue; // this is a permitted write. // writes by subclass methods to superclass fields are // okay. (but not writes by 'this' methods to 'this' // fields, unless the method is a constructor) if (qq.field().getDeclaringClass().isInstanceOf(thisClass) && // XXX i think the presence of the 'isConstructor' // clause here is a bug. constructor writes // should be taken care of by clause above. (isConstructor(hm) || !thisClass.equals(qq.field().getDeclaringClass()))) continue; // subclass writes are permitted. // non-permitted write! badFields.add(qq.field()); } } // on to the next! } // done! we have set of all bad (not subclass-final) fields. return Collections.unmodifiableSet(badFields); }