#ifndef _INIT_EXPANDER_H_
#define _INIT_EXPANDER_H_

#include <string>

#include "utility.h"
#include "SynTree/Mutator.h"
#include "SymTab/Indexer.h"

#include "SynTree/Statement.h"
#include "SynTree/Declaration.h"
#include "SynTree/Type.h"

namespace InitTweak {

  class InitExpander : public Mutator
  {
    typedef Mutator Parent;

  public:
    InitExpander();
    ~InitExpander();

    virtual ObjectDecl *mutate( ObjectDecl * );

    // indexer runs
    virtual FunctionDecl   *mutate( FunctionDecl *functionDecl )
    {
      functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
      mutateAll( functionDecl->get_oldDecls(), *this );
      functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );

      index.visit( functionDecl );
      return functionDecl;
    }

    virtual TypeDecl       *mutate( TypeDecl *typeDecl )
    { index.visit( typeDecl ); return typeDecl; }
    virtual TypedefDecl    *mutate( TypedefDecl *typeDecl )
    { index.visit( typeDecl ); return typeDecl; }
    virtual StructDecl     *mutate( StructDecl *aggregateDecl )
    { index.visit( aggregateDecl ); return aggregateDecl; }
    virtual UnionDecl      *mutate( UnionDecl *aggregateDecl )
    { index.visit( aggregateDecl ); return aggregateDecl; }
    virtual EnumDecl       *mutate( EnumDecl *aggregateDecl )
    { index.visit( aggregateDecl ); return aggregateDecl; }

    virtual Type           *mutate( StructInstType *aggrInst )
    { index.visit( aggrInst ); return aggrInst; }
    virtual Type           *mutate( UnionInstType *aggrInst )
    { index.visit( aggrInst ); return aggrInst; }

  private:
    SymTab::Indexer index;
  };  // class InitExpander

} // namespace InitTweak


#endif // #ifndef _INIT_EXPANDER_H_

/*
  Local Variables:
  mode: c++
  End:
*/
