Index: translator/SymTab/Validate.cc
===================================================================
--- translator/SymTab/Validate.cc	(revision d3d8c3f40ade2153ee67ff69db198d96e7dda414)
+++ 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 );
