#ifndef _ALIASINFOS_H_ #define _ALIASINFOS_H_ #include #include "utils.h" #include "AST.h" #include "bitset.h" #include "code-util.h" #include "decls.h" // the external value may coincide with NULL or any leaked value static const int AA_EXTERNALVALUE = 1; static const int AA_NULLVALUE = 2; // value for 'null' static const int AA_THISVALUE = 3; // value for 'this' static const int AA_UNUSEDVALUE = 4; static const int AA_FIRSTVALUE = 5; static const string nullString = "null"; static const string extString = ""; static const string thisString = "this"; static const string unusedString = ""; class ValueInfo; typedef map > DeclToBitsetMap; typedef map > ValueToValueInfoMap; typedef map > TreeNodeToIntMap; #define isInMap(x, m) (m.find(x) != m.end()) bool isNamedValue(int value); string valueToString(int value); void printBitset(Bitset *b, ostream &os); void purePrintBitset(Bitset *b, ostream &os); bool equalDeclToBitsetMaps(DeclToBitsetMap *d1, DeclToBitsetMap *d2); bool isConstructorCallNode(TreeNode *t); bool isAliasable(TypeNode *t); Bitset *copyBitset(Bitset *b); Bitset *newUnion(Bitset *a, Bitset *b); bool nonTrivialUnion(Bitset *a, Bitset *b); //////////////////// AliasInfo ///////////////////// /* An AliasInfos represents complete information about any aliasing information we know about any variables at a particular point in the program. */ class AliasInfos { public: /* Run this statement or expression through this info to update values. The idea is you run this through every node in the CFG. Everything but MethodCallNode's and AssignNode's are ignored. */ void process(TreeNode *t); /* Print with endline to os. */ void println(ostream &os); /* Print out the aliases to os. */ void printAliases(ostream &os); /* An empty instance, using bitvectors of size _size, for the given (MethodDeclNode*) method. */ AliasInfos(int _size, TreeNode *method); /* True iff this is equivalent to ai. */ bool equivalent(AliasInfos *ai); /* Merge with the given. Returns true if this thing changed as a result. */ bool merge(AliasInfos *ai); /* Run this assignment through this info. Returns true if something changed. */ bool processAssignment(TreeNode *leftSide, TreeNode *rightSide); /* The Bitset associated with decl, or the AA_NULLVALUE's bitset if decl is not in. This Bitset should be read-only! */ Bitset *lookupDecl(Decl *decl) { if (isInMap(decl, declToBitsetMap)) return declToBitsetMap[decl]; else return myNullValueBitset(); } /* Make certain the spot has a ValueInfo. Returns whether it was necessary to add it. */ bool setupValueInfo(int index, TypeNode *t); /* Erase everything I know about any value's fields, and say that any of my fields can now point to any of the given values. */ void ruinFieldInfos(Bitset *incomingValues); public: /* A mapping of local variable declarations to Bitsets. */ DeclToBitsetMap declToBitsetMap; /* A mapping of values (ints) to ValueInfos. */ ValueToValueInfoMap valueToValueInfoMap; /* The total number of values in the method. */ int size; /* The values that are possibly visible outside the method (i.e., the external value may coincide with it (and hence they may coincide with each other)). The thing to remember is that you really only need to worry about dirty values when checking for alias-pairs and on method calls. */ Bitset *leaksSet; private: Bitset *_myNullValueBitset; Bitset *myNullValueBitset() { if (_myNullValueBitset == NULL) _myNullValueBitset = new Bitset(size); return _myNullValueBitset; } }; ////////////////////////////////// ValueInfo ///////////////////////// /* A ValueInfo represents info about a value that a local variable may have. An array element, such as a[i], may have values which in turn have values which in turn are associated with ValueInfo's. */ class ValueInfo { public: /* The unique (within each method) value of associated with this record. This is the index in the Bitset. */ int index; /* The size of the bitsets. */ int size; /* Type 'type' of this value. This is used to check for assignable-ness. */ TypeNode *valueType; /* If this is an array value, the list of values which any element of this array may have. This initially is a Bitset containing the NULLVALUE because initially array values can only be NULL. */ Bitset *arrayValues; /* If this is an Object value, a map giving for each field names the Bitset giving the list of possible values for each field name (a decl). This OVERRIDES the above, so that if a decl is listed here, the anyFieldValues Bitmap DOES NOT APPLY to it. */ DeclToBitsetMap fieldToBitsetMap; /* If not in the above, this is what it has.. */ int unknownFieldValue; public: /* A new ValueInfo representing the value (of type t) i out of numValues possible values. */ ValueInfo(int i, int numValues, TypeNode *t); /* A new, deep copy of this. */ ValueInfo *newCopy(); /* True iff this is equivalent to vi. */ bool equivalent(ValueInfo *vi); /* Merge with the given. Returns whether something changed. */ bool merge(ValueInfo *vi); /* Print my subvalues, prefixed by prefix. */ void println(int prefix, ostream &os); }; #endif // _ALIASINFOS_H_