Index: translator/SymTab/AddVisit.h
===================================================================
--- translator/SymTab/AddVisit.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/AddVisit.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,102 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: AddVisit.h,v 1.2 2005/08/29 20:14:17 rcbilson Exp $
+ *
+ */
+
+
+namespace SymTab {
+
+void addDecls( std::list< Declaration* > &declsToAdd, std::list< Statement* > &statements, std::list< Statement* >::iterator i );
+
+template< typename Visitor >
+inline void
+addVisitStatementList( std::list< Statement* > &statements, Visitor &visitor )
+{
+  for( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
+    addDecls( visitor.get_declsToAdd(), statements, i );
+    (*i)->accept( visitor );
+  }
+  addDecls( visitor.get_declsToAdd(), statements, statements.end() );
+}
+
+template< typename Visitor >
+inline void
+addVisitStatement( Statement *stmt, Visitor &visitor )
+{
+  maybeAccept( stmt, visitor );
+///   if( !declsToAdd.empty() ) {
+///     CompoundStmt *compound = new CompoundStmt( noLabels );
+///     compound->get_kids().push_back( stmt );
+///     addDecls( declsToAdd, compound->get_kids(), compound->get_kids().end() );
+///   }
+}
+
+template< typename Visitor >
+inline void
+addVisit(CompoundStmt *compoundStmt, Visitor &visitor)
+{
+  addVisitStatementList( compoundStmt->get_kids(), visitor );
+}
+
+template< typename Visitor >
+inline void
+addVisit(IfStmt *ifStmt, Visitor &visitor)
+{
+  addVisitStatement( ifStmt->get_thenPart(), visitor );
+  addVisitStatement( ifStmt->get_elsePart(), visitor );
+  maybeAccept( ifStmt->get_condition(), visitor );
+}
+
+template< typename Visitor >
+inline void
+addVisit(WhileStmt *whileStmt, Visitor &visitor)
+{
+  addVisitStatement( whileStmt->get_body(), visitor );
+  maybeAccept( whileStmt->get_condition(), visitor );
+}
+
+template< typename Visitor >
+inline void
+addVisit(ForStmt *forStmt, Visitor &visitor)
+{
+  addVisitStatement( forStmt->get_body(), visitor );
+  maybeAccept( forStmt->get_initialization(), visitor );
+  maybeAccept( forStmt->get_condition(), visitor );
+  maybeAccept( forStmt->get_increment(), visitor );
+}
+
+template< typename Visitor >
+inline void
+addVisit(SwitchStmt *switchStmt, Visitor &visitor)
+{
+  addVisitStatementList( switchStmt->get_branches(), visitor );
+  maybeAccept( switchStmt->get_condition(), visitor );
+}
+
+template< typename Visitor >
+inline void
+addVisit(ChooseStmt *switchStmt, Visitor &visitor)
+{
+  addVisitStatementList( switchStmt->get_branches(), visitor );
+  maybeAccept( switchStmt->get_condition(), visitor );
+}
+
+template< typename Visitor >
+inline void
+addVisit(CaseStmt *caseStmt, Visitor &visitor)
+{
+  addVisitStatementList( caseStmt->get_statements(), visitor );
+  maybeAccept( caseStmt->get_condition(), visitor );
+}
+
+template< typename Visitor >
+inline void
+addVisit(CatchStmt *cathStmt, Visitor &visitor)
+{
+  addVisitStatement( cathStmt->get_body(), visitor );
+  maybeAccept( cathStmt->get_decl(), visitor );
+}
+
+} // namespace SymTab
Index: translator/SymTab/AggregateTable.h
===================================================================
--- translator/SymTab/AggregateTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/AggregateTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,44 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: AggregateTable.h,v 1.4 2005/08/29 20:14:17 rcbilson Exp $
+ *
+ */
+
+#ifndef SYMTAB_AGGREGATETABLE_H
+#define SYMTAB_AGGREGATETABLE_H
+
+#include <map>
+#include <stack>
+#include <string>
+#include <functional>
+
+#include "StackTable.h"
+#include "SynTree/Declaration.h"
+
+namespace SymTab {
+
+template< class AggregateDeclClass >
+class AggregateTableConflictFunction : public std::binary_function< AggregateDeclClass*, AggregateDeclClass*, AggregateDeclClass* >
+{
+public:
+  AggregateDeclClass *operator()( AggregateDeclClass *existing, AggregateDeclClass *added )
+  {
+    if( existing->get_members().empty() ) {
+      return added;
+    } else if( !added->get_members().empty() ) {
+      throw SemanticError( "redeclaration of ", added );
+    }
+    return existing;
+  }
+  
+};
+
+typedef StackTable< StructDecl, AggregateTableConflictFunction< StructDecl > > StructTable;
+typedef StackTable< EnumDecl, AggregateTableConflictFunction< EnumDecl > > EnumTable;
+typedef StackTable< UnionDecl, AggregateTableConflictFunction< UnionDecl > > UnionTable;
+typedef StackTable< ContextDecl, AggregateTableConflictFunction< ContextDecl > > ContextTable;
+
+} // namespace SymTab
+
+#endif /* #ifndef SYMTAB_AGGREGATETABLE_H */
Index: translator/SymTab/FixFunction.cc
===================================================================
--- translator/SymTab/FixFunction.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/FixFunction.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,86 @@
+#include "FixFunction.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+#include "SynTree/Expression.h"
+#include "utility.h"
+
+namespace SymTab {
+
+FixFunction::FixFunction()
+  : isVoid( false )
+{
+}
+
+DeclarationWithType* 
+FixFunction::mutate(FunctionDecl *functionDecl)
+{
+  ObjectDecl *pointer = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0, new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
+  delete functionDecl;
+  return pointer;
+}
+
+Type* 
+FixFunction::mutate(VoidType *voidType)
+{
+  isVoid = true;
+  return voidType;
+}
+
+Type* 
+FixFunction::mutate(BasicType *basicType)
+{
+  return basicType;
+}
+
+Type* 
+FixFunction::mutate(PointerType *pointerType)
+{
+  return pointerType;
+}
+
+Type* 
+FixFunction::mutate(ArrayType *arrayType)
+{
+  PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), maybeClone( arrayType->get_base()->clone() ), maybeClone( arrayType->get_dimension() ), arrayType->get_isVarLen(), arrayType->get_isStatic() );
+  delete arrayType;
+  return pointerType;
+}
+
+Type* 
+FixFunction::mutate(StructInstType *aggregateUseType)
+{
+  return aggregateUseType;
+}
+
+Type* 
+FixFunction::mutate(UnionInstType *aggregateUseType)
+{
+  return aggregateUseType;
+}
+
+Type* 
+FixFunction::mutate(EnumInstType *aggregateUseType)
+{
+  return aggregateUseType;
+}
+
+Type* 
+FixFunction::mutate(ContextInstType *aggregateUseType)
+{
+  return aggregateUseType;
+}
+
+Type* 
+FixFunction::mutate(TypeInstType *aggregateUseType)
+{
+  return aggregateUseType;
+}
+
+Type* 
+FixFunction::mutate(TupleType *tupleType)
+{
+  return tupleType;
+}
+
+
+} // namespace SymTab
Index: translator/SymTab/FixFunction.h
===================================================================
--- translator/SymTab/FixFunction.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/FixFunction.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,44 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: FixFunction.h,v 1.3 2005/08/29 20:14:17 rcbilson Exp $
+ *
+ */
+
+#ifndef SYMTAB_FIXFUNCTION_H
+#define SYMTAB_FIXFUNCTION_H
+
+#include "SynTree/Mutator.h"
+
+namespace SymTab {
+
+class FixFunction : public Mutator
+{
+  typedef Mutator Parent;
+
+public:
+  FixFunction();
+
+  bool get_isVoid() const { return isVoid; }
+  void set_isVoid( bool newValue ) { isVoid = newValue; }
+
+private:
+  virtual DeclarationWithType* mutate(FunctionDecl *functionDecl);
+
+  virtual Type* mutate(VoidType *voidType);
+  virtual Type* mutate(BasicType *basicType);
+  virtual Type* mutate(PointerType *pointerType);
+  virtual Type* mutate(ArrayType *arrayType);
+  virtual Type* mutate(StructInstType *aggregateUseType);
+  virtual Type* mutate(UnionInstType *aggregateUseType);
+  virtual Type* mutate(EnumInstType *aggregateUseType);
+  virtual Type* mutate(ContextInstType *aggregateUseType);
+  virtual Type* mutate(TypeInstType *aggregateUseType);
+  virtual Type* mutate(TupleType *tupleType);
+  
+  bool isVoid;
+};
+
+} // namespace SymTab
+
+#endif /* #ifndef SYMTAB_FIXFUNCTION_H */
Index: translator/SymTab/IdTable.cc
===================================================================
--- translator/SymTab/IdTable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/IdTable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,119 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: IdTable.cc,v 1.6 2005/08/29 20:14:17 rcbilson Exp $
+ *
+ */
+
+#include <cassert>
+
+#include "SynTree/Declaration.h"
+#include "ResolvExpr/typeops.h"
+#include "Indexer.h"
+#include "Mangler.h"
+#include "IdTable.h"
+#include "SemanticError.h"
+
+using std::string;
+
+namespace SymTab {
+
+IdTable::IdTable()
+  : scopeLevel( 0 )
+{
+}
+
+void 
+IdTable::enterScope()
+{
+  scopeLevel++;
+}
+
+void 
+IdTable::leaveScope()
+{
+  for( OuterTableType::iterator outer = table.begin(); outer != table.end(); ++outer ) {
+    for( InnerTableType::iterator inner = outer->second.begin(); inner != outer->second.end(); ++inner ) {
+      std::stack< DeclEntry >& entry = inner->second;
+      if( !entry.empty() && entry.top().second == scopeLevel ) {
+        entry.pop();
+      }
+    }
+  }
+      
+  scopeLevel--;
+  assert( scopeLevel >= 0 );
+}
+
+void 
+IdTable::addDecl( DeclarationWithType *decl )
+{
+  const string &name = decl->get_name();
+  string manglename;
+  if( decl->get_linkage() == LinkageSpec::C ) {
+    manglename = name;
+  } else {
+    manglename = Mangler::mangle( decl );
+  }
+  InnerTableType &declTable = table[ name ];
+  InnerTableType::iterator it = declTable.find( manglename );
+  if( it == declTable.end() ) {
+    declTable[ manglename ].push( DeclEntry( decl, scopeLevel ) );
+  } else {
+    std::stack< DeclEntry >& entry = it->second;
+    if( !entry.empty() && entry.top().second == scopeLevel ) {
+      if( decl->get_linkage() != LinkageSpec::C || ResolvExpr::typesCompatible( decl->get_type(), entry.top().first->get_type(), Indexer() ) ) {
+        FunctionDecl *newentry = dynamic_cast< FunctionDecl* >( decl );
+        FunctionDecl *old = dynamic_cast< FunctionDecl* >( entry.top().first );
+        if( newentry && old && newentry->get_statements() && old->get_statements() ) {
+          throw SemanticError( "duplicate function definition for ", decl );
+        } else {
+          ObjectDecl *newobj = dynamic_cast< ObjectDecl* >( decl );
+          ObjectDecl *oldobj = dynamic_cast< ObjectDecl* >( entry.top().first );
+          if( newobj && oldobj && newobj->get_init() && oldobj->get_init() ) {
+            throw SemanticError( "duplicate definition for ", decl );
+          }
+        }
+      } else {
+        throw SemanticError( "duplicate definition for ", decl );
+      }
+    } else {
+      declTable[ manglename ].push( DeclEntry( decl, scopeLevel ) );
+    }
+  }
+  for( InnerTableType::const_iterator i = declTable.begin(); i != declTable.end(); ++i ) {
+    if( !i->second.empty() && i->second.top().first->get_linkage() == LinkageSpec::C && declTable.size() > 1 ) {
+      throw SemanticError( "invalid overload of C function ", i->second.top().first );
+    }
+  }
+}
+
+void 
+IdTable::lookupId( const std::string &id, std::list< DeclarationWithType* >& decls ) const
+{
+  OuterTableType::const_iterator outer = table.find( id );
+  if( outer == table.end() ) return;
+  const InnerTableType &declTable = outer->second;
+  for( InnerTableType::const_iterator it = declTable.begin(); it != declTable.end(); ++it ) {
+    const std::stack< DeclEntry >& entry = it->second;
+    if( !entry.empty() ) {
+      decls.push_back( entry.top().first );
+    }
+  }
+}
+
+void 
+IdTable::dump( std::ostream &os ) const
+{
+  for( OuterTableType::const_iterator outer = table.begin(); outer != table.end(); ++outer ) {
+    for( InnerTableType::const_iterator inner = outer->second.begin(); inner != outer->second.end(); ++inner ) {
+      const std::stack< DeclEntry >& entry = inner->second;
+      if( !entry.empty() && entry.top().second == scopeLevel ) {
+        os << outer->first << " (" << inner->first << ") (" << scopeLevel << ")" << std::endl;
+      }
+    }
+  }
+}
+
+
+} // namespace SymTab
Index: translator/SymTab/IdTable.h
===================================================================
--- translator/SymTab/IdTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/IdTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: IdTable.h,v 1.4 2005/08/29 20:14:17 rcbilson Exp $
+ *
+ */
+
+#ifndef SYMTAB_IDTABLE_H
+#define SYMTAB_IDTABLE_H
+
+#include <iostream>
+#include <map>
+#include <string>
+#include <stack>
+
+#include "SynTree/SynTree.h"
+
+namespace SymTab {
+
+class IdTable
+{
+public:
+  IdTable();
+  
+  void enterScope();
+  void leaveScope();
+  void addDecl( DeclarationWithType *decl );
+  void lookupId( const std::string &id, std::list< DeclarationWithType* >& decls ) const;
+  
+  void dump( std::ostream &os ) const; // debugging
+
+ private:
+  typedef std::pair< DeclarationWithType*, int > DeclEntry;
+  typedef std::map< std::string, std::stack< DeclEntry > > InnerTableType;
+  typedef std::map< std::string, InnerTableType > OuterTableType;
+
+  OuterTableType table;
+  int scopeLevel;
+};
+
+} // namespace SymTab
+
+#endif /* #ifndef SYMTAB_IDTABLE_H */
Index: translator/SymTab/ImplementationType.cc
===================================================================
--- translator/SymTab/ImplementationType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/ImplementationType.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,140 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: ImplementationType.cc,v 1.4 2005/08/29 20:14:17 rcbilson Exp $
+ *
+ */
+
+#include "ImplementationType.h"
+#include "SynTree/Type.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Visitor.h"
+#include "SymTab/Indexer.h"
+#include "utility.h"
+
+
+namespace SymTab {
+
+class ImplementationType : public Visitor
+{
+public:
+  ImplementationType( const SymTab::Indexer &indexer );
+  
+  Type *get_result() { return result; }
+
+private:
+  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(ContextInstType *aggregateUseType);
+  virtual void visit(TypeInstType *aggregateUseType);
+  virtual void visit(TupleType *tupleType);
+
+  Type *result;			// synthesized
+  const SymTab::Indexer &indexer;
+};
+
+Type*
+implementationType( Type *type, const SymTab::Indexer& indexer )
+{
+  ImplementationType implementor( indexer );
+  type->accept( implementor );
+  if( implementor.get_result() == 0 ) {
+    return type->clone();
+  } else {
+    return implementor.get_result();
+  }
+}
+
+ImplementationType::ImplementationType( const SymTab::Indexer &indexer )
+  : result( 0 ), indexer( indexer )
+{
+}
+
+void 
+ImplementationType::visit(VoidType *voidType)
+{
+}
+
+void 
+ImplementationType::visit(BasicType *basicType)
+{
+}
+
+void 
+ImplementationType::visit(PointerType *pointerType)
+{
+  PointerType *newType = pointerType->clone();
+  newType->set_base( implementationType( pointerType->get_base(), indexer ) );
+  result = newType;
+}
+
+void 
+ImplementationType::visit(ArrayType *arrayType)
+{
+  ArrayType *newType = arrayType->clone();
+  newType->set_base( implementationType( arrayType->get_base(), indexer ) );
+  result = newType;
+}
+
+void 
+ImplementationType::visit(FunctionType *functionType)
+{
+///   FunctionType *newType = functionType->clone();
+///   for( std::list< DeclarationWithType* >::iterator i = newType->get_parameters().begin(); i != newType->get_parameters().end(); ++i ) {
+///     i->set_type( implementationType( i->get_type(), indexer ) );
+///   }
+///   for( std::list< DeclarationWithType* >::iterator i = newType->get_parameters().begin(); i != newType->get_parameters().end(); ++i ) {
+///     i->set_type( implementationType( i->get_type(), indexer ) );
+///   }
+}
+
+void 
+ImplementationType::visit(StructInstType *aggregateUseType)
+{
+}
+
+void 
+ImplementationType::visit(UnionInstType *aggregateUseType)
+{
+}
+
+void 
+ImplementationType::visit(EnumInstType *aggregateUseType)
+{
+}
+
+void 
+ImplementationType::visit(ContextInstType *aggregateUseType)
+{
+}
+
+void 
+ImplementationType::visit(TypeInstType *inst)
+{
+  NamedTypeDecl *typeDecl = indexer.lookupType( inst->get_name() );
+  if( typeDecl && typeDecl->get_base() ) {
+    Type *base = implementationType( typeDecl->get_base(), indexer );
+    base->get_qualifiers() += inst->get_qualifiers();
+    result = base;
+  }
+}
+
+void 
+ImplementationType::visit(TupleType *tupleType)
+{
+  TupleType *newType = new TupleType( Type::Qualifiers() );
+  for( std::list< Type* >::iterator i = tupleType->get_types().begin(); i != tupleType->get_types().end(); ++i ) {
+    Type *implType = implementationType( *i, indexer );
+    implType->get_qualifiers() += tupleType->get_qualifiers();
+    newType->get_types().push_back( implType );
+  }
+  result = newType;
+}
+
+} // namespace SymTab
Index: translator/SymTab/ImplementationType.h
===================================================================
--- translator/SymTab/ImplementationType.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/ImplementationType.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: ImplementationType.h,v 1.3 2005/08/29 20:14:17 rcbilson Exp $
+ *
+ */
+
+#ifndef SYMTAB_IMPLEMENTATIONTYPE_H
+#define SYMTAB_IMPLEMENTATIONTYPE_H
+
+#include "SynTree/SynTree.h"
+#include "SymTab/Indexer.h"
+
+namespace SymTab {
+
+Type *implementationType( Type *, const SymTab::Indexer &indexer );
+
+template< typename InputIterator, typename OutputIterator >
+void
+implementationTypeList( InputIterator begin, InputIterator end, OutputIterator out, const SymTab::Indexer &indexer )
+{
+  while( begin != end ) {
+    *out++ = implementationType( *begin++, indexer );
+  }
+}
+
+} // namespace SymTab
+
+#endif /* #ifndef SYMTAB_IMPLEMENTATIONTYPE_H */
Index: translator/SymTab/Indexer.cc
===================================================================
--- translator/SymTab/Indexer.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/Indexer.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,282 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Indexer.cc,v 1.12 2005/08/29 20:14:17 rcbilson Exp $
+ *
+ */
+
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Initializer.h"
+#include "SynTree/Statement.h"
+#include "Indexer.h"
+#include <typeinfo>
+#include "utility.h"
+
+#define debugPrint(x) if( doDebug ) { std::cout << x; }
+
+namespace SymTab {
+
+Indexer::Indexer( bool useDebug )
+  : doDebug( useDebug )
+{
+}
+
+Indexer::~Indexer()
+{
+}
+
+void 
+Indexer::visit( ObjectDecl *objectDecl )
+{
+  maybeAccept( objectDecl->get_type(), *this );
+  maybeAccept( objectDecl->get_init(), *this );
+  maybeAccept( objectDecl->get_bitfieldWidth(), *this );
+  if( objectDecl->get_name() != "" ) {
+    debugPrint( "Adding object " << objectDecl->get_name() << std::endl );
+    idTable.addDecl( objectDecl );
+  }
+}
+
+void 
+Indexer::visit( FunctionDecl *functionDecl )
+{
+  if( functionDecl->get_name() == "" ) return;
+  debugPrint( "Adding function " << functionDecl->get_name() << std::endl );
+  idTable.addDecl( functionDecl );
+  enterScope();
+  maybeAccept( functionDecl->get_functionType(), *this );
+  acceptAll( functionDecl->get_oldDecls(), *this );
+  maybeAccept( functionDecl->get_statements(), *this );
+  leaveScope();
+}
+
+/********
+ * A NOTE ON THE ORDER OF TRAVERSAL
+ *
+ * Types and typedefs have their base types visited before they are added to the type table.
+ * This is ok, since there is no such thing as a recursive type or typedef.
+ *             typedef struct { T *x; } T; // never allowed
+ *
+ * for structs/unions, it is possible to have recursion, so the decl should be added as if it's
+ * incomplete to begin, the members are traversed, and then the complete type should be added
+ * (assuming the type is completed by this particular declaration).
+ *             struct T { struct T *x; }; // allowed
+ *
+ * It's important to add the complete type to the symbol table *after* the members/base has been
+ * traversed, since that traversal may modify the definition of the type and these modifications
+ * should be visible when the symbol table is queried later in this pass.
+ *
+ * TODO: figure out whether recursive contexts are sensible/possible/reasonable.
+ */
+
+void 
+Indexer::visit( TypeDecl *typeDecl )
+{
+  // see A NOTE ON THE ORDER OF TRAVERSAL, above
+  // note that assertions come after the type is added to the symtab, since they aren't part
+  // of the type proper and may depend on the type itself
+  enterScope();
+  acceptAll( typeDecl->get_parameters(), *this );
+  maybeAccept( typeDecl->get_base(), *this );
+  leaveScope();
+  debugPrint( "Adding type " << typeDecl->get_name() << std::endl );
+  typeTable.add( typeDecl );
+  acceptAll( typeDecl->get_assertions(), *this );
+}
+
+void 
+Indexer::visit( TypedefDecl *typeDecl )
+{
+  enterScope();
+  acceptAll( typeDecl->get_parameters(), *this );
+  maybeAccept( typeDecl->get_base(), *this );
+  leaveScope();
+  debugPrint( "Adding typedef " << typeDecl->get_name() << std::endl );
+  typeTable.add( typeDecl );
+}
+
+void 
+Indexer::visit( StructDecl *aggregateDecl )
+{
+  // make up a forward declaration and add it before processing the members
+  StructDecl fwdDecl( aggregateDecl->get_name() );
+  cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
+  debugPrint( "Adding fwd decl for struct " << fwdDecl.get_name() << std::endl );
+  structTable.add( &fwdDecl );
+  
+  enterScope();
+  acceptAll( aggregateDecl->get_parameters(), *this );
+  acceptAll( aggregateDecl->get_members(), *this );
+  leaveScope();
+  
+  debugPrint( "Adding struct " << aggregateDecl->get_name() << std::endl );
+  // this addition replaces the forward declaration
+  structTable.add( aggregateDecl );
+}
+
+void 
+Indexer::visit( UnionDecl *aggregateDecl )
+{
+  // make up a forward declaration and add it before processing the members
+  UnionDecl fwdDecl( aggregateDecl->get_name() );
+  cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
+  debugPrint( "Adding fwd decl for union " << fwdDecl.get_name() << std::endl );
+  unionTable.add( &fwdDecl );
+  
+  enterScope();
+  acceptAll( aggregateDecl->get_parameters(), *this );
+  acceptAll( aggregateDecl->get_members(), *this );
+  leaveScope();
+  
+  debugPrint( "Adding union " << aggregateDecl->get_name() << std::endl );
+  unionTable.add( aggregateDecl );
+}
+
+void 
+Indexer::visit( EnumDecl *aggregateDecl )
+{
+  debugPrint( "Adding enum " << aggregateDecl->get_name() << std::endl );
+  enumTable.add( aggregateDecl );
+  // unlike structs, contexts, and unions, enums inject their members into the
+  // global scope
+  acceptAll( aggregateDecl->get_members(), *this );
+}
+
+void 
+Indexer::visit( ContextDecl *aggregateDecl )
+{
+  enterScope();
+  acceptAll( aggregateDecl->get_parameters(), *this );
+  acceptAll( aggregateDecl->get_members(), *this );
+  leaveScope();
+  
+  debugPrint( "Adding context " << aggregateDecl->get_name() << std::endl );
+  contextTable.add( aggregateDecl );
+}
+
+void 
+Indexer::visit( CompoundStmt *compoundStmt )
+{
+  enterScope();
+  acceptAll( compoundStmt->get_kids(), *this );
+  leaveScope();
+}
+
+void 
+Indexer::visit( ContextInstType *contextInst )
+{
+  acceptAll( contextInst->get_parameters(), *this );
+  acceptAll( contextInst->get_members(), *this );
+}
+
+void 
+Indexer::visit( StructInstType *structInst )
+{
+  if( !structTable.lookup( structInst->get_name() ) ) {
+    debugPrint( "Adding struct " << structInst->get_name() << " from implicit forward declaration" << std::endl );
+    structTable.add( structInst->get_name() );
+  }
+  enterScope();
+  acceptAll( structInst->get_parameters(), *this );
+  leaveScope();
+}
+
+void 
+Indexer::visit( UnionInstType *unionInst )
+{
+  if( !unionTable.lookup( unionInst->get_name() ) ) {
+    debugPrint( "Adding union " << unionInst->get_name() << " from implicit forward declaration" << std::endl );
+    unionTable.add( unionInst->get_name() );
+  }
+  enterScope();
+  acceptAll( unionInst->get_parameters(), *this );
+  leaveScope();
+}
+
+void
+Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &list ) const
+{
+  idTable.lookupId( id, list );
+}
+
+NamedTypeDecl *
+Indexer::lookupType( const std::string &id ) const
+{
+  return typeTable.lookup( id );
+}
+
+StructDecl *
+Indexer::lookupStruct( const std::string &id ) const
+{
+  return structTable.lookup( id );
+}
+
+EnumDecl *
+Indexer::lookupEnum( const std::string &id ) const
+{
+  return enumTable.lookup( id );
+}
+
+UnionDecl *
+Indexer::lookupUnion( const std::string &id ) const
+{
+  return unionTable.lookup( id );
+}
+
+ContextDecl *
+Indexer::lookupContext( const std::string &id ) const
+{
+  return contextTable.lookup( id );
+}
+
+void 
+Indexer::enterScope()
+{
+  if( doDebug ) {
+    std::cout << "--- Entering scope" << std::endl;
+  }
+  idTable.enterScope();
+  typeTable.enterScope();
+  structTable.enterScope();
+  enumTable.enterScope();
+  unionTable.enterScope();
+  contextTable.enterScope();
+}
+
+void 
+Indexer::leaveScope()
+{
+  using std::cout;
+  using std::endl;
+  
+  if( doDebug ) {
+    cout << "--- Leaving scope containing" << endl;
+    idTable.dump( cout );
+    typeTable.dump( cout );
+    structTable.dump( cout );
+    enumTable.dump( cout );
+    unionTable.dump( cout );
+    contextTable.dump( cout );
+  }
+  idTable.leaveScope();
+  typeTable.leaveScope();
+  structTable.leaveScope();
+  enumTable.leaveScope();
+  unionTable.leaveScope();
+  contextTable.leaveScope();
+}
+
+void 
+Indexer::print( std::ostream &os, int indent ) const
+{
+    idTable.dump( os );
+    typeTable.dump( os );
+    structTable.dump( os );
+    enumTable.dump( os );
+    unionTable.dump( os );
+    contextTable.dump( os );
+}
+
+} // namespace SymTab
Index: translator/SymTab/Indexer.h
===================================================================
--- translator/SymTab/Indexer.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/Indexer.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,74 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * A class that indexes the syntax tree.  It is intended to be subclassed by a visitor class
+ * that wants to use the index.
+ *
+ * $Id: Indexer.h,v 1.9 2005/08/29 20:14:18 rcbilson Exp $
+ *
+ */
+
+#ifndef SYMTAB_INDEXER_H
+#define SYMTAB_INDEXER_H
+
+#include <list>
+#include <string>
+#include <map>
+
+#include "SynTree/Visitor.h"
+#include "IdTable.h"
+#include "AggregateTable.h"
+#include "TypeTable.h"
+
+namespace SymTab {
+
+class Indexer : public Visitor
+{
+public:
+  Indexer( bool useDebug = false );
+  virtual ~Indexer();
+
+///   using Visitor::visit;
+  virtual void visit( ObjectDecl *objectDecl );
+  virtual void visit( FunctionDecl *functionDecl );
+  virtual void visit( TypeDecl *typeDecl );
+  virtual void visit( TypedefDecl *typeDecl );
+  virtual void visit( StructDecl *aggregateDecl );
+  virtual void visit( UnionDecl *aggregateDecl );
+  virtual void visit( EnumDecl *aggregateDecl );
+  virtual void visit( ContextDecl *aggregateDecl );
+
+  virtual void visit( CompoundStmt *compoundStmt );
+
+  virtual void visit( ContextInstType *contextInst );
+  virtual void visit( StructInstType *contextInst );
+  virtual void visit( UnionInstType *contextInst );
+  
+  // when using an indexer manually (e.g., within a mutator traversal), it is
+  // necessary to tell the indexer explicitly when scopes begin and end
+  void enterScope();
+  void leaveScope();
+
+  void lookupId( const std::string &id, std::list< DeclarationWithType* >& ) const;
+  NamedTypeDecl *lookupType( const std::string &id ) const;
+  StructDecl *lookupStruct( const std::string &id ) const;
+  EnumDecl *lookupEnum( const std::string &id ) const;
+  UnionDecl *lookupUnion( const std::string &id ) const;
+  ContextDecl *lookupContext( const std::string &id ) const;
+  
+  void print( std::ostream &os, int indent = 0 ) const;
+
+ private:
+  IdTable idTable;
+  TypeTable typeTable;
+  StructTable structTable;
+  EnumTable enumTable;
+  UnionTable unionTable;
+  ContextTable contextTable;
+  
+  bool doDebug;		// display debugging trace
+};
+
+} // namespace SymTab
+
+#endif /* #ifndef SYMTAB_INDEXER_H */
Index: translator/SymTab/Mangler.cc
===================================================================
--- translator/SymTab/Mangler.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/Mangler.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,277 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Mangler.cc,v 1.13 2005/08/29 20:14:18 rcbilson Exp $
+ *
+ */
+
+#include <cassert>
+#include <string>
+#include <algorithm>
+#include <iterator>
+#include <functional>
+#include <set>
+
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+#include "SynTree/Expression.h"
+#include "SynTree/Initializer.h"
+#include "SynTree/Statement.h"
+#include "Mangler.h"
+#include "CodeGen/OperatorTable.h"
+
+namespace SymTab {
+
+Mangler::Mangler()
+  : nextVarNum( 0 ), isTopLevel( true )
+{
+}
+
+//Mangler::Mangler( const Mangler & )
+//  : mangleName(), varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( isTopLevel )
+//{
+//}
+Mangler::Mangler( const Mangler &rhs )
+  : mangleName()
+{
+  varNums = rhs.varNums;
+  nextVarNum = rhs.nextVarNum;
+  isTopLevel = rhs.isTopLevel;
+}
+
+void 
+Mangler::mangleDecl(DeclarationWithType *declaration)
+{
+  bool wasTopLevel = isTopLevel;
+  if( isTopLevel ) {
+    varNums.clear();
+    nextVarNum = 0;
+    isTopLevel = false;
+  }
+  mangleName << "__";
+  CodeGen::OperatorInfo opInfo;
+  if( operatorLookup( declaration->get_name(), opInfo ) ) {
+    mangleName << opInfo.outputName;
+  } else {
+    mangleName << declaration->get_name();
+  }
+  mangleName << "__";
+  maybeAccept( declaration->get_type(), *this );
+  isTopLevel = wasTopLevel;
+}
+
+void 
+Mangler::visit(ObjectDecl *declaration)
+{
+  mangleDecl( declaration );
+}
+
+void 
+Mangler::visit(FunctionDecl *declaration)
+{
+  mangleDecl( declaration );
+}
+
+void 
+Mangler::visit(VoidType *voidType)
+{
+  printQualifiers( voidType );
+  mangleName << "v";
+}
+
+void 
+Mangler::visit(BasicType *basicType)
+{
+  static const char *btLetter[] = {
+    "b",	// Bool
+    "c",	// Char
+    "Sc",	// SignedChar
+    "Uc",	// UnsignedChar
+    "s",	// ShortSignedInt
+    "Us",	// ShortUnsignedInt
+    "i",	// SignedInt
+    "Ui",	// UnsignedInt
+    "l",	// LongSignedInt
+    "Ul",	// LongUnsignedInt
+    "q",	// LongLongSignedInt
+    "Uq",	// LongLongUnsignedInt
+    "f",	// Float
+    "d",	// Double
+    "r",	// LongDouble
+    "Xf",	// FloatComplex
+    "Xd",	// DoubleComplex
+    "Xr",	// LongDoubleComplex
+    "If",	// FloatImaginary
+    "Id",	// DoubleImaginary
+    "Ir",	// LongDoubleImaginary
+  };
+  
+  printQualifiers( basicType );
+  mangleName << btLetter[ basicType->get_kind() ];
+}
+
+void 
+Mangler::visit(PointerType *pointerType)
+{
+  printQualifiers( pointerType );
+  mangleName << "P";
+  maybeAccept( pointerType->get_base(), *this );
+}
+
+void 
+Mangler::visit(ArrayType *arrayType)
+{
+  // TODO: encode dimension
+  printQualifiers( arrayType );
+  mangleName << "A0";
+  maybeAccept( arrayType->get_base(), *this );
+}
+
+namespace {
+  inline std::list< Type* >
+  getTypes( const std::list< DeclarationWithType* > decls )
+  {
+    std::list< Type* > ret;
+    std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
+                    std::mem_fun( &DeclarationWithType::get_type ) );
+    return ret;
+  }
+}
+
+void 
+Mangler::visit(FunctionType *functionType)
+{
+  printQualifiers( functionType );
+  mangleName << "F";
+  std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() );
+  acceptAll( returnTypes, *this );
+  mangleName << "_";
+  std::list< Type* > paramTypes = getTypes( functionType->get_parameters() );
+  acceptAll( paramTypes, *this );
+  mangleName << "_";
+}
+
+void 
+Mangler::mangleRef(ReferenceToType *refType, std::string prefix)
+{
+  printQualifiers( refType );
+  mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name();
+}
+
+void 
+Mangler::visit(StructInstType *aggregateUseType)
+{
+  mangleRef( aggregateUseType, "s" );
+}
+
+void 
+Mangler::visit(UnionInstType *aggregateUseType)
+{
+  mangleRef( aggregateUseType, "u" );
+}
+
+void 
+Mangler::visit(EnumInstType *aggregateUseType)
+{
+  mangleRef( aggregateUseType, "e" );
+}
+
+void 
+Mangler::visit(TypeInstType *typeInst)
+{
+  VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
+  if( varNum == varNums.end() ) {
+    mangleRef( typeInst, "t" );
+  } else {
+    printQualifiers( typeInst );
+    std::ostrstream numStream;
+    numStream << varNum->second.first;
+    mangleName << (numStream.pcount() + 1);
+    switch( (TypeDecl::Kind)varNum->second.second ) {
+    case TypeDecl::Any:
+      mangleName << "t";
+      break;
+    case TypeDecl::Dtype:
+      mangleName << "d";
+      break;
+    case TypeDecl::Ftype:
+      mangleName << "f";
+      break;
+    }
+    mangleName << std::string( numStream.str(), numStream.pcount() );
+  }
+}
+
+void 
+Mangler::visit(TupleType *tupleType)
+{
+  printQualifiers( tupleType );
+  mangleName << "T";
+  acceptAll( tupleType->get_types(), *this );
+  mangleName << "_";
+}
+
+void 
+Mangler::visit(TypeDecl *decl)
+{
+  static const char *typePrefix[] = { "BT", "BD", "BF" };
+  mangleName << typePrefix[ decl->get_kind() ] << ( decl->get_name().length() + 1 ) << decl->get_name();
+}
+
+void
+printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os )
+{
+  for( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
+    os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;
+  }
+}
+
+void 
+Mangler::printQualifiers( Type *type )
+{
+  if( !type->get_forall().empty() ) {
+    std::list< std::string > assertionNames;
+    int tcount = 0, dcount = 0, fcount = 0;
+    mangleName << "A";
+    for( std::list< TypeDecl* >::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
+      switch( (*i)->get_kind() ) {
+      case TypeDecl::Any:
+        tcount++;
+        break;
+      case TypeDecl::Dtype:
+        dcount++;
+        break;
+      case TypeDecl::Ftype:
+        fcount++;
+        break;
+      }
+      varNums[ (*i)->get_name() ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() );
+      for( std::list< DeclarationWithType* >::iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
+        Mangler sub_mangler;
+        sub_mangler.nextVarNum = nextVarNum;
+        sub_mangler.isTopLevel = false;
+        sub_mangler.varNums = varNums;
+        (*assert)->accept( sub_mangler );
+        assertionNames.push_back( std::string( sub_mangler.mangleName.str(), sub_mangler.mangleName.pcount() ) );
+      }
+    }
+    mangleName << tcount << "_" << dcount << "_" << fcount << "_";
+    std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
+    mangleName << "_";
+  }
+  if( type->get_isConst() ) {
+    mangleName << "C";
+  }
+  if( type->get_isVolatile() ) {
+    mangleName << "V";
+  }
+  if( type->get_isRestrict() ) {
+    mangleName << "R";
+  }
+  if( type->get_isLvalue() ) {
+    mangleName << "L";
+  }
+}
+
+
+} // namespace SymTab
Index: translator/SymTab/Mangler.h
===================================================================
--- translator/SymTab/Mangler.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/Mangler.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,69 @@
+/*
+ * 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 */
Index: translator/SymTab/StackTable.cc
===================================================================
--- translator/SymTab/StackTable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/StackTable.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,87 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: StackTable.cc,v 1.3 2002/09/19 21:02:44 rcbilson Exp $
+ *
+ */
+ 
+#include <cassert>
+
+#include "StackTable.h"
+
+namespace SymTab {
+
+template< typename Element, typename ConflictFunction >
+StackTable< Element, ConflictFunction >::StackTable()
+  : scopeLevel( 0 )
+{
+}
+
+template< typename Element, typename ConflictFunction >
+void 
+StackTable< Element, ConflictFunction >::enterScope()
+{
+  scopeLevel++;
+}
+
+template< typename Element, typename ConflictFunction >
+void 
+StackTable< Element, ConflictFunction >::leaveScope()
+{
+  for( typename TableType::iterator it = table.begin(); it != table.end(); ++it ) {
+    std::stack< Entry >& entry = it->second;
+    if( !entry.empty() && entry.top().second == scopeLevel ) {
+      entry.pop();
+    }
+  }
+      
+  scopeLevel--;
+  assert( scopeLevel >= 0 );
+}
+
+template< typename Element, typename ConflictFunction >
+void 
+StackTable< Element, ConflictFunction >::add( Element *type )
+{
+  std::stack< Entry >& entry = table[ type->get_name() ];
+  if( !entry.empty() && entry.top().second == scopeLevel ) {
+    entry.top().first = conflictFunction( entry.top().first, type );
+  } else {
+    entry.push( Entry( type, scopeLevel ) );
+  }
+}
+
+template< typename Element, typename ConflictFunction >
+void 
+StackTable< Element, ConflictFunction >::add( std::string fwdDeclName )
+{
+  add( new Element( fwdDeclName ) );
+}
+
+template< typename Element, typename ConflictFunction >
+Element *
+StackTable< Element, ConflictFunction >::lookup( std::string id ) const
+{
+  typename TableType::const_iterator it = table.find( id );
+  if( it == table.end() ) {
+    return 0;
+  } else if( !it->second.empty() ) {
+    return it->second.top().first;
+  } else {
+    return 0;
+  }
+}
+
+template< typename Element, typename ConflictFunction >
+void 
+StackTable< Element, ConflictFunction >::dump( std::ostream &os ) const
+{
+  for( typename TableType::const_iterator it = table.begin(); it != table.end(); ++it ) {
+    const std::stack< Entry >& entry = it->second;
+    if( !entry.empty() && entry.top().second == scopeLevel ) {
+      os << it->first << std::endl;
+    }
+  }
+}
+
+} // namespace SymTab
Index: translator/SymTab/StackTable.h
===================================================================
--- translator/SymTab/StackTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/StackTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: StackTable.h,v 1.2 2002/09/19 21:02:44 rcbilson Exp $
+ *
+ */
+
+#ifndef SYMTAB_STACKTABLE_H
+#define SYMTAB_STACKTABLE_H
+
+#include <map>
+#include <stack>
+#include <string>
+#include <functional>
+
+namespace SymTab {
+
+template< typename Element, typename ConflictFunction >
+class StackTable
+{
+public:
+  StackTable();
+
+  void enterScope();
+  void leaveScope();
+  void add( Element *type );
+  void add( std::string fwdDeclName );
+  Element *lookup( std::string id ) const;
+
+  void dump( std::ostream &os ) const; // debugging
+  
+private:
+  typedef std::pair< Element*, int > Entry;
+  typedef std::map< std::string, std::stack< Entry > > TableType;
+  
+  ConflictFunction conflictFunction;
+  TableType table;
+  int scopeLevel;
+};
+
+} // namespace SymTab
+
+#include "StackTable.cc"
+
+#endif /* #ifndef SYMTAB_STACKTABLE_H */
Index: translator/SymTab/TypeTable.h
===================================================================
--- translator/SymTab/TypeTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/TypeTable.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,44 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: TypeTable.h,v 1.2 2005/08/29 20:14:18 rcbilson Exp $
+ *
+ */
+
+#ifndef SYMTAB_TYPETABLE_H
+#define SYMTAB_TYPETABLE_H
+
+#include <cassert>
+#include <map>
+#include <stack>
+#include <string>
+#include <functional>
+
+#include "StackTable.h"
+#include "SynTree/Declaration.h"
+
+namespace SymTab {
+
+class TypeTableConflictFunction : public std::binary_function< NamedTypeDecl*, NamedTypeDecl*, NamedTypeDecl* >
+{
+public:
+  NamedTypeDecl *operator()( NamedTypeDecl *existing, NamedTypeDecl *added )
+  {
+    if( existing->get_base() == 0 ) {
+      return added;
+    } else if( added->get_base() == 0 ) {
+      return existing;
+    } else {
+      throw SemanticError( "redeclaration of ", added );
+    }
+    assert( false );
+    return 0;
+  }
+  
+};
+
+typedef StackTable< NamedTypeDecl, TypeTableConflictFunction > TypeTable;
+
+} // namespace SymTab
+
+#endif /* #ifndef SYMTAB_TYPETABLE_H */
Index: translator/SymTab/Validate.cc
===================================================================
--- translator/SymTab/Validate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/Validate.cc	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,907 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * $Id: Validate.cc,v 1.22 2005/08/29 20:14:18 rcbilson Exp $
+ *
+ */
+
+/*
+   The "validate" phase of translation is used to take a syntax tree and convert it into a
+   standard form that aims to be as regular in structure as possible.  Some assumptions can be
+   made regarding the state of the tree after this pass is complete, including:
+
+   - No nested structure or union definitions; any in the input are "hoisted" to the level of
+     the containing struct or union.
+
+   - All enumeration constants have type EnumInstType.
+
+   - The type "void" never occurs in lists of function parameter or return types; neither do
+     tuple types.  A function taking no arguments has no argument types, and tuples are flattened.
+
+   - No context instances exist; they are all replaced by the set of declarations signified by
+     the context, instantiated by the particular set of type arguments.
+
+   - Every declaration is assigned a unique id.
+
+   - No typedef declarations or instances exist; the actual type is substituted for each instance.
+
+   - Each type, struct, and union definition is followed by an appropriate assignment operator.
+
+   - Each use of a struct or union is connected to a complete definition of that struct or union,
+     even if that definition occurs later in the input.
+*/
+
+#include <list>
+#include <iterator>
+#include "Validate.h"
+#include "SynTree/Visitor.h"
+#include "SynTree/Mutator.h"
+#include "SynTree/Type.h"
+#include "SynTree/Statement.h"
+#include "Indexer.h"
+#include "SynTree/TypeSubstitution.h"
+#include "FixFunction.h"
+#include "ImplementationType.h"
+#include "utility.h"
+#include "UniqueName.h"
+#include "AddVisit.h"
+
+
+#define debugPrint(x) if( doDebug ) { std::cout << x; }
+
+namespace SymTab {
+
+class HoistStruct : public Visitor
+{
+public:
+  static void hoistStruct( std::list< Declaration* > &translationUnit );
+  
+  std::list< Declaration* > &get_declsToAdd() { return declsToAdd; }
+  
+  virtual void visit(StructDecl *aggregateDecl);
+  virtual void visit(UnionDecl *aggregateDecl);
+
+  virtual void visit(CompoundStmt *compoundStmt);
+  virtual void visit(IfStmt *ifStmt);
+  virtual void visit(WhileStmt *whileStmt);
+  virtual void visit(ForStmt *forStmt);
+  virtual void visit(SwitchStmt *switchStmt);
+  virtual void visit(ChooseStmt *chooseStmt);
+  virtual void visit(CaseStmt *caseStmt);
+  virtual void visit(CatchStmt *catchStmt);
+  
+private:
+  HoistStruct();
+
+  template< typename AggDecl > void handleAggregate( AggDecl *aggregateDecl );
+
+  std::list< Declaration* > declsToAdd;
+  bool inStruct;
+};
+
+class Pass1 : public Visitor
+{
+  typedef Visitor Parent;
+  virtual void visit( EnumDecl *aggregateDecl);
+  virtual void visit( FunctionType *func );
+};
+  
+class Pass2 : public Indexer
+{
+  typedef Indexer Parent;
+
+public:
+  Pass2( bool doDebug, const Indexer *indexer );
+
+private:
+  virtual void visit( StructInstType *structInst );
+  virtual void visit( UnionInstType *unionInst );
+  virtual void visit( ContextInstType *contextInst );
+  virtual void visit( StructDecl *structDecl );
+  virtual void visit( UnionDecl *unionDecl );
+  virtual void visit( TypeInstType *typeInst );
+
+  const Indexer *indexer;
+  
+  typedef std::map< std::string, std::list< StructInstType* > > ForwardStructsType;
+  typedef std::map< std::string, std::list< UnionInstType* > > ForwardUnionsType;
+  ForwardStructsType forwardStructs;
+  ForwardUnionsType forwardUnions;
+};
+
+class Pass3 : public Indexer
+{
+  typedef Indexer Parent;
+
+public:
+  Pass3( const Indexer *indexer );
+
+private:
+  virtual void visit( ObjectDecl *object );
+  virtual void visit( FunctionDecl *func );
+
+  const Indexer *indexer;
+};
+
+class AddStructAssignment : public Visitor
+{
+public:
+  static void addStructAssignment( std::list< Declaration* > &translationUnit );
+
+  std::list< Declaration* > &get_declsToAdd() { return declsToAdd; }
+  
+  virtual void visit( StructDecl *structDecl );
+  virtual void visit( UnionDecl *structDecl );
+  virtual void visit( TypeDecl *typeDecl );
+  virtual void visit( ContextDecl *ctxDecl );
+
+  virtual void visit( FunctionType *ftype );
+  virtual void visit( PointerType *ftype );
+  
+  virtual void visit(CompoundStmt *compoundStmt);
+  virtual void visit(IfStmt *ifStmt);
+  virtual void visit(WhileStmt *whileStmt);
+  virtual void visit(ForStmt *forStmt);
+  virtual void visit(SwitchStmt *switchStmt);
+  virtual void visit(ChooseStmt *chooseStmt);
+  virtual void visit(CaseStmt *caseStmt);
+  virtual void visit(CatchStmt *catchStmt);
+  
+private:
+  template< typename StmtClass > void visitStatement(StmtClass *stmt);
+  
+  std::list< Declaration* > declsToAdd;
+  std::set< std::string > structsDone;
+};
+
+class EliminateTypedef : public Mutator
+{
+public:
+  static void eliminateTypedef( std::list< Declaration* > &translationUnit );
+  
+private:
+  virtual Declaration* mutate(TypedefDecl *typeDecl);
+  virtual TypeDecl* mutate(TypeDecl *typeDecl);
+  virtual DeclarationWithType* mutate(FunctionDecl *funcDecl);
+  virtual ObjectDecl* mutate(ObjectDecl *objDecl);
+  virtual CompoundStmt* mutate(CompoundStmt *compoundStmt);
+  virtual Type* mutate(TypeInstType *aggregateUseType);
+  virtual Expression* mutate(CastExpr *castExpr);
+  
+  std::map< std::string, TypedefDecl* > typedefNames;
+};
+
+void 
+validate( std::list< Declaration* > &translationUnit, bool doDebug, const Indexer *indexer )
+{
+  Pass1 pass1;
+  Pass2 pass2( doDebug, indexer );
+  Pass3 pass3( indexer );
+  EliminateTypedef::eliminateTypedef( translationUnit );
+  HoistStruct::hoistStruct( translationUnit );
+  acceptAll( translationUnit, pass1 );
+  acceptAll( translationUnit, pass2 );
+  AddStructAssignment::addStructAssignment( translationUnit );
+  acceptAll( translationUnit, pass3 );
+}
+
+void
+validateType( Type *type, const Indexer *indexer )
+{
+  Pass1 pass1;
+  Pass2 pass2( false, indexer );
+  Pass3 pass3( indexer );
+  type->accept( pass1 );
+  type->accept( pass2 );
+  type->accept( pass3 );
+}
+
+template< typename Visitor >
+void
+acceptAndAdd( std::list< Declaration* > &translationUnit, Visitor &visitor, bool addBefore )
+{
+  std::list< Declaration* >::iterator i = translationUnit.begin();
+  while( i != translationUnit.end() ) {
+    (*i)->accept( visitor );
+    std::list< Declaration* >::iterator next = i;
+    next++;
+    if( !visitor.get_declsToAdd().empty() ) {
+      translationUnit.splice( addBefore ? i : next, visitor.get_declsToAdd() );
+    }
+    i = next;
+  }
+}
+
+/* static class method */
+void 
+HoistStruct::hoistStruct( std::list< Declaration* > &translationUnit )
+{
+  HoistStruct hoister;
+  acceptAndAdd( translationUnit, hoister, true );
+}
+
+HoistStruct::HoistStruct()
+  : inStruct( false )
+{
+}
+
+void
+filter( std::list< Declaration* > &declList, bool (*pred)( Declaration* ), bool doDelete )
+{
+  std::list< Declaration* >::iterator i = declList.begin();
+  while( i != declList.end() ) {
+    std::list< Declaration* >::iterator next = i;
+    ++next;
+    if( pred( *i ) ) {
+      if( doDelete ) {
+        delete *i;
+      }
+      declList.erase( i );
+    }
+    i = next;
+  }
+}
+
+bool
+isStructOrUnion( Declaration *decl )
+{
+  return dynamic_cast< StructDecl* >( decl ) || dynamic_cast< UnionDecl* >( decl );
+}
+
+template< typename AggDecl >
+void
+HoistStruct::handleAggregate( AggDecl *aggregateDecl )
+{
+  if( inStruct ) {
+    declsToAdd.push_back( aggregateDecl );
+    Visitor::visit( aggregateDecl );
+  } else {
+    inStruct = true;
+    Visitor::visit( aggregateDecl );
+    inStruct = false;
+    filter( aggregateDecl->get_members(), isStructOrUnion, false );
+  }
+}
+
+void 
+HoistStruct::visit(StructDecl *aggregateDecl)
+{
+  handleAggregate( aggregateDecl );
+}
+
+void 
+HoistStruct::visit(UnionDecl *aggregateDecl)
+{
+  handleAggregate( aggregateDecl );
+}
+
+void
+HoistStruct::visit(CompoundStmt *compoundStmt)
+{
+  addVisit( compoundStmt, *this );
+}
+
+void
+HoistStruct::visit(IfStmt *ifStmt)
+{
+  addVisit( ifStmt, *this );
+}
+
+void
+HoistStruct::visit(WhileStmt *whileStmt)
+{
+  addVisit( whileStmt, *this );
+}
+
+void
+HoistStruct::visit(ForStmt *forStmt)
+{
+  addVisit( forStmt, *this );
+}
+
+void
+HoistStruct::visit(SwitchStmt *switchStmt)
+{
+  addVisit( switchStmt, *this );
+}
+
+void
+HoistStruct::visit(ChooseStmt *switchStmt)
+{
+  addVisit( switchStmt, *this );
+}
+
+void
+HoistStruct::visit(CaseStmt *caseStmt)
+{
+  addVisit( caseStmt, *this );
+}
+
+void
+HoistStruct::visit(CatchStmt *cathStmt)
+{
+  addVisit( cathStmt, *this );
+}
+
+void 
+Pass1::visit( EnumDecl *enumDecl)
+{
+  // Set the type of each member of the enumeration to be EnumConstant
+  
+  for( std::list< Declaration* >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
+    ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
+    assert( obj );
+    obj->set_type( new EnumInstType( Type::Qualifiers( true, false, false, false ), enumDecl->get_name() ) );
+  }
+  Parent::visit( enumDecl );
+}
+
+namespace {
+template< typename DWTIterator >
+void
+fixFunctionList( DWTIterator begin, DWTIterator end, FunctionType *func )
+{
+  // the only case in which "void" is valid is where it is the only one in the list; then
+  // it should be removed entirely
+  // other fix ups are handled by the FixFunction class
+  if( begin == end ) return;
+  FixFunction fixer;
+  DWTIterator i = begin;
+  *i = (*i)->acceptMutator( fixer );
+  if( fixer.get_isVoid() ) {
+    DWTIterator j = i;
+    ++i;
+    func->get_parameters().erase( j );
+    if( i != end ) { 
+      throw SemanticError( "invalid type void in function type ", func );
+    }
+  } else {
+    ++i;
+    for( ; i != end; ++i ) {
+      FixFunction fixer;
+      *i = (*i)->acceptMutator( fixer );
+      if( fixer.get_isVoid() ) {
+        throw SemanticError( "invalid type void in function type ", func );
+      }
+    }
+  }
+}
+}
+
+void 
+Pass1::visit( FunctionType *func )
+{
+  // Fix up parameters and return types
+  fixFunctionList( func->get_parameters().begin(), func->get_parameters().end(), func );
+  fixFunctionList( func->get_returnVals().begin(), func->get_returnVals().end(), func );
+  Visitor::visit( func );
+}
+
+Pass2::Pass2( bool doDebug, const Indexer *other_indexer )
+  : Indexer( doDebug )
+{
+  if( other_indexer ) {
+    indexer = other_indexer;
+  } else {
+    indexer = this;
+  }
+}
+
+void 
+Pass2::visit( StructInstType *structInst )
+{
+  Parent::visit( structInst );
+  StructDecl *st = indexer->lookupStruct( structInst->get_name() );
+  // it's not a semantic error if the struct is not found, just an implicit forward declaration
+  if( st ) {
+    assert( !structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || !st->get_members().empty() );
+    structInst->set_baseStruct( st );
+  }
+  if( !st || st->get_members().empty() ) {
+    // use of forward declaration
+    forwardStructs[ structInst->get_name() ].push_back( structInst );
+  }
+}
+
+void 
+Pass2::visit( UnionInstType *unionInst )
+{
+  Parent::visit( unionInst );
+  UnionDecl *un = indexer->lookupUnion( unionInst->get_name() );
+  // it's not a semantic error if the union is not found, just an implicit forward declaration
+  if( un ) {
+    unionInst->set_baseUnion( un );
+  }
+  if( !un || un->get_members().empty() ) {
+    // use of forward declaration
+    forwardUnions[ unionInst->get_name() ].push_back( unionInst );
+  }
+}
+
+void 
+Pass2::visit( ContextInstType *contextInst )
+{
+  Parent::visit( contextInst );
+  ContextDecl *ctx = indexer->lookupContext( contextInst->get_name() );
+  if( !ctx ) {
+    throw SemanticError( "use of undeclared context " + contextInst->get_name() );
+  }
+  for( std::list< TypeDecl* >::const_iterator i = ctx->get_parameters().begin(); i != ctx->get_parameters().end(); ++i ) {
+    for( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
+      if( ContextInstType *otherCtx = dynamic_cast< ContextInstType* >(*assert) ) {
+        cloneAll( otherCtx->get_members(), contextInst->get_members() );
+      } else {
+        contextInst->get_members().push_back( (*assert)->clone() );
+      }
+    }
+  }
+  applySubstitution( ctx->get_parameters().begin(), ctx->get_parameters().end(), contextInst->get_parameters().begin(), ctx->get_members().begin(), ctx->get_members().end(), back_inserter( contextInst->get_members() ) );
+}
+
+void 
+Pass2::visit( StructDecl *structDecl )
+{
+  if( !structDecl->get_members().empty() ) {
+    ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->get_name() );
+    if( fwds != forwardStructs.end() ) {
+      for( std::list< StructInstType* >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
+        (*inst)->set_baseStruct( structDecl );
+      }
+      forwardStructs.erase( fwds );
+    }
+  }
+  Indexer::visit( structDecl );
+}
+
+void 
+Pass2::visit( UnionDecl *unionDecl )
+{
+  if( !unionDecl->get_members().empty() ) {
+    ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->get_name() );
+    if( fwds != forwardUnions.end() ) {
+      for( std::list< UnionInstType* >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
+        (*inst)->set_baseUnion( unionDecl );
+      }
+      forwardUnions.erase( fwds );
+    }
+  }
+  Indexer::visit( unionDecl );
+}
+
+void 
+Pass2::visit( TypeInstType *typeInst )
+{
+  if( NamedTypeDecl *namedTypeDecl = lookupType( typeInst->get_name() ) ) {
+    if( TypeDecl *typeDecl = dynamic_cast< TypeDecl* >( namedTypeDecl ) ) {
+      typeInst->set_isFtype( typeDecl->get_kind() == TypeDecl::Ftype );
+    }
+  }
+}
+
+Pass3::Pass3( const Indexer *other_indexer )
+  : Indexer( false )
+{
+  if( other_indexer ) {
+    indexer = other_indexer;
+  } else {
+    indexer = this;
+  }
+}
+
+void 
+forallFixer( Type *func )
+{
+  // Fix up assertions
+  for( std::list< TypeDecl* >::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) {
+    std::list< DeclarationWithType* > toBeDone, nextRound;
+    toBeDone.splice( toBeDone.end(), (*type)->get_assertions() );
+    while( !toBeDone.empty() ) {
+      for( std::list< DeclarationWithType* >::iterator assertion = toBeDone.begin(); assertion != toBeDone.end(); ++assertion ) {
+        if( ContextInstType *ctx = dynamic_cast< ContextInstType* >( (*assertion)->get_type() ) ) {
+          for( std::list< Declaration* >::const_iterator i = ctx->get_members().begin(); i != ctx->get_members().end(); ++i ) {
+            DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i );
+            assert( dwt );
+            nextRound.push_back( dwt->clone() );
+          }
+          delete ctx;
+        } else {
+          FixFunction fixer;
+          *assertion = (*assertion)->acceptMutator( fixer );
+          if( fixer.get_isVoid() ) {
+            throw SemanticError( "invalid type void in assertion of function ", func );
+          }
+          (*type)->get_assertions().push_back( *assertion );
+        }
+      }
+      toBeDone.clear();
+      toBeDone.splice( toBeDone.end(), nextRound );
+    }
+  }
+}
+
+void 
+Pass3::visit( ObjectDecl *object )
+{
+  forallFixer( object->get_type() );
+  if( PointerType *pointer = dynamic_cast< PointerType* >( object->get_type() ) ) {
+    forallFixer( pointer->get_base() );
+  }
+  Parent::visit( object );
+  object->fixUniqueId();
+}
+
+void 
+Pass3::visit( FunctionDecl *func )
+{
+  forallFixer( func->get_type() );
+  Parent::visit( func );
+  func->fixUniqueId();
+}
+
+static const std::list< std::string > noLabels;
+
+/* static class method */
+void
+AddStructAssignment::addStructAssignment( std::list< Declaration* > &translationUnit )
+{
+  AddStructAssignment visitor;
+  acceptAndAdd( translationUnit, visitor, false );
+}
+
+template< typename OutputIterator >
+void
+makeScalarAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, OutputIterator out )
+{
+  UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
+  
+  UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
+  derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
+  
+  // do something special for unnamed members
+  Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
+  assignExpr->get_args().push_back( dstselect );
+  
+  Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
+  assignExpr->get_args().push_back( srcselect );
+  
+  *out++ = new ExprStmt( noLabels, assignExpr );
+}
+
+template< typename OutputIterator >
+void
+makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out )
+{
+  static UniqueName indexName( "_index" );
+  
+  // for a flexible array member nothing is done -- user must define own assignment
+  if( !array->get_dimension() ) return;
+  
+  ObjectDecl *index = new ObjectDecl( indexName.newName(), Declaration::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 );
+  *out++ = new DeclStmt( noLabels, index );
+  
+  UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
+  init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
+  init->get_args().push_back( new NameExpr( "0" ) );
+  Statement *initStmt = new ExprStmt( noLabels, init );
+  
+  UntypedExpr *cond = new UntypedExpr( new NameExpr( "?<?" ) );
+  cond->get_args().push_back( new VariableExpr( index ) );
+  cond->get_args().push_back( array->get_dimension()->clone() );
+  
+  UntypedExpr *inc = new UntypedExpr( new NameExpr( "++?" ) );
+  inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
+  
+  UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
+  
+  UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
+  derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
+  
+  Expression *dstselect = new MemberExpr( member, derefExpr );
+  UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) );
+  dstIndex->get_args().push_back( dstselect );
+  dstIndex->get_args().push_back( new VariableExpr( index ) );
+  assignExpr->get_args().push_back( dstIndex );
+  
+  Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
+  UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
+  srcIndex->get_args().push_back( srcselect );
+  srcIndex->get_args().push_back( new VariableExpr( index ) );
+  assignExpr->get_args().push_back( srcIndex );
+  
+  *out++ = new ForStmt( noLabels, initStmt, cond, inc, new ExprStmt( noLabels, assignExpr ) );
+}
+
+Declaration*
+makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType )
+{
+  FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
+  
+  ObjectDecl *returnVal = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
+  assignType->get_returnVals().push_back( returnVal );
+  
+  ObjectDecl *dstParam = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
+  assignType->get_parameters().push_back( dstParam );
+  
+  ObjectDecl *srcParam = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
+  assignType->get_parameters().push_back( srcParam );
+  
+  FunctionDecl *assignDecl = new FunctionDecl( "?=?", Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true );
+  assignDecl->fixUniqueId();
+  
+  for( std::list< Declaration* >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
+    if( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *member ) ) {
+      if( ArrayType *array = dynamic_cast< ArrayType* >( dwt->get_type() ) ) {
+        makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
+      } else {
+        makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
+      }
+    }
+  }
+  assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
+  
+  return assignDecl;
+}
+
+Declaration*
+makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType )
+{
+  FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
+  
+  ObjectDecl *returnVal = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
+  assignType->get_returnVals().push_back( returnVal );
+  
+  ObjectDecl *dstParam = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
+  assignType->get_parameters().push_back( dstParam );
+  
+  ObjectDecl *srcParam = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
+  assignType->get_parameters().push_back( srcParam );
+  
+  FunctionDecl *assignDecl = new FunctionDecl( "?=?", Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true );
+  assignDecl->fixUniqueId();
+  
+  UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
+  copy->get_args().push_back( new VariableExpr( dstParam ) );
+  copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
+  copy->get_args().push_back( new SizeofExpr( refType->clone() ) );
+
+  assignDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, copy ) );
+  assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
+  
+  return assignDecl;
+}
+
+void
+AddStructAssignment::visit( StructDecl *structDecl )
+{
+  if( !structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
+    StructInstType *structInst = new StructInstType( Type::Qualifiers(), structDecl->get_name() );
+    structInst->set_baseStruct( structDecl );
+    declsToAdd.push_back( makeStructAssignment( structDecl, structInst ) );
+    structsDone.insert( structDecl->get_name() );
+  }
+}
+
+void
+AddStructAssignment::visit( UnionDecl *unionDecl )
+{
+  if( !unionDecl->get_members().empty() ) {
+    UnionInstType *unionInst = new UnionInstType( Type::Qualifiers(), unionDecl->get_name() );
+    unionInst->set_baseUnion( unionDecl );
+    declsToAdd.push_back( makeUnionAssignment( unionDecl, unionInst ) );
+  }
+}
+
+void
+AddStructAssignment::visit( TypeDecl *typeDecl )
+{
+  CompoundStmt *stmts = 0;
+  TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false );
+  typeInst->set_baseType( typeDecl );
+  ObjectDecl *src = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, typeInst->clone(), 0 );
+  ObjectDecl *dst = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), typeInst->clone() ), 0 );
+  if( typeDecl->get_base() ) {
+    stmts = new CompoundStmt( std::list< Label >() );
+    UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
+    assign->get_args().push_back( new CastExpr( new VariableExpr( dst ), new PointerType( Type::Qualifiers(), typeDecl->get_base()->clone() ) ) );
+    assign->get_args().push_back( new CastExpr( new VariableExpr( src ), typeDecl->get_base()->clone() ) );
+    stmts->get_kids().push_back( new ReturnStmt( std::list< Label >(), assign ) );
+  }
+  FunctionType *type = new FunctionType( Type::Qualifiers(), false );
+  type->get_returnVals().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, typeInst, 0 ) );
+  type->get_parameters().push_back( dst );
+  type->get_parameters().push_back( src );
+  FunctionDecl *func = new FunctionDecl( "?=?", Declaration::NoStorageClass, LinkageSpec::AutoGen, type, stmts, false );
+  declsToAdd.push_back( func );
+}
+
+void
+addDecls( std::list< Declaration* > &declsToAdd, std::list< Statement* > &statements, std::list< Statement* >::iterator i )
+{
+  if( !declsToAdd.empty() ) {
+    for( std::list< Declaration* >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) {
+      statements.insert( i, new DeclStmt( noLabels, *decl ) );
+    }
+    declsToAdd.clear();
+  }
+}
+
+void
+AddStructAssignment::visit(FunctionType *)
+{
+  // ensure that we don't add assignment ops for types defined
+  // as part of the function
+}
+
+void
+AddStructAssignment::visit(PointerType *)
+{
+  // ensure that we don't add assignment ops for types defined
+  // as part of the pointer
+}
+
+void
+AddStructAssignment::visit(ContextDecl *)
+{
+  // ensure that we don't add assignment ops for types defined
+  // as part of the context
+}
+
+template< typename StmtClass >
+inline void
+AddStructAssignment::visitStatement(StmtClass *stmt)
+{
+  std::set< std::string > oldStructs = structsDone;
+  addVisit( stmt, *this );
+  structsDone = oldStructs;
+}
+
+void
+AddStructAssignment::visit(CompoundStmt *compoundStmt)
+{
+  visitStatement( compoundStmt );
+}
+
+void
+AddStructAssignment::visit(IfStmt *ifStmt)
+{
+  visitStatement( ifStmt );
+}
+
+void
+AddStructAssignment::visit(WhileStmt *whileStmt)
+{
+  visitStatement( whileStmt );
+}
+
+void
+AddStructAssignment::visit(ForStmt *forStmt)
+{
+  visitStatement( forStmt );
+}
+
+void
+AddStructAssignment::visit(SwitchStmt *switchStmt)
+{
+  visitStatement( switchStmt );
+}
+
+void
+AddStructAssignment::visit(ChooseStmt *switchStmt)
+{
+  visitStatement( switchStmt );
+}
+
+void
+AddStructAssignment::visit(CaseStmt *caseStmt)
+{
+  visitStatement( caseStmt );
+}
+
+void
+AddStructAssignment::visit(CatchStmt *cathStmt)
+{
+  visitStatement( cathStmt );
+}
+
+bool
+isTypedef( Declaration *decl )
+{
+  return dynamic_cast< TypedefDecl* >( decl );
+}
+
+
+/* static class method */
+void 
+EliminateTypedef::eliminateTypedef( std::list< Declaration* > &translationUnit )
+{
+  EliminateTypedef eliminator;
+  mutateAll( translationUnit, eliminator );
+  filter( translationUnit, isTypedef, true );
+}
+
+Type*
+EliminateTypedef::mutate( TypeInstType *typeInst )
+{
+  std::map< std::string, TypedefDecl* >::const_iterator def = typedefNames.find( typeInst->get_name() );
+  if( def != typedefNames.end() ) {
+    Type *ret = def->second->get_base()->clone();
+    ret->get_qualifiers() += typeInst->get_qualifiers();
+    delete typeInst;
+    return ret;
+  }
+  return typeInst;
+}
+
+Declaration*
+EliminateTypedef::mutate( TypedefDecl *tyDecl )
+{
+  Declaration *ret = Mutator::mutate( tyDecl );
+  typedefNames[ tyDecl->get_name() ] = tyDecl;
+  if( AggregateDecl *aggDecl = dynamic_cast< AggregateDecl* >( tyDecl->get_base() ) ) {
+    tyDecl->set_base( 0 );
+    delete tyDecl;
+    return aggDecl;
+  } else {
+    return ret;
+  }
+}
+
+TypeDecl*
+EliminateTypedef::mutate(TypeDecl *typeDecl)
+{
+  std::map< std::string, TypedefDecl* >::iterator i = typedefNames.find( typeDecl->get_name() );
+  if( i != typedefNames.end() ) {
+    typedefNames.erase( i ) ;
+  }
+  return typeDecl;
+}
+
+DeclarationWithType*
+EliminateTypedef::mutate(FunctionDecl *funcDecl)
+{
+  std::map< std::string, TypedefDecl* > oldNames = typedefNames;
+  DeclarationWithType *ret = Mutator::mutate( funcDecl );
+  typedefNames = oldNames;
+  return ret;
+}
+
+ObjectDecl*
+EliminateTypedef::mutate(ObjectDecl *objDecl)
+{
+  std::map< std::string, TypedefDecl* > oldNames = typedefNames;
+  ObjectDecl *ret = Mutator::mutate( objDecl );
+  typedefNames = oldNames;
+  return ret;
+}
+
+Expression*
+EliminateTypedef::mutate(CastExpr *castExpr)
+{
+  std::map< std::string, TypedefDecl* > oldNames = typedefNames;
+  Expression *ret = Mutator::mutate( castExpr );
+  typedefNames = oldNames;
+  return ret;
+}
+
+CompoundStmt * 
+EliminateTypedef::mutate( CompoundStmt *compoundStmt )
+{
+  std::map< std::string, TypedefDecl* > oldNames = typedefNames;
+  CompoundStmt *ret = Mutator::mutate( compoundStmt );
+  std::list< Statement* >::iterator i = compoundStmt->get_kids().begin();
+  while( i != compoundStmt->get_kids().end() ) {
+    std::list< Statement* >::iterator next = i;
+    ++next;
+    if( DeclStmt *declStmt = dynamic_cast< DeclStmt* >( *i ) ) {
+      if( dynamic_cast< TypedefDecl* >( declStmt->get_decl() ) ) {
+        delete *i;
+        compoundStmt->get_kids().erase( i );
+      }
+    }
+    i = next;
+  }
+  typedefNames = oldNames;
+  return ret;
+}
+
+} // namespace SymTab
Index: translator/SymTab/Validate.h
===================================================================
--- translator/SymTab/Validate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/Validate.h	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the Cforall project
+ *
+ * This class is intended to perform pre-processing of declarations, validating their
+ * correctness and computing some auxilliary data that is necessary for the indexer.
+ *
+ * $Id: Validate.h,v 1.7 2005/08/29 20:14:18 rcbilson Exp $
+ *
+ */
+
+#ifndef SYMTAB_VALIDATE_H
+#define SYMTAB_VALIDATE_H
+
+#include "SynTree/SynTree.h"
+
+namespace SymTab {
+
+class Indexer;
+
+void validate( std::list< Declaration* > &translationUnit, bool doDebug = false,
+               const Indexer *indexer = 0 );
+
+void validateType( Type *type, const Indexer *indexer );
+
+} // namespace SymTab
+
+#endif /* #ifndef SYMTAB_VALIDATE_H */
Index: translator/SymTab/module.mk
===================================================================
--- translator/SymTab/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
+++ translator/SymTab/module.mk	(revision 51b734528489f81a5af985bfee9aa3b6625b9774)
@@ -0,0 +1,7 @@
+SRC += SymTab/IdTable.cc \
+       SymTab/Indexer.cc \
+       SymTab/Mangler.cc \
+       SymTab/Validate.cc \
+       SymTab/FixFunction.cc \
+       SymTab/ImplementationType.cc
+
