Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 7e13b11d45b7d7c4335e8c883c9737a3ef39079d)
+++ src/Parser/parser.yy	(revision 6cef439b516739e0c306c51c0ccf41d2090929b9)
@@ -317,22 +317,33 @@
 
 %union {
+	// A raw token can be used.
 	Token tok;
+
+	// The general node types hold some generic node or list of nodes.
+	DeclarationNode * decl;
+	InitializerNode * init;
 	ExpressionNode * expr;
-	DeclarationNode * decl;
-	ast::AggregateDecl::Aggregate aggKey;
-	ast::TypeDecl::Kind tclass;
 	StatementNode * stmt;
 	ClauseNode * clause;
-	ast::WaitForStmt * wfs;
-    ast::WaitUntilStmt::ClauseNode * wucn;
+	TypeData * type;
+
+	// Special "nodes" containing compound information.
 	CondCtl * ifctl;
 	ForCtrl * forctl;
 	LabelNode * labels;
-	InitializerNode * init;
+
+	// Various flags and single values that become fields later.
+	ast::AggregateDecl::Aggregate aggKey;
+	ast::TypeDecl::Kind tclass;
 	OperKinds oper;
-	std::string * str;
 	bool is_volatile;
 	EnumHiding enum_hiding;
 	ast::ExceptionKind except_kind;
+	// String passes ownership with it.
+	std::string * str;
+
+	// Narrower node types are used to avoid constant unwrapping.
+	ast::WaitForStmt * wfs;
+	ast::WaitUntilStmt::ClauseNode * wucn;
 	ast::GenericExpr * genexpr;
 }
@@ -464,5 +475,6 @@
 
 %type<decl> basic_declaration_specifier basic_type_name basic_type_specifier direct_type indirect_type
-%type<decl> vtable vtable_opt default_opt
+%type<type> basic_type_name_type
+%type<type> vtable vtable_opt default_opt
 
 %type<decl> trait_declaration trait_declaration_list trait_declaring_list trait_specifier
@@ -519,5 +531,6 @@
 %type<decl> type_declarator type_declarator_name type_declaring_list
 
-%type<decl> type_declaration_specifier type_type_specifier type_name typegen_name
+%type<decl> type_declaration_specifier type_type_specifier
+%type<type> type_name typegen_name
 %type<decl> typedef_name typedef_declaration typedef_expression
 
@@ -532,5 +545,6 @@
 %type<expr> type_parameters_opt type_list array_type_list // array_dimension_list
 
-%type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list
+%type<decl> type_qualifier forall type_qualifier_list_opt type_qualifier_list
+%type<type> type_qualifier_name
 %type<decl> type_specifier type_specifier_nobody
 
@@ -687,6 +701,4 @@
 		{ $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
 	| TYPEDIMname										// CFA, generic length argument
-		// { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( DeclarationNode::newFromTypedef( $1 ) ) ) ); }
-		// { $$ = new ExpressionNode( build_varref( $1 ) ); }
 		{ $$ = new ExpressionNode( build_dimensionref( yylloc, $1 ) ); }
 	| tuple
@@ -696,5 +708,5 @@
 		{ $$ = new ExpressionNode( new ast::StmtExpr( yylloc, dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( $2 ) ) ) ); }
 	| type_name '.' identifier							// CFA, nested type
-		{ $$ = new ExpressionNode( build_qualified_expr( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
+		{ $$ = new ExpressionNode( build_qualified_expr( yylloc, DeclarationNode::newFromTypeData( $1 ), build_varref( yylloc, $3 ) ) ); }
 	| type_name '.' '[' field_name_list ']'				// CFA, nested type / tuple field selector
 		{ SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
@@ -978,5 +990,5 @@
 		{ $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); }
 	| '(' VIRTUAL ')' cast_expression					// CFA
-		{ $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $4 ), maybeMoveBuildType( nullptr ) ) ); }
+		{ $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $4 ), nullptr ) ); }
 	| '(' VIRTUAL type_no_function ')' cast_expression	// CFA
 		{ $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $5 ), maybeMoveBuildType( $3 ) ) ); }
@@ -2215,4 +2227,5 @@
 type_qualifier:
 	type_qualifier_name
+		{ $$ = DeclarationNode::newFromTypeData( $1 ); }
 	| attribute											// trick handles most attribute locations
 	;
@@ -2220,11 +2233,11 @@
 type_qualifier_name:
 	CONST
-		{ $$ = DeclarationNode::newTypeQualifier( ast::CV::Const ); }
+		{ $$ = build_type_qualifier( ast::CV::Const ); }
 	| RESTRICT
-		{ $$ = DeclarationNode::newTypeQualifier( ast::CV::Restrict ); }
+		{ $$ = build_type_qualifier( ast::CV::Restrict ); }
 	| VOLATILE
-		{ $$ = DeclarationNode::newTypeQualifier( ast::CV::Volatile ); }
+		{ $$ = build_type_qualifier( ast::CV::Volatile ); }
 	| ATOMIC
-		{ $$ = DeclarationNode::newTypeQualifier( ast::CV::Atomic ); }
+		{ $$ = build_type_qualifier( ast::CV::Atomic ); }
 
 		// forall must be a CV qualifier because it can appear in places where SC qualifiers are disallowed.
@@ -2233,5 +2246,5 @@
 		//   void bar( static int ); // static disallowed (gcc/CFA)
 	| forall
-		{ $$ = DeclarationNode::newForall( $1 ); }
+		{ $$ = build_forall( $1 ); }
 	;
 
@@ -2283,36 +2296,42 @@
 
 basic_type_name:
+	basic_type_name_type
+		{ $$ = DeclarationNode::newFromTypeData( $1 ); }
+	;
+
+// Just an intermediate value for conversion.
+basic_type_name_type:
 	VOID
-		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Void ); }
+		{ $$ = build_basic_type( DeclarationNode::Void ); }
 	| BOOL												// C99
-		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Bool ); }
+		{ $$ = build_basic_type( DeclarationNode::Bool ); }
 	| CHAR
-		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Char ); }
+		{ $$ = build_basic_type( DeclarationNode::Char ); }
 	| INT
-		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Int ); }
+		{ $$ = build_basic_type( DeclarationNode::Int ); }
 	| INT128
-		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Int128 ); }
+		{ $$ = build_basic_type( DeclarationNode::Int128 ); }
 	| UINT128
-		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Int128 )->addType( DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ); }
+		{ $$ = addType( build_basic_type( DeclarationNode::Int128 ), build_signedness( DeclarationNode::Unsigned ) ); }
 	| FLOAT
-		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Float ); }
+		{ $$ = build_basic_type( DeclarationNode::Float ); }
 	| DOUBLE
-		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Double ); }
+		{ $$ = build_basic_type( DeclarationNode::Double ); }
 	| uuFLOAT80
-		{ $$ = DeclarationNode::newBasicType( DeclarationNode::uuFloat80 ); }
+		{ $$ = build_basic_type( DeclarationNode::uuFloat80 ); }
 	| uuFLOAT128
-		{ $$ = DeclarationNode::newBasicType( DeclarationNode::uuFloat128 ); }
+		{ $$ = build_basic_type( DeclarationNode::uuFloat128 ); }
 	| uFLOAT16
-		{ $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat16 ); }
+		{ $$ = build_basic_type( DeclarationNode::uFloat16 ); }
 	| uFLOAT32
-		{ $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat32 ); }
+		{ $$ = build_basic_type( DeclarationNode::uFloat32 ); }
 	| uFLOAT32X
-		{ $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat32x ); }
+		{ $$ = build_basic_type( DeclarationNode::uFloat32x ); }
 	| uFLOAT64
-		{ $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat64 ); }
+		{ $$ = build_basic_type( DeclarationNode::uFloat64 ); }
 	| uFLOAT64X
-		{ $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat64x ); }
+		{ $$ = build_basic_type( DeclarationNode::uFloat64x ); }
 	| uFLOAT128
-		{ $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat128 ); }
+		{ $$ = build_basic_type( DeclarationNode::uFloat128 ); }
 	| DECIMAL32
 		{ SemanticError( yylloc, "_Decimal32 is currently unimplemented." ); $$ = nullptr; }
@@ -2322,19 +2341,19 @@
 		{ SemanticError( yylloc, "_Decimal128 is currently unimplemented." ); $$ = nullptr; }
 	| COMPLEX											// C99
-		{ $$ = DeclarationNode::newComplexType( DeclarationNode::Complex ); }
+		{ $$ = build_complex_type( DeclarationNode::Complex ); }
 	| IMAGINARY											// C99
-		{ $$ = DeclarationNode::newComplexType( DeclarationNode::Imaginary ); }
+		{ $$ = build_complex_type( DeclarationNode::Imaginary ); }
 	| SIGNED
-		{ $$ = DeclarationNode::newSignedNess( DeclarationNode::Signed ); }
+		{ $$ = build_signedness( DeclarationNode::Signed ); }
 	| UNSIGNED
-		{ $$ = DeclarationNode::newSignedNess( DeclarationNode::Unsigned ); }
+		{ $$ = build_signedness( DeclarationNode::Unsigned ); }
 	| SHORT
-		{ $$ = DeclarationNode::newLength( DeclarationNode::Short ); }
+		{ $$ = build_length( DeclarationNode::Short ); }
 	| LONG
-		{ $$ = DeclarationNode::newLength( DeclarationNode::Long ); }
+		{ $$ = build_length( DeclarationNode::Long ); }
 	| VA_LIST											// GCC, __builtin_va_list
-		{ $$ = DeclarationNode::newBuiltinType( DeclarationNode::Valist ); }
+		{ $$ = build_builtin_type( DeclarationNode::Valist ); }
 	| AUTO_TYPE
-		{ $$ = DeclarationNode::newBuiltinType( DeclarationNode::AutoType ); }
+		{ $$ = build_builtin_type( DeclarationNode::AutoType ); }
 	| vtable
 	;
@@ -2348,6 +2367,5 @@
 vtable:
 	VTABLE '(' type_name ')' default_opt
-		{ $$ = DeclarationNode::newVtableType( $3 ); }
-		// { SemanticError( yylloc, "vtable is currently unimplemented." ); $$ = nullptr; }
+		{ $$ = build_vtable_type( $3 ); }
 	;
 
@@ -2399,7 +2417,7 @@
 		{ $$ = DeclarationNode::newTypeof( $3, true ); }
 	| ZERO_T											// CFA
-		{ $$ = DeclarationNode::newBuiltinType( DeclarationNode::Zero ); }
+		{ $$ = DeclarationNode::newFromTypeData( build_builtin_type( DeclarationNode::Zero ) ); }
 	| ONE_T												// CFA
-		{ $$ = DeclarationNode::newBuiltinType( DeclarationNode::One ); }
+		{ $$ = DeclarationNode::newFromTypeData( build_builtin_type( DeclarationNode::One ) ); }
 	;
 
@@ -2457,6 +2475,7 @@
 type_type_specifier:									// typedef types
 	type_name
+		{ $$ = DeclarationNode::newFromTypeData( $1 ); }
 	| type_qualifier_list type_name
-		{ $$ = $2->addQualifiers( $1 ); }
+		{ $$ = DeclarationNode::newFromTypeData( $2 )->addQualifiers( $1 ); }
 	| type_type_specifier type_qualifier
 		{ $$ = $1->addQualifiers( $2 ); }
@@ -2465,23 +2484,23 @@
 type_name:
 	TYPEDEFname
-		{ $$ = DeclarationNode::newFromTypedef( $1 ); }
+		{ $$ = build_typedef( $1 ); }
 	| '.' TYPEDEFname
-		{ $$ = DeclarationNode::newQualifiedType( DeclarationNode::newFromGlobalScope(), DeclarationNode::newFromTypedef( $2 ) ); }
+		{ $$ = build_qualified_type( build_global_scope(), build_typedef( $2 ) ); }
 	| type_name '.' TYPEDEFname
-		{ $$ = DeclarationNode::newQualifiedType( $1, DeclarationNode::newFromTypedef( $3 ) ); }
+		{ $$ = build_qualified_type( $1, build_typedef( $3 ) ); }
 	| typegen_name
 	| '.' typegen_name
-		{ $$ = DeclarationNode::newQualifiedType( DeclarationNode::newFromGlobalScope(), $2 ); }
+		{ $$ = build_qualified_type( build_global_scope(), $2 ); }
 	| type_name '.' typegen_name
-		{ $$ = DeclarationNode::newQualifiedType( $1, $3 ); }
+		{ $$ = build_qualified_type( $1, $3 ); }
 	;
 
 typegen_name:											// CFA
 	TYPEGENname
-		{ $$ = DeclarationNode::newFromTypeGen( $1, nullptr ); }
+		{ $$ = build_type_gen( $1, nullptr ); }
 	| TYPEGENname '(' ')'
-		{ $$ = DeclarationNode::newFromTypeGen( $1, nullptr ); }
+		{ $$ = build_type_gen( $1, nullptr ); }
 	| TYPEGENname '(' type_list ')'
-		{ $$ = DeclarationNode::newFromTypeGen( $1, $3 ); }
+		{ $$ = build_type_gen( $1, $3 ); }
 	;
 
@@ -2519,5 +2538,5 @@
 	  '{' field_declaration_list_opt '}' type_parameters_opt
 		{
-			DeclarationNode::newFromTypedef( $3 );
+			DeclarationNode::newFromTypeData( build_typedef( $3 ) );
 			$$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
 		}
@@ -2529,5 +2548,5 @@
 	  '{' field_declaration_list_opt '}' type_parameters_opt
 		{
-			DeclarationNode::newFromTypeGen( $3, nullptr );
+			DeclarationNode::newFromTypeData( build_type_gen( $3, nullptr ) );
 			$$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
 		}
@@ -2554,11 +2573,10 @@
 			// Create new generic declaration with same name as previous forward declaration, where the IDENTIFIER is
 			// switched to a TYPEGENname. Link any generic arguments from typegen_name to new generic declaration and
-			// delete newFromTypeGen.
-			if ( $3->type->kind == TypeData::SymbolicInst && ! $3->type->symbolic.isTypedef ) {
-				$$ = $3->addQualifiers( $2 );
+			if ( $3->kind == TypeData::SymbolicInst && ! $3->symbolic.isTypedef ) {
+				$$ = DeclarationNode::newFromTypeData( $3 )->addQualifiers( $2 );
 			} else {
-				$$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $3->type->symbolic.actuals, nullptr, false )->addQualifiers( $2 );
-				$3->type->symbolic.name = nullptr;			// copied to $$
-				$3->type->symbolic.actuals = nullptr;
+				$$ = DeclarationNode::newAggregate( $1, $3->symbolic.name, $3->symbolic.actuals, nullptr, false )->addQualifiers( $2 );
+				$3->symbolic.name = nullptr;			// copied to $$
+				$3->symbolic.actuals = nullptr;
 				delete $3;
 			}
@@ -2785,6 +2803,6 @@
 	| ENUM attribute_list_opt type_name
 		{
-			typedefTable.makeTypedef( *$3->type->symbolic.name, "enum_type_nobody 2" );
-			$$ = DeclarationNode::newEnum( $3->type->symbolic.name, nullptr, false, false )->addQualifiers( $2 );
+			typedefTable.makeTypedef( *$3->symbolic.name, "enum_type_nobody 2" );
+			$$ = DeclarationNode::newEnum( $3->symbolic.name, nullptr, false, false )->addQualifiers( $2 );
 		}
 	;
@@ -2794,5 +2812,5 @@
 		{ $$ = DeclarationNode::newEnumValueGeneric( $2, $3 ); }
 	| INLINE type_name
-		{ $$ = DeclarationNode::newEnumInLine( *$2->type->symbolic.name ); }
+		{ $$ = DeclarationNode::newEnumInLine( *$2->symbolic.name ); }
 	| enumerator_list ',' visible_hide_opt identifier_or_type_name enumerator_value_opt
 		{ $$ = $1->set_last( DeclarationNode::newEnumValueGeneric( $4, $5 ) ); }
@@ -2839,5 +2857,5 @@
 cfa_parameter_list_ellipsis_opt:						// CFA, abstract + real
 	// empty
-		{ $$ = DeclarationNode::newBasicType( DeclarationNode::Void ); }
+		{ $$ = DeclarationNode::newFromTypeData( build_basic_type( DeclarationNode::Void ) ); }
 	| ELLIPSIS
 		{ $$ = nullptr; }
@@ -3775,5 +3793,5 @@
 		{ $$ = $1->addQualifiers( $2 ); }
 	| '&' MUTEX paren_identifier attribute_list_opt
-		{ $$ = $3->addPointer( DeclarationNode::newPointer( DeclarationNode::newTypeQualifier( ast::CV::Mutex ),
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( DeclarationNode::newFromTypeData( build_type_qualifier( ast::CV::Mutex ) ),
 															OperKinds::AddressOf ) )->addQualifiers( $4 ); }
 	| identifier_parameter_ptr
@@ -3826,5 +3844,5 @@
 		{ $$ = $1->addQualifiers( $2 ); }
 	| '&' MUTEX typedef_name attribute_list_opt
-		{ $$ = $3->addPointer( DeclarationNode::newPointer( DeclarationNode::newTypeQualifier( ast::CV::Mutex ),
+		{ $$ = $3->addPointer( DeclarationNode::newPointer( DeclarationNode::newFromTypeData( build_type_qualifier( ast::CV::Mutex ) ),
 															OperKinds::AddressOf ) )->addQualifiers( $4 ); }
 	| type_parameter_ptr
@@ -4010,5 +4028,5 @@
 	abstract_parameter_ptr
 	| '&' MUTEX attribute_list_opt
-		{ $$ = DeclarationNode::newPointer( DeclarationNode::newTypeQualifier( ast::CV::Mutex ), OperKinds::AddressOf )->addQualifiers( $3 ); }
+		{ $$ = DeclarationNode::newPointer( DeclarationNode::newFromTypeData( build_type_qualifier( ast::CV::Mutex ) ), OperKinds::AddressOf )->addQualifiers( $3 ); }
 	| abstract_parameter_array attribute_list_opt
 		{ $$ = $1->addQualifiers( $2 ); }
