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

#ifndef SYMTAB_MANGLER_H
#define SYMTAB_MANGLER_H

#include <strstream>
#include "SynTree/SynTree.h"
#include "SynTree/Visitor.h"

namespace SymTab {

class Mangler : public Visitor
{
public:
  template< typename SynTreeClass >
  static std::string mangle( SynTreeClass *decl );		// interface to clients

///   using Visitor::visit;
  virtual void visit(ObjectDecl *declaration);
  virtual void visit(FunctionDecl *declaration);
  virtual void visit(TypeDecl *declaration);

  virtual void visit(VoidType *voidType);
  virtual void visit(BasicType *basicType);
  virtual void visit(PointerType *pointerType);
  virtual void visit(ArrayType *arrayType);
  virtual void visit(FunctionType *functionType);
  virtual void visit(StructInstType *aggregateUseType);
  virtual void visit(UnionInstType *aggregateUseType);
  virtual void visit(EnumInstType *aggregateUseType);
  virtual void visit(TypeInstType *aggregateUseType);
  virtual void visit(TupleType *tupleType);
  
  std::string get_mangleName() { return std::string( mangleName.str(), mangleName.pcount() ); }

private:
  std::ostrstream mangleName;
  typedef std::map< std::string, std::pair< int, int > > VarMapType;
  VarMapType varNums;
  int nextVarNum;
  bool isTopLevel;
  
  Mangler();
  Mangler( const Mangler & );
  
  void mangleDecl(DeclarationWithType *declaration);
  void mangleRef(ReferenceToType *refType, std::string prefix);
  
  void printQualifiers( Type *type );
};

/* static class method */
template< typename SynTreeClass >
std::string 
Mangler::mangle( SynTreeClass *decl )
{
  Mangler mangler;
  maybeAccept( decl, mangler );
  return mangler.get_mangleName();
}

} // namespace SymTab

#endif /* #ifndef SYMTAB_MANGLER_H */
