// // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // Copy.hpp -- Provides functions to copy the AST. // // Author : Andrew Beach // Created On : Wed Jul 10 16:13:00 2019 // Last Modified By : Andrew Beach // Last Modified On : Thr Jul 11 10:38:00 2019 // Update Count : 0 // #include "Decl.hpp" #include "Expr.hpp" #include "Pass.hpp" #include "Stmt.hpp" #include "Type.hpp" namespace ast { template const node_t * shallowCopy( const node_t * node ) { /* Create a shallow copy of the node given. * * The new node has all the same primitive field values and points to the * same children nodes as the parent. */ template node_t * deepCopy( node_t const * localRoot ); /* Create a deep copy of the tree rooted at localRoot. * * This creates a copy of every node in the sub-tree (reachable by strong * reference from local_root) and updates any readonly pointers on those nodes * that point to another node in the sub-tree to the new version of that node. */ class DeepCopyCore { std::unordered_map< const Node *, const Node * > nodeCache; std::unordered_set< readonly * > readonlyCache; public: template const node_t * previsit( const node_t * node ) { const node_t * copy = shallowCopy( node ); nodeCache.insert( std::make_pair( node, copy ) ); return copy; } void postvisit( const AggregateDecl * node ) { readonlyCache.insert( (readonly *) & node->parent ); } void postvisit( const StructInstType * node ) { readonlyCache.insert( (readonly *) & node->base ); } void postvisit( const UnionInstType * node ) { readonlyCache.insert( (readonly *) & node->base ); } void postvisit( const EnumInstType * node ) { readonlyCache.insert( (readonly *) & node->base ); } void postvisit( const TraitInstType * node ) { readonlyCache.insert( (readonly *) & node->base ); } void postvisit( const TypeInstType * node ) { readonlyCache.insert( (readonly *) & node->base ); } void postvisit( const ImplicitCtorDtorStmt * node ) { readonlyCache.insert( (readonly *) & node->callStmt ); } void postvisit( const MemberExpr * node ) { readonlyCache.insert( (readonly *) & node->member ); } void postvisit( const VariableExpr * node ) { readonlyCache.insert( (readonly *) & node->var ); } void postvisit( const OffsetofExpr * node ) { readonlyCache.insert( (readonly *) & node->member ); } void postvisit( const DeletedExpr * node ) { readonlyCache.insert( (readonly *) & node->deleteStmt ); } void readonlyUpdates() { for ( readonly * ptr : readonlyCache ) { auto it = nodeCache.find( ptr->get() ); if ( nodeCache.end() != it ) { *ptr = it->second; } } } }; template node_t * shallowCopy( node_t const * localRoot ) { return localRoot->clone(); } template node_t * deepCopy( node_t const * localRoot ) { Pass< DeepCopyCore > dc; node_t const * newRoot = localRoot->accept( dc ); dc.pass.readonlyUpdates(); return const_cast< node_t * >( newRoot ); } } // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //