Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision f8729be0e90d582895a768c6e50c1bf64f8f790b)
+++ src/Parser/DeclarationNode.cc	(revision 692c1cc34a498a7e67b3530da9dae4fecc12439c)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 12:34:05 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Aug  8 17:07:00 2022
-// Update Count     : 1185
+// Last Modified On : Thu Feb 16 14:12:03 2023
+// Update Count     : 1388
 //
 
@@ -154,7 +154,10 @@
 	} // if
 
-	for ( Attribute * attr: reverseIterate( attributes ) ) {
-		os << string( indent + 2, ' ' ) << "attr " << attr->name.c_str();
-	} // for
+	if ( ! attributes.empty() ) {
+		os << string( indent + 2, ' ' ) << "with attributes " << endl;
+		for ( Attribute * attr: reverseIterate( attributes ) ) {
+			os << string( indent + 4, ' ' ) << attr->name.c_str() << endl;
+		} // for
+	} // if
 
 	os << endl;
@@ -244,5 +247,6 @@
 	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.anon = name == nullptr;
+	newnode->type->aggregate.name = newnode->type->aggregate.anon ? new string( DeclarationNode::anonymous.newName() ) : name;
 	newnode->type->aggregate.actuals = actuals;
 	newnode->type->aggregate.fields = fields;
@@ -250,5 +254,4 @@
 	newnode->type->aggregate.tagged = false;
 	newnode->type->aggregate.parent = nullptr;
-	newnode->type->aggregate.anon = name == nullptr;
 	return newnode;
 } // DeclarationNode::newAggregate
@@ -257,8 +260,8 @@
 	DeclarationNode * newnode = new DeclarationNode;
 	newnode->type = new TypeData( TypeData::Enum );
-	newnode->type->enumeration.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
+	newnode->type->enumeration.anon = name == nullptr;
+	newnode->type->enumeration.name = newnode->type->enumeration.anon ? new string( DeclarationNode::anonymous.newName() ) : name;
 	newnode->type->enumeration.constants = constants;
 	newnode->type->enumeration.body = body;
-	newnode->type->enumeration.anon = name == nullptr;
 	newnode->type->enumeration.typed = typed;
 	newnode->type->enumeration.hiding = hiding;
@@ -989,13 +992,17 @@
 	for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) {
 		try {
-			bool extracted = false;
-			bool anon = false;
+			bool extracted = false, anon = false;
+			AggregateDecl * unionDecl = nullptr;
+
 			if ( DeclarationNode * extr = cur->extractAggregate() ) {
 				// handle the case where a structure declaration is contained within an object or type declaration
+
 				Declaration * decl = extr->build();
 				if ( decl ) {
-					// hoist the structure declaration
+					// Remember the declaration if it is a union aggregate ?
+					unionDecl = dynamic_cast<UnionDecl *>( decl );
+
 					decl->location = cur->location;
-					* out++ = decl;
+					*out++ = decl;
 
 					// need to remember the cases where a declaration contains an anonymous aggregate definition
@@ -1003,7 +1010,8 @@
 					assert( extr->type );
 					if ( extr->type->kind == TypeData::Aggregate ) {
+						// typedef struct { int A } B is the only case?
 						anon = extr->type->aggregate.anon;
 					} else if ( extr->type->kind == TypeData::Enum ) {
-						// xxx - is it useful to have an implicit anonymous enum member?
+						// typedef enum { A } B is the only case?
 						anon = extr->type->enumeration.anon;
 					}
@@ -1014,4 +1022,33 @@
 			Declaration * decl = cur->build();
 			if ( decl ) {
+				if ( TypedefDecl * typedefDecl = dynamic_cast<TypedefDecl *>( decl ) ) {
+					if ( unionDecl ) {					// is the typedef alias a union aggregate ?
+						// This code handles a special issue with the attribute transparent_union.
+						//
+						//    typedef union U { int i; } typedef_name __attribute__(( aligned(16) )) __attribute__(( transparent_union ))
+						//
+						// Here the attribute aligned goes with the typedef_name, so variables declared of this type are
+						// aligned.  However, the attribute transparent_union must be moved from the typedef_name to
+						// alias union U.  Currently, this is the only know attribute that must be moved from typedef to
+						// alias.
+
+						// If typedef is an alias for a union, then its alias type was hoisted above and remembered.
+						if ( UnionInstType * unionInstType = dynamic_cast<UnionInstType *>( typedefDecl->base ) ) {
+							// Remove all transparent_union attributes from typedef and move to alias union.
+							list<Attribute *>::iterator attr;
+							for ( attr = unionInstType->attributes.begin(); attr != unionInstType->attributes.end(); ) { // forward order
+								if ( (*attr)->name == "transparent_union" || (*attr)->name == "__transparent_union__" ) {
+									list<Attribute *>::iterator cur = attr; // remember current node
+									attr++;				// advance iterator
+									unionDecl->attributes.emplace_back( *cur ); // move current
+									unionInstType->attributes.erase( cur ); // remove current
+								} else {
+									attr++;				// advance iterator
+								} // if
+							} // for
+						} // if
+					} // if
+				} // if
+
 				// don't include anonymous declaration for named aggregates, but do include them for anonymous aggregates, e.g.:
 				// struct S {
