Index: src/CodeGen/LinkOnce.cc
===================================================================
--- src/CodeGen/LinkOnce.cc	(revision aff7e862f837ed8e7b405341103d8c3a6aa5a387)
+++ src/CodeGen/LinkOnce.cc	(revision aff7e862f837ed8e7b405341103d8c3a6aa5a387)
@@ -0,0 +1,65 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2021 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// LinkOnce.cc -- Translate the cfa_linkonce attribute.
+//
+// Author           : Andrew Beach
+// Created On       : Thur May 13 10:10:00 2021
+// Last Modified By : Andrew Beach
+// Last Modified On : Thur May 13 14:39:00 2021
+// Update Count     : 0
+//
+
+#include "LinkOnce.h"
+
+#include <algorithm>
+
+#include "Common/PassVisitor.h"       // for PassVisitor, WithShortCircuiting
+
+namespace CodeGen {
+
+static bool is_cfa_linkonce( Attribute const * attr ) {
+	return std::string("cfa_linkonce") == attr->name;
+}
+
+static bool is_section_attribute( Attribute const * attr ) {
+	return std::string("section") == attr->name;
+}
+
+class LinkOnceVisitorCore : public WithShortCircuiting {
+public:
+	void previsit( Declaration * ) {
+		visit_children = false;
+	}
+
+	void previsit( DeclarationWithType * decl ) {
+		std::list< Attribute * > & attributes = decl->attributes;
+		// See if we can find the element:
+		auto found = std::find_if(attributes.begin(), attributes.end(), is_cfa_linkonce );
+		if ( attributes.end() != found ) {
+			// Remove any other sections:
+			attributes.remove_if( is_section_attribute );
+			// Iterator to the cfa_linkonce attribute should still be valid.
+			Attribute * attribute = *found;
+			assert( attribute->parameters.empty() );
+			assert( !decl->mangleName.empty() );
+			// Overwrite the attribute in place.
+			const std::string section_name = ".gnu.linkonce." + decl->mangleName;
+			attribute->name = "section";
+			attribute->parameters.push_back(
+				new ConstantExpr( Constant::from_string( section_name ) )
+			);
+		}
+		visit_children = false;
+	}
+};
+
+void translateLinkOnce( std::list< Declaration *> & translationUnit ) {
+	PassVisitor<LinkOnceVisitorCore> translator;
+	acceptAll( translationUnit, translator );
+}
+
+}
Index: src/CodeGen/LinkOnce.h
===================================================================
--- src/CodeGen/LinkOnce.h	(revision aff7e862f837ed8e7b405341103d8c3a6aa5a387)
+++ src/CodeGen/LinkOnce.h	(revision aff7e862f837ed8e7b405341103d8c3a6aa5a387)
@@ -0,0 +1,34 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2021 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// LinkOnce.h -- Translate the cfa_linkonce attribute.
+//
+// Author           : Andrew Beach
+// Created On       : Thur May 13 10:06:00 2021
+// Last Modified By : Andrew Beach
+// Last Modified On : Thur May 13 14:38:00 2021
+// Update Count     : 0
+//
+
+#pragma once
+
+// This could either be an early step in code-generation or a step of the
+// Cforall to C lowering. It could also be part of attribute handling but
+// for now its almost the only attribute we handle.
+
+#include <list>  // for list
+
+class Declaration;
+
+namespace CodeGen {
+
+void translateLinkOnce( std::list< Declaration *> & translationUnit );
+/* Convert the cfa_linkonce attribute on top level declaration into
+ * a special section declaration (.gnu.linkonce) so that it may be defined
+ * multiple times (same name and same type, must have the same value).
+ */
+
+}
Index: src/CodeGen/module.mk
===================================================================
--- src/CodeGen/module.mk	(revision 67b421c05a280cde8747b61757656154a9f530c9)
+++ src/CodeGen/module.mk	(revision aff7e862f837ed8e7b405341103d8c3a6aa5a387)
@@ -25,4 +25,6 @@
 	CodeGen/GenType.cc \
 	CodeGen/GenType.h \
+	CodeGen/LinkOnce.cc \
+	CodeGen/LinkOnce.h \
 	CodeGen/OperatorTable.cc \
 	CodeGen/OperatorTable.h \
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 67b421c05a280cde8747b61757656154a9f530c9)
+++ src/InitTweak/InitTweak.cc	(revision aff7e862f837ed8e7b405341103d8c3a6aa5a387)
@@ -1216,15 +1216,13 @@
 
 	void addDataSectonAttribute( ObjectDecl * objDecl ) {
-		Type *strLitT = new PointerType( Type::Qualifiers( ),
-			new BasicType( Type::Qualifiers( ), BasicType::Char ) );
-		std::list< Expression * > attr_params;
-		attr_params.push_back( 
-			new ConstantExpr( Constant( strLitT, "\".data#\"", std::nullopt ) ) );
-		objDecl->attributes.push_back(new Attribute("section", attr_params));
+		objDecl->attributes.push_back(new Attribute("section", {
+			new ConstantExpr( Constant::from_string(".data#") ),
+		}));
 	}
 
 	void addDataSectionAttribute( ast::ObjectDecl * objDecl ) {
-		auto strLitT = new ast::PointerType(new ast::BasicType(ast::BasicType::Char));
-		objDecl->attributes.push_back(new ast::Attribute("section", {new ast::ConstantExpr(objDecl->location, strLitT, "\".data#\"", std::nullopt)}));
+		objDecl->attributes.push_back(new ast::Attribute("section", {
+			ast::ConstantExpr::from_string(objDecl->location, ".data#"),
+		}));
 	}
 
Index: src/Virtual/Tables.cc
===================================================================
--- src/Virtual/Tables.cc	(revision 67b421c05a280cde8747b61757656154a9f530c9)
+++ src/Virtual/Tables.cc	(revision aff7e862f837ed8e7b405341103d8c3a6aa5a387)
@@ -172,11 +172,4 @@
 }
 
-Attribute * linkonce( const std::string & subsection ) {
-	const std::string section = ".gnu.linkonce." + subsection;
-	return new Attribute( "section", {
-		new ConstantExpr( Constant::from_string( section ) ),
-	} );
-}
-
 ObjectDecl * makeTypeIdInstance( StructInstType const * typeIdType ) {
 	assert( typeIdType );
@@ -193,5 +186,5 @@
 			new AddressExpr( new NameExpr( "__cfatid_exception_t" ) )
 			) } ),
-		{ linkonce( typeid_name ) },
+		{ new Attribute( "cfa_linkonce", {} ) },
 		noFuncSpecifiers
 	);
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 67b421c05a280cde8747b61757656154a9f530c9)
+++ src/main.cc	(revision aff7e862f837ed8e7b405341103d8c3a6aa5a387)
@@ -37,4 +37,5 @@
 #include "CodeGen/FixNames.h"               // for fixNames
 #include "CodeGen/Generate.h"               // for generate
+#include "CodeGen/LinkOnce.h"               // for translateLinkOnce
 #include "CodeTools/DeclStats.h"            // for printDeclStats
 #include "CodeTools/ResolvProtoDump.h"      // for dumpAsResolvProto
@@ -405,4 +406,8 @@
 		PASS( "Box", GenPoly::box( translationUnit ) );
 
+		PASS( "Link-Once", CodeGen::translateLinkOnce( translationUnit ) );
+
+		// Code has been lowered to C, now we can start generation.
+
 		if ( bcodegenp ) {
 			dump( translationUnit );
