/*
 * This file is part of the Cforall project
 *
 * $Id: AddVisit.h,v 1.2 2005/08/29 20:14:17 rcbilson Exp $
 *
 */


namespace SymTab {

void addDecls( std::list< Declaration* > &declsToAdd, std::list< Statement* > &statements, std::list< Statement* >::iterator i );

template< typename Visitor >
inline void
addVisitStatementList( std::list< Statement* > &statements, Visitor &visitor )
{
  for( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
    addDecls( visitor.get_declsToAdd(), statements, i );
    (*i)->accept( visitor );
  }
  addDecls( visitor.get_declsToAdd(), statements, statements.end() );
}

template< typename Visitor >
inline void
addVisitStatement( Statement *stmt, Visitor &visitor )
{
  maybeAccept( stmt, visitor );
///   if( !declsToAdd.empty() ) {
///     CompoundStmt *compound = new CompoundStmt( noLabels );
///     compound->get_kids().push_back( stmt );
///     addDecls( declsToAdd, compound->get_kids(), compound->get_kids().end() );
///   }
}

template< typename Visitor >
inline void
addVisit(CompoundStmt *compoundStmt, Visitor &visitor)
{
  addVisitStatementList( compoundStmt->get_kids(), visitor );
}

template< typename Visitor >
inline void
addVisit(IfStmt *ifStmt, Visitor &visitor)
{
  addVisitStatement( ifStmt->get_thenPart(), visitor );
  addVisitStatement( ifStmt->get_elsePart(), visitor );
  maybeAccept( ifStmt->get_condition(), visitor );
}

template< typename Visitor >
inline void
addVisit(WhileStmt *whileStmt, Visitor &visitor)
{
  addVisitStatement( whileStmt->get_body(), visitor );
  maybeAccept( whileStmt->get_condition(), visitor );
}

template< typename Visitor >
inline void
addVisit(ForStmt *forStmt, Visitor &visitor)
{
  addVisitStatement( forStmt->get_body(), visitor );
  maybeAccept( forStmt->get_initialization(), visitor );
  maybeAccept( forStmt->get_condition(), visitor );
  maybeAccept( forStmt->get_increment(), visitor );
}

template< typename Visitor >
inline void
addVisit(SwitchStmt *switchStmt, Visitor &visitor)
{
  addVisitStatementList( switchStmt->get_branches(), visitor );
  maybeAccept( switchStmt->get_condition(), visitor );
}

template< typename Visitor >
inline void
addVisit(ChooseStmt *switchStmt, Visitor &visitor)
{
  addVisitStatementList( switchStmt->get_branches(), visitor );
  maybeAccept( switchStmt->get_condition(), visitor );
}

template< typename Visitor >
inline void
addVisit(CaseStmt *caseStmt, Visitor &visitor)
{
  addVisitStatementList( caseStmt->get_statements(), visitor );
  maybeAccept( caseStmt->get_condition(), visitor );
}

template< typename Visitor >
inline void
addVisit(CatchStmt *cathStmt, Visitor &visitor)
{
  addVisitStatement( cathStmt->get_body(), visitor );
  maybeAccept( cathStmt->get_decl(), visitor );
}

} // namespace SymTab
