#include "AST.h" #include "code-util.h" #include "clone.h" #define DEBUG_SHARED DEBUG_PHASE_ENABLED("shared", currentFilename) /* Recursively go through a tree, fixing all the _parent pointers. Returns how many it fixed. */ int TreeNode::fixParent() { const int n = arity(); int count = 0; for (int i = 0; i < n; i++) { TreeNode *c = child(i); if (c != NULL && !c->absent()) { if (c->_parent != this) { c->_parent = this; count++; } count += c->fixParent(); } } return count; } /* Assumes that if the _parent pointer is incorrect that the node is shared. It is recommended that one use fixSubtreeSharing(), below, rather than calling this method directly. */ TreeNode * TreeNode::cloneSharedSubtrees() { const int n = arity(); for (int i = 0; i < n; i++) { TreeNode *c = child(i); if (c != NULL && !c->absent()) { if (c->_parent != this) { if (DEBUG_SHARED) { cout << "Shared:" << endl; c->print(cout, 0); cout << endl; } child(i, c = deepCloneWithCrossTreeFixup(c)); } child(i, c->cloneSharedSubtrees()); } } return this; } TreeNode *fixSubtreeSharing(TreeNode *t) { int n; t->fixParent(); t = t->cloneSharedSubtrees(); n = t->fixParent(); if (DEBUG_SHARED && n != 0) cout << "fixParent(): " << n << endl; return t; }