Index: src/SymTab/Autogen.cc
===================================================================
--- src/SymTab/Autogen.cc	(revision a43694718462ba1b32dfae2db7da760ceb7c581a)
+++ src/SymTab/Autogen.cc	(revision d0f8b1986e86ea6328fec1b91571f6b6f0757877)
@@ -102,52 +102,56 @@
 		FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
 
+		ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType ), 0 );
+		assignType->get_parameters().push_back( dstParam );
+
+		// void ?{}(E *); void ^?{}(E *);
+		FunctionType * ctorType = assignType->clone();
+		FunctionType * dtorType = assignType->clone();
+
+		ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
+		assignType->get_parameters().push_back( srcParam );
+		// void ?{}(E *, E);
+		FunctionType *copyCtorType = assignType->clone();
+
+		// T ?=?(E *, E);
 		ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
 		assignType->get_returnVals().push_back( returnVal );
 
-		// need two assignment operators with different types
-		FunctionType * assignType2 = assignType->clone();
-
-		// E ?=?(E volatile *, E)
-		Type *etype = refType->clone();
-		// etype->get_qualifiers() += Type::Qualifiers(false, true, false, false, false, false);
-
-		ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), etype ), 0 );
-		assignType->get_parameters().push_back( dstParam );
-
-		ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, etype->clone(), 0 );
-		assignType->get_parameters().push_back( srcParam );
-
-		// E ?=?(E volatile *, int)
-		assignType2->get_parameters().push_back( dstParam->clone() );
-		BasicType * paramType = new BasicType(Type::Qualifiers(), BasicType::SignedInt);
-		ObjectDecl *srcParam2 = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, paramType, 0 );
-		assignType2->get_parameters().push_back( srcParam2 );
+		// xxx - should we also generate void ?{}(E *, int) and E ?{}(E *, E)?
+		// right now these cases work, but that might change.
 
 		// 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.
-
-		// since there is no definition, these should not be inline
-		// make these intrinsic so that the code generator does not make use of them
-		FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, assignType, 0, true, false );
+		// xxx - Temporary: make these functions intrinsic so they codegen as C assignment.
+		// Really they're something of a cross between instrinsic and autogen, so should
+		// probably make a new linkage type
+		FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, assignType, new CompoundStmt( noLabels ), true, false );
+		FunctionDecl *ctorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, ctorType, new CompoundStmt( noLabels ), true, false );
+		FunctionDecl *copyCtorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, copyCtorType, new CompoundStmt( noLabels ), true, false );
+		FunctionDecl *dtorDecl = new FunctionDecl( "^?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, dtorType, new CompoundStmt( noLabels ), true, false );
 		assignDecl->fixUniqueId();
-		FunctionDecl *assignDecl2 = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, assignType2, 0, true, false );
-		assignDecl2->fixUniqueId();
-
-		// these should be built in the same way that the prelude
-		// functions are, so build a list containing the prototypes
-		// and allow MakeLibCfa to autogenerate the bodies.
-		std::list< Declaration * > assigns;
-		assigns.push_back( assignDecl );
-		assigns.push_back( assignDecl2 );
-
-		LibCfa::makeLibCfa( assigns );
-
-		// need to remove the prototypes, since this may be nested in a routine
-		for (int start = 0, end = assigns.size()/2; start < end; start++) {
-			delete assigns.front();
-			assigns.pop_front();
-		} // for
-
-		declsToAdd.insert( declsToAdd.begin(), assigns.begin(), assigns.end() );
+		ctorDecl->fixUniqueId();
+		copyCtorDecl->fixUniqueId();
+		dtorDecl->fixUniqueId();
+
+		// enum copy construct and assignment is just C-style assignment.
+		// this looks like a bad recursive call, but code gen will turn it into
+		// a C-style assignment.
+		// This happens before function pointer type conversion, so need to do it manually here
+		VariableExpr * assignVarExpr = new VariableExpr( assignDecl );
+		Type *& assignVarExprType = assignVarExpr->get_results().front();
+		assignVarExprType = new PointerType( Type::Qualifiers(), assignVarExprType );
+		ApplicationExpr * assignExpr = new ApplicationExpr( assignVarExpr );
+		assignExpr->get_args().push_back( new VariableExpr( dstParam ) );
+		assignExpr->get_args().push_back( new VariableExpr( srcParam ) );
+
+		// body is either return stmt or expr stmt
+		assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, assignExpr ) );
+		copyCtorDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, assignExpr->clone() ) );
+
+		declsToAdd.push_back( assignDecl );
+		declsToAdd.push_back( ctorDecl );
+		declsToAdd.push_back( copyCtorDecl );
+		declsToAdd.push_back( dtorDecl );
 	}
 
