Index: src/AST/Expr.cpp
===================================================================
--- src/AST/Expr.cpp	(revision ecfd7589e4796949fcc35b475a024d4acda6e636)
+++ src/AST/Expr.cpp	(revision a017ee7e5c430fc297274eb5bf2b1e7a1e81c6ad)
@@ -260,4 +260,13 @@
 }
 
+ConstantExpr * ConstantExpr::from_string( const CodeLocation & loc, const std::string & str ) {
+	const Type * charType = new BasicType( BasicType::Char );
+	// Adjust the length of the string for the terminator.
+	const Expr * strSize = from_ulong( loc, str.size() + 1 );
+	const Type * strType = new ArrayType( charType, strSize, FixedLen, StaticDim );
+	const std::string strValue = "\"" + str + "\"";
+	return new ConstantExpr( loc, strType, strValue, std::nullopt );
+}
+
 ConstantExpr * ConstantExpr::null( const CodeLocation & loc, const Type * ptrType ) {
 	return new ConstantExpr{
Index: src/AST/Expr.hpp
===================================================================
--- src/AST/Expr.hpp	(revision ecfd7589e4796949fcc35b475a024d4acda6e636)
+++ src/AST/Expr.hpp	(revision a017ee7e5c430fc297274eb5bf2b1e7a1e81c6ad)
@@ -438,11 +438,13 @@
 	long long int intValue() const;
 
-	/// generates a boolean constant of the given bool
+	/// Generates a boolean constant of the given bool.
 	static ConstantExpr * from_bool( const CodeLocation & loc, bool b );
-	/// generates an integer constant of the given int
+	/// Generates an integer constant of the given int.
 	static ConstantExpr * from_int( const CodeLocation & loc, int i );
-	/// generates an integer constant of the given unsigned long int
+	/// Generates an integer constant of the given unsigned long int.
 	static ConstantExpr * from_ulong( const CodeLocation & loc, unsigned long i );
-	/// generates a null pointer value for the given type. void * if omitted.
+	/// Generates a string constant from the given string (char type, unquoted string).
+	static ConstantExpr * from_string( const CodeLocation & loc, const std::string & string );
+	/// Generates a null pointer value for the given type. void * if omitted.
 	static ConstantExpr * null( const CodeLocation & loc, const Type * ptrType = nullptr );
 
Index: src/SynTree/Constant.cc
===================================================================
--- src/SynTree/Constant.cc	(revision ecfd7589e4796949fcc35b475a024d4acda6e636)
+++ src/SynTree/Constant.cc	(revision a017ee7e5c430fc297274eb5bf2b1e7a1e81c6ad)
@@ -42,4 +42,13 @@
 }
 
+Constant Constant::from_string( const std::string & str ) {
+	Type * charType = new BasicType( noQualifiers, BasicType::Char );
+	// Adjust the length of the string for the terminator.
+	Expression * strSize = new ConstantExpr( Constant::from_ulong( str.size() + 1 ) );
+	Type * strType = new ArrayType( noQualifiers, charType, strSize, false, false );
+	const std::string strValue = "\"" + str + "\"";
+	return Constant( strType, strValue, std::nullopt );
+}
+
 Constant Constant::null( Type * ptrtype ) {
 	if ( nullptr == ptrtype ) {
Index: src/SynTree/Constant.h
===================================================================
--- src/SynTree/Constant.h	(revision ecfd7589e4796949fcc35b475a024d4acda6e636)
+++ src/SynTree/Constant.h	(revision a017ee7e5c430fc297274eb5bf2b1e7a1e81c6ad)
@@ -47,4 +47,6 @@
 	/// generates an integer constant of the given unsigned long int
 	static Constant from_ulong( unsigned long i );
+	/// generates a string constant from the given string (char type, unquoted string)
+	static Constant from_string( const std::string & string );
 
 	/// generates a null pointer value for the given type. void * if omitted.
Index: src/Virtual/ExpandCasts.cc
===================================================================
--- src/Virtual/ExpandCasts.cc	(revision ecfd7589e4796949fcc35b475a024d4acda6e636)
+++ src/Virtual/ExpandCasts.cc	(revision a017ee7e5c430fc297274eb5bf2b1e7a1e81c6ad)
@@ -77,5 +77,5 @@
 
 	class VirtualCastCore {
-		Type * pointer_to_pvt(int level_of_indirection) {
+		CastExpr * cast_to_type_id( Expression * expr, int level_of_indirection ) {
 			Type * type = new StructInstType(
 				Type::Qualifiers( Type::Const ), pvt_decl );
@@ -83,5 +83,5 @@
 				type = new PointerType( noQualifiers, type );
 			}
-			return type;
+			return new CastExpr( expr, type );
 		}
 
@@ -253,12 +253,6 @@
 		Expression * result = new CastExpr(
 			new ApplicationExpr( VariableExpr::functionPointer( vcast_decl ), {
-					new CastExpr(
-						new AddressExpr( new VariableExpr( type_id ) ),
-						pointer_to_pvt(1)
-					),
-					new CastExpr(
-						castExpr->get_arg(),
-						pointer_to_pvt(2)
-					)
+				cast_to_type_id( new AddressExpr( new VariableExpr( type_id ) ), 1 ),
+				cast_to_type_id( castExpr->get_arg(), 2 ),
 			} ),
 			castExpr->get_result()->clone()
Index: src/Virtual/Tables.cc
===================================================================
--- src/Virtual/Tables.cc	(revision ecfd7589e4796949fcc35b475a024d4acda6e636)
+++ src/Virtual/Tables.cc	(revision a017ee7e5c430fc297274eb5bf2b1e7a1e81c6ad)
@@ -172,17 +172,7 @@
 
 Attribute * linkonce( const std::string & subsection ) {
-	const std::string section = "\".gnu.linkonce." + subsection + "\"";
-	// Adjust for terminator and quotes.
-	size_t str_size = section.size() + 1 - 2;
+	const std::string section = ".gnu.linkonce." + subsection;
 	return new Attribute( "section", {
-		new ConstantExpr( Constant(
-			new ArrayType(
-				noQualifiers,
-				new BasicType( noQualifiers, BasicType::Char ),
-				new ConstantExpr( Constant::from_ulong( str_size ) ),
-				false, false ),
-			section,
-			std::nullopt
-		) ),
+		new ConstantExpr( Constant::from_string( section ) ),
 	} );
 }
