/*******************************************************************\

Module: Pointer Logic

Author: Daniel Kroening, kroening@cs.cmu.edu

\*******************************************************************/

#ifndef CPROVER_POINTER_LOGIC_H
#define CPROVER_POINTER_LOGIC_H

#include <mp_arith.h>
#include <hash_cont.h>
#include <expr.h>

class pointer_logict
{
public:
  struct pointert
  {
    unsigned object;
    mp_integer offset;
  };

  virtual void pointer_expr(
    const pointert &pointer,
    const typet &type,
    exprt &dest) const;
    
  virtual void object_expr(
    unsigned object,
    const typet &type,
    exprt &dest) const;
    
  virtual ~pointer_logict();
  
  pointer_logict();
  
  unsigned add_object(const exprt &expr)
  {
    object_mapt::iterator it=
      object_map.insert(std::pair<exprt, unsigned>
        (expr, object_map.size())).first;

    return it->second;
  }
  
  unsigned get_null_object() const
  {
    return null_object;
  }

  unsigned get_invalid_object() const
  {
    return invalid_object;
  }

  typedef hash_map_cont<exprt, unsigned, irep_hash> object_mapt;

  object_mapt get_object_map()
  {
    return object_map;
  }
  
protected:
  object_mapt object_map;
  
  unsigned null_object, invalid_object;  

  void pointer_expr(
    const mp_integer &offset,
    const exprt &object,
    exprt &dest) const;

  void pointer_expr_rec(
    const mp_integer &offset,
    const typet &pointer_type,
    exprt &dest,
    mp_integer &offset_rest) const;
};

#endif
