//
// 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 : Tue Jul 12 17:39:01 2016
// Update Count     : 2
//

#ifndef _DECLMUTATOR_H
#define _DECLMUTATOR_H

#include <list>
#include <vector>

#include "SynTree/SynTree.h"
#include "SynTree/Declaration.h"
#include "SynTree/Mutator.h"

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

#endif // _DECLMUTATOR_H

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