#ifndef SQUASH_MIN_MAX_LINE_VISITOR
#define SQUASH_MIN_MAX_LINE_VISITOR

#include "cc_ast.h" // ASTVisitor
#include <string>
#include "exprloc.h"
// See License.txt for copyright and terms of use

// Records the line range of an AST
// This provides positions for patch output

class MinMaxLineVisitor : public ASTVisitor {
private:
  unsigned int minCol;
  std::string file;

public:
  // TODO: maxCol is gimped until else provides end-of-ast-node pos
  unsigned int maxCol;
  unsigned int minLine;
  unsigned int maxLine;

  MinMaxLineVisitor();
  MinMaxLineVisitor(MinMaxLineVisitor const &);
  MinMaxLineVisitor& operator=(MinMaxLineVisitor const &);

  void notice(SourceLoc loc, SourceLoc endloc = SL_UNKNOWN);
  void reset();
  unsigned int getIndent() const;
  void setIndent(unsigned int);
  std::string toString() const;
  std::string getFile() const;
  virtual bool visitTopForm(TopForm *obj) { 
    notice(obj->loc); 
    return true; }

  virtual bool visitFunction(Function *obj) { 
    notice(obj->getLoc()); 
    return true;
  }
  
  virtual bool visitPQName(PQName *obj) { 
    notice(obj->loc); 
    return true;
  }
  
  virtual bool visitTypeSpecifier(TypeSpecifier *obj) { 
    notice(obj->loc); 
    return true;
  }
  
  virtual bool visitEnumerator(Enumerator *obj) { 
    notice(obj->loc); 
    return true;
  }
  
  virtual bool visitMember(Member *obj) { 
    notice(obj->loc); 
    return true;
  }
  
  virtual bool visitDeclarator(Declarator *obj) { 
    notice(obj->getLoc()); 
    return true;
  }
  
  virtual bool visitIDeclarator(IDeclarator *obj) { 
    notice(obj->loc); 
    return true; 
  }
  
  virtual bool visitStatement(Statement *obj) { 
    notice(obj->loc); 
    return true;
  }
  
  virtual bool visitInitializer(Initializer *obj) { 
    notice(obj->loc); 
    return true;
  }
  
  EXPR_LOC1(virtual bool visitExpression(Expression *obj) {
      notice(obj->loc, obj->endloc);
      return true;
    })
  
    virtual bool visitTemplateParameter(TemplateParameter *obj) {
    notice(obj->loc); 
    return true;
  }
  virtual bool visitDesignator(Designator *obj) {
    notice(obj->loc); 
    return true;
  }

  virtual bool visitAttribute(Attribute *obj) { 
    notice(obj->loc); 
    return true;
  }
};

#endif // SQUASH_MIN_MAX_LINE_VISITOR
