Index: translator/ResolvExpr/PtrsAssignable.cc
===================================================================
--- translator/ResolvExpr/PtrsAssignable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/ResolvExpr/PtrsAssignable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,161 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: PtrsAssignable.cc,v 1.3 2005/08/29 20:14:16 rcbilson Exp $
+ *
+ */
+
+#include "typeops.h"
+#include "SynTree/Type.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Visitor.h"
+
+
+namespace ResolvExpr {
+
+class PtrsAssignable : public Visitor
+{
+public:
+  PtrsAssignable( Type *dest, const TypeEnvironment &env );
+  
+  int get_result() const { return result; }
+
+  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 *inst);
+  virtual void visit(UnionInstType *inst);
+  virtual void visit(EnumInstType *inst);
+  virtual void visit(ContextInstType *inst);
+  virtual void visit(TypeInstType *inst);
+  virtual void visit(TupleType *tupleType);
+
+private:
+  Type *dest;
+  int result;
+  const TypeEnvironment &env;
+};
+
+int
+ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env )
+{
+  if( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
+    EqvClass eqvClass;
+    if( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
+      return ptrsAssignable( src, eqvClass.type, env );
+    }
+  }
+  if( dynamic_cast< VoidType* >( dest ) ) {
+    return 1;
+  } else {
+    PtrsAssignable ptrs( dest, env );
+    src->accept( ptrs );
+    return ptrs.get_result();
+  }
+}
+
+PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env )
+  : dest( dest ), result( 0 ), env( env )
+{
+}
+
+void 
+PtrsAssignable::visit(VoidType *voidType)
+{
+  if( dynamic_cast< FunctionType* >( dest ) ) {
+    result = 0;
+  } else {
+    result = -1;
+  }
+}
+
+void 
+PtrsAssignable::visit(BasicType *basicType)
+{
+}
+
+void 
+PtrsAssignable::visit(PointerType *pointerType)
+{
+}
+
+void 
+PtrsAssignable::visit(ArrayType *arrayType)
+{
+}
+
+void 
+PtrsAssignable::visit(FunctionType *functionType)
+{
+  result = -1;
+}
+
+void 
+PtrsAssignable::visit(StructInstType *inst)
+{
+  // I don't think we should be doing anything here, but I'm willing to admit that I might be wrong
+}
+
+void 
+PtrsAssignable::visit(UnionInstType *inst)
+{
+  // I don't think we should be doing anything here, but I'm willing to admit that I might be wrong
+}
+
+void 
+PtrsAssignable::visit(EnumInstType *inst)
+{
+  if( dynamic_cast< EnumInstType* >( inst ) ) {
+    result = 1;
+  } else if( BasicType *bt = dynamic_cast< BasicType* >( inst ) ) {
+    result = bt->get_kind() == BasicType::SignedInt;
+  }
+}
+
+void 
+PtrsAssignable::visit(ContextInstType *inst)
+{
+  // I definitely don't think we should be doing anything here
+}
+
+void 
+PtrsAssignable::visit(TypeInstType *inst)
+{
+  EqvClass eqvClass;
+  if( env.lookup( inst->get_name(), eqvClass ) ) {
+    result = ptrsAssignable( eqvClass.type, dest, env );
+  } else {
+    result = 0;
+  }
+}
+
+void 
+PtrsAssignable::visit(TupleType *tupleType)
+{
+///  // This code doesn't belong here, but it might be useful somewhere else
+///   if( TupleType *destAsTuple = dynamic_cast< TupleType* >( dest ) ) {
+///     int ret = 0;
+///     std::list< Type* >::const_iterator srcIt = tupleType->get_types().begin();
+///     std::list< Type* >::const_iterator destIt = destAsTuple->get_types().begin();
+///     while( srcIt != tupleType->get_types().end() && destIt != destAsTuple->get_types().end() ) {
+///       int assignResult = ptrsAssignable( *srcIt++, *destIt++ );
+///       if( assignResult == 0 ) {
+///         result = assignResult;
+///         return;
+///       } else if ( assignResult < 0 ) {
+///         ret = -1;
+///       } else if ( ret > 0 ) {
+///         ret += assignResult;
+///       }
+///     }
+///     if( srcIt == tupleType->get_types().end() && destIt == destAsTuple->get_types().end() ) {
+///       result = ret;
+///     } else {
+///       result = 0;
+///     }
+///   }
+}
+
+} // namespace ResolvExpr
