// // 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. // // DeclMutator.cc -- // // Author : Aaron B. Moss // Created On : Fri Nov 27 14:44:00 2015 // Last Modified By : Andrew Beach // Last Modified On : Thu Jun 22 13:49:00 2017 // Update Count : 4 // #include "DeclMutator.h" #include "SynTree/Expression.h" #include "SynTree/Statement.h" namespace GenPoly { DeclMutator::DeclMutator() : Mutator(), declsToAdd(1), declsToAddAfter(1) {} DeclMutator::~DeclMutator() {} void DeclMutator::mutateDeclarationList( std::list< Declaration* > &decls ) { for ( std::list< Declaration* >::iterator decl = decls.begin(); ; ++decl ) { // splice in new declarations after previous decl decls.splice( decl, declsToAddAfter.back() ); if ( decl == decls.end() ) break; // run mutator on declaration *decl = maybeMutate( *decl, *this ); // splice in new declarations before current decl decls.splice( decl, declsToAdd.back() ); } } void DeclMutator::doBeginScope() { // add new decl lists for inside of scope declsToAdd.resize( declsToAdd.size()+1 ); declsToAddAfter.resize( declsToAddAfter.size()+1 ); } void DeclMutator::doEndScope() { // splice any leftover declarations from this scope onto the containing scope std::vector< std::list< Declaration* > >::reverse_iterator back = declsToAdd.rbegin(); std::vector< std::list< Declaration* > >::reverse_iterator newBack = back + 1; newBack->splice( newBack->end(), *back ); declsToAdd.pop_back(); back = declsToAddAfter.rbegin(); newBack = back + 1; newBack->splice( newBack->end(), *back ); declsToAddAfter.pop_back(); } Statement* DeclMutator::mutateStatement( Statement *stmt ) { // shunt over to compound statement handling if applicable CompoundStmt *compoundStmt = dynamic_cast< CompoundStmt* >(stmt); if ( compoundStmt ) return mutate( compoundStmt ); doBeginScope(); // run mutator on statement stmt = maybeMutate( stmt, *this ); // return if no declarations to add if ( declsToAdd.back().empty() && declsToAddAfter.back().empty() ) { doEndScope(); return stmt; } // otherwise add declarations to new compound statement CompoundStmt *compound = new CompoundStmt( noLabels ); for ( std::list< Declaration* >::iterator decl = declsToAdd.back().begin(); decl != declsToAdd.back().end(); ++decl ) { DeclStmt *declStmt = new DeclStmt( noLabels, *decl ); compound->get_kids().push_back( declStmt ); } declsToAdd.back().clear(); // add mutated statement compound->get_kids().push_back( stmt ); // add declarations after to new compound statement for ( std::list< Declaration* >::iterator decl = declsToAddAfter.back().begin(); decl != declsToAddAfter.back().end(); ++decl ) { DeclStmt *declStmt = new DeclStmt( noLabels, *decl ); compound->get_kids().push_back( declStmt ); } declsToAddAfter.back().clear(); doEndScope(); return compound; } void DeclMutator::mutateStatementList( std::list< Statement* > &stmts ) { doBeginScope(); for ( std::list< Statement* >::iterator stmt = stmts.begin(); ; ++stmt ) { // add any new declarations after the previous statement for ( std::list< Declaration* >::iterator decl = declsToAddAfter.back().begin(); decl != declsToAddAfter.back().end(); ++decl ) { DeclStmt *declStmt = new DeclStmt( noLabels, *decl ); stmts.insert( stmt, declStmt ); } declsToAddAfter.back().clear(); if ( stmt == stmts.end() ) break; // run mutator on statement *stmt = maybeMutate( *stmt, *this ); // add any new declarations before the statement for ( std::list< Declaration* >::iterator decl = declsToAdd.back().begin(); decl != declsToAdd.back().end(); ++decl ) { DeclStmt *declStmt = new DeclStmt( noLabels, *decl ); stmts.insert( stmt, declStmt ); } declsToAdd.back().clear(); } doEndScope(); } void DeclMutator::addDeclaration( Declaration *decl ) { declsToAdd.back().push_back( decl ); } void DeclMutator::addDeclarationAfter( Declaration *decl ) { declsToAddAfter.back().push_back( decl ); } CompoundStmt* DeclMutator::mutate(CompoundStmt *compoundStmt) { mutateStatementList( compoundStmt->get_kids() ); return compoundStmt; } Statement* DeclMutator::mutate(IfStmt *ifStmt) { ifStmt->set_condition( maybeMutate( ifStmt->get_condition(), *this ) ); ifStmt->set_thenPart( mutateStatement( ifStmt->get_thenPart() ) ); ifStmt->set_elsePart( mutateStatement( ifStmt->get_elsePart() ) ); return ifStmt; } Statement* DeclMutator::mutate(WhileStmt *whileStmt) { whileStmt->set_condition( maybeMutate( whileStmt->get_condition(), *this ) ); whileStmt->set_body( mutateStatement( whileStmt->get_body() ) ); return whileStmt; } Statement* DeclMutator::mutate(ForStmt *forStmt) { mutateAll( forStmt->get_initialization(), *this ); forStmt->set_condition( maybeMutate( forStmt->get_condition(), *this ) ); forStmt->set_increment( maybeMutate( forStmt->get_increment(), *this ) ); forStmt->set_body( mutateStatement( forStmt->get_body() ) ); return forStmt; } Statement* DeclMutator::mutate(SwitchStmt *switchStmt) { switchStmt->set_condition( maybeMutate( switchStmt->get_condition(), *this ) ); mutateAll( switchStmt->get_statements(), *this ); return switchStmt; } Statement* DeclMutator::mutate(CaseStmt *caseStmt) { caseStmt->set_condition( maybeMutate( caseStmt->get_condition(), *this ) ); mutateAll( caseStmt->get_statements(), *this ); return caseStmt; } Statement* DeclMutator::mutate(TryStmt *tryStmt) { tryStmt->set_block( maybeMutate( tryStmt->get_block(), *this ) ); mutateAll( tryStmt->get_catchers(), *this ); tryStmt->set_finally( maybeMutate( tryStmt->get_finally(), *this ) ); return tryStmt; } Statement* DeclMutator::mutate(CatchStmt *catchStmt) { catchStmt->set_decl( maybeMutate( catchStmt->get_decl(), *this ) ); catchStmt->set_cond( maybeMutate( catchStmt->get_cond(), *this ) ); catchStmt->set_body( mutateStatement( catchStmt->get_body() ) ); return catchStmt; } } // namespace GenPoly // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //