Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/CodeGen/CodeGenerator.cc	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -164,5 +164,5 @@
 		previsit( (BaseSyntaxNode *)node );
 		GuardAction( [this, node](){
-			if ( printExprTypes ) {
+			if ( printExprTypes && node->result ) {
 				output << " /* " << genType( node->result, "", pretty, genC ) << " */ ";
 			}
@@ -224,8 +224,8 @@
 
 	void CodeGenerator::handleAggregate( AggregateDecl * aggDecl, const std::string & kind ) {
-		if( ! aggDecl->get_parameters().empty() && ! genC ) {
+		if( ! aggDecl->parameters.empty() && ! genC ) {
 			// assertf( ! genC, "Aggregate type parameters should not reach code generation." );
 			output << "forall(";
-			genCommaList( aggDecl->get_parameters().begin(), aggDecl->get_parameters().end() );
+			genCommaList( aggDecl->parameters.begin(), aggDecl->parameters.end() );
 			output << ")" << endl;
 			output << indent;
@@ -233,9 +233,9 @@
 
 		output << kind;
-		genAttributes( aggDecl->get_attributes() );
-		output << aggDecl->get_name();
+		genAttributes( aggDecl->attributes );
+		output << aggDecl->name;
 
 		if ( aggDecl->has_body() ) {
-			std::list< Declaration * > & memb = aggDecl->get_members();
+			std::list< Declaration * > & memb = aggDecl->members;
 			output << " {" << endl;
 
Index: src/CodeGen/GenType.cc
===================================================================
--- src/CodeGen/GenType.cc	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/CodeGen/GenType.cc	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -48,6 +48,8 @@
 		void postvisit( ZeroType * zeroType );
 		void postvisit( OneType * oneType );
+		void postvisit( GlobalScopeType * globalType );
 		void postvisit( TraitInstType * inst );
 		void postvisit( TypeofType * typeof );
+		void postvisit( QualifiedType * qualType );
 
 	  private:
@@ -291,4 +293,9 @@
 	}
 
+	void GenType::postvisit( GlobalScopeType * globalType ) {
+		assertf( ! genC, "Global scope type should not reach code generation." );
+		handleQualifiers( globalType );
+	}
+
 	void GenType::postvisit( TraitInstType * inst ) {
 		assertf( ! genC, "Trait types should not reach code generation." );
@@ -307,4 +314,12 @@
 	}
 
+	void GenType::postvisit( QualifiedType * qualType ) {
+		assertf( ! genC, "Qualified types should not reach code generation." );
+		std::ostringstream os;
+		os << genType( qualType->parent, "", pretty, genC, lineMarks ) << "." << genType( qualType->child, "", pretty, genC, lineMarks ) << typeString;
+		typeString = os.str();
+		handleQualifiers( qualType );
+	}
+
 	void GenType::handleQualifiers( Type * type ) {
 		if ( type->get_const() ) {
Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/Common/PassVisitor.h	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -133,4 +133,5 @@
 	virtual void visit( ArrayType * arrayType ) override final;
 	virtual void visit( ReferenceType * referenceType ) override final;
+	virtual void visit( QualifiedType * qualType ) override final;
 	virtual void visit( FunctionType * functionType ) override final;
 	virtual void visit( StructInstType * aggregateUseType ) override final;
@@ -145,4 +146,5 @@
 	virtual void visit( ZeroType * zeroType ) override final;
 	virtual void visit( OneType * oneType ) override final;
+	virtual void visit( GlobalScopeType * globalType ) override final;
 
 	virtual void visit( Designation * designation ) override final;
@@ -233,4 +235,5 @@
 	virtual Type * mutate( ArrayType * arrayType ) override final;
 	virtual Type * mutate( ReferenceType * referenceType ) override final;
+	virtual Type * mutate( QualifiedType * qualType ) override final;
 	virtual Type * mutate( FunctionType * functionType ) override final;
 	virtual Type * mutate( StructInstType * aggregateUseType ) override final;
@@ -245,4 +248,5 @@
 	virtual Type * mutate( ZeroType * zeroType ) override final;
 	virtual Type * mutate( OneType * oneType ) override final;
+	virtual Type * mutate( GlobalScopeType * globalType ) override final;
 
 	virtual Designation * mutate( Designation * designation ) override final;
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/Common/PassVisitor.impl.h	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -2262,4 +2262,28 @@
 
 //--------------------------------------------------------------------------
+// QualifiedType
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( QualifiedType * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+	maybeAccept_impl( node->parent, *this );
+	maybeAccept_impl( node->child, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Type * PassVisitor< pass_type >::mutate( QualifiedType * node ) {
+	MUTATE_START( node );
+
+	maybeMutate_impl( node->forall, *this );
+	maybeMutate_impl( node->parent, *this );
+	maybeMutate_impl( node->child, *this );
+
+	MUTATE_END( Type, node );
+}
+
+//--------------------------------------------------------------------------
 // FunctionType
 template< typename pass_type >
@@ -2554,4 +2578,24 @@
 
 //--------------------------------------------------------------------------
+// GlobalScopeType
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( GlobalScopeType * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->forall, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Type * PassVisitor< pass_type >::mutate( GlobalScopeType * node ) {
+	MUTATE_START( node );
+
+	maybeMutate_impl( node->forall, *this );
+
+	MUTATE_END( Type, node );
+}
+
+//--------------------------------------------------------------------------
 // Designation
 template< typename pass_type >
Index: src/Concurrency/Keywords.cc
===================================================================
--- src/Concurrency/Keywords.cc	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/Concurrency/Keywords.cc	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -501,13 +501,13 @@
 	void MutexKeyword::postvisit(StructDecl* decl) {
 
-		if( decl->name == "monitor_desc" ) {
+		if( decl->name == "monitor_desc" && decl->body ) {
 			assert( !monitor_decl );
 			monitor_decl = decl;
 		}
-		else if( decl->name == "monitor_guard_t" ) {
+		else if( decl->name == "monitor_guard_t" && decl->body ) {
 			assert( !guard_decl );
 			guard_decl = decl;
 		}
-		else if( decl->name == "monitor_dtor_guard_t" ) {
+		else if( decl->name == "monitor_dtor_guard_t" && decl->body ) {
 			assert( !dtor_guard_decl );
 			dtor_guard_decl = decl;
Index: src/InitTweak/FixInit.cc
===================================================================
--- src/InitTweak/FixInit.cc	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/InitTweak/FixInit.cc	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -1163,7 +1163,7 @@
 
 			std::string fname = getFunctionName( appExpr );
-			if ( fname == function->get_name() ) {
+			if ( fname == function->name ) {
 				// call to same kind of function
-				Expression * firstParam = appExpr->get_args().front();
+				Expression * firstParam = appExpr->args.front();
 
 				if ( isThisExpression( firstParam, thisParam ) ) {
@@ -1174,6 +1174,6 @@
 					// if first parameter is a member expression on the this parameter,
 					// then remove the member from unhandled set.
-					if ( isThisExpression( memberExpr->get_aggregate(), thisParam ) ) {
-						unhandled.erase( memberExpr->get_member() );
+					if ( isThisExpression( memberExpr->aggregate, thisParam ) ) {
+						unhandled.erase( memberExpr->member );
 					}
 				}
Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/Parser/DeclarationNode.cc	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -254,10 +254,27 @@
 } // DeclarationNode::newFromTypedef
 
+DeclarationNode * DeclarationNode::newFromGlobalScope() {
+	DeclarationNode * newnode = new DeclarationNode;
+	newnode->type = new TypeData( TypeData::GlobalScope );
+	return newnode;
+}
+
+DeclarationNode * DeclarationNode::newQualifiedType( DeclarationNode * parent, DeclarationNode * child) {
+	DeclarationNode * newnode = new DeclarationNode;
+	newnode->type = new TypeData( TypeData::Qualified );
+	newnode->type->qualified.parent = parent->type;
+	newnode->type->qualified.child = child->type;
+	parent->type = nullptr;
+	child->type = nullptr;
+	delete parent;
+	delete child;
+	return newnode;
+}
+
 DeclarationNode * DeclarationNode::newAggregate( Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
-	assert( name );
 	DeclarationNode * newnode = new DeclarationNode;
 	newnode->type = new TypeData( TypeData::Aggregate );
 	newnode->type->aggregate.kind = kind;
-	newnode->type->aggregate.name = name;
+	newnode->type->aggregate.name =  name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
 	newnode->type->aggregate.actuals = actuals;
 	newnode->type->aggregate.fields = fields;
@@ -265,14 +282,15 @@
 	newnode->type->aggregate.tagged = false;
 	newnode->type->aggregate.parent = nullptr;
+	newnode->type->aggregate.anon = name == nullptr;
 	return newnode;
 } // DeclarationNode::newAggregate
 
 DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body ) {
-	assert( name );
 	DeclarationNode * newnode = new DeclarationNode;
 	newnode->type = new TypeData( TypeData::Enum );
-	newnode->type->enumeration.name = name;
+	newnode->type->enumeration.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
 	newnode->type->enumeration.constants = constants;
 	newnode->type->enumeration.body = body;
+	newnode->type->enumeration.anon = name == nullptr;
 	return newnode;
 } // DeclarationNode::newEnum
@@ -953,10 +971,23 @@
 	for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) {
 		try {
+			bool extracted = false;
+			bool anon = false;
 			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
 					decl->location = cur->location;
 					* out++ = decl;
+
+					// need to remember the cases where a declaration contains an anonymous aggregate definition
+					extracted = true;
+					assert( extr->type );
+					if ( extr->type->kind == TypeData::Aggregate ) {
+						anon = extr->type->aggregate.anon;
+					} else if ( extr->type->kind == TypeData::Enum ) {
+						// xxx - is it useful to have an implicit anonymous enum member?
+						anon = extr->type->enumeration.anon;
+					}
 				} // if
 				delete extr;
@@ -965,6 +996,14 @@
 			Declaration * decl = cur->build();
 			if ( decl ) {
-				decl->location = cur->location;
-				* out++ = decl;
+				// don't include anonymous declaration for named aggregates, but do include them for anonymous aggregates, e.g.:
+				// struct S {
+				//   struct T { int x; }; // no anonymous member
+				//   struct { int y; };   // anonymous member
+				//   struct T;            // anonymous member
+				// };
+				if ( ! (extracted && decl->name == "" && ! anon) ) {
+					decl->location = cur->location;
+					* out++ = decl;
+				}
 			} // if
 		} catch( SemanticErrorException &e ) {
@@ -978,4 +1017,5 @@
 } // buildList
 
+// currently only builds assertions, function parameters, and return values
 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList ) {
 	SemanticErrorException errors;
@@ -985,20 +1025,27 @@
 		try {
 			Declaration * decl = cur->build();
-			if ( decl ) {
-				if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
-					dwt->location = cur->location;
-					* out++ = dwt;
-				} else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) {
-					StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->get_name() );
-					auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
-					obj->location = cur->location;
-					* out++ = obj;
-					delete agg;
-				} else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) {
-					UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->get_name() );
-					auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
-					obj->location = cur->location;
-					* out++ = obj;
-				} // if
+			assert( decl );
+			if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
+				dwt->location = cur->location;
+				* out++ = dwt;
+			} else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) {
+				// e.g., int foo(struct S) {}
+				StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->name );
+				auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
+				obj->location = cur->location;
+				* out++ = obj;
+				delete agg;
+			} else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) {
+				// e.g., int foo(union U) {}
+				UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->name );
+				auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
+				obj->location = cur->location;
+				* out++ = obj;
+			} else if ( EnumDecl * agg = dynamic_cast< EnumDecl * >( decl ) ) {
+				// e.g., int foo(enum E) {}
+				EnumInstType * inst = new EnumInstType( Type::Qualifiers(), agg->name );
+				auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
+				obj->location = cur->location;
+				* out++ = obj;
 			} // if
 		} catch( SemanticErrorException &e ) {
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/Parser/ParseNode.h	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -231,4 +231,6 @@
 	static DeclarationNode * newForall( DeclarationNode * );
 	static DeclarationNode * newFromTypedef( const std::string * );
+	static DeclarationNode * newFromGlobalScope();
+	static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
 	static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
 	static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/Parser/TypeData.cc	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -37,4 +37,5 @@
 	  case Reference:
 	  case EnumConstant:
+	  case GlobalScope:
 		// nothing else to initialize
 		break;
@@ -62,4 +63,5 @@
 		enumeration.constants = nullptr;
 		enumeration.body = false;
+		enumeration.anon = false;
 		break;
 	  case Aggregate:
@@ -73,4 +75,5 @@
 		aggregate.tagged = false;
 		aggregate.parent = nullptr;
+		aggregate.anon = false;
 		break;
 	  case AggregateInst:
@@ -98,4 +101,7 @@
 	  case Builtin:
 		// builtin = new Builtin_t;
+		case Qualified:
+		qualified.parent = nullptr;
+		qualified.child = nullptr;
 		break;
 	} // switch
@@ -112,4 +118,5 @@
 	  case Reference:
 	  case EnumConstant:
+	  case GlobalScope:
 		// nothing to destroy
 		break;
@@ -165,4 +172,7 @@
 		// delete builtin;
 		break;
+	  case Qualified:
+		delete qualified.parent;
+		delete qualified.child;
 	} // switch
 } // TypeData::~TypeData
@@ -180,4 +190,5 @@
 	  case Pointer:
 	  case Reference:
+	  case GlobalScope:
 		// nothing else to copy
 		break;
@@ -207,4 +218,5 @@
 		newtype->aggregate.fields = maybeClone( aggregate.fields );
 		newtype->aggregate.body = aggregate.body;
+		newtype->aggregate.anon = aggregate.anon;
 		newtype->aggregate.tagged = aggregate.tagged;
 		newtype->aggregate.parent = aggregate.parent ? new string( *aggregate.parent ) : nullptr;
@@ -219,4 +231,5 @@
 		newtype->enumeration.constants = maybeClone( enumeration.constants );
 		newtype->enumeration.body = enumeration.body;
+		newtype->enumeration.anon = enumeration.anon;
 		break;
 	  case Symbolic:
@@ -238,4 +251,8 @@
 		newtype->builtintype = builtintype;
 		break;
+		case Qualified:
+		newtype->qualified.parent = maybeClone( qualified.parent );
+		newtype->qualified.child = maybeClone( qualified.child );
+		break;
 	} // switch
 	return newtype;
@@ -406,4 +423,33 @@
 	} // switch
 } // TypeData::print
+
+const std::string * TypeData::leafName() const {
+	switch ( kind ) {
+	  case Unknown:
+	  case Pointer:
+	  case Reference:
+	  case EnumConstant:
+	  case GlobalScope:
+	  case Array:
+	  case Basic:
+	  case Function:
+	  case AggregateInst:
+	  case Tuple:
+	  case Typeof:
+	  case Builtin:
+		assertf(false, "Tried to get leaf name from kind without a name: %d", kind);
+		break;
+	  case Aggregate:
+		return aggregate.name;
+	  case Enum:
+		return enumeration.name;
+	  case Symbolic:
+	  case SymbolicInst:
+		return symbolic.name;
+	  case Qualified:
+		return qualified.child->leafName();
+	} // switch
+	assert(false);
+}
 
 
@@ -465,5 +511,5 @@
 		return new EnumInstType( buildQualifiers( td ), "" );
 	  case TypeData::SymbolicInst:
-		return buildSymbolicInst( td );;
+		return buildSymbolicInst( td );
 	  case TypeData::Tuple:
 		return buildTuple( td );
@@ -480,4 +526,8 @@
 			return new VarArgsType( buildQualifiers( td ) );
 		}
+	  case TypeData::GlobalScope:
+		return new GlobalScopeType();
+		case TypeData::Qualified:
+		return new QualifiedType( buildQualifiers( td ), typebuild( td->qualified.parent ), typebuild( td->qualified.child ) );
 	  case TypeData::Symbolic:
 	  case TypeData::Enum:
@@ -485,4 +535,5 @@
 		assert( false );
 	} // switch
+
 	return nullptr;
 } // typebuild
@@ -893,10 +944,10 @@
 	assert( td->kind == TypeData::Function );
 	FunctionType * ft = new FunctionType( buildQualifiers( td ), ! td->function.params || td->function.params->hasEllipsis );
-	buildList( td->function.params, ft->get_parameters() );
-	buildForall( td->forall, ft->get_forall() );
+	buildList( td->function.params, ft->parameters );
+	buildForall( td->forall, ft->forall );
 	if ( td->base ) {
 		switch ( td->base->kind ) {
 		  case TypeData::Tuple:
-			buildList( td->base->tuple, ft->get_returnVals() );
+			buildList( td->base->tuple, ft->returnVals );
 			break;
 		  default:
Index: src/Parser/TypeData.h
===================================================================
--- src/Parser/TypeData.h	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/Parser/TypeData.h	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -27,5 +27,5 @@
 struct TypeData {
 	enum Kind { Basic, Pointer, Array, Reference, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic,
-				SymbolicInst, Tuple, Typeof, Builtin, Unknown };
+				SymbolicInst, Tuple, Typeof, Builtin, GlobalScope, Qualified, Unknown };
 
 	struct Aggregate_t {
@@ -36,4 +36,5 @@
 		DeclarationNode * fields;
 		bool body;
+		bool anon;
 
 		bool tagged;
@@ -57,4 +58,5 @@
 		DeclarationNode * constants;
 		bool body;
+		bool anon;
 	};
 
@@ -75,4 +77,9 @@
 	};
 
+	struct Qualified_t { // qualified type S.T
+		TypeData * parent;
+		TypeData * child;
+	};
+
 	CodeLocation location;
 
@@ -88,12 +95,11 @@
 	DeclarationNode * forall;
 
-	// Basic_t basic;
 	Aggregate_t aggregate;
 	AggInst_t aggInst;
 	Array_t array;
 	Enumeration_t enumeration;
-	// Variable_t variable;
 	Function_t function;
 	Symbolic_t symbolic;
+	Qualified_t qualified;
 	DeclarationNode * tuple;
 	ExpressionNode * typeexpr;
@@ -103,4 +109,6 @@
 	void print( std::ostream &, int indent = 0 ) const;
 	TypeData * clone() const;
+
+	const std::string * leafName() const;
 };
 
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/Parser/parser.yy	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Jul 11 11:20:51 2018
-// Update Count     : 3738
+// Last Modified On : Wed Jul 11 11:55:24 2018
+// Update Count     : 3739
 //
 
@@ -1825,12 +1825,12 @@
 		{ $$ = DeclarationNode::newFromTypedef( $1 ); }
 	| '.' TYPEDEFname
-		{ SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
+		{ $$ = DeclarationNode::newQualifiedType( DeclarationNode::newFromGlobalScope(), DeclarationNode::newFromTypedef( $2 ) ); }
 	| type_name '.' TYPEDEFname
-		{ SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
+		{ $$ = DeclarationNode::newQualifiedType( $1, DeclarationNode::newFromTypedef( $3 ) ); }
 	| typegen_name
 	| '.' typegen_name
-		{ SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
+		{ $$ = DeclarationNode::newQualifiedType( DeclarationNode::newFromGlobalScope(), $2 ); }
 	| type_name '.' typegen_name
-		{ SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
+		{ $$ = DeclarationNode::newQualifiedType( $1, $3 ); }
 	;
 
@@ -1863,5 +1863,5 @@
 		{ forall = false; }								// reset
 	  '{' field_declaration_list_opt '}' type_parameters_opt
-		{ $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), $7, $5, true )->addQualifiers( $2 ); }
+		{ $$ = DeclarationNode::newAggregate( $1, nullptr, $7, $5, true )->addQualifiers( $2 ); }
 	| aggregate_key attribute_list_opt no_attr_identifier fred
 		{
@@ -1873,5 +1873,6 @@
 	| aggregate_key attribute_list_opt type_name fred
 		{
-			typedefTable.makeTypedef( *$3->type->symbolic.name, forall | typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname ); // create typedef
+			// for type_name can be a qualified type name S.T, in which case only the last name in the chain needs a typedef (other names in the chain should already have one)
+			typedefTable.makeTypedef( *$3->type->leafName(), forall | typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname ); // create typedef
 			forall = false;								// reset
 		}
@@ -1936,10 +1937,8 @@
 		{ distExt( $3 ); $$ = distAttr( $2, $3 ); }		// mark all fields in list
 	| typedef_declaration ';'							// CFA
-		{ SemanticError( yylloc, "Typedef in aggregate is currently unimplemented." ); $$ = nullptr; }
 	| cfa_field_declaring_list ';'						// CFA, new style field declaration
 	| EXTENSION cfa_field_declaring_list ';'			// GCC
 		{ distExt( $2 ); $$ = $2; }						// mark all fields in list
 	| cfa_typedef_declaration ';'						// CFA
-		{ SemanticError( yylloc, "Typedef in aggregate is currently unimplemented." ); $$ = nullptr; }
 	| static_assert										// C11
 	;
@@ -1990,5 +1989,5 @@
 enum_type:												// enum
 	ENUM attribute_list_opt '{' enumerator_list comma_opt '}'
-		{ $$ = DeclarationNode::newEnum( new string( DeclarationNode::anonymous.newName() ), $4, true )->addQualifiers( $2 ); }
+		{ $$ = DeclarationNode::newEnum( nullptr, $4, true )->addQualifiers( $2 ); }
 	| ENUM attribute_list_opt no_attr_identifier
 		{ typedefTable.makeTypedef( *$3 ); }
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/SymTab/Indexer.cc	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -272,4 +272,20 @@
 	}
 
+	NamedTypeDecl *Indexer::globalLookupType( const std::string &id ) const {
+		return lookupTypeAtScope( id, 0 );
+	}
+
+	StructDecl *Indexer::globalLookupStruct( const std::string &id ) const {
+		return lookupStructAtScope( id, 0 );
+	}
+
+	UnionDecl *Indexer::globalLookupUnion( const std::string &id ) const {
+		return lookupUnionAtScope( id, 0 );
+	}
+
+	EnumDecl *Indexer::globalLookupEnum( const std::string &id ) const {
+		return lookupEnumAtScope( id, 0 );
+	}
+
 	EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
 		if ( ! tables ) return 0;
@@ -347,4 +363,5 @@
 		if ( ! tables ) return 0;
 		if ( tables->scope < scope ) return 0;
+		if ( tables->scope > scope ) return tables->base.lookupTypeAtScope( id, scope );
 
 		TypeTable::const_iterator ret = tables->typeTable.find( id );
@@ -355,4 +372,5 @@
 		if ( ! tables ) return 0;
 		if ( tables->scope < scope ) return 0;
+		if ( tables->scope > scope ) return tables->base.lookupStructAtScope( id, scope );
 
 		StructTable::const_iterator ret = tables->structTable.find( id );
@@ -363,4 +381,5 @@
 		if ( ! tables ) return 0;
 		if ( tables->scope < scope ) return 0;
+		if ( tables->scope > scope ) return tables->base.lookupEnumAtScope( id, scope );
 
 		EnumTable::const_iterator ret = tables->enumTable.find( id );
@@ -371,4 +390,5 @@
 		if ( ! tables ) return 0;
 		if ( tables->scope < scope ) return 0;
+		if ( tables->scope > scope ) return tables->base.lookupUnionAtScope( id, scope );
 
 		UnionTable::const_iterator ret = tables->unionTable.find( id );
@@ -379,4 +399,5 @@
 		if ( ! tables ) return 0;
 		if ( tables->scope < scope ) return 0;
+		if ( tables->scope > scope ) return tables->base.lookupTraitAtScope( id, scope );
 
 		TraitTable::const_iterator ret = tables->traitTable.find( id );
@@ -486,11 +507,17 @@
 
 	bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) {
-		if ( existing->get_base() == 0 ) {
+		if ( existing->base == nullptr ) {
 			return false;
-		} else if ( added->get_base() == 0 ) {
+		} else if ( added->base == nullptr ) {
 			return true;
 		} else {
-			SemanticError( added, "redeclaration of " );
-		}
+			assert( existing->base && added->base );
+			// typedef redeclarations are errors only if types are different
+			if ( ! ResolvExpr::typesCompatible( existing->base, added->base, Indexer() ) ) {
+				SemanticError( added->location, "redeclaration of " + added->name );
+			}
+		}
+		// does not need to be added to the table if both existing and added have a base that are the same
+		return true;
 	}
 
@@ -499,5 +526,5 @@
 		makeWritable();
 
-		const std::string &id = decl->get_name();
+		const std::string &id = decl->name;
 		TypeTable::iterator existing = tables->typeTable.find( id );
 		if ( existing == tables->typeTable.end() ) {
@@ -532,5 +559,5 @@
 		makeWritable();
 
-		const std::string &id = decl->get_name();
+		const std::string &id = decl->name;
 		StructTable::iterator existing = tables->structTable.find( id );
 		if ( existing == tables->structTable.end() ) {
@@ -551,5 +578,5 @@
 		makeWritable();
 
-		const std::string &id = decl->get_name();
+		const std::string &id = decl->name;
 		EnumTable::iterator existing = tables->enumTable.find( id );
 		if ( existing == tables->enumTable.end() ) {
@@ -575,5 +602,5 @@
 		makeWritable();
 
-		const std::string &id = decl->get_name();
+		const std::string &id = decl->name;
 		UnionTable::iterator existing = tables->unionTable.find( id );
 		if ( existing == tables->unionTable.end() ) {
@@ -594,5 +621,5 @@
 		makeWritable();
 
-		const std::string &id = decl->get_name();
+		const std::string &id = decl->name;
 		TraitTable::iterator existing = tables->traitTable.find( id );
 		if ( existing == tables->traitTable.end() ) {
Index: src/SymTab/Indexer.h
===================================================================
--- src/SymTab/Indexer.h	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/SymTab/Indexer.h	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -70,4 +70,13 @@
 		/// Gets the top-most trait declaration with the given ID
 		TraitDecl *lookupTrait( const std::string &id ) const;
+
+		/// Gets the type declaration with the given ID at global scope
+		NamedTypeDecl *globalLookupType( const std::string &id ) const;
+		/// Gets the struct declaration with the given ID at global scope
+		StructDecl *globalLookupStruct( const std::string &id ) const;
+		/// Gets the union declaration with the given ID at global scope
+		UnionDecl *globalLookupUnion( const std::string &id ) const;
+		/// Gets the enum declaration with the given ID at global scope
+		EnumDecl *globalLookupEnum( const std::string &id ) const;
 
 		void print( std::ostream &os, int indent = 0 ) const;
Index: src/SymTab/Mangler.cc
===================================================================
--- src/SymTab/Mangler.cc	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/SymTab/Mangler.cc	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -60,4 +60,5 @@
 				void postvisit( ZeroType * zeroType );
 				void postvisit( OneType * oneType );
+				void postvisit( QualifiedType * qualType );
 
 				std::string get_mangleName() { return mangleName.str(); }
@@ -171,6 +172,6 @@
 					"w",	// SignedInt128
 					"Uw",	// UnsignedInt128
-					"x",   // Float80
-					"y",   // Float128
+					"x",	// Float80
+					"y",	// Float128
 				};
 				static_assert(
@@ -312,4 +313,10 @@
 			void Mangler::postvisit( OneType * ) {
 				mangleName << "O";
+			}
+
+			void Mangler::postvisit( QualifiedType * qualType ) {
+				maybeAccept( qualType->parent, *visitor );
+				mangleName << "__";
+				maybeAccept( qualType->child, *visitor );
 			}
 
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/SymTab/Validate.cc	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -77,17 +77,29 @@
 class SwitchStmt;
 
-#define debugPrint( x ) if ( doDebug ) { std::cout << x; }
+#define debugPrint( x ) if ( doDebug ) x
 
 namespace SymTab {
+	/// hoists declarations that are difficult to hoist while parsing
+	struct HoistTypeDecls final : public WithDeclsToAdd {
+		void previsit( SizeofExpr * );
+		void previsit( AlignofExpr * );
+		void previsit( UntypedOffsetofExpr * );
+		void handleType( Type * );
+	};
+
+	struct FixQualifiedTypes final : public WithIndexer {
+		Type * postmutate( QualifiedType * );
+	};
+
 	struct HoistStruct final : public WithDeclsToAdd, public WithGuards {
 		/// Flattens nested struct types
 		static void hoistStruct( std::list< Declaration * > &translationUnit );
 
-		void previsit( EnumInstType * enumInstType );
-		void previsit( StructInstType * structInstType );
-		void previsit( UnionInstType * unionInstType );
 		void previsit( StructDecl * aggregateDecl );
 		void previsit( UnionDecl * aggregateDecl );
 		void previsit( StaticAssertDecl * assertDecl );
+		void previsit( StructInstType * type );
+		void previsit( UnionInstType * type );
+		void previsit( EnumInstType * type );
 
 	  private:
@@ -112,5 +124,5 @@
 
 	/// Associates forward declarations of aggregates with their definitions
-	struct LinkReferenceToTypes final : public WithIndexer, public WithGuards {
+	struct LinkReferenceToTypes final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes>, public WithShortCircuiting {
 		LinkReferenceToTypes( const Indexer *indexer );
 		void postvisit( TypeInstType *typeInst );
@@ -120,4 +132,6 @@
 		void postvisit( UnionInstType *unionInst );
 		void postvisit( TraitInstType *traitInst );
+		void previsit( QualifiedType * qualType );
+		void postvisit( QualifiedType * qualType );
 
 		void postvisit( EnumDecl *enumDecl );
@@ -165,9 +179,11 @@
 	};
 
-	struct EliminateTypedef final : public WithVisitorRef<EliminateTypedef>, public WithGuards {
-		EliminateTypedef() : scopeLevel( 0 ) {}
+	struct ReplaceTypedef final : public WithVisitorRef<ReplaceTypedef>, public WithGuards, public WithShortCircuiting, public WithDeclsToAdd {
+		ReplaceTypedef() : scopeLevel( 0 ) {}
 		/// Replaces typedefs by forward declarations
-		static void eliminateTypedef( std::list< Declaration * > &translationUnit );
-
+		static void replaceTypedef( std::list< Declaration * > &translationUnit );
+
+		void premutate( QualifiedType * );
+		Type * postmutate( QualifiedType * qualType );
 		Type * postmutate( TypeInstType * aggregateUseType );
 		Declaration * postmutate( TypedefDecl * typeDecl );
@@ -180,13 +196,9 @@
 
 		void premutate( CompoundStmt * compoundStmt );
-		CompoundStmt * postmutate( CompoundStmt * compoundStmt );
 
 		void premutate( StructDecl * structDecl );
-		Declaration * postmutate( StructDecl * structDecl );
 		void premutate( UnionDecl * unionDecl );
-		Declaration * postmutate( UnionDecl * unionDecl );
 		void premutate( EnumDecl * enumDecl );
-		Declaration * postmutate( EnumDecl * enumDecl );
-		Declaration * postmutate( TraitDecl * contextDecl );
+		void premutate( TraitDecl * );
 
 		void premutate( FunctionType * ftype );
@@ -194,16 +206,27 @@
 	  private:
 		template<typename AggDecl>
-		AggDecl *handleAggregate( AggDecl * aggDecl );
-
-		template<typename AggDecl>
 		void addImplicitTypedef( AggDecl * aggDecl );
+		template< typename AggDecl >
+		void handleAggregate( AggDecl * aggr );
 
 		typedef std::unique_ptr<TypedefDecl> TypedefDeclPtr;
 		typedef ScopedMap< std::string, std::pair< TypedefDeclPtr, int > > TypedefMap;
-		typedef std::map< std::string, TypeDecl * > TypeDeclMap;
+		typedef ScopedMap< std::string, TypeDecl * > TypeDeclMap;
 		TypedefMap typedefNames;
 		TypeDeclMap typedeclNames;
 		int scopeLevel;
 		bool inFunctionType = false;
+	};
+
+	struct EliminateTypedef {
+		/// removes TypedefDecls from the AST
+		static void eliminateTypedef( std::list< Declaration * > &translationUnit );
+
+		template<typename AggDecl>
+		void handleAggregate( AggDecl *aggregateDecl );
+
+		void previsit( StructDecl * aggregateDecl );
+		void previsit( UnionDecl * aggregateDecl );
+		void previsit( CompoundStmt * compoundStmt );
 	};
 
@@ -263,10 +286,15 @@
 		PassVisitor<FindSpecialDeclarations> finder;
 		PassVisitor<LabelAddressFixer> labelAddrFixer;
-
-		EliminateTypedef::eliminateTypedef( translationUnit );
-		HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order
+		PassVisitor<HoistTypeDecls> hoistDecls;
+		PassVisitor<FixQualifiedTypes> fixQual;
+
+		acceptAll( translationUnit, hoistDecls );
+		ReplaceTypedef::replaceTypedef( translationUnit );
 		ReturnTypeFixer::fix( translationUnit ); // must happen before autogen
 		acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes because it is an indexer and needs correct types for mangling
 		acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions
+		mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes, because aggregate members are accessed
+		HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order
+		EliminateTypedef::eliminateTypedef( translationUnit ); //
 		acceptAll( translationUnit, genericParams );  // check as early as possible - can't happen before LinkReferenceToTypes
 		VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
@@ -294,4 +322,101 @@
 	}
 
+
+	void HoistTypeDecls::handleType( Type * type ) {
+		// some type declarations are buried in expressions and not easy to hoist during parsing; hoist them here
+		AggregateDecl * aggr = nullptr;
+		if ( StructInstType * inst = dynamic_cast< StructInstType * >( type ) ) {
+			aggr = inst->baseStruct;
+		} else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( type ) ) {
+			aggr = inst->baseUnion;
+		} else if ( EnumInstType * inst = dynamic_cast< EnumInstType * >( type ) ) {
+			aggr = inst->baseEnum;
+		}
+		if ( aggr && aggr->body ) {
+			declsToAddBefore.push_front( aggr );
+		}
+	}
+
+	void HoistTypeDecls::previsit( SizeofExpr * expr ) {
+		handleType( expr->type );
+	}
+
+	void HoistTypeDecls::previsit( AlignofExpr * expr ) {
+		handleType( expr->type );
+	}
+
+	void HoistTypeDecls::previsit( UntypedOffsetofExpr * expr ) {
+		handleType( expr->type );
+	}
+
+
+	Type * FixQualifiedTypes::postmutate( QualifiedType * qualType ) {
+		Type * parent = qualType->parent;
+		Type * child = qualType->child;
+		if ( dynamic_cast< GlobalScopeType * >( qualType->parent ) ) {
+			// .T => lookup T at global scope
+			if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( child ) ) {
+				auto td = indexer.globalLookupType( inst->name );
+				if ( ! td ) {
+					SemanticError( qualType->location, toString("Use of undefined global type ", inst->name) );
+				}
+				auto base = td->base;
+				assert( base );
+				return base->clone();
+			} else {
+				// .T => T is not a type name
+				assertf( false, "unhandled global qualified child type: %s", toCString(child) );
+			}
+		} else {
+			// S.T => S must be an aggregate type, find the declaration for T in S.
+			AggregateDecl * aggr = nullptr;
+			if ( StructInstType * inst = dynamic_cast< StructInstType * >( parent ) ) {
+				aggr = inst->baseStruct;
+			} else if ( UnionInstType * inst = dynamic_cast< UnionInstType * > ( parent ) ) {
+				aggr = inst->baseUnion;
+			} else {
+				SemanticError( qualType->location, toString("Qualified type requires an aggregate on the left, but has: ", parent) );
+			}
+			assert( aggr ); // TODO: need to handle forward declarations
+			for ( Declaration * member : aggr->members ) {
+				if ( StructInstType * inst = dynamic_cast< StructInstType * >( child ) ) {
+					if ( StructDecl * aggr = dynamic_cast< StructDecl * >( member ) ) {
+						if ( aggr->name == inst->name ) {
+							return new StructInstType( qualType->get_qualifiers(), aggr );
+						}
+					}
+				} else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( child ) ) {
+					if ( UnionDecl * aggr = dynamic_cast< UnionDecl * > ( member ) ) {
+						if ( aggr->name == inst->name ) {
+							return new UnionInstType( qualType->get_qualifiers(), aggr );
+						}
+					}
+				} else if ( EnumInstType * inst = dynamic_cast< EnumInstType * >( child ) ) {
+					if ( EnumDecl * aggr = dynamic_cast< EnumDecl * > ( member ) ) {
+						if ( aggr->name == inst->name ) {
+							return new EnumInstType( qualType->get_qualifiers(), aggr );
+						}
+					}
+				} else if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( child ) ) {
+					// struct typedefs are being replaced by forward decls too early; move it to hoist struct
+					if ( NamedTypeDecl * aggr = dynamic_cast< NamedTypeDecl * > ( member ) ) {
+						if ( aggr->name == inst->name ) {
+							assert( aggr->base );
+							return aggr->base->clone();
+						}
+					}
+				} else {
+					// S.T - S is not an aggregate => error
+					assertf( false, "unhandled qualified child type: %s", toCString(qualType) );
+				}
+			}
+			// failed to find a satisfying definition of type
+			SemanticError( qualType->location, toString("Undefined type in qualified type: ", qualType) );
+		}
+
+		// ... may want to link canonical SUE definition to each forward decl so that it becomes easier to lookup?
+	}
+
+
 	void HoistStruct::hoistStruct( std::list< Declaration * > &translationUnit ) {
 		PassVisitor<HoistStruct> hoister;
@@ -303,7 +428,23 @@
 	}
 
+	namespace {
+		void qualifiedName( AggregateDecl * aggr, std::ostringstream & ss ) {
+			if ( aggr->parent ) qualifiedName( aggr->parent, ss );
+			ss << "__" << aggr->name;
+		}
+
+		// mangle nested type names using entire parent chain
+		std::string qualifiedName( AggregateDecl * aggr ) {
+			std::ostringstream ss;
+			qualifiedName( aggr, ss );
+			return ss.str();
+		}
+	}
+
 	template< typename AggDecl >
 	void HoistStruct::handleAggregate( AggDecl *aggregateDecl ) {
 		if ( parentAggr ) {
+			aggregateDecl->parent = parentAggr;
+			aggregateDecl->name = qualifiedName( aggregateDecl );
 			// Add elements in stack order corresponding to nesting structure.
 			declsToAddBefore.push_front( aggregateDecl );
@@ -316,22 +457,4 @@
 	}
 
-	void HoistStruct::previsit( EnumInstType * inst ) {
-		if ( inst->baseEnum && inst->baseEnum->body ) {
-			declsToAddBefore.push_front( inst->baseEnum );
-		}
-	}
-
-	void HoistStruct::previsit( StructInstType * inst ) {
-		if ( inst->baseStruct && inst->baseStruct->body ) {
-			declsToAddBefore.push_front( inst->baseStruct );
-		}
-	}
-
-	void HoistStruct::previsit( UnionInstType * inst ) {
-		if ( inst->baseUnion && inst->baseUnion->body ) {
-			declsToAddBefore.push_front( inst->baseUnion );
-		}
-	}
-
 	void HoistStruct::previsit( StaticAssertDecl * assertDecl ) {
 		if ( parentAggr ) {
@@ -348,10 +471,62 @@
 	}
 
+	void HoistStruct::previsit( StructInstType * type ) {
+		// need to reset type name after expanding to qualified name
+		assert( type->baseStruct );
+		type->name = type->baseStruct->name;
+	}
+
+	void HoistStruct::previsit( UnionInstType * type ) {
+		assert( type->baseUnion );
+		type->name = type->baseUnion->name;
+	}
+
+	void HoistStruct::previsit( EnumInstType * type ) {
+		assert( type->baseEnum );
+		type->name = type->baseEnum->name;
+	}
+
+
+	bool isTypedef( Declaration *decl ) {
+		return dynamic_cast< TypedefDecl * >( decl );
+	}
+
+	void EliminateTypedef::eliminateTypedef( std::list< Declaration * > &translationUnit ) {
+		PassVisitor<EliminateTypedef> eliminator;
+		acceptAll( translationUnit, eliminator );
+		filter( translationUnit, isTypedef, true );
+	}
+
+	template< typename AggDecl >
+	void EliminateTypedef::handleAggregate( AggDecl *aggregateDecl ) {
+		filter( aggregateDecl->members, isTypedef, true );
+	}
+
+	void EliminateTypedef::previsit( StructDecl * aggregateDecl ) {
+		handleAggregate( aggregateDecl );
+	}
+
+	void EliminateTypedef::previsit( UnionDecl * aggregateDecl ) {
+		handleAggregate( aggregateDecl );
+	}
+
+	void EliminateTypedef::previsit( CompoundStmt * compoundStmt ) {
+		// remove and delete decl stmts
+		filter( compoundStmt->kids, [](Statement * stmt) {
+			if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
+				if ( dynamic_cast< TypedefDecl * >( declStmt->decl ) ) {
+					return true;
+				} // if
+			} // if
+			return false;
+		}, true);
+	}
+
 	void EnumAndPointerDecay::previsit( EnumDecl *enumDecl ) {
 		// Set the type of each member of the enumeration to be EnumConstant
-		for ( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
+		for ( std::list< Declaration * >::iterator i = enumDecl->members.begin(); i != enumDecl->members.end(); ++i ) {
 			ObjectDecl * obj = dynamic_cast< ObjectDecl * >( *i );
 			assert( obj );
-			obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->get_name() ) );
+			obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->name ) );
 		} // for
 	}
@@ -395,13 +570,12 @@
 
 	void LinkReferenceToTypes::postvisit( EnumInstType *enumInst ) {
-		EnumDecl *st = local_indexer->lookupEnum( enumInst->get_name() );
+		EnumDecl *st = local_indexer->lookupEnum( enumInst->name );
 		// it's not a semantic error if the enum is not found, just an implicit forward declaration
 		if ( st ) {
-			//assert( ! enumInst->get_baseEnum() || enumInst->get_baseEnum()->get_members().empty() || ! st->get_members().empty() );
-			enumInst->set_baseEnum( st );
-		} // if
-		if ( ! st || st->get_members().empty() ) {
+			enumInst->baseEnum = st;
+		} // if
+		if ( ! st || ! st->body ) {
 			// use of forward declaration
-			forwardEnums[ enumInst->get_name() ].push_back( enumInst );
+			forwardEnums[ enumInst->name ].push_back( enumInst );
 		} // if
 	}
@@ -416,13 +590,12 @@
 
 	void LinkReferenceToTypes::postvisit( StructInstType *structInst ) {
-		StructDecl *st = local_indexer->lookupStruct( structInst->get_name() );
+		StructDecl *st = local_indexer->lookupStruct( structInst->name );
 		// it's not a semantic error if the struct is not found, just an implicit forward declaration
 		if ( st ) {
-			//assert( ! structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || ! st->get_members().empty() );
-			structInst->set_baseStruct( st );
-		} // if
-		if ( ! st || st->get_members().empty() ) {
+			structInst->baseStruct = st;
+		} // if
+		if ( ! st || ! st->body ) {
 			// use of forward declaration
-			forwardStructs[ structInst->get_name() ].push_back( structInst );
+			forwardStructs[ structInst->name ].push_back( structInst );
 		} // if
 		checkGenericParameters( structInst );
@@ -430,14 +603,23 @@
 
 	void LinkReferenceToTypes::postvisit( UnionInstType *unionInst ) {
-		UnionDecl *un = local_indexer->lookupUnion( unionInst->get_name() );
+		UnionDecl *un = local_indexer->lookupUnion( unionInst->name );
 		// it's not a semantic error if the union is not found, just an implicit forward declaration
 		if ( un ) {
-			unionInst->set_baseUnion( un );
-		} // if
-		if ( ! un || un->get_members().empty() ) {
+			unionInst->baseUnion = un;
+		} // if
+		if ( ! un || ! un->body ) {
 			// use of forward declaration
-			forwardUnions[ unionInst->get_name() ].push_back( unionInst );
+			forwardUnions[ unionInst->name ].push_back( unionInst );
 		} // if
 		checkGenericParameters( unionInst );
+	}
+
+	void LinkReferenceToTypes::previsit( QualifiedType * ) {
+		visit_children = false;
+	}
+
+	void LinkReferenceToTypes::postvisit( QualifiedType * qualType ) {
+		// linking only makes sense for the 'oldest ancestor' of the qualified type
+		qualType->parent->accept( *visitor );
 	}
 
@@ -450,5 +632,5 @@
 			DeclarationWithType * dwt2 = dynamic_cast<DeclarationWithType *>( d2 );
 			if ( dwt1 && dwt2 ) {
-				if ( dwt1->get_name() == dwt2->get_name() && ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) {
+				if ( dwt1->name == dwt2->name && ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) {
 					// std::cerr << "=========== equal:" << std::endl;
 					// std::cerr << "d1: " << d1 << std::endl;
@@ -475,5 +657,5 @@
 	template< typename Iterator >
 	void expandAssertions( TraitInstType * inst, Iterator out ) {
-		assertf( inst->baseTrait, "Trait instance not linked to base trait: %s", toString( inst ).c_str() );
+		assertf( inst->baseTrait, "Trait instance not linked to base trait: %s", toCString( inst ) );
 		std::list< DeclarationWithType * > asserts;
 		for ( Declaration * decl : inst->baseTrait->members ) {
@@ -512,5 +694,5 @@
 			SemanticError( traitInst->location, "use of undeclared trait " + traitInst->name );
 		} // if
-		if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) {
+		if ( traitDecl->parameters.size() != traitInst->parameters.size() ) {
 			SemanticError( traitInst, "incorrect number of trait parameters: " );
 		} // if
@@ -518,5 +700,5 @@
 
 		// need to carry over the 'sized' status of each decl in the instance
-		for ( auto p : group_iterate( traitDecl->get_parameters(), traitInst->get_parameters() ) ) {
+		for ( auto p : group_iterate( traitDecl->parameters, traitInst->parameters ) ) {
 			TypeExpr * expr = dynamic_cast< TypeExpr * >( std::get<1>(p) );
 			if ( ! expr ) {
@@ -525,5 +707,5 @@
 			if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( expr->get_type() ) ) {
 				TypeDecl * formalDecl = std::get<0>(p);
-				TypeDecl * instDecl = inst->get_baseType();
+				TypeDecl * instDecl = inst->baseType;
 				if ( formalDecl->get_sized() ) instDecl->set_sized( true );
 			}
@@ -534,9 +716,9 @@
 	void LinkReferenceToTypes::postvisit( EnumDecl *enumDecl ) {
 		// visit enum members first so that the types of self-referencing members are updated properly
-		if ( ! enumDecl->get_members().empty() ) {
-			ForwardEnumsType::iterator fwds = forwardEnums.find( enumDecl->get_name() );
+		if ( enumDecl->body ) {
+			ForwardEnumsType::iterator fwds = forwardEnums.find( enumDecl->name );
 			if ( fwds != forwardEnums.end() ) {
 				for ( std::list< EnumInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
-					(*inst )->set_baseEnum( enumDecl );
+					(*inst)->baseEnum = enumDecl;
 				} // for
 				forwardEnums.erase( fwds );
@@ -574,9 +756,9 @@
 		// visit struct members first so that the types of self-referencing members are updated properly
 		// xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults)
-		if ( ! structDecl->get_members().empty() ) {
-			ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->get_name() );
+		if ( structDecl->body ) {
+			ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->name );
 			if ( fwds != forwardStructs.end() ) {
 				for ( std::list< StructInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
-					(*inst )->set_baseStruct( structDecl );
+					(*inst)->baseStruct = structDecl;
 				} // for
 				forwardStructs.erase( fwds );
@@ -586,9 +768,9 @@
 
 	void LinkReferenceToTypes::postvisit( UnionDecl *unionDecl ) {
-		if ( ! unionDecl->get_members().empty() ) {
-			ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->get_name() );
+		if ( unionDecl->body ) {
+			ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->name );
 			if ( fwds != forwardUnions.end() ) {
 				for ( std::list< UnionInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
-					(*inst )->set_baseUnion( unionDecl );
+					(*inst)->baseUnion = unionDecl;
 				} // for
 				forwardUnions.erase( fwds );
@@ -600,5 +782,5 @@
 		// ensure generic parameter instances are renamed like the base type
 		if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name;
-		if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->get_name() ) ) {
+		if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->name ) ) {
 			if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) {
 				typeInst->set_isFtype( typeDecl->get_kind() == TypeDecl::Ftype );
@@ -679,14 +861,10 @@
 
 
-	bool isTypedef( Declaration *decl ) {
-		return dynamic_cast< TypedefDecl * >( decl );
-	}
-
-	void EliminateTypedef::eliminateTypedef( std::list< Declaration * > &translationUnit ) {
-		PassVisitor<EliminateTypedef> eliminator;
+	void ReplaceTypedef::replaceTypedef( std::list< Declaration * > &translationUnit ) {
+		PassVisitor<ReplaceTypedef> eliminator;
 		mutateAll( translationUnit, eliminator );
 		if ( eliminator.pass.typedefNames.count( "size_t" ) ) {
 			// grab and remember declaration of size_t
-			SizeType = eliminator.pass.typedefNames["size_t"].first->get_base()->clone();
+			SizeType = eliminator.pass.typedefNames["size_t"].first->base->clone();
 		} else {
 			// xxx - missing global typedef for size_t - default to long unsigned int, even though that may be wrong
@@ -694,13 +872,23 @@
 			SizeType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
 		}
-		filter( translationUnit, isTypedef, true );
-	}
-
-	Type * EliminateTypedef::postmutate( TypeInstType * typeInst ) {
+	}
+
+	void ReplaceTypedef::premutate( QualifiedType * ) {
+		visit_children = false;
+	}
+
+	Type * ReplaceTypedef::postmutate( QualifiedType * qualType ) {
+		// replacing typedefs only makes sense for the 'oldest ancestor' of the qualified type
+		qualType->parent = qualType->parent->acceptMutator( *visitor );
+		return qualType;
+	}
+
+	Type * ReplaceTypedef::postmutate( TypeInstType * typeInst ) {
 		// instances of typedef types will come here. If it is an instance
 		// of a typdef type, link the instance to its actual type.
-		TypedefMap::const_iterator def = typedefNames.find( typeInst->get_name() );
+		TypedefMap::const_iterator def = typedefNames.find( typeInst->name );
 		if ( def != typedefNames.end() ) {
 			Type *ret = def->second.first->base->clone();
+			ret->location = typeInst->location;
 			ret->get_qualifiers() |= typeInst->get_qualifiers();
 			// attributes are not carried over from typedef to function parameters/return values
@@ -717,5 +905,5 @@
 					SemanticError( typeInst->location, "Cannot apply type parameters to base type of " + typeInst->name );
 				}
-				rtt->get_parameters().clear();
+				rtt->parameters.clear();
 				cloneAll( typeInst->parameters, rtt->parameters );
 				mutateAll( rtt->parameters, *visitor );  // recursively fix typedefs on parameters
@@ -724,9 +912,12 @@
 			return ret;
 		} else {
-			TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->get_name() );
-			assertf( base != typedeclNames.end(), "Cannot find typedecl name %s", typeInst->name.c_str() );
+			TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->name );
+			if ( base == typedeclNames.end() ) {
+				SemanticError( typeInst->location, toString("Use of undefined type ", typeInst->name) );
+			}
 			typeInst->set_baseType( base->second );
-		} // if
-		return typeInst;
+			return typeInst;
+		} // if
+		assert( false );
 	}
 
@@ -745,11 +936,11 @@
 	}
 
-	Declaration *EliminateTypedef::postmutate( TypedefDecl * tyDecl ) {
-		if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) {
+	Declaration * ReplaceTypedef::postmutate( TypedefDecl * tyDecl ) {
+		if ( typedefNames.count( tyDecl->name ) == 1 && typedefNames[ tyDecl->name ].second == scopeLevel ) {
 			// typedef to the same name from the same scope
 			// must be from the same type
 
-			Type * t1 = tyDecl->get_base();
-			Type * t2 = typedefNames[ tyDecl->get_name() ].first->get_base();
+			Type * t1 = tyDecl->base;
+			Type * t2 = typedefNames[ tyDecl->name ].first->base;
 			if ( ! ResolvExpr::typesCompatible( t1, t2, Indexer() ) ) {
 				SemanticError( tyDecl->location, "Cannot redefine typedef: " + tyDecl->name );
@@ -763,5 +954,5 @@
 			}
 		} else {
-			typedefNames[ tyDecl->get_name() ] = std::make_pair( TypedefDeclPtr( tyDecl ), scopeLevel );
+			typedefNames[ tyDecl->name ] = std::make_pair( TypedefDeclPtr( tyDecl ), scopeLevel );
 		} // if
 
@@ -775,38 +966,39 @@
 		// Note, qualifiers on the typedef are superfluous for the forward declaration.
 
-		Type *designatorType = tyDecl->get_base()->stripDeclarator();
+		Type *designatorType = tyDecl->base->stripDeclarator();
 		if ( StructInstType *aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) {
-			return new StructDecl( aggDecl->get_name(), DeclarationNode::Struct, noAttributes, tyDecl->get_linkage() );
+			declsToAddBefore.push_back( new StructDecl( aggDecl->name, DeclarationNode::Struct, noAttributes, tyDecl->linkage ) );
 		} else if ( UnionInstType *aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) {
-			return new UnionDecl( aggDecl->get_name(), noAttributes, tyDecl->get_linkage() );
+			declsToAddBefore.push_back( new UnionDecl( aggDecl->name, noAttributes, tyDecl->linkage ) );
 		} else if ( EnumInstType *enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) {
-			return new EnumDecl( enumDecl->get_name(), noAttributes, tyDecl->get_linkage() );
-		} else {
-			return tyDecl->clone();
-		} // if
-	}
-
-	void EliminateTypedef::premutate( TypeDecl * typeDecl ) {
-		TypedefMap::iterator i = typedefNames.find( typeDecl->get_name() );
+			declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage ) );
+		} // if
+		return tyDecl->clone();
+	}
+
+	void ReplaceTypedef::premutate( TypeDecl * typeDecl ) {
+		TypedefMap::iterator i = typedefNames.find( typeDecl->name );
 		if ( i != typedefNames.end() ) {
 			typedefNames.erase( i ) ;
 		} // if
 
-		typedeclNames[ typeDecl->get_name() ] = typeDecl;
-	}
-
-	void EliminateTypedef::premutate( FunctionDecl * ) {
+		typedeclNames.insert( typeDecl->name, typeDecl );
+	}
+
+	void ReplaceTypedef::premutate( FunctionDecl * ) {
 		GuardScope( typedefNames );
-	}
-
-	void EliminateTypedef::premutate( ObjectDecl * ) {
+		GuardScope( typedeclNames );
+	}
+
+	void ReplaceTypedef::premutate( ObjectDecl * ) {
 		GuardScope( typedefNames );
-	}
-
-	DeclarationWithType *EliminateTypedef::postmutate( ObjectDecl * objDecl ) {
-		if ( FunctionType *funtype = dynamic_cast<FunctionType *>( objDecl->get_type() ) ) { // function type?
+		GuardScope( typedeclNames );
+	}
+
+	DeclarationWithType * ReplaceTypedef::postmutate( ObjectDecl * objDecl ) {
+		if ( FunctionType *funtype = dynamic_cast<FunctionType *>( objDecl->type ) ) { // function type?
 			// replace the current object declaration with a function declaration
-			FunctionDecl * newDecl = new FunctionDecl( objDecl->get_name(), objDecl->get_storageClasses(), objDecl->get_linkage(), funtype, 0, objDecl->get_attributes(), objDecl->get_funcSpec() );
-			objDecl->get_attributes().clear();
+			FunctionDecl * newDecl = new FunctionDecl( objDecl->name, objDecl->get_storageClasses(), objDecl->linkage, funtype, 0, objDecl->attributes, objDecl->get_funcSpec() );
+			objDecl->attributes.clear();
 			objDecl->set_type( nullptr );
 			delete objDecl;
@@ -816,37 +1008,18 @@
 	}
 
-	void EliminateTypedef::premutate( CastExpr * ) {
+	void ReplaceTypedef::premutate( CastExpr * ) {
 		GuardScope( typedefNames );
-	}
-
-	void EliminateTypedef::premutate( CompoundStmt * ) {
+		GuardScope( typedeclNames );
+	}
+
+	void ReplaceTypedef::premutate( CompoundStmt * ) {
 		GuardScope( typedefNames );
+		GuardScope( typedeclNames );
 		scopeLevel += 1;
 		GuardAction( [this](){ scopeLevel -= 1; } );
 	}
 
-	CompoundStmt *EliminateTypedef::postmutate( CompoundStmt * compoundStmt ) {
-		// remove and delete decl stmts
-		filter( compoundStmt->kids, [](Statement * stmt) {
-			if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
-				if ( dynamic_cast< TypedefDecl * >( declStmt->get_decl() ) ) {
-					return true;
-				} // if
-			} // if
-			return false;
-		}, true);
-		return compoundStmt;
-	}
-
-	// there may be typedefs nested within aggregates. in order for everything to work properly, these should be removed
-	// as well
 	template<typename AggDecl>
-	AggDecl *EliminateTypedef::handleAggregate( AggDecl * aggDecl ) {
-		filter( aggDecl->members, isTypedef, true );
-		return aggDecl;
-	}
-
-	template<typename AggDecl>
-	void EliminateTypedef::addImplicitTypedef( AggDecl * aggDecl ) {
+	void ReplaceTypedef::addImplicitTypedef( AggDecl * aggDecl ) {
 		if ( typedefNames.count( aggDecl->get_name() ) == 0 ) {
 			Type *type = nullptr;
@@ -860,39 +1033,63 @@
 			TypedefDeclPtr tyDecl( new TypedefDecl( aggDecl->get_name(), aggDecl->location, Type::StorageClasses(), type, aggDecl->get_linkage() ) );
 			typedefNames[ aggDecl->get_name() ] = std::make_pair( std::move( tyDecl ), scopeLevel );
-		} // if
-	}
-
-	void EliminateTypedef::premutate( StructDecl * structDecl ) {
+			// add the implicit typedef to the AST
+			declsToAddBefore.push_back( new TypedefDecl( aggDecl->get_name(), aggDecl->location, Type::StorageClasses(), type->clone(), aggDecl->get_linkage() ) );
+		} // if
+	}
+
+	template< typename AggDecl >
+	void ReplaceTypedef::handleAggregate( AggDecl * aggr ) {
+		SemanticErrorException errors;
+
+		ValueGuard< std::list<Declaration * > > oldBeforeDecls( declsToAddBefore );
+		ValueGuard< std::list<Declaration * > > oldAfterDecls ( declsToAddAfter  );
+		declsToAddBefore.clear();
+		declsToAddAfter.clear();
+
+		GuardScope( typedefNames );
+		GuardScope( typedeclNames );
+		mutateAll( aggr->parameters, *visitor );
+
+		// unroll mutateAll for aggr->members so that implicit typedefs for nested types are added to the aggregate body.
+		for ( std::list< Declaration * >::iterator i = aggr->members.begin(); i != aggr->members.end(); ++i ) {
+			if ( !declsToAddAfter.empty() ) { aggr->members.splice( i, declsToAddAfter ); }
+
+			try {
+				*i = maybeMutate( *i, *visitor );
+			} catch ( SemanticErrorException &e ) {
+				errors.append( e );
+			}
+
+			if ( !declsToAddBefore.empty() ) { aggr->members.splice( i, declsToAddBefore ); }
+		}
+
+		if ( !declsToAddAfter.empty() ) { aggr->members.splice( aggr->members.end(), declsToAddAfter ); }
+		if ( !errors.isEmpty() ) { throw errors; }
+	}
+
+	void ReplaceTypedef::premutate( StructDecl * structDecl ) {
+		visit_children = false;
 		addImplicitTypedef( structDecl );
-	}
-
-
-	Declaration *EliminateTypedef::postmutate( StructDecl * structDecl ) {
-		return handleAggregate( structDecl );
-	}
-
-	void EliminateTypedef::premutate( UnionDecl * unionDecl ) {
+		handleAggregate( structDecl );
+	}
+
+	void ReplaceTypedef::premutate( UnionDecl * unionDecl ) {
+		visit_children = false;
 		addImplicitTypedef( unionDecl );
-	}
-
-	Declaration *EliminateTypedef::postmutate( UnionDecl * unionDecl ) {
-		return handleAggregate( unionDecl );
-	}
-
-	void EliminateTypedef::premutate( EnumDecl * enumDecl ) {
+		handleAggregate( unionDecl );
+	}
+
+	void ReplaceTypedef::premutate( EnumDecl * enumDecl ) {
 		addImplicitTypedef( enumDecl );
 	}
 
-	Declaration *EliminateTypedef::postmutate( EnumDecl * enumDecl ) {
-		return handleAggregate( enumDecl );
-	}
-
-	Declaration *EliminateTypedef::postmutate( TraitDecl * traitDecl ) {
-		return handleAggregate( traitDecl );
-	}
-
-	void EliminateTypedef::premutate( FunctionType * ) {
+	void ReplaceTypedef::premutate( FunctionType * ) {
 		GuardValue( inFunctionType );
 		inFunctionType = true;
+	}
+
+	void ReplaceTypedef::premutate( TraitDecl * ) {
+		GuardScope( typedefNames );
+		GuardScope( typedeclNames);
 	}
 
@@ -1024,8 +1221,8 @@
 
 	void ArrayLength::previsit( ObjectDecl * objDecl ) {
-		if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) {
+		if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->type ) ) {
 			if ( at->get_dimension() ) return;
-			if ( ListInit * init = dynamic_cast< ListInit * >( objDecl->get_init() ) ) {
-				at->set_dimension( new ConstantExpr( Constant::from_ulong( init->get_initializers().size() ) ) );
+			if ( ListInit * init = dynamic_cast< ListInit * >( objDecl->init ) ) {
+				at->set_dimension( new ConstantExpr( Constant::from_ulong( init->initializers.size() ) ) );
 			}
 		}
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/SynTree/Declaration.h	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -266,4 +266,5 @@
 	bool body;
 	std::list< Attribute * > attributes;
+	AggregateDecl * parent = nullptr;
 
 	AggregateDecl( const std::string &name, const std::list< Attribute * > & attributes = std::list< class Attribute * >(), LinkageSpec::Spec linkage = LinkageSpec::Cforall );
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/SynTree/Mutator.h	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -101,4 +101,5 @@
 	virtual Type * mutate( ArrayType * arrayType ) = 0;
 	virtual Type * mutate( ReferenceType * refType ) = 0;
+	virtual Type * mutate( QualifiedType * qualType ) = 0;
 	virtual Type * mutate( FunctionType * functionType ) = 0;
 	virtual Type * mutate( StructInstType * aggregateUseType ) = 0;
@@ -113,4 +114,5 @@
 	virtual Type * mutate( ZeroType * zeroType ) = 0;
 	virtual Type * mutate( OneType * oneType ) = 0;
+	virtual Type * mutate( GlobalScopeType * globalType ) = 0;
 
 	virtual Designation * mutate( Designation * designation ) = 0 ;
Index: src/SynTree/ReferenceToType.cc
===================================================================
--- src/SynTree/ReferenceToType.cc	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/SynTree/ReferenceToType.cc	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -76,5 +76,5 @@
 bool StructInstType::isComplete() const { return baseStruct ? baseStruct->has_body() : false; }
 
-AggregateDecl * StructInstType::getAggr() { return baseStruct; }
+AggregateDecl * StructInstType::getAggr() const { return baseStruct; }
 
 TypeSubstitution StructInstType::genericSubstitution() const {
@@ -119,5 +119,5 @@
 bool UnionInstType::isComplete() const { return baseUnion ? baseUnion->has_body() : false; }
 
-AggregateDecl * UnionInstType::getAggr() { return baseUnion; }
+AggregateDecl * UnionInstType::getAggr() const { return baseUnion; }
 
 TypeSubstitution UnionInstType::genericSubstitution() const {
@@ -152,4 +152,6 @@
 bool EnumInstType::isComplete() const { return baseEnum ? baseEnum->has_body() : false; }
 
+AggregateDecl * EnumInstType::getAggr() const { return baseEnum; }
+
 void EnumInstType::print( std::ostream &os, Indenter indent ) const {
 	using std::endl;
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/SynTree/SynTree.h	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -110,4 +110,5 @@
 class ArrayType;
 class ReferenceType;
+class QualifiedType;
 class FunctionType;
 class ReferenceToType;
@@ -123,4 +124,5 @@
 class ZeroType;
 class OneType;
+class GlobalScopeType;
 
 class Designation;
Index: src/SynTree/Type.cc
===================================================================
--- src/SynTree/Type.cc	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/SynTree/Type.cc	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -105,4 +105,33 @@
 }
 
+
+QualifiedType::QualifiedType( const Type::Qualifiers & tq, Type * parent, Type * child ) : Type( tq, {} ), parent( parent ), child( child ) {
+}
+
+QualifiedType::QualifiedType( const QualifiedType & other ) : Type( other ), parent( maybeClone( other.parent ) ), child( maybeClone( other.child ) ) {
+}
+
+QualifiedType::~QualifiedType() {
+	delete parent;
+	delete child;
+}
+
+void QualifiedType::print( std::ostream & os, Indenter indent ) const {
+	os << "Qualified Type: " << endl;
+	os << indent+1;
+	parent->print( os, indent+1 );
+	os << endl << indent+1;
+	child->print( os, indent+1 );
+	os << endl;
+	Type::print( os, indent+1 );
+}
+
+GlobalScopeType::GlobalScopeType() : Type( Type::Qualifiers(), {} ) {}
+
+void GlobalScopeType::print( std::ostream & os, Indenter ) const {
+	os << "Global Scope Type" << endl;
+}
+
+
 // Empty Variable declarations:
 const Type::FuncSpecifiers noFuncSpecifiers;
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/SynTree/Type.h	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -178,5 +178,5 @@
 	virtual bool isComplete() const { return true; }
 
-	virtual AggregateDecl * getAggr() { assertf( false, "Non-aggregate type: %s", toCString( this ) ); }
+	virtual AggregateDecl * getAggr() const { assertf( false, "Non-aggregate type: %s", toCString( this ) ); }
 
 	virtual TypeSubstitution genericSubstitution() const;
@@ -315,4 +315,19 @@
 };
 
+class QualifiedType : public Type {
+public:
+	Type * parent;
+	Type * child;
+
+	QualifiedType( const Type::Qualifiers & tq, Type * parent, Type * child );
+	QualifiedType( const QualifiedType & tq );
+	virtual ~QualifiedType();
+
+	virtual QualifiedType *clone() const override { return new QualifiedType( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
+};
+
 class ReferenceType : public Type {
 public:
@@ -416,5 +431,5 @@
 	virtual bool isComplete() const override;
 
-	virtual AggregateDecl * getAggr() override;
+	virtual AggregateDecl * getAggr() const override;
 
 	virtual TypeSubstitution genericSubstitution() const override;
@@ -453,5 +468,5 @@
 	virtual bool isComplete() const override;
 
-	virtual AggregateDecl * getAggr() override;
+	virtual AggregateDecl * getAggr() const override;
 
 	virtual TypeSubstitution genericSubstitution() const override;
@@ -485,4 +500,6 @@
 
 	virtual bool isComplete() const override;
+
+	virtual AggregateDecl * getAggr() const override;
 
 	virtual EnumInstType *clone() const override { return new EnumInstType( *this ); }
@@ -665,4 +682,14 @@
 };
 
+class GlobalScopeType : public Type {
+  public:
+	GlobalScopeType();
+
+	virtual GlobalScopeType *clone() const override { return new GlobalScopeType( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
+};
+
 // Local Variables: //
 // tab-width: 4 //
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/SynTree/Visitor.h	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -103,4 +103,5 @@
 	virtual void visit( ArrayType * arrayType ) = 0;
 	virtual void visit( ReferenceType * refType ) = 0;
+	virtual void visit( QualifiedType * qualType ) = 0;
 	virtual void visit( FunctionType * functionType ) = 0;
 	virtual void visit( StructInstType * aggregateUseType ) = 0;
@@ -115,4 +116,5 @@
 	virtual void visit( ZeroType * zeroType ) = 0;
 	virtual void visit( OneType * oneType ) = 0;
+	virtual void visit( GlobalScopeType * globalType ) = 0;
 
 	virtual void visit( Designation * designation ) = 0;
Index: src/main.cc
===================================================================
--- src/main.cc	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/main.cc	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -247,4 +247,9 @@
 		} // if
 
+		// Temporary: fill locations after parsing so that every node has a location, for early error messages.
+		// Eventually we should pass the locations from the parser to every node, but this quick and dirty solution
+		// works okay for now.
+		CodeTools::fillLocations( translationUnit );
+
 		// add the assignment statement after the initialization of a type parameter
 		PASS( "validate", SymTab::validate( translationUnit, symtabp ) );
Index: src/prelude/prelude.old.cf
===================================================================
--- src/prelude/prelude.old.cf	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/prelude/prelude.old.cf	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -728,5 +728,4 @@
 forall( dtype DT ) void ?{}(	   volatile  DT *	   &,			DT * );
 forall( dtype DT ) void ?{}(	   volatile  DT *	   &,	    volatile	DT * );
-
 forall( dtype DT ) void ?{}( const volatile  DT *	   &,			DT * );
 forall( dtype DT ) void ?{}( const volatile  DT *	   &, const		DT * );
Index: src/tests/.expect/attributes.x86.txt
===================================================================
--- src/tests/.expect/attributes.x86.txt	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/tests/.expect/attributes.x86.txt	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -0,0 +1,515 @@
+signed int __la__Fi___1(){
+    __attribute__ ((unused)) signed int ___retval_la__i_1;
+    L: __attribute__ ((unused)) ((void)1);
+}
+struct __attribute__ ((unused)) __anonymous0 {
+};
+static inline void ___constructor__F_13s__anonymous0_autogen___1(struct __anonymous0 *___dst__13s__anonymous0_1);
+static inline void ___constructor__F_13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1);
+static inline void ___destructor__F_13s__anonymous0_autogen___1(struct __anonymous0 *___dst__13s__anonymous0_1);
+static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1);
+static inline void ___constructor__F_13s__anonymous0_autogen___1(struct __anonymous0 *___dst__13s__anonymous0_1){
+}
+static inline void ___constructor__F_13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1){
+}
+static inline void ___destructor__F_13s__anonymous0_autogen___1(struct __anonymous0 *___dst__13s__anonymous0_1){
+}
+static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1){
+    struct __anonymous0 ___ret__13s__anonymous0_1;
+    ((void)___constructor__F_13s__anonymous013s__anonymous0_autogen___1((&___ret__13s__anonymous0_1), (*___dst__13s__anonymous0_1)));
+    return ___ret__13s__anonymous0_1;
+}
+struct __attribute__ ((unused)) Agn1;
+struct __attribute__ ((unused)) Agn2 {
+};
+static inline void ___constructor__F_5sAgn2_autogen___1(struct Agn2 *___dst__5sAgn2_1);
+static inline void ___constructor__F_5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__5sAgn2_1, struct Agn2 ___src__5sAgn2_1);
+static inline void ___destructor__F_5sAgn2_autogen___1(struct Agn2 *___dst__5sAgn2_1);
+static inline struct Agn2 ___operator_assign__F5sAgn2_5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__5sAgn2_1, struct Agn2 ___src__5sAgn2_1);
+static inline void ___constructor__F_5sAgn2_autogen___1(struct Agn2 *___dst__5sAgn2_1){
+}
+static inline void ___constructor__F_5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__5sAgn2_1, struct Agn2 ___src__5sAgn2_1){
+}
+static inline void ___destructor__F_5sAgn2_autogen___1(struct Agn2 *___dst__5sAgn2_1){
+}
+static inline struct Agn2 ___operator_assign__F5sAgn2_5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__5sAgn2_1, struct Agn2 ___src__5sAgn2_1){
+    struct Agn2 ___ret__5sAgn2_1;
+    ((void)___constructor__F_5sAgn25sAgn2_autogen___1((&___ret__5sAgn2_1), (*___dst__5sAgn2_1)));
+    return ___ret__5sAgn2_1;
+}
+enum __attribute__ ((unused)) __anonymous1 {
+    __E1__C13e__anonymous1_1,
+};
+enum __attribute__ ((unused)) Agn3;
+enum __attribute__ ((packed)) Agn3 {
+    __E2__C5eAgn3_1,
+};
+struct __attribute__ ((unused)) __anonymous2 {
+};
+static inline void ___constructor__F_13s__anonymous2_autogen___1(struct __anonymous2 *___dst__13s__anonymous2_1);
+static inline void ___constructor__F_13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1);
+static inline void ___destructor__F_13s__anonymous2_autogen___1(struct __anonymous2 *___dst__13s__anonymous2_1);
+static inline struct __anonymous2 ___operator_assign__F13s__anonymous2_13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1);
+static inline void ___constructor__F_13s__anonymous2_autogen___1(struct __anonymous2 *___dst__13s__anonymous2_1){
+}
+static inline void ___constructor__F_13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1){
+}
+static inline void ___destructor__F_13s__anonymous2_autogen___1(struct __anonymous2 *___dst__13s__anonymous2_1){
+}
+static inline struct __anonymous2 ___operator_assign__F13s__anonymous2_13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1){
+    struct __anonymous2 ___ret__13s__anonymous2_1;
+    ((void)___constructor__F_13s__anonymous213s__anonymous2_autogen___1((&___ret__13s__anonymous2_1), (*___dst__13s__anonymous2_1)));
+    return ___ret__13s__anonymous2_1;
+}
+struct __attribute__ ((unused)) Agn4 {
+};
+static inline void ___constructor__F_5sAgn4_autogen___1(struct Agn4 *___dst__5sAgn4_1);
+static inline void ___constructor__F_5sAgn45sAgn4_autogen___1(struct Agn4 *___dst__5sAgn4_1, struct Agn4 ___src__5sAgn4_1);
+static inline void ___destructor__F_5sAgn4_autogen___1(struct Agn4 *___dst__5sAgn4_1);
+static inline struct Agn4 ___operator_assign__F5sAgn4_5sAgn45sAgn4_autogen___1(struct Agn4 *___dst__5sAgn4_1, struct Agn4 ___src__5sAgn4_1);
+static inline void ___constructor__F_5sAgn4_autogen___1(struct Agn4 *___dst__5sAgn4_1){
+}
+static inline void ___constructor__F_5sAgn45sAgn4_autogen___1(struct Agn4 *___dst__5sAgn4_1, struct Agn4 ___src__5sAgn4_1){
+}
+static inline void ___destructor__F_5sAgn4_autogen___1(struct Agn4 *___dst__5sAgn4_1){
+}
+static inline struct Agn4 ___operator_assign__F5sAgn4_5sAgn45sAgn4_autogen___1(struct Agn4 *___dst__5sAgn4_1, struct Agn4 ___src__5sAgn4_1){
+    struct Agn4 ___ret__5sAgn4_1;
+    ((void)___constructor__F_5sAgn45sAgn4_autogen___1((&___ret__5sAgn4_1), (*___dst__5sAgn4_1)));
+    return ___ret__5sAgn4_1;
+}
+struct Fdl {
+    __attribute__ ((unused)) signed int __f1__i_1;
+    __attribute__ ((unused)) signed int __f2__i_1;
+    __attribute__ ((unused,unused)) signed int __f3__i_1;
+    __attribute__ ((unused)) signed int __f4__i_1;
+    __attribute__ ((unused,unused)) signed int __f5__i_1;
+    __attribute__ ((used,packed)) signed int __f6__i_1;
+    __attribute__ ((used,unused,unused)) signed int __f7__i_1;
+    __attribute__ ((used,used,unused)) signed int __f8__i_1;
+    __attribute__ ((unused)) signed int __anonymous_object0;
+    __attribute__ ((unused,unused)) signed int *__f9__Pi_1;
+};
+static inline void ___constructor__F_4sFdl_autogen___1(struct Fdl *___dst__4sFdl_1);
+static inline void ___constructor__F_4sFdl4sFdl_autogen___1(struct Fdl *___dst__4sFdl_1, struct Fdl ___src__4sFdl_1);
+static inline void ___destructor__F_4sFdl_autogen___1(struct Fdl *___dst__4sFdl_1);
+static inline struct Fdl ___operator_assign__F4sFdl_4sFdl4sFdl_autogen___1(struct Fdl *___dst__4sFdl_1, struct Fdl ___src__4sFdl_1);
+static inline void ___constructor__F_4sFdli_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1);
+static inline void ___constructor__F_4sFdlii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1);
+static inline void ___constructor__F_4sFdliii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1);
+static inline void ___constructor__F_4sFdliiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1);
+static inline void ___constructor__F_4sFdliiiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1);
+static inline void ___constructor__F_4sFdliiiiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1, signed int __f6__i_1);
+static inline void ___constructor__F_4sFdliiiiiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1, signed int __f6__i_1, __attribute__ ((unused,unused)) signed int __f7__i_1);
+static inline void ___constructor__F_4sFdliiiiiiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1, signed int __f6__i_1, __attribute__ ((unused,unused)) signed int __f7__i_1, __attribute__ ((unused)) signed int __f8__i_1);
+static inline void ___constructor__F_4sFdliiiiiiiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1, signed int __f6__i_1, __attribute__ ((unused,unused)) signed int __f7__i_1, __attribute__ ((unused)) signed int __f8__i_1, __attribute__ ((unused)) signed int __anonymous_object1);
+static inline void ___constructor__F_4sFdliiiiiiiiiPi_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1, signed int __f6__i_1, __attribute__ ((unused,unused)) signed int __f7__i_1, __attribute__ ((unused)) signed int __f8__i_1, __attribute__ ((unused)) signed int __anonymous_object2, __attribute__ ((unused,unused)) signed int *__f9__Pi_1);
+static inline void ___constructor__F_4sFdl_autogen___1(struct Fdl *___dst__4sFdl_1){
+    ((void)((*___dst__4sFdl_1).__f1__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f2__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f3__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f4__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f5__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f6__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f7__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f8__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__anonymous_object0) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ?{} */);
+}
+static inline void ___constructor__F_4sFdl4sFdl_autogen___1(struct Fdl *___dst__4sFdl_1, struct Fdl ___src__4sFdl_1){
+    ((void)((*___dst__4sFdl_1).__f1__i_1=___src__4sFdl_1.__f1__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f2__i_1=___src__4sFdl_1.__f2__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f3__i_1=___src__4sFdl_1.__f3__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f4__i_1=___src__4sFdl_1.__f4__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f5__i_1=___src__4sFdl_1.__f5__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f6__i_1=___src__4sFdl_1.__f6__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f7__i_1=___src__4sFdl_1.__f7__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f8__i_1=___src__4sFdl_1.__f8__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__anonymous_object0=___src__4sFdl_1.__anonymous_object0) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f9__Pi_1=___src__4sFdl_1.__f9__Pi_1) /* ?{} */);
+}
+static inline void ___destructor__F_4sFdl_autogen___1(struct Fdl *___dst__4sFdl_1){
+    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ^?{} */);
+    ((void)((*___dst__4sFdl_1).__anonymous_object0) /* ^?{} */);
+    ((void)((*___dst__4sFdl_1).__f8__i_1) /* ^?{} */);
+    ((void)((*___dst__4sFdl_1).__f7__i_1) /* ^?{} */);
+    ((void)((*___dst__4sFdl_1).__f6__i_1) /* ^?{} */);
+    ((void)((*___dst__4sFdl_1).__f5__i_1) /* ^?{} */);
+    ((void)((*___dst__4sFdl_1).__f4__i_1) /* ^?{} */);
+    ((void)((*___dst__4sFdl_1).__f3__i_1) /* ^?{} */);
+    ((void)((*___dst__4sFdl_1).__f2__i_1) /* ^?{} */);
+    ((void)((*___dst__4sFdl_1).__f1__i_1) /* ^?{} */);
+}
+static inline struct Fdl ___operator_assign__F4sFdl_4sFdl4sFdl_autogen___1(struct Fdl *___dst__4sFdl_1, struct Fdl ___src__4sFdl_1){
+    struct Fdl ___ret__4sFdl_1;
+    ((void)((*___dst__4sFdl_1).__f1__i_1=___src__4sFdl_1.__f1__i_1));
+    ((void)((*___dst__4sFdl_1).__f2__i_1=___src__4sFdl_1.__f2__i_1));
+    ((void)((*___dst__4sFdl_1).__f3__i_1=___src__4sFdl_1.__f3__i_1));
+    ((void)((*___dst__4sFdl_1).__f4__i_1=___src__4sFdl_1.__f4__i_1));
+    ((void)((*___dst__4sFdl_1).__f5__i_1=___src__4sFdl_1.__f5__i_1));
+    ((void)((*___dst__4sFdl_1).__f6__i_1=___src__4sFdl_1.__f6__i_1));
+    ((void)((*___dst__4sFdl_1).__f7__i_1=___src__4sFdl_1.__f7__i_1));
+    ((void)((*___dst__4sFdl_1).__f8__i_1=___src__4sFdl_1.__f8__i_1));
+    ((void)((*___dst__4sFdl_1).__anonymous_object0=___src__4sFdl_1.__anonymous_object0));
+    ((void)((*___dst__4sFdl_1).__f9__Pi_1=___src__4sFdl_1.__f9__Pi_1));
+    ((void)___constructor__F_4sFdl4sFdl_autogen___1((&___ret__4sFdl_1), (*___dst__4sFdl_1)));
+    return ___ret__4sFdl_1;
+}
+static inline void ___constructor__F_4sFdli_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1){
+    ((void)((*___dst__4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f2__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f3__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f4__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f5__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f6__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f7__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f8__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__anonymous_object0) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ?{} */);
+}
+static inline void ___constructor__F_4sFdlii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1){
+    ((void)((*___dst__4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f3__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f4__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f5__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f6__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f7__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f8__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__anonymous_object0) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ?{} */);
+}
+static inline void ___constructor__F_4sFdliii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1){
+    ((void)((*___dst__4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f3__i_1=__f3__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f4__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f5__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f6__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f7__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f8__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__anonymous_object0) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ?{} */);
+}
+static inline void ___constructor__F_4sFdliiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1){
+    ((void)((*___dst__4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f3__i_1=__f3__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f4__i_1=__f4__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f5__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f6__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f7__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f8__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__anonymous_object0) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ?{} */);
+}
+static inline void ___constructor__F_4sFdliiiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1){
+    ((void)((*___dst__4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f3__i_1=__f3__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f4__i_1=__f4__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f5__i_1=__f5__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f6__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f7__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f8__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__anonymous_object0) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ?{} */);
+}
+static inline void ___constructor__F_4sFdliiiiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1, signed int __f6__i_1){
+    ((void)((*___dst__4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f3__i_1=__f3__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f4__i_1=__f4__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f5__i_1=__f5__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f6__i_1=__f6__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f7__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f8__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__anonymous_object0) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ?{} */);
+}
+static inline void ___constructor__F_4sFdliiiiiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1, signed int __f6__i_1, __attribute__ ((unused,unused)) signed int __f7__i_1){
+    ((void)((*___dst__4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f3__i_1=__f3__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f4__i_1=__f4__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f5__i_1=__f5__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f6__i_1=__f6__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f8__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__anonymous_object0) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ?{} */);
+}
+static inline void ___constructor__F_4sFdliiiiiiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1, signed int __f6__i_1, __attribute__ ((unused,unused)) signed int __f7__i_1, __attribute__ ((unused)) signed int __f8__i_1){
+    ((void)((*___dst__4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f3__i_1=__f3__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f4__i_1=__f4__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f5__i_1=__f5__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f6__i_1=__f6__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f8__i_1=__f8__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__anonymous_object0) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ?{} */);
+}
+static inline void ___constructor__F_4sFdliiiiiiiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1, signed int __f6__i_1, __attribute__ ((unused,unused)) signed int __f7__i_1, __attribute__ ((unused)) signed int __f8__i_1, __attribute__ ((unused)) signed int __anonymous_object3){
+    ((void)((*___dst__4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f3__i_1=__f3__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f4__i_1=__f4__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f5__i_1=__f5__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f6__i_1=__f6__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f8__i_1=__f8__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__anonymous_object0=__anonymous_object3) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ?{} */);
+}
+static inline void ___constructor__F_4sFdliiiiiiiiiPi_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1, signed int __f6__i_1, __attribute__ ((unused,unused)) signed int __f7__i_1, __attribute__ ((unused)) signed int __f8__i_1, __attribute__ ((unused)) signed int __anonymous_object4, __attribute__ ((unused,unused)) signed int *__f9__Pi_1){
+    ((void)((*___dst__4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f3__i_1=__f3__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f4__i_1=__f4__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f5__i_1=__f5__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f6__i_1=__f6__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f8__i_1=__f8__i_1) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__anonymous_object0=__anonymous_object4) /* ?{} */);
+    ((void)((*___dst__4sFdl_1).__f9__Pi_1=__f9__Pi_1) /* ?{} */);
+}
+__attribute__ ((unused)) signed int __f__Fi___1() asm ( "xyz" );
+__attribute__ ((used,used)) const signed int __vd1__Ci_1;
+__attribute__ ((used,unused)) const signed int __vd2__Ci_1;
+__attribute__ ((used,used,used,used)) const signed int *__vd3__PCi_1;
+__attribute__ ((used,used,unused,used,unused)) const signed int *__vd4__PCi_1;
+__attribute__ ((used,used,used)) const signed int __vd5__A0Ci_1[((unsigned int )5)];
+__attribute__ ((used,used,unused,used)) const signed int __vd6__A0Ci_1[((unsigned int )5)];
+__attribute__ ((used,used,used,used)) const signed int (*__vd7__Fi___1)();
+__attribute__ ((used,used,unused,used,used)) const signed int (*__vd8__Fi___1)();
+__attribute__ ((unused,used)) signed int __f1__Fi___1();
+__attribute__ ((unused)) signed int __f1__Fi___1(){
+    __attribute__ ((unused)) signed int ___retval_f1__i_1;
+}
+__attribute__ ((unused,unused,unused,used)) signed int **const __f2__FPPi___1();
+__attribute__ ((unused,unused,unused)) signed int **const __f2__FPPi___1(){
+    __attribute__ ((unused)) signed int **const ___retval_f2__CPPi_1;
+}
+__attribute__ ((unused,used,unused)) signed int (*__f3__FPA0i_i__1(signed int __anonymous_object5))[];
+__attribute__ ((unused,unused)) signed int (*__f3__FPA0i_i__1(signed int __p__i_1))[]{
+    __attribute__ ((unused)) signed int (*___retval_f3__PA0i_1)[];
+}
+__attribute__ ((unused,used,unused)) signed int (*__f4__FFi_i____1())(signed int __anonymous_object6);
+__attribute__ ((unused,unused)) signed int (*__f4__FFi_i____1())(signed int __anonymous_object7){
+    __attribute__ ((unused)) signed int (*___retval_f4__Fi_i__1)(signed int __anonymous_object8);
+}
+signed int __vtr__Fi___1(){
+    __attribute__ ((unused)) signed int ___retval_vtr__i_1;
+    __attribute__ ((unused,unused,used)) signed int __t1__i_2;
+    __attribute__ ((unused,unused,unused,unused,unused)) signed int **__t2__PPi_2;
+    __attribute__ ((unused,unused,unused)) signed int __t3__A0i_2[((unsigned int )5)];
+    __attribute__ ((unused,unused,unused,unused,unused)) signed int **__t4__A0PPi_2[((unsigned int )5)];
+    __attribute__ ((unused,unused,unused)) signed int __t5__Fi___2();
+    __attribute__ ((unused,unused,unused,unused)) signed int *__t6__FPi___2();
+}
+signed int __ipd1__Fi_ii__1(__attribute__ ((unused,unused,unused)) signed int __p__i_1, __attribute__ ((unused,unused,unused)) signed int __q__i_1);
+signed int __ipd1__Fi_ii__1(__attribute__ ((unused,unused,unused)) signed int __p__i_1, __attribute__ ((unused,unused,unused)) signed int __q__i_1){
+    __attribute__ ((unused)) signed int ___retval_ipd1__i_1;
+}
+signed int __ipd2__Fi_PiPi__1(__attribute__ ((unused,unused,unused,unused)) signed int *__p__Pi_1, __attribute__ ((unused,unused,unused)) signed int *__q__Pi_1);
+signed int __ipd2__Fi_PiPi__1(__attribute__ ((unused,unused,unused,unused)) signed int *__p__Pi_1, __attribute__ ((unused,unused,unused)) signed int *__q__Pi_1){
+    __attribute__ ((unused)) signed int ___retval_ipd2__i_1;
+}
+signed int __ipd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__p__Pi_1, __attribute__ ((unused,unused,unused)) signed int *__q__Pi_1);
+signed int __ipd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__p__Pi_1, __attribute__ ((unused,unused,unused)) signed int *__q__Pi_1){
+    __attribute__ ((unused)) signed int ___retval_ipd3__i_1;
+}
+signed int __ipd4__Fi_Fi__Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__p__Fi___1)(), __attribute__ ((unused,unused,unused)) signed int (*__q__Fi___1)());
+signed int __ipd4__Fi_Fi__Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__p__Fi___1)(), __attribute__ ((unused,unused,unused)) signed int (*__q__Fi___1)()){
+    __attribute__ ((unused)) signed int ___retval_ipd4__i_1;
+}
+signed int __tpr1__Fi_i__1(__attribute__ ((unused,unused,unused)) signed int __Foo__i_1);
+signed int __tpr2__Fi_PPi__1(__attribute__ ((unused,unused,unused,unused,unused,unused)) signed int **__Foo__PPi_1);
+signed int __tpr3__Fi_Pi__1(__attribute__ ((unused,unused,unused)) signed int *__Foo__Pi_1);
+signed int __tpr4__Fi_Fi_Pi___1(__attribute__ ((unused,unused)) signed int (*__anonymous_object9)(__attribute__ ((unused,unused)) signed int __anonymous_object10[((unsigned int )5)]));
+signed int __tpr5__Fi_Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__Foo__Fi___1)());
+signed int __tpr6__Fi_Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__Foo__Fi___1)());
+signed int __tpr7__Fi_Fi_Fi_i____1(__attribute__ ((unused,unused)) signed int (*__anonymous_object11)(__attribute__ ((unused)) signed int (*__anonymous_object12)(__attribute__ ((unused,unused)) signed int __anonymous_object13)));
+signed int __ad__Fi___1(){
+    __attribute__ ((unused)) signed int ___retval_ad__i_1;
+    __attribute__ ((used,unused)) signed int __ad1__i_2;
+    __attribute__ ((unused,unused,unused)) signed int *__ad2__Pi_2;
+    __attribute__ ((unused,unused,unused)) signed int __ad3__A0i_2[((unsigned int )5)];
+    __attribute__ ((unused,unused,unused,unused,unused)) signed int (*__ad4__PA0i_2)[((unsigned int )10)];
+    __attribute__ ((unused,unused,unused,unused,used)) signed int __ad5__i_2;
+    __attribute__ ((unused,unused,unused,unused,unused)) signed int __ad6__Fi___2();
+    ((void)sizeof(__attribute__ ((unused,unused)) signed int ));
+    ((void)sizeof(__attribute__ ((unused,unused,unused,unused)) signed int **));
+    ((void)sizeof(__attribute__ ((unused,unused,unused)) signed int [5]));
+    ((void)sizeof(__attribute__ ((unused,unused,unused)) signed int (*)[10]));
+    ((void)sizeof(__attribute__ ((unused,unused,unused)) signed int ()));
+    struct __attribute__ ((unused)) __anonymous3 {
+        signed int __i__i_2;
+    };
+    inline void ___constructor__F_13s__anonymous3_autogen___2(struct __anonymous3 *___dst__13s__anonymous3_2){
+        ((void)((*___dst__13s__anonymous3_2).__i__i_2) /* ?{} */);
+    }
+    inline void ___constructor__F_13s__anonymous313s__anonymous3_autogen___2(struct __anonymous3 *___dst__13s__anonymous3_2, struct __anonymous3 ___src__13s__anonymous3_2){
+        ((void)((*___dst__13s__anonymous3_2).__i__i_2=___src__13s__anonymous3_2.__i__i_2) /* ?{} */);
+    }
+    inline void ___destructor__F_13s__anonymous3_autogen___2(struct __anonymous3 *___dst__13s__anonymous3_2){
+        ((void)((*___dst__13s__anonymous3_2).__i__i_2) /* ^?{} */);
+    }
+    inline struct __anonymous3 ___operator_assign__F13s__anonymous3_13s__anonymous313s__anonymous3_autogen___2(struct __anonymous3 *___dst__13s__anonymous3_2, struct __anonymous3 ___src__13s__anonymous3_2){
+        struct __anonymous3 ___ret__13s__anonymous3_2;
+        ((void)((*___dst__13s__anonymous3_2).__i__i_2=___src__13s__anonymous3_2.__i__i_2));
+        ((void)___constructor__F_13s__anonymous313s__anonymous3_autogen___2((&___ret__13s__anonymous3_2), (*___dst__13s__anonymous3_2)));
+        return ___ret__13s__anonymous3_2;
+    }
+    inline void ___constructor__F_13s__anonymous3i_autogen___2(struct __anonymous3 *___dst__13s__anonymous3_2, signed int __i__i_2){
+        ((void)((*___dst__13s__anonymous3_2).__i__i_2=__i__i_2) /* ?{} */);
+    }
+    ((void)sizeof(struct __anonymous3 ));
+    enum __attribute__ ((unused)) __anonymous4 {
+        __R__C13e__anonymous4_2,
+    };
+    inline void ___constructor__F_13e__anonymous4_intrinsic___2(__attribute__ ((unused)) enum __anonymous4 *___dst__13e__anonymous4_2){
+    }
+    inline void ___constructor__F_13e__anonymous413e__anonymous4_intrinsic___2(enum __anonymous4 *___dst__13e__anonymous4_2, enum __anonymous4 ___src__13e__anonymous4_2){
+        ((void)((*___dst__13e__anonymous4_2)=___src__13e__anonymous4_2) /* ?{} */);
+    }
+    inline void ___destructor__F_13e__anonymous4_intrinsic___2(__attribute__ ((unused)) enum __anonymous4 *___dst__13e__anonymous4_2){
+    }
+    inline enum __anonymous4 ___operator_assign__F13e__anonymous4_13e__anonymous413e__anonymous4_intrinsic___2(enum __anonymous4 *___dst__13e__anonymous4_2, enum __anonymous4 ___src__13e__anonymous4_2){
+        enum __anonymous4 ___ret__13e__anonymous4_2;
+        ((void)((*___dst__13e__anonymous4_2)=___src__13e__anonymous4_2));
+        ((void)(___ret__13e__anonymous4_2=(*___dst__13e__anonymous4_2)) /* ?{} */);
+        return ___ret__13e__anonymous4_2;
+    }
+    ((void)sizeof(enum __anonymous4 ));
+}
+signed int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object14, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object15);
+signed int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object16, __attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object17);
+signed int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object18, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object19);
+signed int __apd4__Fi_Fi__Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object20)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object21)());
+signed int __apd5__Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object22)(__attribute__ ((unused)) signed int __anonymous_object23), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object24)(__attribute__ ((unused)) signed int __anonymous_object25));
+signed int __apd6__Fi_Fi__Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object26)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object27)());
+signed int __apd7__Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object28)(__attribute__ ((unused)) signed int __anonymous_object29), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object30)(__attribute__ ((unused)) signed int __anonymous_object31));
+struct Vad {
+    __attribute__ ((unused)) signed int __anonymous_object32;
+    __attribute__ ((unused,unused)) signed int *__anonymous_object33;
+    __attribute__ ((unused,unused)) signed int __anonymous_object34[((unsigned int )10)];
+    __attribute__ ((unused,unused)) signed int (*__anonymous_object35)();
+};
+static inline void ___constructor__F_4sVad_autogen___1(struct Vad *___dst__4sVad_1);
+static inline void ___constructor__F_4sVad4sVad_autogen___1(struct Vad *___dst__4sVad_1, struct Vad ___src__4sVad_1);
+static inline void ___destructor__F_4sVad_autogen___1(struct Vad *___dst__4sVad_1);
+static inline struct Vad ___operator_assign__F4sVad_4sVad4sVad_autogen___1(struct Vad *___dst__4sVad_1, struct Vad ___src__4sVad_1);
+static inline void ___constructor__F_4sVadi_autogen___1(struct Vad *___dst__4sVad_1, __attribute__ ((unused)) signed int __anonymous_object36);
+static inline void ___constructor__F_4sVadiPi_autogen___1(struct Vad *___dst__4sVad_1, __attribute__ ((unused)) signed int __anonymous_object37, __attribute__ ((unused,unused)) signed int *__anonymous_object38);
+static inline void ___constructor__F_4sVadiPiA0i_autogen___1(struct Vad *___dst__4sVad_1, __attribute__ ((unused)) signed int __anonymous_object39, __attribute__ ((unused,unused)) signed int *__anonymous_object40, __attribute__ ((unused,unused)) signed int __anonymous_object41[((unsigned int )10)]);
+static inline void ___constructor__F_4sVadiPiA0iFi___autogen___1(struct Vad *___dst__4sVad_1, __attribute__ ((unused)) signed int __anonymous_object42, __attribute__ ((unused,unused)) signed int *__anonymous_object43, __attribute__ ((unused,unused)) signed int __anonymous_object44[((unsigned int )10)], __attribute__ ((unused,unused)) signed int (*__anonymous_object45)());
+static inline void ___constructor__F_4sVad_autogen___1(struct Vad *___dst__4sVad_1){
+    ((void)((*___dst__4sVad_1).__anonymous_object32) /* ?{} */);
+    ((void)((*___dst__4sVad_1).__anonymous_object33) /* ?{} */);
+    {
+        signed int _index0 = 0;
+        for (;(_index0<10);((void)(++_index0))) {
+            ((void)((*___dst__4sVad_1).__anonymous_object34[_index0]) /* ?{} */);
+        }
+
+    }
+
+    ((void)((*___dst__4sVad_1).__anonymous_object35) /* ?{} */);
+}
+static inline void ___constructor__F_4sVad4sVad_autogen___1(struct Vad *___dst__4sVad_1, struct Vad ___src__4sVad_1){
+    ((void)((*___dst__4sVad_1).__anonymous_object32=___src__4sVad_1.__anonymous_object32) /* ?{} */);
+    ((void)((*___dst__4sVad_1).__anonymous_object33=___src__4sVad_1.__anonymous_object33) /* ?{} */);
+    {
+        signed int _index1 = 0;
+        for (;(_index1<10);((void)(++_index1))) {
+            ((void)((*___dst__4sVad_1).__anonymous_object34[_index1]=___src__4sVad_1.__anonymous_object34[_index1]) /* ?{} */);
+        }
+
+    }
+
+    ((void)((*___dst__4sVad_1).__anonymous_object35=___src__4sVad_1.__anonymous_object35) /* ?{} */);
+}
+static inline void ___destructor__F_4sVad_autogen___1(struct Vad *___dst__4sVad_1){
+    ((void)((*___dst__4sVad_1).__anonymous_object35) /* ^?{} */);
+    {
+        signed int _index2 = (10-1);
+        for (;(_index2>=0);((void)(--_index2))) {
+            ((void)((*___dst__4sVad_1).__anonymous_object34[_index2]) /* ^?{} */);
+        }
+
+    }
+
+    ((void)((*___dst__4sVad_1).__anonymous_object33) /* ^?{} */);
+    ((void)((*___dst__4sVad_1).__anonymous_object32) /* ^?{} */);
+}
+static inline struct Vad ___operator_assign__F4sVad_4sVad4sVad_autogen___1(struct Vad *___dst__4sVad_1, struct Vad ___src__4sVad_1){
+    struct Vad ___ret__4sVad_1;
+    ((void)((*___dst__4sVad_1).__anonymous_object32=___src__4sVad_1.__anonymous_object32));
+    ((void)((*___dst__4sVad_1).__anonymous_object33=___src__4sVad_1.__anonymous_object33));
+    {
+        signed int _index3 = 0;
+        for (;(_index3<10);((void)(++_index3))) {
+            ((void)((*___dst__4sVad_1).__anonymous_object34[_index3]=___src__4sVad_1.__anonymous_object34[_index3]));
+        }
+
+    }
+
+    ((void)((*___dst__4sVad_1).__anonymous_object35=___src__4sVad_1.__anonymous_object35));
+    ((void)___constructor__F_4sVad4sVad_autogen___1((&___ret__4sVad_1), (*___dst__4sVad_1)));
+    return ___ret__4sVad_1;
+}
+static inline void ___constructor__F_4sVadi_autogen___1(struct Vad *___dst__4sVad_1, __attribute__ ((unused)) signed int __anonymous_object46){
+    ((void)((*___dst__4sVad_1).__anonymous_object32=__anonymous_object46) /* ?{} */);
+    ((void)((*___dst__4sVad_1).__anonymous_object33) /* ?{} */);
+    {
+        signed int _index4 = 0;
+        for (;(_index4<10);((void)(++_index4))) {
+            ((void)((*___dst__4sVad_1).__anonymous_object34[_index4]) /* ?{} */);
+        }
+
+    }
+
+    ((void)((*___dst__4sVad_1).__anonymous_object35) /* ?{} */);
+}
+static inline void ___constructor__F_4sVadiPi_autogen___1(struct Vad *___dst__4sVad_1, __attribute__ ((unused)) signed int __anonymous_object47, __attribute__ ((unused,unused)) signed int *__anonymous_object48){
+    ((void)((*___dst__4sVad_1).__anonymous_object32=__anonymous_object47) /* ?{} */);
+    ((void)((*___dst__4sVad_1).__anonymous_object33=__anonymous_object48) /* ?{} */);
+    {
+        signed int _index5 = 0;
+        for (;(_index5<10);((void)(++_index5))) {
+            ((void)((*___dst__4sVad_1).__anonymous_object34[_index5]) /* ?{} */);
+        }
+
+    }
+
+    ((void)((*___dst__4sVad_1).__anonymous_object35) /* ?{} */);
+}
+static inline void ___constructor__F_4sVadiPiA0i_autogen___1(struct Vad *___dst__4sVad_1, __attribute__ ((unused)) signed int __anonymous_object49, __attribute__ ((unused,unused)) signed int *__anonymous_object50, __attribute__ ((unused,unused)) signed int __anonymous_object51[((unsigned int )10)]){
+    ((void)((*___dst__4sVad_1).__anonymous_object32=__anonymous_object49) /* ?{} */);
+    ((void)((*___dst__4sVad_1).__anonymous_object33=__anonymous_object50) /* ?{} */);
+    {
+        signed int _index6 = 0;
+        for (;(_index6<10);((void)(++_index6))) {
+            ((void)((*___dst__4sVad_1).__anonymous_object34[_index6]=__anonymous_object51[_index6]) /* ?{} */);
+        }
+
+    }
+
+    ((void)((*___dst__4sVad_1).__anonymous_object35) /* ?{} */);
+}
+static inline void ___constructor__F_4sVadiPiA0iFi___autogen___1(struct Vad *___dst__4sVad_1, __attribute__ ((unused)) signed int __anonymous_object52, __attribute__ ((unused,unused)) signed int *__anonymous_object53, __attribute__ ((unused,unused)) signed int __anonymous_object54[((unsigned int )10)], __attribute__ ((unused,unused)) signed int (*__anonymous_object55)()){
+    ((void)((*___dst__4sVad_1).__anonymous_object32=__anonymous_object52) /* ?{} */);
+    ((void)((*___dst__4sVad_1).__anonymous_object33=__anonymous_object53) /* ?{} */);
+    {
+        signed int _index7 = 0;
+        for (;(_index7<10);((void)(++_index7))) {
+            ((void)((*___dst__4sVad_1).__anonymous_object34[_index7]=__anonymous_object54[_index7]) /* ?{} */);
+        }
+
+    }
+
+    ((void)((*___dst__4sVad_1).__anonymous_object35=__anonymous_object55) /* ?{} */);
+}
Index: src/tests/.expect/nested-types-ERR1.txt
===================================================================
--- src/tests/.expect/nested-types-ERR1.txt	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
+++ src/tests/.expect/nested-types-ERR1.txt	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -0,0 +1,1 @@
+nested-types.c:70:1 error: Use of undefined type T
Index: src/tests/.expect/nested-types-ERR2.txt
===================================================================
--- src/tests/.expect/nested-types-ERR2.txt	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
+++ src/tests/.expect/nested-types-ERR2.txt	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -0,0 +1,6 @@
+nested-types.c:73:1 error: Use of undefined global type Z
+nested-types.c:74:1 error: Qualified type requires an aggregate on the left, but has: signed int
+nested-types.c:75:1 error: Undefined type in qualified type: Qualified Type: 
+  instance of struct S with body 1 
+  instance of type Z (not function type) 
+
Index: src/tests/Makefile.am
===================================================================
--- src/tests/Makefile.am	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/tests/Makefile.am	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -17,5 +17,5 @@
 debug=yes
 
-quick_test=avl_test operators numericConstants expression enum array typeof cast attributes
+quick_test=avl_test operators numericConstants expression enum array typeof cast raii/dtor-early-exit raii/init_once attributes
 
 if BUILD_CONCURRENCY
@@ -110,4 +110,10 @@
 	${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@}
 
+nested-types-ERR1: nested-types.c @CFA_BINDIR@/@CFA_NAME@
+	${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@}
+
+nested-types-ERR2: nested-types.c @CFA_BINDIR@/@CFA_NAME@
+	${CC} ${AM_CFLAGS} ${CFLAGS} -DERR2 ${<} -o ${@}
+
 # Constructor/destructor tests
 raii/dtor-early-exit-ERR1: raii/dtor-early-exit.c @CFA_BINDIR@/@CFA_NAME@
Index: src/tests/Makefile.in
===================================================================
--- src/tests/Makefile.in	(revision fc20514eea90ea2d9e7e72cd6a6a11c02dc1886f)
+++ src/tests/Makefile.in	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -303,5 +303,5 @@
 top_srcdir = @top_srcdir@
 debug = yes
-quick_test = avl_test operators numericConstants expression enum array typeof cast dtor-early-exit init_once attributes
+quick_test = avl_test operators numericConstants expression enum array typeof cast raii/dtor-early-exit raii/init_once attributes
 @BUILD_CONCURRENCY_FALSE@concurrent = '-Econcurrent'
 @BUILD_CONCURRENCY_TRUE@concurrent = 
@@ -787,4 +787,10 @@
 	${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@}
 
+nested-types-ERR1: nested-types.c @CFA_BINDIR@/@CFA_NAME@
+	${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@}
+
+nested-types-ERR2: nested-types.c @CFA_BINDIR@/@CFA_NAME@
+	${CC} ${AM_CFLAGS} ${CFLAGS} -DERR2 ${<} -o ${@}
+
 # Constructor/destructor tests
 raii/dtor-early-exit-ERR1: raii/dtor-early-exit.c @CFA_BINDIR@/@CFA_NAME@
Index: src/tests/nested-types.c
===================================================================
--- src/tests/nested-types.c	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
+++ src/tests/nested-types.c	(revision 777ed2b6fddb63be60f52f784e80cc5897a6d457)
@@ -0,0 +1,91 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// nested-types.c --
+//
+// Author           : Rob Schluntz
+// Created On       : Mon Jul 9 10:20:03 2018
+// Last Modified By : Rob Schluntz
+// Last Modified On : Mon Jul 9 10:20:03 2017
+// Update Count     : 1
+//
+
+typedef int N;
+struct A {
+  forall(otype T)
+  struct N {
+    T x;
+  };
+};
+
+struct S {
+  struct T {
+    int i;
+    typedef int Bar;
+  };
+  T x;
+
+  // struct U;
+  typedef T Bar;
+  typedef int Baz;
+};
+
+// // // // need a way to stuff a qualified name into a struct decl
+// // struct S.U {
+// //   double z;
+// // };
+
+// // what will this do?
+// struct U {
+//   union S {
+//     int i;
+//     double d;
+//   };
+// };
+
+// struct T {
+//   double d;
+// };
+
+int main() {
+  // access nested struct
+  S.T x;
+
+  {
+    struct S {
+      int i;
+      struct Z {
+        double d;
+      };
+    };
+
+    S.Z z;   // gets local S
+    .S.T y;  // lookup at global scope only
+
+    const volatile .S.T q;
+#if ERR1
+    T err1;           // error: no T in scope
+#endif
+#if ERR2
+    .Z err2;          // error: no Z in global scope
+    .S.Baz.Bar err3;  // error: .S.Baz => int, int is not aggregate and should not appear left of the dot
+    .S.Z err4;        // error: no Z in global S
+#endif
+  }
+
+  // U.S un;
+
+  S.Bar y;
+  S.Baz x;
+  S.T.Bar z;
+
+  // A.N(int) x;  // xxx - should not be an error, but currently is.
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa nested-types.c" //
+// End: //
