//
// 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.h --
//
// Author           : Aaron B. Moss
// Created On       : Fri Nov 27 14:44:00 2015
// Last Modified By : Peter A. Buhr
// Last Modified On : Sat Jul 22 09:21:12 2017
// Update Count     : 4
//

#pragma once

#include <list>               // for list
#include <vector>             // for vector

#include "SynTree/Mutator.h"  // for Mutator
#include "SynTree/SynTree.h"  // for Visitor Nodes

namespace GenPoly {
	/// Mutates a list of declarations, providing a means of adding new declarations into the list
	class DeclMutator : public Mutator {
	  public:
		typedef Mutator Parent;

		DeclMutator();
		virtual ~DeclMutator();

		using Parent::mutate;
		virtual CompoundStmt* mutate(CompoundStmt *compoundStmt);
		virtual Statement* mutate(IfStmt *ifStmt);
		virtual Statement* mutate(WhileStmt *whileStmt);
		virtual Statement* mutate(ForStmt *forStmt);
		virtual Statement* mutate(SwitchStmt *switchStmt);
		virtual Statement* mutate(CaseStmt *caseStmt);
		virtual Statement* mutate(TryStmt *tryStmt);
		virtual Statement* mutate(CatchStmt *catchStmt);

		/// Mutates a list of declarations with this visitor
		void mutateDeclarationList(std::list< Declaration* >& decls);

		/// Called on entry to a new scope; overriders should call this as a super-class call
		virtual void doBeginScope();
		/// Called on exit from a scope; overriders should call this as a super-class call
		virtual void doEndScope();
	  protected:
		/// Mutate a statement that forms its own scope
		Statement* mutateStatement( Statement *stmt );
		/// Mutate a list of statements that form a scope
		void mutateStatementList( std::list< Statement* > &stmts );
		/// Add a declaration to the list to be added before the current position
		void addDeclaration( Declaration* decl );
		/// Add a declaration to the list to be added after the current position
		void addDeclarationAfter( Declaration* decl );
	  private:
		/// A stack of declarations to add before the current declaration or statement
		std::vector< std::list< Declaration* > > declsToAdd;
		/// A stack of declarations to add after the current declaration or statement
		std::vector< std::list< Declaration* > > declsToAddAfter;
	};
} // namespace

// Local Variables: //
// tab-width: 4 //
// mode: c++ //
// compile-command: "make install" //
// End: //
