Index: src/AST/Create.cpp
===================================================================
--- src/AST/Create.cpp	(revision 8f1e03582aaeca10f66354d884763209e5fe44bc)
+++ src/AST/Create.cpp	(revision 8f1e03582aaeca10f66354d884763209e5fe44bc)
@@ -0,0 +1,63 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Create.cpp -- Helpers to create pieces of the AST.
+//
+// Author           : Andrew Beach
+// Created On       : Tue Sep 20 13:28:00 2022
+// Last Modified By : Andrew Beach
+// Last Modified On : Tue Sep 20 14:55:00 2022
+// Update Count     : 0
+//
+
+#include "AST/Create.hpp"
+
+#include "AST/Attribute.hpp"
+#include "AST/Copy.hpp"
+#include "AST/Decl.hpp"
+
+namespace ast {
+
+namespace {
+
+	template<typename node_t>
+	std::vector<ast::ptr<node_t>> vectorCopy(
+			std::vector<ast::ptr<node_t>> const & nodes ) {
+		return map_range<std::vector<ast::ptr<node_t>>>( nodes,
+			[]( ptr<node_t> const & node ){
+				return deepCopy<node_t>( node );
+			}
+		);
+	}
+
+} // namespace
+
+StructDecl * asForward( StructDecl const * decl ) {
+	if ( !decl->body ) {
+		return nullptr;
+	}
+	StructDecl * fwd = new StructDecl( decl->location,
+		decl->name,
+		decl->kind,
+		vectorCopy<ast::Attribute>( decl->attributes ),
+		decl->linkage );
+	fwd->params = vectorCopy( decl->params );
+	return fwd;
+}
+
+UnionDecl * asForward( UnionDecl const * decl ) {
+	if ( !decl->body ) {
+		return nullptr;
+	}
+	UnionDecl * fwd = new UnionDecl( decl->location,
+		decl->name,
+		vectorCopy( decl->attributes ),
+		decl->linkage );
+	fwd->params = vectorCopy( decl->params );
+	return fwd;
+}
+
+}
Index: src/AST/Create.hpp
===================================================================
--- src/AST/Create.hpp	(revision 8f1e03582aaeca10f66354d884763209e5fe44bc)
+++ src/AST/Create.hpp	(revision 8f1e03582aaeca10f66354d884763209e5fe44bc)
@@ -0,0 +1,26 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Create.hpp -- Helpers to create pieces of the AST.
+//
+// Author           : Andrew Beach
+// Created On       : Tue Sep 20 13:25:00 2022
+// Last Modified By : Andrew Beach
+// Last Modified On : Tue Sep 20 14:38:00 2022
+// Update Count     : 0
+//
+
+#include "AST/Fwd.hpp"
+
+namespace ast {
+
+/// Create a forward declaration of the existing declaration.
+/// If the argument is already a forward declaration, return nullptr instead.
+/// More efficient than the deepCopy and clear pattern.
+StructDecl * asForward( StructDecl const * );
+UnionDecl * asForward( UnionDecl const * );
+
+}
Index: src/AST/module.mk
===================================================================
--- src/AST/module.mk	(revision 72d1118e381aa61e11a9b801611aa8cd2fc8eb45)
+++ src/AST/module.mk	(revision 8f1e03582aaeca10f66354d884763209e5fe44bc)
@@ -24,4 +24,6 @@
 	AST/Copy.cpp \
 	AST/Copy.hpp \
+	AST/Create.cpp \
+	AST/Create.hpp \
 	AST/CVQualifiers.hpp \
 	AST/Decl.cpp \
Index: src/GenPoly/InstantiateGenericNew.cpp
===================================================================
--- src/GenPoly/InstantiateGenericNew.cpp	(revision 72d1118e381aa61e11a9b801611aa8cd2fc8eb45)
+++ src/GenPoly/InstantiateGenericNew.cpp	(revision 8f1e03582aaeca10f66354d884763209e5fe44bc)
@@ -22,4 +22,5 @@
 
 #include "AST/Copy.hpp"                // for deepCopy
+#include "AST/Create.hpp"              // for asForward
 #include "AST/Pass.hpp"                // for Pass, WithGuard, WithShortCi...
 #include "AST/TranslationUnit.hpp"     // for TranslationUnit
@@ -255,16 +256,4 @@
 void stripInstParams( ast::BaseInstType * inst ) {
 	inst->params.clear();
-}
-
-// TODO: I think this should become a generic helper.
-template<typename Aggr>
-Aggr * asForward( Aggr const * decl ) {
-	if ( !decl->body ) {
-		return nullptr;
-	}
-	Aggr * mut = ast::deepCopy( decl );
-	mut->body = false;
-	mut->members.clear();
-	return mut;
 }
 
@@ -553,5 +542,5 @@
 			// Forward declare before recursion. (TODO: Only when needed, #199.)
 			insert( inst, typeSubs, newDecl );
-			if ( AggrDecl const * forwardDecl = asForward( newDecl ) ) {
+			if ( AggrDecl const * forwardDecl = ast::asForward( newDecl ) ) {
 				declsToAddBefore.push_back( forwardDecl );
 			}
