Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision e0016a502a6906a272ff601bf65e13c188c6148a)
+++ src/AST/Convert.cpp	(revision ca8704f3e50701178a86b4ddd436ef95b8d6dfe5)
@@ -10,6 +10,6 @@
 // Created On       : Thu May 09 15::37::05 2019
 // Last Modified By : Andrew Beach
-// Last Modified On : Fri May 17 16:01:00 2019
-// Update Count     : 4
+// Last Modified On : Tue May 21 15:30:00 2019
+// Update Count     : 5
 //
 
@@ -93,56 +93,162 @@
 
 private:
+	void declPostamble( Declaration * decl, const ast::Decl * node ) {
+		decl->location = node->location;
+		// name comes from constructor
+		// linkage comes from constructor
+		decl->extension = node->extension;
+		decl->uniqueId = node->uniqueId;
+		// storageClasses comes from constructor
+		this->node = decl;
+	}
+
+	const ast::DeclWithType * declWithTypePostamble (
+			DeclarationWithType * decl, const ast::DeclWithType * node ) {
+		declPostamble( decl, node );
+		decl->mangleName = node->mangleName;
+		decl->scopeLevel = node->scopeLevel;
+		decl->asmName = get<Expression>().accept1( node->asmName );
+		// attributes comes from constructor
+		decl->isDeleted = node->isDeleted;
+		// fs comes from constructor
+		return nullptr;
+	}
+
 	const ast::DeclWithType * visit( const ast::ObjectDecl * node ) override final {
-		(void)node;
-		return nullptr;
+		auto decl = new ObjectDecl(
+			node->name,
+			Type::StorageClasses( node->storage.val ),
+			LinkageSpec::Spec( node->linkage.val ),
+			get<Expression>().accept1( node->bitfieldWidth ),
+			get<Type>().accept1( node->type ),
+			get<Initializer>().accept1( node->init ),
+			get<Attribute>().acceptL( node->attributes ),
+			Type::FuncSpecifiers( node->funcSpec.val )
+		);
+		return declWithTypePostamble( decl, node );
 	}
 
 	const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final {
-		(void)node;
+		auto decl = new FunctionDecl(
+			node->name,
+			Type::StorageClasses( node->storage.val ),
+			LinkageSpec::Spec( node->linkage.val ),
+			get<FunctionType>().accept1( node->type ),
+			get<CompoundStmt>().accept1( node->stmts ),
+			get<Attribute>().acceptL( node->attributes ),
+			Type::FuncSpecifiers( node->funcSpec.val )
+		);
+		decl->withExprs = get<Expression>().acceptL( node->withExprs );
+		return declWithTypePostamble( decl, node );
+	}
+
+	// NamedTypeDecl
+	const ast::Decl * namedTypePostamble( NamedTypeDecl * decl, const ast::NamedTypeDecl * node ) {
+		declPostamble( decl, node );
+		// base comes from constructor
+		decl->parameters = get<TypeDecl>().acceptL( node->params );
+		decl->assertions = get<DeclarationWithType>().acceptL( node->assertions );
+		return nullptr;
+	}
+
+	const ast::Decl * visit( const ast::TypeDecl * node ) override final {
+		TypeDecl::Kind kind;
+		switch (node->kind) {
+		case ast::TypeVar::Dtype:
+			kind = TypeDecl::Dtype;
+			break;
+		case ast::TypeVar::Ftype:
+			kind = TypeDecl::Ftype;
+			break;
+		case ast::TypeVar::Ttype:
+			kind = TypeDecl::Ttype;
+			break;
+		default:
+			assertf(false, "Invalid ast::TypeVar::Kind: %d\n", node->kind);
+		};
+		auto decl = new TypeDecl(
+			node->name,
+			Type::StorageClasses( node->storage.val ),
+			get<Type>().accept1( node->base ),
+			kind,
+			node->sized,
+			get<Type>().accept1( node->init )
+		);
+		return namedTypePostamble( decl, node );
+	}
+
+	const ast::Decl * visit( const ast::TypedefDecl * node ) override final {
+		auto decl = new TypedefDecl(
+			node->name,
+			node->location,
+			Type::StorageClasses( node->storage.val ),
+            get<Type>().accept1( node->base ),
+			LinkageSpec::Spec( node->linkage.val )
+		);
+		return namedTypePostamble( decl, node );
+	}
+
+	const ast::Decl * aggregatePostamble( AggregateDecl * decl, const ast::AggregateDecl * node ) {
+		decl->members = get<Declaration>().acceptL( node->members );
+		decl->parameters = get<TypeDecl>().acceptL( node->params );
+		decl->body = node->body;
+		// attributes come from constructor
+		// TODO: Need caching for: decl->parent = node->parent;
 		return nullptr;
 	}
 
 	const ast::Decl * visit( const ast::StructDecl * node ) override final {
-		(void)node;
-		return nullptr;
+		auto decl = new StructDecl(
+			node->name,
+			node->kind,
+			get<Attribute>().acceptL( node->attributes ),
+			LinkageSpec::Spec( node->linkage.val )
+		);
+		return aggregatePostamble( decl, node );
 	}
 
 	const ast::Decl * visit( const ast::UnionDecl * node ) override final {
-		(void)node;
-		return nullptr;
+		auto decl = new UnionDecl(
+			node->name,
+			get<Attribute>().acceptL( node->attributes ),
+			LinkageSpec::Spec( node->linkage.val )
+		);
+		return aggregatePostamble( decl, node );
 	}
 
 	const ast::Decl * visit( const ast::EnumDecl * node ) override final {
-		(void)node;
-		return nullptr;
+		auto decl = new EnumDecl(
+			node->name,
+			get<Attribute>().acceptL( node->attributes ),
+			LinkageSpec::Spec( node->linkage.val )
+		);
+		return aggregatePostamble( decl, node );
 	}
 
 	const ast::Decl * visit( const ast::TraitDecl * node ) override final {
-		(void)node;
-		return nullptr;
-	}
-
-	const ast::Decl * visit( const ast::TypeDecl * node ) override final {
-		(void)node;
-		return nullptr;
-	}
-
-	const ast::Decl * visit( const ast::TypedefDecl * node ) override final {
-		(void)node;
-		return nullptr;
+		auto decl = new TraitDecl(
+			node->name,
+			{},
+			LinkageSpec::Spec( node->linkage.val )
+		);
+		return aggregatePostamble( decl, node );
 	}
 
 	const ast::AsmDecl * visit( const ast::AsmDecl * node ) override final {
-		(void)node;
+		auto decl = new AsmDecl( get<AsmStmt>().accept1( node->stmt ) );
+		declPostamble( decl, node );
 		return nullptr;
 	}
 
 	const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) override final {
-		(void)node;
-		return nullptr;
-	}
-
-	const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) override final {
-		auto stmt = new CompoundStmt( get<Statement>().acceptL( node->kids ) );
+		auto decl = new StaticAssertDecl(
+			get<Expression>().accept1( node->cond ),
+			get<ConstantExpr>().accept1( node->msg )
+		);
+		declPostamble( decl, node );
+		return nullptr;
+	}
+
+	const ast::Stmt * stmtPostamble( Statement * stmt, const ast::Stmt * node ) {
 		stmt->location = node->location;
 		stmt->labels = makeLabelL( stmt, node->labels );
@@ -151,10 +257,13 @@
 	}
 
+	const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) override final {
+		auto stmt = new CompoundStmt( get<Statement>().acceptL( node->kids ) );
+		stmtPostamble( stmt, node );
+		return nullptr;
+	}
+
 	const ast::Stmt * visit( const ast::ExprStmt * node ) override final {
 		auto stmt = new ExprStmt( get<Expression>().accept1( node->expr ) );
-		stmt->location = node->location;
-		stmt->labels = makeLabelL( stmt, node->labels );
-		this->node = stmt;
-		return nullptr;
+		return stmtPostamble( stmt, node );
 	}
 
@@ -168,16 +277,10 @@
 			makeLabelL( nullptr, node->gotoLabels ) // What are these labelling?
 		);
-		stmt->location = node->location;
-		stmt->labels = makeLabelL( stmt, node->labels );
-		this->node = stmt;
-		return nullptr;
+		return stmtPostamble( stmt, node );
 	}
 
 	const ast::Stmt * visit( const ast::DirectiveStmt * node ) override final {
 		auto stmt = new DirectiveStmt( node->directive );
-		stmt->location = node->location;
-		stmt->labels = makeLabelL( stmt, node->labels );
-		this->node = stmt;
-		return nullptr;
+		return stmtPostamble( stmt, node );
 	}
 
@@ -189,8 +292,5 @@
 			get<Statement>().acceptL( node->inits )
 		);
-		stmt->location = node->location;
-		stmt->labels = makeLabelL( stmt, node->labels );
-		this->node = stmt;
-		return nullptr;
+		return stmtPostamble( stmt, node );
 	}
 
@@ -200,8 +300,5 @@
 			get<Statement>().acceptL( node->stmts )
 		);
-		stmt->location = node->location;
-		stmt->labels = makeLabelL( stmt, node->labels );
-		this->node = stmt;
-		return nullptr;
+		return stmtPostamble( stmt, node );
 	}
 
@@ -212,8 +309,5 @@
 			node->isDefault()
 		);
-		stmt->location = node->location;
-		stmt->labels = makeLabelL( stmt, node->labels );
-		this->node = stmt;
-		return nullptr;
+		return stmtPostamble( stmt, node );
 	}
 
@@ -226,8 +320,5 @@
 			node->isDoWhile
 		);
-		stmt->location = node->location;
-		stmt->labels = makeLabelL( stmt, node->labels );
-		this->node = stmt;
-		return nullptr;
+		return stmtPostamble( stmt, node );
 	}
 
@@ -239,8 +330,5 @@
 			get<Statement>().accept1( node->body )
 		);
-		stmt->location = node->location;
-		stmt->labels = makeLabelL( stmt, node->labels );
-		this->node = stmt;
-		return nullptr;
+		return stmtPostamble( stmt, node );
 	}
 
@@ -271,16 +359,10 @@
 			stmt->target = makeLabel( stmt, node->target );
 		}
-		stmt->location = node->location;
-		stmt->labels = makeLabelL( stmt, node->labels );
-		this->node = stmt;
-		return nullptr;
+		return stmtPostamble( stmt, node );
 	}
 
 	const ast::Stmt * visit( const ast::ReturnStmt * node ) override final {
 		auto stmt = new ReturnStmt( get<Expression>().accept1( node->expr ) );
-		stmt->location = node->location;
-		stmt->labels = makeLabelL( stmt, node->labels );
-		this->node = stmt;
-		return nullptr;
+		return stmtPostamble( stmt, node );
 	}
 
@@ -302,8 +384,5 @@
 			get<Expression>().accept1( node->target )
 		);
-		stmt->location = node->location;
-		stmt->labels = makeLabelL( stmt, node->labels );
-		this->node = stmt;
-		return nullptr;
+		return stmtPostamble( stmt, node );
 	}
 
@@ -315,8 +394,5 @@
 			get<FinallyStmt>().accept1( node->finally )
 		);
-		stmt->location = node->location;
-		stmt->labels = makeLabelL( stmt, node->labels );
-		this->node = stmt;
-		return nullptr;
+		return stmtPostamble( stmt, node );
 	}
 
@@ -339,16 +415,10 @@
 			get<Statement>().accept1( node->body )
 		);
-		stmt->location = node->location;
-		stmt->labels = makeLabelL( stmt, node->labels );
-		this->node = stmt;
-		return nullptr;
+		return stmtPostamble( stmt, node );
 	}
 
 	const ast::Stmt * visit( const ast::FinallyStmt * node ) override final {
 		auto stmt = new FinallyStmt( get<CompoundStmt>().accept1( node->body ) );
-		stmt->location = node->location;
-		stmt->labels = makeLabelL( stmt, node->labels );
-		this->node = stmt;
-		return nullptr;
+		return stmtPostamble( stmt, node );
 	}
 
@@ -374,8 +444,5 @@
 			get<Expression>().accept1( node->orElse.cond ),
 		};
-		stmt->location = node->location;
-		stmt->labels = makeLabelL( stmt, node->labels );
-		this->node = stmt;
-		return nullptr;
+		return stmtPostamble( stmt, node );
 	}
 
@@ -385,15 +452,10 @@
 			get<Statement>().accept1( node->stmt )
 		);
-		stmt->location = node->location;
-		stmt->labels = makeLabelL( stmt, node->labels );
-		this->node = stmt;
-		return nullptr;
+		return stmtPostamble( stmt, node );
 	}
 
 	const ast::NullStmt * visit( const ast::NullStmt * node ) override final {
 		auto stmt = new NullStmt();
-		stmt->location = node->location;
-		stmt->labels = makeLabelL( stmt, node->labels );
-		this->node = stmt;
+		stmtPostamble( stmt, node );
 		return nullptr;
 	}
@@ -401,8 +463,5 @@
 	const ast::Stmt * visit( const ast::DeclStmt * node ) override final {
 		auto stmt = new DeclStmt( get<Declaration>().accept1( node->decl ) );
-		stmt->location = node->location;
-		stmt->labels = makeLabelL( stmt, node->labels );
-		this->node = stmt;
-		return nullptr;
+		return stmtPostamble( stmt, node );
 	}
 
