#ifndef SQUASH_OUTPARAM_REMOVER
#define SQUASH_OUTPARAM_REMOVER

// See License.txt for copyright and terms of use

#include "expr_visitor.h"
#include "cc_ast.h" // ASTVisitor
#include <string>
#include <map>
#include <list>

class Patcher;
class SquashCmd;
class MinMaxLineVisitor;
// Manages rewriting functions to use return values instead of out-params
class OutparamRemover : public ExpressionVisitor {
public:
  OutparamRemover(SquashCmd const &cmd, Patcher &patcher);

  void postvisitMember(Member *m);
  void rewriteFunction(Function *obj);

  virtual bool visitS_return(S_return *s);
  virtual bool visitE_deref(E_deref *e);
  virtual void postvisitE_funCall(E_funCall *e);

private:
  struct OutParamInfo {
  OutParamInfo():paramVar(NULL), function(NULL) {
  }
    std::string className;
    std::string memberName;
    // index of the param to remove
    unsigned int param;
    // elsa instance of the param to remove
    Variable *paramVar;
    // elsa instance of the func being rewritten
    Variable *function;
    std::string assign;
  };
  OutParamInfo* isMatch(D_func *df, std::string const &className,
			Variable *member, ASTTypeId *&outparam, 
			Type *type = NULL);
 
  void rewriteFunctionDeclaration(MR_decl *m,
				  OutParamInfo &opi,
				  ASTTypeId *outparam);

  std::string rewriteFuncDeclOrDef(MinMaxLineVisitor mmlvDecl, 
			    MinMaxLineVisitor mmlvFunc,
			    std::string const &startOfFunc,
			    ASTTypeId *outparam);


  template<class T> MinMaxLineVisitor traverseWithMaxCol(T *obj, 
							 std::string const &chars,
							 int offset = 0) const;
  std::list<OutParamInfo> ls;
  SquashCmd const &cmd;
  Patcher &patcher; 
  OutParamInfo *curr_opi;
};

#endif // SQUASH_OUTPARAM_REMOVER
