Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision 5bdeb35417a73e8fd167c82279d470a561872af1)
+++ src/Parser/DeclarationNode.cc	(revision 250e29aaaa0931bfc8c6848e02e825b3cec0ac0e)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 12:34:05 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Jun  7 12:08:55 2018
-// Update Count     : 1079
+// Last Modified On : Fri Jul  6 06:56:08 2018
+// Update Count     : 1088
 //
 
@@ -504,12 +504,4 @@
 
 static void addQualifiersToType( TypeData *&src, TypeData * dst ) {
-	if ( src->forall && dst->kind == TypeData::Function ) {
-		if ( dst->forall ) {
-			dst->forall->appendList( src->forall );
-		} else {
-			dst->forall = src->forall;
-		} // if
-		src->forall = nullptr;
-	} // if
 	if ( dst->base ) {
 		addQualifiersToType( src, dst->base );
@@ -1065,4 +1057,12 @@
 			SemanticError( this, "invalid function specifier for " );
 		} // if
+		// Forall qualifier can only appear on a function/aggregate definition/declaration.
+		//
+		//    forall int f();					// allowed
+		//    forall int g( int i );			// allowed
+		//    forall int i;						// disallowed
+		if ( type->kind != TypeData::Function && type->forall ) {
+			SemanticError( this, "invalid type qualifier for " );
+		} // if
 		bool isDelete = initializer && initializer->get_isDelete();
 		Declaration * decl = buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, isDelete ? nullptr : maybeBuild< Initializer >(initializer), attributes )->set_extension( extension );
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 5bdeb35417a73e8fd167c82279d470a561872af1)
+++ src/Parser/parser.yy	(revision 250e29aaaa0931bfc8c6848e02e825b3cec0ac0e)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Jul  4 20:56:04 2018
-// Update Count     : 3616
+// Last Modified On : Fri Jul  6 08:02:38 2018
+// Update Count     : 3716
 //
 
@@ -116,9 +116,32 @@
 
 void distQual( DeclarationNode * declaration, DeclarationNode * qualifiers ) {
-	// distribute qualifiers across all declarations in a distribution statemement
+	// distribute qualifiers across all non-variable declarations in a distribution statemement
 	for ( DeclarationNode * iter = declaration; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
-		iter->addQualifiers( qualifiers->clone() );
+		// SKULLDUGGERY: Distributions are parsed inside out, so qualifiers are added to declarations inside out. Since
+		// addQualifiers appends to the back of the list, the forall clauses are in the wrong order (right to left). To
+		// get the qualifiers in the correct order and still use addQualifiers (otherwise, 90% of addQualifiers has to
+		// be copied to add to front), the appropriate forall pointers are interchanged before calling addQualifiers.
+		DeclarationNode * clone = qualifiers->clone();
+		if ( qualifiers->type ) {						// forall clause ? (handles SC)
+			if ( iter->type->kind == TypeData::Aggregate ) { // struct/union ?
+				swap( clone->type->forall, iter->type->aggregate.params );
+				iter->addQualifiers( clone );
+			} else if ( iter->type->kind == TypeData::AggregateInst && iter->type->aggInst.aggregate->aggregate.body ) { // struct/union ?
+				// Create temporary node to hold aggregate, call addQualifiers as above, then put nodes back together.
+				DeclarationNode newnode;
+				swap( newnode.type, iter->type->aggInst.aggregate );
+				swap( clone->type->forall, newnode.type->aggregate.params );
+				newnode.addQualifiers( clone );
+				swap( newnode.type, iter->type->aggInst.aggregate );
+			} else if ( iter->type->kind == TypeData::Function ) { // routines ?
+				swap( clone->type->forall, iter->type->forall );
+				iter->addQualifiers( clone );
+			} // if
+		} else {										// just SC qualifiers
+			iter->addQualifiers( clone );
+		} // if
 	} // for
-} // distExt
+	delete qualifiers;
+} // distQual
 
 // There is an ambiguity for inline generic-routine return-types and generic routines.
@@ -364,5 +387,5 @@
 %type<decl> type_parameter type_parameter_list type_initializer_opt
 
-%type<en> type_list
+%type<en> type_parameters_opt type_list
 
 %type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list
@@ -404,4 +427,5 @@
 // Order of these lines matters (low-to-high precedence).
 %precedence TYPEGENname
+%precedence '}'
 %precedence '('
 
@@ -1751,5 +1775,8 @@
 		{ $$ = $3->addQualifiers( $1 ); }
 	| sue_type_specifier type_qualifier
-		{ $$ = $1->addQualifiers( $2 ); }
+		{
+			if ( $2->type != nullptr && $2->type->forall ) forall = true; // remember generic type
+			$$ = $1->addQualifiers( $2 );
+		}
 	;
 
@@ -1829,6 +1856,6 @@
 
 aggregate_type:											// struct, union
-	aggregate_key attribute_list_opt '{' field_declaration_list_opt '}'
-		{ $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), nullptr, $4, true )->addQualifiers( $2 ); }
+	aggregate_key attribute_list_opt '{' field_declaration_list_opt '}' type_parameters_opt
+		{ $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), $6, $4, true )->addQualifiers( $2 ); }
 	| aggregate_key attribute_list_opt no_attr_identifier fred
 		{
@@ -1836,6 +1863,6 @@
 			forall = false;								// reset
 		}
-	  '{' field_declaration_list_opt '}'
-		{ $$ = DeclarationNode::newAggregate( $1, $3, nullptr, $7, true )->addQualifiers( $2 ); }
+	  '{' field_declaration_list_opt '}' type_parameters_opt
+		{ $$ = DeclarationNode::newAggregate( $1, $3, $9, $7, true )->addQualifiers( $2 ); }
 	| aggregate_key attribute_list_opt type_name fred
 		{
@@ -1843,9 +1870,14 @@
 			forall = false;								// reset
 		}
-	  '{' field_declaration_list_opt '}'
-		{ $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, nullptr, $7, true )->addQualifiers( $2 ); }
-	| aggregate_key attribute_list_opt '(' type_list ')' '{' field_declaration_list_opt '}' // CFA
-		{ $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), $4, $7, false )->addQualifiers( $2 ); }
+	  '{' field_declaration_list_opt '}' type_parameters_opt
+		{ $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $9, $7, true )->addQualifiers( $2 ); }
 	| aggregate_type_nobody
+	;
+
+type_parameters_opt:
+	// empty
+		{ $$ = nullptr; }								%prec '}'
+	| '(' type_list ')'
+		{ $$ = $2; }
 	;
 
@@ -2386,5 +2418,4 @@
 			distQual( $5, $1 );
  			xxx = false;
-			delete $1;
 			$$ = $5;
 		}
@@ -2398,5 +2429,4 @@
 			distQual( $5, $1 );
  			xxx = false;
-			delete $1;
 			$$ = $5;
 		}
@@ -2408,9 +2438,6 @@
 	  '{' up external_definition_list_opt down '}'		// CFA, namespace
 		{
-			distQual( $6, $2 );
-			distQual( $6, $1 );
+			distQual( $6, $1->addQualifiers( $2 ) );
  			xxx = false;
-			delete $1;
-			delete $2;
 			$$ = $6;
 		}
