Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision 12df6fe35a1d7d73a64293320db6c3a0b195af33)
+++ src/Parser/DeclarationNode.cc	(revision a065f1ffe843ea0a3ceecdf36a1210abe07a2441)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 12:34:05 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Jul 14 17:36:57 2021
-// Update Count     : 1154
+// Last Modified On : Mon Aug  8 17:07:00 2022
+// Update Count     : 1185
 //
 
@@ -128,6 +128,4 @@
 	if ( name ) {
 		os << *name << ": ";
-	} else {
-		os << "unnamed: ";
 	} // if
 
@@ -154,6 +152,9 @@
 		initializer->printOneLine( os );
 		os << " maybe constructed? " << initializer->get_maybeConstructed();
-
-	} // if
+	} // if
+
+	for ( Attribute * attr: reverseIterate( attributes ) ) {
+		os << string( indent + 2, ' ' ) << "attr " << attr->name.c_str();
+	} // for
 
 	os << endl;
@@ -243,5 +244,5 @@
 	newnode->type = new TypeData( TypeData::Aggregate );
 	newnode->type->aggregate.kind = kind;
-	newnode->type->aggregate.name =  name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
+	newnode->type->aggregate.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
 	newnode->type->aggregate.actuals = actuals;
 	newnode->type->aggregate.fields = fields;
@@ -262,5 +263,5 @@
 	newnode->type->enumeration.typed = typed;
 	if ( base && base->type)  {
-		newnode->type->base = base->type;	
+		newnode->type->base = base->type;
 	} // if
 
@@ -504,5 +505,5 @@
 			} // for
 			// src is the new item being added and has a single bit
-		} else if ( ! src->storageClasses.is_threadlocal ) { // conflict ?
+		} else if ( ! src->storageClasses.is_threadlocal_any() ) { // conflict ?
 			appendError( error, string( "conflicting " ) + Type::StorageClassesNames[storageClasses.ffs()] +
 						 " & " + Type::StorageClassesNames[src->storageClasses.ffs()] );
@@ -518,5 +519,5 @@
 	storageClasses |= q->storageClasses;
 
-	for ( Attribute *attr: reverseIterate( q->attributes ) ) {
+	for ( Attribute * attr: reverseIterate( q->attributes ) ) {
 		attributes.push_front( attr->clone() );
 	} // for
@@ -683,4 +684,5 @@
 	} // if
 	delete o;
+
 	return this;
 }
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision 12df6fe35a1d7d73a64293320db6c3a0b195af33)
+++ src/Parser/TypeData.cc	(revision a065f1ffe843ea0a3ceecdf36a1210abe07a2441)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Sat May 16 15:12:51 2015
-// Last Modified By : Henry Xue
-// Last Modified On : Tue Jul 20 04:10:50 2021
-// Update Count     : 673
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Tue May 10 22:36:52 2022
+// Update Count     : 677
 //
 
@@ -283,12 +283,6 @@
 		if ( signedness != DeclarationNode::NoSignedness ) os << DeclarationNode::signednessNames[ signedness ] << " ";
 		if ( length != DeclarationNode::NoLength ) os << DeclarationNode::lengthNames[ length ] << " ";
-		if ( complextype == DeclarationNode::NoComplexType ) { // basic type
-			assert( basictype != DeclarationNode::NoBasicType );
-			os << DeclarationNode::basicTypeNames[ basictype ] << " ";
-		} else {										// complex type
-			// handle double _Complex
-			if ( basictype != DeclarationNode::NoBasicType ) os << DeclarationNode::basicTypeNames[ basictype ] << " ";
-			os << DeclarationNode::complexTypeNames[ complextype ] << " ";
-		} // if
+		if ( complextype != DeclarationNode::NoComplexType ) os << DeclarationNode::complexTypeNames[ complextype ] << " ";
+		if ( basictype != DeclarationNode::NoBasicType ) os << DeclarationNode::basicTypeNames[ basictype ] << " ";
 		break;
 	  case Pointer:
@@ -437,4 +431,5 @@
 			__attribute__((fallthrough));
 		#endif
+		// FALL THROUGH
 	  case Typeof:
 		os << "type-of expression ";
@@ -442,4 +437,7 @@
 			typeexpr->print( os, indent + 2 );
 		} // if
+		break;
+	  case Vtable:
+		os << "vtable";
 		break;
 	  case Builtin:
Index: src/Parser/TypeData.h
===================================================================
--- src/Parser/TypeData.h	(revision 12df6fe35a1d7d73a64293320db6c3a0b195af33)
+++ src/Parser/TypeData.h	(revision a065f1ffe843ea0a3ceecdf36a1210abe07a2441)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 15:18:36 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Jul 14 17:44:05 2021
-// Update Count     : 202
+// Last Modified On : Tue May 10 22:18:49 2022
+// Update Count     : 203
 //
 
@@ -27,5 +27,5 @@
 struct TypeData {
 	enum Kind { Basic, Pointer, Reference, Array, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic,
-				SymbolicInst, Tuple, Typeof, Basetypeof, Vtable, Builtin, GlobalScope, Qualified, Unknown };
+				SymbolicInst, Tuple, Basetypeof, Typeof, Vtable, Builtin, GlobalScope, Qualified, Unknown };
 
 	struct Aggregate_t {
Index: src/Parser/TypedefTable.cc
===================================================================
--- src/Parser/TypedefTable.cc	(revision 12df6fe35a1d7d73a64293320db6c3a0b195af33)
+++ src/Parser/TypedefTable.cc	(revision a065f1ffe843ea0a3ceecdf36a1210abe07a2441)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 15:20:13 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed May 19 08:30:14 2021
-// Update Count     : 262
+// Last Modified On : Tue Feb 15 08:27:24 2022
+// Update Count     : 275
 //
 
@@ -18,4 +18,5 @@
 #include <cassert>										// for assert
 #include <iostream>
+using namespace std;
 
 #if 0
@@ -28,16 +29,16 @@
 
 debugPrint(
-static const char *kindName( int kind ) {
-	switch ( kind ) {
-	  case IDENTIFIER: return "identifier";
-	  case TYPEDIMname: return "typedim";
-	  case TYPEDEFname: return "typedef";
-	  case TYPEGENname: return "typegen";
-	  default:
-		cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl;
-		abort();
-	} // switch
-} // kindName
-)
+	static const char *kindName( int kind ) {
+		switch ( kind ) {
+		  case IDENTIFIER: return "identifier";
+		  case TYPEDIMname: return "typedim";
+		  case TYPEDEFname: return "typedef";
+		  case TYPEGENname: return "typegen";
+		  default:
+			cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl;
+			abort();
+		} // switch
+	} // kindName
+);
 
 TypedefTable::~TypedefTable() {
@@ -80,5 +81,5 @@
 
 void TypedefTable::addToScope( const string & identifier, int kind, const char * locn __attribute__((unused)) ) {
-	auto scope = kindTable.currentScope();
+	KindTable::size_type scope = kindTable.currentScope();
 	debugPrint( cerr << "Adding current at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << endl );
 	kindTable.insertAt( scope, identifier, kind );
@@ -86,8 +87,8 @@
 
 void TypedefTable::addToEnclosingScope( const string & identifier, int kind, const char * locn __attribute__((unused)) ) {
-	auto scope = kindTable.currentScope() - 1 - kindTable.getNote( kindTable.currentScope() - 1 ).level;
-//	auto scope = level - kindTable.getNote( kindTable.currentScope() - 1 ).level;
+	KindTable::size_type scope = kindTable.currentScope() - 1 - kindTable.getNote( kindTable.currentScope() - 1 ).level;
+//	size_type scope = level - kindTable.getNote( kindTable.currentScope() - 1 ).level;
 	debugPrint( cerr << "Adding enclosing at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << " level " << level << " note " << kindTable.getNote( kindTable.currentScope() - 1 ).level << endl );
-	auto ret = kindTable.insertAt( scope, identifier, kind );
+	pair< KindTable::iterator, bool > ret = kindTable.insertAt( scope, identifier, kind );
 	if ( ! ret.second ) ret.first->second = kind;		// exists => update
 } // TypedefTable::addToEnclosingScope
Index: src/Parser/lex.ll
===================================================================
--- src/Parser/lex.ll	(revision 12df6fe35a1d7d73a64293320db6c3a0b195af33)
+++ src/Parser/lex.ll	(revision a065f1ffe843ea0a3ceecdf36a1210abe07a2441)
@@ -10,6 +10,6 @@
  * Created On       : Sat Sep 22 08:58:10 2001
  * Last Modified By : Peter A. Buhr
- * Last Modified On : Sun Jun 20 18:41:09 2021
- * Update Count     : 759
+ * Last Modified On : Tue Aug 30 18:39:54 2022
+ * Update Count     : 760
  */
 
@@ -314,5 +314,6 @@
 switch			{ KEYWORD_RETURN(SWITCH); }
 thread			{ KEYWORD_RETURN(THREAD); }				// C11
-_Thread_local	{ KEYWORD_RETURN(THREADLOCAL); }		// C11
+__thread		{ KEYWORD_RETURN(THREADLOCALGCC); }		// GCC
+_Thread_local	{ KEYWORD_RETURN(THREADLOCALC11); }		// C11
 throw			{ KEYWORD_RETURN(THROW); }				// CFA
 throwResume		{ KEYWORD_RETURN(THROWRESUME); }		// CFA
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 12df6fe35a1d7d73a64293320db6c3a0b195af33)
+++ src/Parser/parser.yy	(revision a065f1ffe843ea0a3ceecdf36a1210abe07a2441)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Jul  1 15:35:08 2022
-// Update Count     : 5405
+// Last Modified On : Sat Aug 27 13:21:28 2022
+// Update Count     : 5661
 //
 
@@ -58,5 +58,7 @@
 
 // lex uses __null in a boolean context, it's fine.
+#pragma GCC diagnostic ignored "-Wpragmas"
 #pragma GCC diagnostic ignored "-Wparentheses-equality"
+#pragma GCC diagnostic warning "-Wpragmas"
 
 extern DeclarationNode * parseTree;
@@ -197,4 +199,25 @@
 } // fieldDecl
 
+#define NEW_ZERO new ExpressionNode( build_constantInteger( *new string( "0" ) ) )
+#define NEW_ONE  new ExpressionNode( build_constantInteger( *new string( "1" ) ) )
+#define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right)
+#define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body."
+#define MISSING_LOW "Missing low value for up-to range so index is uninitialized."
+#define MISSING_HIGH "Missing high value for down-to range so index is uninitialized."
+
+ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
+	if ( index->initializer ) {
+		SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." );
+	} // if
+	if ( index->next ) {
+		SemanticError( yylloc, "Multiple loop indexes disallowed in for-loop declaration." );
+	} // if
+	return new ForCtrl( index->addInitializer( new InitializerNode( start ) ),
+		// NULL comp/inc => leave blank
+		comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index->name ) ) ), comp ) ) : nullptr,
+		inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto
+							OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index->name ) ) ), inc ) ) : nullptr );
+} // forCtrl
+
 ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
 	ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get());
@@ -206,7 +229,7 @@
 		distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ),
 		// NULL comp/inc => leave blank
-		comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : 0,
+		comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : nullptr,
 		inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto
-							OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) : 0 );
+							OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) : nullptr );
 } // forCtrl
 
@@ -272,5 +295,5 @@
 %token TYPEDEF
 %token EXTERN STATIC AUTO REGISTER
-%token THREADLOCAL										// C11
+%token THREADLOCALGCC THREADLOCALC11						// GCC, C11
 %token INLINE FORTRAN									// C99, extension ISO/IEC 9899:1999 Section J.5.9(1)
 %token NORETURN											// C11
@@ -346,5 +369,5 @@
 %type<ifctl> conditional_declaration
 %type<fctl> for_control_expression		for_control_expression_list
-%type<compop> inclexcl
+%type<compop> updown updowneq downupdowneq
 %type<en> subrange
 %type<decl> asm_name_opt
@@ -1239,8 +1262,8 @@
 iteration_statement:
 	WHILE '(' ')' statement								%prec THEN // CFA => while ( 1 )
-		{ $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) ); }
+		{ $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); }
 	| WHILE '(' ')' statement ELSE statement			// CFA
 		{
-			$$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) );
+			$$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) );
 			SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
 		}
@@ -1250,8 +1273,8 @@
 		{ $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); }
 	| DO statement WHILE '(' ')' ';'					// CFA => do while( 1 )
-		{ $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) ); }
+		{ $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); }
 	| DO statement WHILE '(' ')' ELSE statement			// CFA
 		{
-			$$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) );
+			$$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) );
 			SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
 		}
@@ -1304,53 +1327,179 @@
 		{ $$ = new ForCtrl( $1, $2, $4 ); }
 
-	| comma_expression									// CFA
-		{ $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
-						OperKinds::LThan, $1->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
-	| '=' comma_expression								// CFA
-		{ $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
-						OperKinds::LEThan, $2->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
-	| comma_expression inclexcl comma_expression		// CFA
-		{ $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
-	| comma_expression inclexcl comma_expression '~' comma_expression // CFA
-		{ $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, $5 ); }
-	| comma_expression ';'								// CFA
-		{ $$ = forCtrl( new ExpressionNode( build_constantInteger( *new string( "0u" ) ) ), $1, nullptr, OperKinds::LThan, nullptr, nullptr ); }
+	| '@' ';' comma_expression							// CFA, empty loop-index
+		{ $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, nullptr ); }
+	| '@' ';' comma_expression ';' comma_expression		// CFA, empty loop-index
+		{ $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, $5 ); }
+
+	| comma_expression									// CFA, anonymous loop-index
+		{ $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }
+	| downupdowneq comma_expression						// CFA, anonymous loop-index
+		{ $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }
+
+	| comma_expression updowneq comma_expression		// CFA, anonymous loop-index
+		{ $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }
+	| '@' updowneq comma_expression						// CFA, anonymous loop-index
+		{
+			if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
+			else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );
+		}
+	| comma_expression updowneq '@'						// CFA, anonymous loop-index
+		{
+			if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
+			else { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
+		}
+	| comma_expression updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index
+		{ $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }
+	| '@' updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index
+		{
+			if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
+			else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );
+		}
+	| comma_expression updowneq '@' '~' comma_expression // CFA, anonymous loop-index
+		{
+			if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
+			else { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
+		}
+	| comma_expression updowneq comma_expression '~' '@' // CFA, error
+		{ SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
+	| '@' updowneq '@'									// CFA, error
+		{ SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
+	| '@' updowneq comma_expression '~' '@'				// CFA, error
+		{ SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
+	| comma_expression updowneq '@' '~' '@'				// CFA, error
+		{ SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
+	| '@' updowneq '@' '~' '@'							// CFA, error
+		{ SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
+
 	| comma_expression ';' comma_expression				// CFA
-		{ $$ = forCtrl( $3, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
-						OperKinds::LThan, $3->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
-	| comma_expression ';' '=' comma_expression			// CFA
-		{ $$ = forCtrl( $4, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
-						OperKinds::LEThan, $4->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
-	| comma_expression ';' comma_expression inclexcl comma_expression // CFA
-		{ $$ = forCtrl( $3, $1, $3->clone(), $4, $5, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
-	| comma_expression ';' comma_expression inclexcl comma_expression '~' comma_expression // CFA
-		{ $$ = forCtrl( $3, $1, $3->clone(), $4, $5, $7 ); }
+		{ $$ = forCtrl( $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
+	| comma_expression ';' downupdowneq comma_expression // CFA
+		{ $$ = forCtrl( $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }
+
+	| comma_expression ';' comma_expression updowneq comma_expression // CFA
+		{ $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }
+	| comma_expression ';' '@' updowneq comma_expression // CFA
+		{
+			if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
+			else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, NEW_ONE );
+		}
+	| comma_expression ';' comma_expression updowneq '@' // CFA
+		{
+			if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
+			else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
+			else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, NEW_ONE );
+		}
+	| comma_expression ';' '@' updowneq '@'				// CFA, error
+		{ SemanticError( yylloc, "Missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
+
+	| comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA
+		{ $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }
+	| comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, error
+		{
+			if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
+			else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, $7 );
+		}
+	| comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA
+		{
+			if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
+			else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
+			else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, $7 );
+		}
+	| comma_expression ';' comma_expression updowneq comma_expression '~' '@' // CFA
+		{ $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }
+	| comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, error
+		{
+			if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
+			else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, nullptr );
+		}
+	| comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA
+		{
+			if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
+			else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
+			else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, nullptr );
+		}
+	| comma_expression ';' '@' updowneq '@' '~' '@' // CFA
+		{ SemanticError( yylloc, "Missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
+
+	| declaration comma_expression						// CFA
+		{ $$ = forCtrl( $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }
+	| declaration downupdowneq comma_expression			// CFA
+		{ $$ = forCtrl( $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }
+
+	| declaration comma_expression updowneq comma_expression // CFA
+		{ $$ = forCtrl( $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }
+	| declaration '@' updowneq comma_expression			// CFA
+		{
+			if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
+			else $$ = forCtrl( $1, $4, $3, nullptr, NEW_ONE );
+		}
+	| declaration comma_expression updowneq '@'			// CFA
+		{
+			if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
+			else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
+			else $$ = forCtrl( $1, $2, $3, nullptr, NEW_ONE );
+		}
+
+	| declaration comma_expression updowneq comma_expression '~' comma_expression // CFA
+		{ $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }
+	| declaration '@' updowneq comma_expression '~' comma_expression // CFA
+		{
+			if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
+			else $$ = forCtrl( $1, $4, $3, nullptr, $6 );
+		}
+	| declaration comma_expression updowneq '@' '~' comma_expression // CFA
+		{
+			if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
+			else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
+			else $$ = forCtrl( $1, $2, $3, nullptr, $6 );
+		}
+	| declaration comma_expression updowneq comma_expression '~' '@' // CFA
+		{ $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }
+	| declaration '@' updowneq comma_expression '~' '@' // CFA
+		{
+			if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
+			else $$ = forCtrl( $1, $4, $3, nullptr, nullptr );
+		}
+	| declaration comma_expression updowneq '@' '~' '@'	// CFA
+		{
+			if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
+			else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
+			else $$ = forCtrl( $1, $2, $3, nullptr, nullptr );
+		}
+	| declaration '@' updowneq '@' '~' '@'				// CFA, error
+		{ SemanticError( yylloc, "Missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
 
 	| comma_expression ';' TYPEDEFname					// CFA, array type
 		{
-			SemanticError( yylloc, "Array interator is currently unimplemented." ); $$ = nullptr;
-			$$ = forCtrl( new ExpressionNode( build_varref( $3 ) ), $1, nullptr, OperKinds::Range, nullptr, nullptr );
-		}
-
-		// There is a S/R conflicit if ~ and -~ are factored out.
-	| comma_expression ';' comma_expression '~' '@'		// CFA
-		{ $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
-	| comma_expression ';' comma_expression ErangeDown '@' // CFA
-		{ $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
-	| comma_expression ';' comma_expression '~' '@' '~' comma_expression // CFA
-		{ $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, $7 ); }
-	| comma_expression ';' comma_expression ErangeDown '@' '~' comma_expression // CFA
-		{ $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, $7 ); }
-	| comma_expression ';' comma_expression '~' '@' '~' '@' // CFA
-		{ $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, nullptr ); }
+			SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr;
+			//$$ = forCtrl( new ExpressionNode( build_varref( $3 ) ), $1, nullptr, OperKinds::Range, nullptr, nullptr );
+		}
+	| comma_expression ';' downupdowneq TYPEDEFname		// CFA, array type
+		{
+			if ( $3 == OperKinds::LEThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, "All enumation ranges are equal (all values). Remove \"=~\"." ); $$ = nullptr; }
+			SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr;
+		}
  	;
 
-inclexcl:
+downupdowneq:
+	ErangeDown
+		{ $$ = OperKinds::GThan; }
+	| ErangeUpEq
+		{ $$ = OperKinds::LEThan; }
+	| ErangeDownEq
+		{ $$ = OperKinds::GEThan; }
+ 	;
+
+updown:
 	'~'
 		{ $$ = OperKinds::LThan; }
+	| ErangeDown
+		{ $$ = OperKinds::GThan; }
+ 	;
+
+updowneq:
+	updown
 	| ErangeUpEq
 		{ $$ = OperKinds::LEThan; }
-	| ErangeDown
-		{ $$ = OperKinds::GThan; }
 	| ErangeDownEq
 		{ $$ = OperKinds::GEThan; }
@@ -1935,6 +2084,8 @@
 	| REGISTER
 		{ $$ = DeclarationNode::newStorageClass( Type::Register ); }
-	| THREADLOCAL										// C11
-		{ $$ = DeclarationNode::newStorageClass( Type::Threadlocal ); }
+	| THREADLOCALGCC										// GCC
+		{ $$ = DeclarationNode::newStorageClass( Type::ThreadlocalGcc ); }
+	| THREADLOCALC11										// C11
+		{ $$ = DeclarationNode::newStorageClass( Type::ThreadlocalC11 ); }
 		// Put function specifiers here to simplify parsing rules, but separate them semantically.
 	| INLINE											// C99
