#ifndef _TOUCHSET_H_ #define _TOUCHSET_H_ /* TouchSets keep track of memory locations that might be touched at runtime. The five subcases: 1. A local variable or parameter 2. A field of an immutable local variable or parameter 3. A field of an object (other than case 2) 4. An element of an array of type T 5. An element of a java array of type T Also, one could have unknown method calls: those affect cases 3 through 5. */ #include "code-defs.h" #include "StringSet.h" #include extern const string long2hexstring(long val); class Decl; class TouchSet; TouchSet *TouchSet_union(const TouchSet *x, const TouchSet *y); bool TouchSet_does_intersect(const TouchSet *x, const TouchSet *y, bool check_arrays); class TouchSet : public gc { public: TouchSet() : unknownMethods(false) {} TouchSet(bool u) : unknownMethods(u) {} TouchSet(Decl *d) : unknownMethods(false) { local.insert(d); } TouchSet(Decl *d, string f) : unknownMethods(false) { field_of_immutable_local.insert(pair(d, f)); } TouchSet(xtype x, string f) : unknownMethods(false) { field.insert(pair(x, f)); } TouchSet(llist *l) : unknownMethods(false) { while (l != NULL) { array.insert(type2xtype(l->front())); l = l->tail(); } } friend TouchSet *TouchSet_union(const TouchSet *x, const TouchSet *y); TouchSet *TouchSet_union(const TouchSet *s) const { return ::TouchSet_union(this, s); } friend bool TouchSet_does_intersect(const TouchSet *x, const TouchSet *y, bool check_arrays); bool does_intersect(const TouchSet *s, bool check_arrays) const { return ::TouchSet_does_intersect(this, s, check_arrays); } string to_string() const { string s("Locals/params: "); for (set::const_iterator i = local.begin(); i != local.end(); i++) s += ' ' + *(*i)->name(); s += "\nFields of immutable locals/params:"; for (set< pair >::const_iterator i = field_of_immutable_local.begin(); i != field_of_immutable_local.end(); i++) s += " <" + *(*i).first->name() + ", " + (*i).second + ">"; s += "\nFields:"; for (set< pair >::const_iterator i = field.begin(); i != field.end(); i++) s += " <" + xtype2str((*i).first) + ", " + (*i).second + ">"; s += "\nElements of arrays with type:"; for (set::const_iterator i = array.begin(); i != array.end(); i++) s += ' ' + xtype2str(*i); s += "\nUnknown Methods: " + string(unknownMethods ? "1" : "0"); return s + "\n"; } private: /* internal representation */ /* The five cases (except the arrays and java arrays are handled together) */ set local; set< pair > field_of_immutable_local; set< pair > field; set array; bool unknownMethods; }; static inline TouchSet * makeTouchSetThis() { return new TouchSet(Defs::fakeThisDecl); } TouchSet *writes(const TreeNode *t, bool ignore_junk_method = false); TouchSet *reads(const TreeNode *t, bool ignore_junk_method = false); #endif // !_TOUCHSET_H_