Index: translator/SymTab/TypeTable.h
===================================================================
--- translator/SymTab/TypeTable.h	(revision 1db2c5be186b17e66fbf9cdd4a6bffc6987810de)
+++ translator/SymTab/TypeTable.h	(revision 3c70d383ff7630d9cdc9dd98340ba26c715dfeaa)
@@ -1,9 +1,2 @@
-/*
- * 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
@@ -19,26 +12,21 @@
 
 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;
+	}
+    };
 
-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;
+} // SymTab
 
-typedef StackTable< NamedTypeDecl, TypeTableConflictFunction > TypeTable;
-
-} // namespace SymTab
-
-#endif /* #ifndef SYMTAB_TYPETABLE_H */
+#endif // SYMTAB_TYPETABLE_H
Index: translator/SymTab/Validate.cc
===================================================================
--- translator/SymTab/Validate.cc	(revision 1db2c5be186b17e66fbf9cdd4a6bffc6987810de)
+++ translator/SymTab/Validate.cc	(revision 3c70d383ff7630d9cdc9dd98340ba26c715dfeaa)
@@ -117,4 +117,5 @@
 	virtual void visit( TypeDecl *typeDecl );
 	virtual void visit( ContextDecl *ctxDecl );
+	virtual void visit( FunctionDecl *functionDecl );
 
 	virtual void visit( FunctionType *ftype );
@@ -129,4 +130,6 @@
 	virtual void visit( CaseStmt *caseStmt );
 	virtual void visit( CatchStmt *catchStmt );
+
+	AddStructAssignment() : functionNesting( 0 ) {}
       private:
 	template< typename StmtClass > void visitStatement( StmtClass *stmt );
@@ -134,4 +137,5 @@
 	std::list< Declaration * > declsToAdd;
 	std::set< std::string > structsDone;
+	unsigned int functionNesting;			// current level of nested functions
     };
 
@@ -194,5 +198,5 @@
     }
 
-    void filter( std::list< Declaration * > &declList, bool (*pred )( Declaration * ), bool doDelete ) {
+    void filter( std::list< Declaration * > &declList, bool (*pred)( Declaration * ), bool doDelete ) {
 	std::list< Declaration * >::iterator i = declList.begin();
 	while ( i != declList.end() ) {
@@ -216,5 +220,6 @@
     void HoistStruct::handleAggregate( AggDecl *aggregateDecl ) {
 	if ( inStruct ) {
-	    declsToAdd.push_back( aggregateDecl );
+	    // Add elements in stack order corresponding to nesting structure.
+	    declsToAdd.push_front( aggregateDecl );
 	    Visitor::visit( aggregateDecl );
 	} else {
@@ -222,6 +227,7 @@
 	    Visitor::visit( aggregateDecl );
 	    inStruct = false;
-	    filter( aggregateDecl->get_members(), isStructOrUnion, false );
-	}
+	}
+	// Always remove the hoisted aggregate from the inner structure.
+	filter( aggregateDecl->get_members(), isStructOrUnion, false );
     }
 
@@ -523,5 +529,5 @@
     }
 
-    Declaration *makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType ) {
+    Declaration *makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting ) {
 	FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
   
@@ -534,6 +540,8 @@
 	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 );
+
+	// Routines at global scope marked "static" to prevent multiple definitions is separate translation units
+	// because each unit generates copies of the default routines for each aggregate.
+	FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? Declaration::NoStorageClass : Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true );
 	assignDecl->fixUniqueId();
   
@@ -552,5 +560,5 @@
     }
 
-    Declaration *makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType ) {
+    Declaration *makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType, unsigned int functionNesting ) {
 	FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
   
@@ -564,5 +572,7 @@
 	assignType->get_parameters().push_back( srcParam );
   
-	FunctionDecl *assignDecl = new FunctionDecl( "?=?", Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true );
+	// Routines at global scope marked "static" to prevent multiple definitions is separate translation units
+	// because each unit generates copies of the default routines for each aggregate.
+	FunctionDecl *assignDecl = new FunctionDecl( "?=?",  functionNesting > 0 ? Declaration::NoStorageClass : Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true );
 	assignDecl->fixUniqueId();
   
@@ -582,5 +592,5 @@
 	    StructInstType *structInst = new StructInstType( Type::Qualifiers(), structDecl->get_name() );
 	    structInst->set_baseStruct( structDecl );
-	    declsToAdd.push_back( makeStructAssignment( structDecl, structInst ) );
+	    declsToAdd.push_back( makeStructAssignment( structDecl, structInst, functionNesting ) );
 	    structsDone.insert( structDecl->get_name() );
 	}
@@ -591,5 +601,5 @@
 	    UnionInstType *unionInst = new UnionInstType( Type::Qualifiers(), unionDecl->get_name() );
 	    unionInst->set_baseUnion( unionDecl );
-	    declsToAdd.push_back( makeUnionAssignment( unionDecl, unionInst ) );
+	    declsToAdd.push_back( makeUnionAssignment( unionDecl, unionInst, functionNesting ) );
 	}
     }
@@ -647,4 +657,12 @@
     }
 
+    void AddStructAssignment::visit( FunctionDecl *functionDecl ) {
+	maybeAccept( functionDecl->get_functionType(), *this );
+	acceptAll( functionDecl->get_oldDecls(), *this );
+	functionNesting += 1;
+	maybeAccept( functionDecl->get_statements(), *this );
+	functionNesting -= 1;
+    }
+
     void AddStructAssignment::visit( CompoundStmt *compoundStmt ) {
 	visitStatement( compoundStmt );
Index: translator/SymTab/Validate.h
===================================================================
--- translator/SymTab/Validate.h	(revision 1db2c5be186b17e66fbf9cdd4a6bffc6987810de)
+++ translator/SymTab/Validate.h	(revision 3c70d383ff7630d9cdc9dd98340ba26c715dfeaa)
@@ -1,11 +1,4 @@
-/*
- * 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 $
- *
- */
+// This class is intended to perform pre-processing of declarations, validating their
+// correctness and computing some auxilliary data that is necessary for the indexer.
 
 #ifndef SYMTAB_VALIDATE_H
@@ -15,13 +8,9 @@
 
 namespace SymTab {
+    class Indexer;
 
-class Indexer;
+    void validate( std::list< Declaration * > &translationUnit, bool doDebug = false, const Indexer *indexer = 0 );
+    void validateType( Type *type, const Indexer *indexer );
+} // SymTab
 
-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 */
+#endif // SYMTAB_VALIDATE_H
