Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/AST/Convert.cpp	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -321,8 +321,4 @@
 			get<Type>().accept1(node->base)
 		);
-		// decl->data_constructors = get<StructDecl>().acceptL( node->data_constructors );
-		// decl->data_union = get<UnionDecl>().accept1( node->data_union );
-		// decl->tag = get<EnumDecl>().accept1( node->tag );
-		// decl->tag_union = get<StructDecl>().accept1( node->tag_union );
 		return aggregatePostamble( decl, node );
 	}
@@ -334,5 +330,4 @@
 			get<Attribute>().acceptL( node->attributes ),
 			LinkageSpec::Spec( node->linkage.val ),
-			get<StructDecl>().acceptL( node->data_constructors ),
 			get<UnionDecl>().accept1( node->data_union ),
 			get<EnumDecl>().accept1( node->tag ),
@@ -1344,4 +1339,8 @@
 	}
 
+	const ast::Type * visit( [[maybe_unused]]const ast::AdtInstType * node ) override final {
+		return nullptr;
+	}
+
 	const ast::Type * visit( const ast::UnionInstType * node ) override final {
 		UnionInstType * ty;
@@ -1824,5 +1823,4 @@
 		decl->uniqueId = old->uniqueId;
 		decl->storage = { old->storageClasses.val };
-		decl->data_constructors = GET_ACCEPT_V( data_constructors, StructDecl );
 		decl->data_union = GET_ACCEPT_1( data_union, UnionDecl );
 		decl->tag = GET_ACCEPT_1( tag, EnumDecl );
@@ -2876,4 +2874,22 @@
 		postvisit( old, ty );
 	}
+	
+	virtual void visit( const AdtInstType * old ) override final {
+		ast::AdtInstType * ty;
+		if ( old->baseAdt ) {
+			ty = new ast::AdtInstType{
+				GET_ACCEPT_1( baseAdt, AdtDecl ),
+				cv( old ),
+				GET_ACCEPT_V( attributes, Attribute )
+			};
+		} else {
+			ty = new ast::AdtInstType{
+				old->name,
+				cv( old ),
+				GET_ACCEPT_V( attributes, Attribute )
+			};
+		}
+		postvisit( old, ty );
+	}
 
 	virtual void visit( const UnionInstType * old ) override final {
Index: src/AST/Decl.hpp
===================================================================
--- src/AST/Decl.hpp	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/AST/Decl.hpp	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -248,5 +248,5 @@
 class AggregateDecl : public Decl {
 public:
-	enum Aggregate { Struct, Union, Enum, Exception, Trait, Generator, Coroutine, Monitor, Thread, NoAggregate, Adt };
+	enum Aggregate { Undecided, Struct, Union, Enum, Exception, Trait, Generator, Coroutine, Monitor, Thread, NoAggregate, Adt };
 	static const char * aggrString( Aggregate aggr );
 
@@ -346,5 +346,4 @@
 class AdtDecl final : public AggregateDecl {
 public:
-	std::vector<ptr<StructDecl>> data_constructors; // Todo: members?
 	ptr<UnionDecl> data_union;
 	ptr<EnumDecl> tag;
Index: src/AST/Fwd.hpp
===================================================================
--- src/AST/Fwd.hpp	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/AST/Fwd.hpp	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -123,4 +123,5 @@
 using UnionInstType = SueInstType<UnionDecl>;
 using EnumInstType = SueInstType<EnumDecl>;
+using AdtInstType = SueInstType<AdtDecl>;
 class TraitInstType;
 class TypeInstType;
Index: src/AST/Pass.hpp
===================================================================
--- src/AST/Pass.hpp	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/AST/Pass.hpp	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -219,4 +219,5 @@
 	const ast::Type *             visit( const ast::FunctionType         * ) override final;
 	const ast::Type *             visit( const ast::StructInstType       * ) override final;
+	const ast::Type *             visit( const ast::AdtInstType          * ) override final; 
 	const ast::Type *             visit( const ast::UnionInstType        * ) override final;
 	const ast::Type *             visit( const ast::EnumInstType         * ) override final;
Index: src/AST/Pass.impl.hpp
===================================================================
--- src/AST/Pass.impl.hpp	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/AST/Pass.impl.hpp	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -585,4 +585,27 @@
 
 //--------------------------------------------------------------------------
+// AdtDecl
+template< typename core_t >
+const ast::Decl * ast::Pass< core_t >::visit( const ast::AdtDecl * node ) {
+	VISIT_START( node );
+
+	__pass::symtab::addAdtFwd( core, 0, node );
+
+	if ( __visit_children() ) {
+		guard_symtab guard { *this };
+		maybe_accept( node, &AdtDecl::params );
+		maybe_accept( node, &AdtDecl::members );
+		maybe_accept( node, &AdtDecl::attributes );
+
+		maybe_accept( node, &AdtDecl::data_union );
+		maybe_accept( node, &AdtDecl::tag );
+		maybe_accept( node, &AdtDecl::tag_union );
+	}
+
+	__pass::symtab::addAdt( core, 0, node );
+	VISIT_END( Decl, node );
+}
+
+//--------------------------------------------------------------------------
 // UnionDecl
 template< typename core_t >
@@ -620,9 +643,4 @@
 			maybe_accept( node, &EnumDecl::members    );
 			maybe_accept( node, &EnumDecl::attributes );
-
-			// maybe_accept( node, &EnumDecl::data_constructors );
-			// maybe_accept( node, &EnumDecl::data_union );
-			// maybe_accept( node, &EnumDecl::tag );
-			// maybe_accept( node, &EnumDecl::tag_union );
 		} else {
 			maybe_accept( node, &EnumDecl::base );
@@ -630,31 +648,5 @@
 			maybe_accept( node, &EnumDecl::members    );
 			maybe_accept( node, &EnumDecl::attributes );
-
-			// maybe_accept( node, &EnumDecl::data_constructors );
-			// maybe_accept( node, &EnumDecl::data_union );
-			// maybe_accept( node, &EnumDecl::tag );
-			// maybe_accept( node, &EnumDecl::tag_union );
-		}
-	}
-
-	VISIT_END( Decl, node );
-}
-
-template< typename core_t >
-const ast::Decl * ast::Pass< core_t >::visit( const ast::AdtDecl * node ) {
-	VISIT_START( node );
-
-	__pass::symtab::addAdt( core, 0, node );
-
-	if ( __visit_children() ) {
-		guard_symtab guard { *this };
-		maybe_accept( node, &AdtDecl::params );
-		maybe_accept( node, &AdtDecl::members );
-		maybe_accept( node, &AdtDecl::attributes );
-
-		maybe_accept( node, &AdtDecl::data_constructors );
-		maybe_accept( node, &AdtDecl::data_union );
-		maybe_accept( node, &AdtDecl::tag );
-		maybe_accept( node, &AdtDecl::tag_union );
+		}
 	}
 
@@ -1967,4 +1959,20 @@
 
 //--------------------------------------------------------------------------
+// AdtInstType
+template< typename core_t >
+const ast::Type * ast::Pass< core_t >::visit( const ast::AdtInstType * node ) {
+	VISIT_START( node );
+
+	__pass::symtab::addAdt( core, 0, node->name );
+
+	if ( __visit_children() ) {
+		guard_symtab guard { *this };
+		maybe_accept( node, &AdtInstType::params );
+	}
+
+	VISIT_END( Type, node );
+}
+
+//--------------------------------------------------------------------------
 // UnionInstType
 template< typename core_t >
Index: src/AST/Pass.proto.hpp
===================================================================
--- src/AST/Pass.proto.hpp	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/AST/Pass.proto.hpp	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -477,4 +477,16 @@
 
 	template<typename core_t>
+	static inline auto addAdtFwd( core_t & core, int, const ast::AdtDecl * decl ) -> decltype( core.symtab.addAdt( decl ), void() ) {
+		ast::AdtDecl * fwd = new ast::AdtDecl( decl->location, decl->name );
+		for ( const auto & param : decl->params ) {
+			fwd->params.push_back( deepCopy( param.get() ) );
+		}
+		core.symtab.addAdt( fwd );
+	}
+
+	template<typename core_t>
+	static inline auto addAdtFwd( core_t &, long, const ast::AdtDecl * ) {}
+
+	template<typename core_t>
 	static inline auto addUnionFwd( core_t & core, int, const ast::UnionDecl * decl ) -> decltype( core.symtab.addUnion( decl ), void() ) {
 		ast::UnionDecl * fwd = new ast::UnionDecl( decl->location, decl->name );
@@ -489,20 +501,4 @@
 
 	template<typename core_t>
-	static inline auto addAdtFwd( core_t & core, int, const ast::AdtDecl * decl ) -> decltype( core.symtab.addAdt( decl ), void() ) {
-		ast::AdtDecl * fwd = new ast::AdtDecl( decl->location, decl->name );
-		for ( const auto & param : decl->params ) {
-			fwd->params.push_back( deepCopy( param.get() ) );
-		}
-		// Experimental
-		for ( const auto & ctor : decl->data_constructors ) {
-			addStructFwd( core, 0, ctor  );
-		} 
-		core.symtab.addAdt( fwd );
-	}
-
-	template<typename core_t>
-	static inline auto addAdtFwd( core_t &, long, const ast::AdtDecl) {}
-
-	template<typename core_t>
 	static inline auto addStruct( core_t & core, int, const std::string & str ) -> decltype( core.symtab.addStruct( str ), void() ) {
 		if ( ! core.symtab.lookupStruct( str ) ) {
@@ -513,4 +509,14 @@
 	template<typename core_t>
 	static inline void addStruct( core_t &, long, const std::string & ) {}
+
+		template<typename core_t>
+	static inline auto addAdt( core_t & core, int, const std::string & str ) -> decltype( core.symtab.addAdt( str ), void() ) {
+		if ( ! core.symtab.lookupAdt( str ) ) {
+			core.symtab.addAdt( str );
+		}
+	}
+
+	template<typename core_t>
+	static inline void addAdt( core_t &, long, const std::string & ) {}
 
 	template<typename core_t>
Index: src/AST/Print.cpp
===================================================================
--- src/AST/Print.cpp	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/AST/Print.cpp	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -1501,4 +1501,11 @@
 	}
 
+	virtual const ast::Type * visit( const ast::AdtInstType * node ) override final {
+		preprint( node );
+		os << "instance of Adt " << node->name;
+		print( node->params );
+		return node;
+	}
+
 	virtual const ast::Type * visit( const ast::UnionInstType * node ) override final {
 		preprint( node );
Index: src/AST/SymbolTable.cpp
===================================================================
--- src/AST/SymbolTable.cpp	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/AST/SymbolTable.cpp	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -218,4 +218,11 @@
 }
 
+const AdtDecl * SymbolTable::lookupAdt( const std::string &id ) const {
+	++*stats().lookup_calls;
+	if ( ! adtTable ) return nullptr;
+	auto it = adtTable->find( id );
+	return it == adtTable->end() ? nullptr : it->second.decl;
+}
+
 const EnumDecl * SymbolTable::lookupEnum( const std::string &id ) const {
 	++*stats().lookup_calls;
@@ -339,21 +346,6 @@
 }
 
-void SymbolTable::addEnum( const EnumDecl *decl ) {
-	++*stats().add_calls;
-	const std::string &id = decl->name;
-
-	if ( ! enumTable ) {
-		enumTable = EnumTable::new_ptr();
-	} else {
-		++*stats().map_lookups;
-		auto existing = enumTable->find( id );
-		if ( existing != enumTable->end()
-			&& existing->second.scope == scope
-			&& addedDeclConflicts( existing->second.decl, decl ) ) return;
-	}
-
-	lazyInitScope();
-	++*stats().map_mutations;
-	enumTable = enumTable->set( id, scoped<EnumDecl>{ decl, scope } );
+void SymbolTable::addAdt( const std::string &id ) {
+	addAdt( new AdtDecl( CodeLocation(), id ) );
 }
 
@@ -377,4 +369,24 @@
 	adtTable = adtTable->set( id, scoped<AdtDecl>{ decl, scope });
 }
+
+void SymbolTable::addEnum( const EnumDecl *decl ) {
+	++*stats().add_calls;
+	const std::string &id = decl->name;
+
+	if ( ! enumTable ) {
+		enumTable = EnumTable::new_ptr();
+	} else {
+		++*stats().map_lookups;
+		auto existing = enumTable->find( id );
+		if ( existing != enumTable->end()
+			&& existing->second.scope == scope
+			&& addedDeclConflicts( existing->second.decl, decl ) ) return;
+	}
+
+	lazyInitScope();
+	++*stats().map_mutations;
+	enumTable = enumTable->set( id, scoped<EnumDecl>{ decl, scope } );
+}
+
 
 void SymbolTable::addUnion( const std::string &id ) {
Index: src/AST/SymbolTable.hpp
===================================================================
--- src/AST/SymbolTable.hpp	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/AST/SymbolTable.hpp	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -111,4 +111,6 @@
 	/// Gets the top-most struct declaration with the given ID
 	const StructDecl * lookupStruct( const std::string &id ) const;
+
+	const AdtDecl * lookupAdt( const std::string &id ) const;
 	/// Gets the top-most enum declaration with the given ID
 	const EnumDecl * lookupEnum( const std::string &id ) const;
@@ -141,4 +143,5 @@
 	void addEnum( const EnumDecl * decl );
 	/// Adds an adt declaration to the symbol table
+	void addAdt( const std::string & id );
 	void addAdt( const AdtDecl * decl );
 	/// Adds a union declaration to the symbol table by name
Index: src/AST/Type.cpp
===================================================================
--- src/AST/Type.cpp	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/AST/Type.cpp	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -138,4 +138,5 @@
 template class SueInstType<UnionDecl>;
 template class SueInstType<EnumDecl>;
+template class SueInstType<AdtDecl>;
 
 // --- TraitInstType
Index: src/AST/Visitor.hpp
===================================================================
--- src/AST/Visitor.hpp	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/AST/Visitor.hpp	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -111,4 +111,5 @@
     virtual const ast::Type *             visit( const ast::TraitInstType        * ) = 0;
     virtual const ast::Type *             visit( const ast::TypeInstType         * ) = 0;
+    virtual const ast::Type *             visit( const ast::AdtInstType          * ) = 0;
     virtual const ast::Type *             visit( const ast::TupleType            * ) = 0;
     virtual const ast::Type *             visit( const ast::TypeofType           * ) = 0;
Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/CodeGen/CodeGenerator.cc	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -296,20 +296,8 @@
 
 	void CodeGenerator::handleData( EnumDecl * ) {
-		// output << " /** data type */" << endl;
-		// for ( StructDecl * decl : dataDecl->data_constructors ) {
-		// 	postvisit(decl);
-		// 	output << ";" << endl;
-		// }
-		// postvisit( dataDecl->data_union );
-		// output << ";" << endl;
-		// postvisit( dataDecl->tag );
-		// output << ";" << endl;
-		// postvisit( dataDecl->tag_union );
-		// output << ";" << endl;
 		assert(false);
 	}
 
 	void CodeGenerator::postvisit( EnumDecl * enumDecl ) {
-		// if ( enumDecl->data_constructors.size() > 0 ) return handleData( enumDecl );
  		extension( enumDecl );
 		std::list< Declaration* > &memb = enumDecl->get_members();
@@ -350,6 +338,12 @@
 	}
 
-	void CodeGenerator::postvisit( AdtDecl * ) {
-		// TODO
+	// Temporary fix, But visitor should be able to handle this
+	void CodeGenerator::postvisit( AdtDecl * adtDecl ) {
+		output << endl << "/* AdtDecl Code Section */" << endl;
+		postvisit( adtDecl->tag );
+		output << ";" << endl;
+		postvisit( adtDecl->data_union );
+		output << ";" << endl;
+		postvisit( adtDecl->tag_union );
 	}
 
Index: src/Common/CodeLocationTools.cpp
===================================================================
--- src/Common/CodeLocationTools.cpp	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/Common/CodeLocationTools.cpp	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -185,4 +185,5 @@
     macro(FunctionType, Type) \
     macro(StructInstType, Type) \
+    macro(AdtInstType, Type) \
     macro(UnionInstType, Type) \
     macro(EnumInstType, Type) \
Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/Common/PassVisitor.h	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -226,4 +226,6 @@
 	virtual void visit( StructInstType * aggregateUseType ) override final;
 	virtual void visit( const StructInstType * aggregateUseType ) override final;
+	virtual void visit( AdtInstType * aggregateUseType ) override final;
+	virtual void visit( const AdtInstType * aggregateUseType ) override final;
 	virtual void visit( UnionInstType * aggregateUseType ) override final;
 	virtual void visit( const UnionInstType * aggregateUseType ) override final;
@@ -351,4 +353,5 @@
 	virtual Type * mutate( FunctionType * functionType ) override final;
 	virtual Type * mutate( StructInstType * aggregateUseType ) override final;
+	virtual Type * mutate( AdtInstType * aggregateUseType ) override final;
 	virtual Type * mutate( UnionInstType * aggregateUseType ) override final;
 	virtual Type * mutate( EnumInstType * aggregateUseType ) override final;
@@ -442,4 +445,5 @@
 	void indexerAddStructFwd( const StructDecl          * node  ) { indexer_impl_addStructFwd( pass, 0, node ); }
 	void indexerAddEnum     ( const EnumDecl            * node  ) { indexer_impl_addEnum     ( pass, 0, node ); }
+	void indexerAddAdt		( const std::string			& id    ) { indexer_impl_addAdt      ( pass, 0, id   ); }
 	void indexerAddAdt		( const AdtDecl				* node  ) { indexer_impl_addAdt		 ( pass, 0, node ); }
 	void indexerAddAdtFwd	( const AdtDecl				* node  ) { indexer_impl_addAdtFwd   ( pass, 0, node  ); }
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/Common/PassVisitor.impl.h	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -688,4 +688,61 @@
 
 //--------------------------------------------------------------------------
+// AdtDecl
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( AdtDecl * node ) {
+	VISIT_START( node );
+
+	indexerAddAdtFwd( node );
+
+	maybeAccept_impl( node->data_union, *this );
+	maybeAccept_impl( node->tag, *this );
+
+	maybeAccept_impl( node->parameters, *this );
+	maybeAccept_impl( node->members   , *this );
+	maybeAccept_impl( node->attributes, *this );
+
+	indexerAddAdt( node );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const AdtDecl * node ) {
+	VISIT_START( node );
+
+	indexerAddAdtFwd( node );
+
+	maybeAccept_impl( node->data_union, *this );
+	maybeAccept_impl( node->tag, *this );
+
+	maybeAccept_impl( node->parameters, *this );
+	maybeAccept_impl( node->members   , *this );
+	maybeAccept_impl( node->attributes, *this );
+
+	indexerAddAdt( node );
+
+	VISIT_END( node );
+}  
+
+template< typename pass_type >
+Declaration * PassVisitor< pass_type >::mutate( AdtDecl * node ) {
+	MUTATE_START( node );
+	
+	indexerAddAdtFwd( node );
+
+	maybeMutate_impl( node->data_union, *this );
+	maybeMutate_impl( node->tag, *this );
+
+	maybeMutate_impl( node->parameters, *this );
+	maybeMutate_impl( node->members   , *this );
+	maybeMutate_impl( node->attributes, *this );
+
+	indexerAddAdt( node );
+
+	MUTATE_END( Declaration, node );
+}
+
+
+//--------------------------------------------------------------------------
 // UnionDecl
 template< typename pass_type >
@@ -789,56 +846,4 @@
 }
 
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( AdtDecl * node ) {
-	VISIT_START( node );
-
-	indexerAddAdtFwd( node );
-
-	// unlike structs, traits, and unions, enums inject their members into the global scope
-	maybeAccept_impl( node->data_constructors, *this );
-	maybeAccept_impl( node->data_union, *this );
-	maybeAccept_impl( node->tag, *this );
-
-	maybeAccept_impl( node->parameters, *this );
-	maybeAccept_impl( node->members   , *this );
-	maybeAccept_impl( node->attributes, *this );
-
-	VISIT_END( node );
-}
-
-template< typename pass_type >
-void PassVisitor< pass_type >::visit( const AdtDecl * node ) {
-	VISIT_START( node );
-
-	indexerAddAdtFwd( node );
-
-	maybeAccept_impl( node->data_constructors, *this );
-	maybeAccept_impl( node->data_union, *this );
-	maybeAccept_impl( node->tag, *this );
-
-	maybeAccept_impl( node->parameters, *this );
-	maybeAccept_impl( node->members   , *this );
-	maybeAccept_impl( node->attributes, *this );
-
-
-	VISIT_END( node );
-}  
-
-template< typename pass_type >
-Declaration * PassVisitor< pass_type >::mutate( AdtDecl * node ) {
-	MUTATE_START( node );
-	
-	indexerAddAdtFwd( node );
-
-	maybeMutate_impl( node->data_constructors, *this );
-	maybeMutate_impl( node->data_union, *this );
-	maybeMutate_impl( node->tag, *this );
-
-	maybeMutate_impl( node->parameters, *this );
-	maybeMutate_impl( node->members   , *this );
-	maybeMutate_impl( node->attributes, *this );
-
-	MUTATE_END( Declaration, node );
-}
 
 //--------------------------------------------------------------------------
@@ -3540,4 +3545,51 @@
 
 	indexerAddStruct( node->name );
+
+	{
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeMutate_impl( node->forall    , *this );
+		maybeMutate_impl( node->parameters, *this );
+	}
+
+	MUTATE_END( Type, node );
+}
+
+//--------------------------------------------------------------------------
+// AdtInstType
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( AdtInstType * node ) {
+	VISIT_START( node );
+
+	indexerAddAdt( node->name );
+
+	{
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->forall    , *this );
+		maybeAccept_impl( node->parameters, *this );
+	}
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const AdtInstType * node ) {
+	VISIT_START( node );
+
+	indexerAddAdt( node->name );
+
+	{
+		auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
+		maybeAccept_impl( node->forall    , *this );
+		maybeAccept_impl( node->parameters, *this );
+	}
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Type * PassVisitor< pass_type >::mutate( AdtInstType * node ) {
+	MUTATE_START( node );
+
+	indexerAddAdt( node->name );
 
 	{
Index: src/Common/PassVisitor.proto.h
===================================================================
--- src/Common/PassVisitor.proto.h	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/Common/PassVisitor.proto.h	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -256,9 +256,4 @@
 	cloneAll( decl->parameters, fwd->parameters );
 
-	// Experimental
-	for ( const StructDecl * ctor : fwd->data_constructors ) {
-		indexer_impl_addStructFwd( pass, 0, ctor );
-	}
-
 	pass.indexer.addAdt( fwd );
 } 
@@ -288,4 +283,17 @@
 
 template<typename pass_type>
+static inline auto indexer_impl_addAdt( pass_type & pass, int, const std::string & str ) -> decltype( pass.indexer.addAdt( str ), void() ) {
+	assert( false );
+	if ( ! pass.indexer.lookupAdt( str )) {
+		pass.indexer.addAdt( str );
+	}
+}
+
+template<typename pass_type>
+static inline auto indexer_impl_addAdt( pass_type &, long, const std::string & ) {
+	assert( false );
+}
+
+template<typename pass_type>
 static inline auto indexer_impl_addUnion( pass_type & pass, int, const std::string & str ) -> decltype( pass.indexer.addUnion( str ), void() ) {
 	if ( ! pass.indexer.lookupUnion( str ) ) {
Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/GenPoly/Box.cc	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -185,4 +185,5 @@
 			void premutate( StructDecl * );
 			void premutate( UnionDecl * );
+			void premutate( AdtDecl * );
 
 			void beginScope();
@@ -1513,4 +1514,8 @@
 		}
 
+		void PolyGenericCalculator::premutate( AdtDecl * adtDecl ) {
+			mutateMembers( adtDecl );
+		}
+
 		void PolyGenericCalculator::premutate( DeclStmt *declStmt ) {
 			if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) {
Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/Parser/DeclarationNode.cc	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -1104,5 +1104,5 @@
 	std::back_insert_iterator<std::vector<ast::ptr<ast::StructDecl>>> out( outputList );
 	for ( const DeclarationNode * cur = firstNode; cur; cur = strict_next( cur ) ) {
-		// td->kind == TypeData::Symbolic
+
 		assert( cur->type->kind == TypeData::Symbolic );
 		const std::string * name = cur->name;
@@ -1125,4 +1125,5 @@
 			member->name = "field_" + std::to_string(i);
 		}
+
 		*out++ = ctor;		
 	}
@@ -1130,11 +1131,40 @@
 }
 
-ast::UnionDecl * buildDataUnion( const CodeLocation & loc, const std::vector<ast::ptr<ast::StructDecl>> & typeList ) {
+void buildDataConstructorsAsMember( DeclarationNode * firstNode, ast::AdtDecl * adtDecl ) {
+	std::back_insert_iterator<std::vector<ast::ptr<ast::Decl>>> out( adtDecl->members );
+	for ( const DeclarationNode * cur = firstNode; cur; cur = strict_next( cur ) ) {
+
+		assert( cur->type->kind == TypeData::Symbolic );
+		const std::string * name = cur->name;
+		auto ctor = new ast::StructDecl( cur->location,
+			std::string(*name),
+			ast::AggregateDecl::Aggregate::Struct
+		);
+		ctor->set_body(true);
+		TypeData * td = cur->type;
+		TypeData::Symbolic_t st = td->symbolic;
+		DeclarationNode * params = st.params;
+		
+		if ( params ) {
+			buildList( params, ctor->members );
+		}
+
+		for ( std::size_t i = 0; i < ctor->members.size(); ++i ) {
+			assert(ctor->members[i]->name == "");
+			ast::Decl * member = ctor->members[i].get_and_mutate();
+			member->name = "field_" + std::to_string(i);
+		}
+
+		*out++ = ctor;		
+	}
+}
+
+ast::UnionDecl * buildDataUnion( const CodeLocation & loc, const std::vector<ast::ptr<ast::Decl>> & typeList ) {
 	ast::UnionDecl * out = new ast::UnionDecl( loc, "temp_data_union" );
 	// size_t index = 0;
 	if ( typeList.size() > 0 ) out->set_body( true );
 	size_t i = 0;
-	for (const ast::ptr<ast::StructDecl> structDecl : typeList ) {
-		ast::StructInstType * inst = new ast::StructInstType(structDecl);
+	for (const ast::ptr<ast::Decl> structDecl : typeList ) {
+		ast::StructInstType * inst = new ast::StructInstType( structDecl.as< ast::StructDecl >() );
 		ast::ObjectDecl * instObj = new ast::ObjectDecl(
 			structDecl->location,
@@ -1149,8 +1179,8 @@
 }
 
-ast::EnumDecl * buildTag( const CodeLocation & loc, std::vector<ast::ptr<ast::StructDecl>> & typeList ) {
+ast::EnumDecl * buildTag( const CodeLocation & loc, std::vector<ast::ptr<ast::Decl>> & typeList ) {
 	ast::EnumDecl * out = new ast::EnumDecl( loc, "temp_data_tag" );
 	if ( typeList.size() > 0 ) out->set_body( true );
-	for ( const ast::ptr<ast::StructDecl> structDecl : typeList ) {
+	for ( const ast::ptr<ast::Decl> structDecl : typeList ) {
 		ast::EnumInstType * inst = new ast::EnumInstType( out );
 		assert( inst->base != nullptr );
@@ -1167,5 +1197,5 @@
 ast::StructDecl * buildTaggedUnions( const TypeData * data, const ast::EnumDecl * tags, const ast::UnionDecl * data_union ) {
 	assert( tags->members.size() == data_union->members.size() );
-	ast::StructDecl * out = new ast::StructDecl( data->location, *(data->adt.name) );
+	ast::StructDecl * out = new ast::StructDecl( data->location, (*(data->adt.name)) + "_tag_union" );
 	out->kind = ast::AggregateDecl::Adt;
 
Index: src/Parser/DeclarationNode.h
===================================================================
--- src/Parser/DeclarationNode.h	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/Parser/DeclarationNode.h	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -218,6 +218,7 @@
 
 std::vector<ast::ptr<ast::StructDecl>> buildDataConstructors( DeclarationNode * firstNode );
-ast::UnionDecl * buildDataUnion( const CodeLocation & loc, const std::vector<ast::ptr<ast::StructDecl>> & typeList );
-ast::EnumDecl * buildTag( const CodeLocation & loc, std::vector<ast::ptr<ast::StructDecl>> & typeList );
+void buildDataConstructorsAsMember( DeclarationNode * firstNode, ast::AdtDecl * adtDecl );
+ast::UnionDecl * buildDataUnion( const CodeLocation & loc, const std::vector<ast::ptr<ast::Decl>> & typeList );
+ast::EnumDecl * buildTag( const CodeLocation & loc, std::vector<ast::ptr<ast::Decl>> & typeList );
 ast::StructDecl * buildTaggedUnions( const TypeData * data, const ast::EnumDecl * tag, const ast::UnionDecl * data_union );
 
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/Parser/TypeData.cc	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -81,4 +81,6 @@
 	case Symbolic:
 	case SymbolicInst:
+		aggregate.kind =  ast::AggregateDecl::Aggregate::Undecided;
+		
 		symbolic.name = nullptr;
 		symbolic.params = nullptr;
@@ -225,8 +227,7 @@
 		newtype->enumeration.body = enumeration.body;
 		newtype->enumeration.anon = enumeration.anon;
-		newtype->enumeration.data_constructors = maybeClone( enumeration.data_constructors );
 		break;
 	case Adt:
-		newtype->adt.data_constructors = maybeClone( enumeration.data_constructors );
+		newtype->adt.data_constructors = maybeClone( adt.data_constructors );
 		newtype->adt.name = new string ( *adt.name );
 		break;
@@ -1276,13 +1277,5 @@
 	);
 	buildList( td->enumeration.constants, ret->members );
-	if ( td->enumeration.data_constructors != nullptr ) {
-		assert( false );
-		// ret->data_constructors = buildDataConstructors( td->enumeration.data_constructors );
-		// ret->data_union = buildDataUnion( td->location, ret->data_constructors );
-		// ret->tag = buildTag( td->location, ret->data_constructors );
-		// ret->tag_union = buildTaggedUnions( td, ret->tag.get(), ret->data_union.get() );
-	}
-
-	// if ( ret->data_constructors.size() > 0 ) ret->isData = true;
+
 	auto members = ret->members.begin();
 	ret->hide = td->enumeration.hiding == EnumHiding::Hide ? ast::EnumDecl::EnumHiding::Hide : ast::EnumDecl::EnumHiding::Visible;
@@ -1317,7 +1310,9 @@
 	assert( td->kind == TypeData::Adt );
 	ast::AdtDecl * ret = new ast::AdtDecl( td->location, *(td->adt.name) );
-	ret->data_constructors = buildDataConstructors( td->adt.data_constructors );
-	ret->data_union = buildDataUnion( td->location, ret->data_constructors );
-	ret->tag = buildTag( td->location, ret->data_constructors );
+
+	buildDataConstructorsAsMember( td->adt.data_constructors, ret );
+
+	ret->data_union = buildDataUnion( td->location, ret->members );
+	ret->tag = buildTag( td->location, ret->members );
 	ret->tag_union = buildTaggedUnions( td, ret->tag.get(), ret->data_union.get() );
 	return ret;
Index: src/Parser/TypeData.h
===================================================================
--- src/Parser/TypeData.h	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/Parser/TypeData.h	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -25,5 +25,5 @@
 struct TypeData {
 	enum Kind { Basic, Pointer, Reference, Array, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic,
-				SymbolicInst, Tuple, Basetypeof, Typeof, Vtable, Builtin, GlobalScope, Qualified, Adt, Ctor, Unknown };
+				SymbolicInst, Tuple, Basetypeof, Typeof, Vtable, Builtin, GlobalScope, Qualified, Adt, Unknown };
 
 	struct Aggregate_t {
@@ -59,6 +59,4 @@
 		EnumHiding hiding;
 		bool isData = false;
-
-		DeclarationNode * data_constructors = nullptr;
 	};
 
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/SymTab/Validate.cc	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -210,4 +210,5 @@
 		void previsit( StructDecl * aggregateDecl );
 		void previsit( UnionDecl * aggregateDecl );
+		void previsit( AdtDecl * AggregateDecl );
 		void previsit( CompoundStmt * compoundStmt );
 	};
@@ -569,4 +570,8 @@
 
 	void EliminateTypedef::previsit( UnionDecl * aggregateDecl ) {
+		handleAggregate( aggregateDecl );
+	}
+
+	void EliminateTypedef::previsit( AdtDecl * aggregateDecl ) {
 		handleAggregate( aggregateDecl );
 	}
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/SynTree/Declaration.h	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -365,5 +365,4 @@
 	typedef AggregateDecl Parent;
   public:
-	std::list<StructDecl*> data_constructors;
 	UnionDecl * data_union;
 	EnumDecl * tag;
@@ -373,7 +372,6 @@
 	 const std::list< Attribute * > & attributes = std::list< class Attribute * >(),
 	 LinkageSpec::Spec linkage = LinkageSpec::Cforall, 
-	 const std::list< StructDecl* > data_constructors = std::list< StructDecl * >(),
 	 UnionDecl * data_union = nullptr, EnumDecl * tag = nullptr, StructDecl * tag_union = nullptr )
-	 : Parent( name, attributes, linkage ), data_constructors(data_constructors), 
+	 : Parent( name, attributes, linkage ), 
 	 data_union( data_union ), tag( tag ), tag_union( tag_union ) {}
 
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/SynTree/Mutator.h	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -110,4 +110,5 @@
 	virtual Type * mutate( FunctionType * functionType ) = 0;
 	virtual Type * mutate( StructInstType * aggregateUseType ) = 0;
+	virtual Type * mutate( AdtInstType * aggregateUseType ) = 0;
 	virtual Type * mutate( UnionInstType * aggregateUseType ) = 0;
 	virtual Type * mutate( EnumInstType * aggregateUseType ) = 0;
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/SynTree/SynTree.h	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -119,4 +119,5 @@
 class UnionInstType;
 class EnumInstType;
+class AdtInstType;
 class TraitInstType;
 class TypeInstType;
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/SynTree/Type.h	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -476,4 +476,37 @@
 };
 
+class AdtInstType : public ReferenceToType {
+	typedef ReferenceToType  Parent;
+  public:
+	AdtDecl * baseAdt;
+
+	AdtInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >()  ) : Parent( tq, name, attributes ), baseAdt( 0 ) {}
+	AdtInstType( const Type::Qualifiers & tq, AdtDecl * baseAdt, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
+	AdtInstType( const AdtInstType & other ) : Parent( other ), baseAdt( other.baseAdt ) {}
+
+	AdtDecl * get_baseAdt() const { return baseAdt; }
+	void set_baseAdt( AdtDecl * newValue ) { baseAdt = newValue; }
+	
+	std::list<TypeDecl*> * get_baseParameters();
+	const std::list<TypeDecl*> * get_baseParameters() const;
+
+	virtual bool isComplete() const override;
+
+	virtual AggregateDecl * getAggr() const override;
+	
+	virtual TypeSubstitution genericSubstitution() const override;
+
+	void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const override;
+
+	virtual AdtInstType * clone() const override { return new AdtInstType( * this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual void accept( Visitor & v ) const override { v.visit( this ); }
+	virtual Type * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+
+	virtual void print( std::ostream & os, Indenter indenter = {} ) const override;
+  private:
+	virtual std::string typeString() const override;
+};
+
 class UnionInstType : public ReferenceToType {
 	typedef ReferenceToType Parent;
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/SynTree/Visitor.h	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -196,4 +196,6 @@
 	virtual void visit( UnionInstType * node ) { visit( const_cast<const UnionInstType *>(node) ); }
 	virtual void visit( const UnionInstType * aggregateUseType ) = 0;
+	virtual void visit( AdtInstType * node ) { visit( const_cast<const AdtInstType *>(node) ); }
+	virtual void visit( const AdtInstType * node ) = 0;
 	virtual void visit( EnumInstType * node ) { visit( const_cast<const EnumInstType *>(node) ); }
 	virtual void visit( const EnumInstType * aggregateUseType ) = 0;
Index: src/Validate/EliminateTypedef.cpp
===================================================================
--- src/Validate/EliminateTypedef.cpp	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/Validate/EliminateTypedef.cpp	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -31,4 +31,5 @@
 	ast::StructDecl const * previsit( ast::StructDecl const * decl );
 	ast::UnionDecl const * previsit( ast::UnionDecl const * decl );
+	ast::AdtDecl const * previsit( ast::AdtDecl const * decl );
 	// Remove typedefs from statement lists.
 	ast::CompoundStmt const * previsit( ast::CompoundStmt const * stmt );
@@ -65,4 +66,8 @@
 }
 
+ast::AdtDecl const * EliminateTypedefCore::previsit( ast::AdtDecl const * decl ) {
+	return field_erase_if( decl, &ast::AdtDecl::members, isTypedef );
+}
+
 ast::CompoundStmt const * EliminateTypedefCore::previsit( ast::CompoundStmt const * stmt ) {
 	return field_erase_if( stmt, &ast::CompoundStmt::kids, isTypedefStmt );
Index: src/Validate/FixQualifiedTypes.cpp
===================================================================
--- src/Validate/FixQualifiedTypes.cpp	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/Validate/FixQualifiedTypes.cpp	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -59,4 +59,7 @@
 				instp = inst;
 			} else if ( auto inst = parent.as<ast::UnionInstType>() ) {
+				aggr = inst->base;
+				instp = inst;
+			} else if ( auto inst = parent.as<ast::AdtInstType>() ) {
 				aggr = inst->base;
 				instp = inst;
Index: src/Validate/HoistStruct.cpp
===================================================================
--- src/Validate/HoistStruct.cpp	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/Validate/HoistStruct.cpp	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -28,5 +28,6 @@
 	return dynamic_cast< ast::StructDecl const * >( decl )
 		|| dynamic_cast< ast::UnionDecl const * >( decl )
-		|| dynamic_cast< ast::StaticAssertDecl const * >( decl );
+		|| dynamic_cast< ast::StaticAssertDecl const * >( decl )
+		|| dynamic_cast< ast::AdtDecl const * >( decl );
 }
 
@@ -45,4 +46,6 @@
 	ast::UnionInstType const * previsit( ast::UnionInstType const * type );
 	ast::EnumInstType const * previsit( ast::EnumInstType const * type );
+	ast::AdtDecl const * previsit( ast::AdtDecl const * decl );
+	ast::AdtDecl const * postvisit( ast::AdtDecl const * decl );
 
 private:
@@ -100,4 +103,12 @@
 }
 
+ast::AdtDecl const * HoistStructCore::previsit( ast::AdtDecl const * decl ) {
+	return preAggregate( decl );
+}
+
+ast::AdtDecl const * HoistStructCore::postvisit( ast::AdtDecl const * decl ) {
+	return postAggregate( decl );
+}
+
 ast::StructDecl const * HoistStructCore::postvisit( ast::StructDecl const * decl ) {
 	return postAggregate( decl );
@@ -138,8 +149,4 @@
 }
 
-void hoistAdt( [[maybe_unused]] ast::TranslationUnit & trnaslationUnit ) {
-	
-}
-
 } // namespace Validate
 
Index: src/Validate/HoistStruct.hpp
===================================================================
--- src/Validate/HoistStruct.hpp	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/Validate/HoistStruct.hpp	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -24,5 +24,4 @@
 /// Flattens nested type declarations. (Run right after Fix Qualified Types.)
 void hoistStruct( ast::TranslationUnit & translationUnit );
-void hoistAdt( ast::TranslationUnit & trnaslationUnit );
 
 }
Index: src/Validate/LinkReferenceToTypes.cpp
===================================================================
--- src/Validate/LinkReferenceToTypes.cpp	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/Validate/LinkReferenceToTypes.cpp	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -20,4 +20,5 @@
 #include "Validate/ForallPointerDecay.hpp"
 #include "Validate/NoIdSymbolTable.hpp"
+#include <assert.h>
 
 namespace Validate {
@@ -35,4 +36,5 @@
 	ast::UnionInstType const * postvisit( ast::UnionInstType const * type );
 	ast::TraitInstType const * postvisit( ast::TraitInstType const * type );
+	ast::AdtInstType const * postvisit( ast::AdtInstType const * type );
 	void previsit( ast::QualifiedType const * type );
 	void postvisit( ast::QualifiedType const * type );
@@ -107,4 +109,15 @@
 		auto mut = ast::mutate( type );
 		forwardStructs[ mut->name ].push_back( mut );
+		type = mut;
+	}
+	return type;
+}
+
+ast::AdtInstType const * LinkTypesCore::postvisit( ast::AdtInstType const * type ) {
+	ast::AdtDecl const * decl = symtab.lookupAdt( type->name );
+	assert( decl != nullptr );
+	if ( decl ) {
+		auto mut = ast::mutate( type );
+		mut->base = const_cast<ast::AdtDecl *>( decl );
 		type = mut;
 	}
Index: src/Validate/NoIdSymbolTable.hpp
===================================================================
--- src/Validate/NoIdSymbolTable.hpp	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/Validate/NoIdSymbolTable.hpp	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -41,4 +41,5 @@
 	FORWARD_1( lookupUnion , const std::string & )
 	FORWARD_1( lookupTrait , const std::string & )
+	FORWARD_1( lookupAdt   , const std::string & )
 	FORWARD_1( addType  , const ast::NamedTypeDecl * )
 	FORWARD_1( addStruct, const ast::StructDecl *    )
@@ -49,4 +50,5 @@
 	FORWARD_1( addStruct, const std::string &        )
 	FORWARD_1( addUnion , const std::string &        )
+	FORWARD_1( addAdt   , const std::string &		 )
 	FORWARD_2( addWith  , const std::vector< ast::ptr<ast::Expr> > &, const ast::Decl * )
 
Index: src/Validate/ReplaceTypedef.cpp
===================================================================
--- src/Validate/ReplaceTypedef.cpp	(revision 044ae62f3758370207e9bd48aa003fbc826b3d4d)
+++ src/Validate/ReplaceTypedef.cpp	(revision fa2c005cdb7210e3aaf9b1170f05fbc75444ece7)
@@ -60,4 +60,5 @@
 	ast::StructDecl const * previsit( ast::StructDecl const * );
 	ast::UnionDecl const * previsit( ast::UnionDecl const * );
+	ast::AdtDecl const * previsit( ast::AdtDecl const * );
 	void previsit( ast::EnumDecl const * );
 	void previsit( ast::TraitDecl const * );
@@ -90,9 +91,10 @@
 }
 
+// Here, 5/30
 ast::Type const * ReplaceTypedefCore::postvisit(
 		ast::TypeInstType const * type ) {
 	// Instances of typedef types will come here. If it is an instance
 	// of a typedef type, link the instance to its actual type.
-	TypedefMap::const_iterator def = typedefNames.find( type->name );
+	TypedefMap::const_iterator def = typedefNames.find( type->name ); // because of this
 	if ( def != typedefNames.end() ) {
 		ast::Type * ret = ast::deepCopy( def->second.first->base );
@@ -260,4 +262,10 @@
 }
 
+ast::AdtDecl const * ReplaceTypedefCore::previsit( ast::AdtDecl const * decl ) {
+	visit_children = false;
+	addImplicitTypedef( decl );
+	return handleAggregate( decl );
+}
+
 ast::UnionDecl const * ReplaceTypedefCore::previsit( ast::UnionDecl const * decl ) {
 	visit_children = false;
@@ -287,4 +295,6 @@
 	} else if ( auto enumDecl = dynamic_cast<const ast::EnumDecl *>( aggrDecl ) ) {
 		type = new ast::EnumInstType( enumDecl->name );
+	} else if ( auto adtDecl = dynamic_cast<const ast::AdtDecl *>( aggrDecl )) {
+		type = new ast::AdtInstType( adtDecl->name );
 	}
 	assert( type );
