Index: src/AST/Print.cpp
===================================================================
--- src/AST/Print.cpp	(revision ef5ef56042ce2b547da955746d9986e26cf628ca)
+++ src/AST/Print.cpp	(revision 5902625312b0f730ef5d4cca6254a8283c7cff36)
@@ -22,4 +22,5 @@
 #include "TypeSubstitution.hpp"
 
+using namespace std;
 
 namespace ast {
@@ -27,8 +28,8 @@
 template <typename C, typename... T>
 constexpr auto make_array(T&&... values) ->
-	std::array<C,sizeof...(T)>
+	array<C,sizeof...(T)>
 {
-	return std::array<C,sizeof...(T)>{
-		std::forward<T>(values)...
+	return array<C,sizeof...(T)>{
+		forward<T>(values)...
 	};
 }
@@ -36,8 +37,9 @@
 class Printer : public Visitor {
 public:
-	std::ostream & os;
+	ostream & os;
 	Indenter indent;
-
-	Printer(std::ostream & os, Indenter indent) : os( os ), indent( indent ) {}
+	bool short_mode;
+
+	Printer(ostream & os, Indenter indent, bool short_mode) : os( os ), indent( indent ), short_mode(short_mode) {}
 
 private:
@@ -50,5 +52,5 @@
 				// need an endl after each element because it's not
 				// easy to know when each individual item should end
-				os << std::endl;
+				os << endl;
 			} // if
 		} // for
@@ -73,5 +75,5 @@
 
 	template<typename storage_t, size_t N>
-	void print(const storage_t & storage, const std::array<const char *, N> & Names ) {
+	void print(const storage_t & storage, const array<const char *, N> & Names ) {
 		if ( storage.any() ) {
 			for ( size_t i = 0; i < Names.size(); i += 1 ) {
@@ -95,7 +97,63 @@
 	}
 
+	void print( const ast::AggregateDecl * node ) {
+		os << node->typeString() << " " << node->name << ":";
+		if ( node->linkage != Linkage::Cforall ) {
+			os << " " << Linkage::name( node->linkage );
+		} // if
+		os << " with body : " << (node->body ? "yes " : "no ");
+
+		if ( ! node->params.empty() ) {
+			os << endl << indent << "... with parameters" << endl;
+			++indent;
+			printAll( node->params );
+			--indent;
+		} // if
+		if ( ! node->members.empty() ) {
+			os << endl << indent << "... with members" << endl;
+			++indent;
+			printAll( node->members );
+			--indent;
+		} // if
+		if ( ! node->attributes.empty() ) {
+			os << endl << indent << "... with attributes" << endl;
+			++indent;
+			printAll( node->attributes );
+			--indent;
+		} // if
+		os << endl;
+	}
+
+	void print( const ast::NamedTypeDecl * node ) {
+		if ( !node->name.empty() ) os << node->name << ": ";
+
+		if ( node->linkage != Linkage::Cforall ) {
+			os << Linkage::name( node->linkage ) << " ";
+		} // if
+		print( node->storage );
+		os << node->typeString();
+		if ( node->base ) {
+			os << " for ";
+			++indent;
+			node->base->accept( *this );
+			--indent;
+		} // if
+		if ( ! node->params.empty() ) {
+			os << endl << indent << "... with parameters" << endl;
+			++indent;
+			printAll( node->params );
+			--indent;
+		} // if
+		if ( ! node->assertions.empty() ) {
+			os << endl << indent << "... with assertions" << endl;
+			++indent;
+			printAll( node->assertions );
+			--indent;
+		} // if
+	}
+
 public:
-	virtual const ast::DeclWithType *     visit( const ast::ObjectDecl           * node ) {
-		if ( node->name != "" ) os << node->name << ": ";
+	virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) {
+		if (  !node->name.empty() ) os << node->name << ": ";
 
 		if ( node->linkage != Linkage::Cforall ) {
@@ -116,14 +174,14 @@
 					? "maybe constructed"
 					: "not constructed"
-				) << ")" << std::endl << indent+1;
+				) << ")" << endl << indent+1;
 
 			++indent;
 			node->init->accept( *this );
 			--indent;
-			os << std::endl;
+			os << endl;
 		} // if
 
 		if ( ! node->attributes.empty() ) {
-			os << std::endl << indent << "... with attributes:" << std::endl;
+			os << endl << indent << "... with attributes:" << endl;
 			++indent;
 			printAll( node->attributes );
@@ -138,361 +196,464 @@
 	}
 
-	virtual const ast::DeclWithType *     visit( const ast::FunctionDecl         * node ) {
-		return node;
-	}
-
-	virtual const ast::Decl *             visit( const ast::StructDecl           * node ) {
-		return node;
-	}
-
-	virtual const ast::Decl *             visit( const ast::UnionDecl            * node ) {
-		return node;
-	}
-
-	virtual const ast::Decl *             visit( const ast::EnumDecl             * node ) {
-		return node;
-	}
-
-	virtual const ast::Decl *             visit( const ast::TraitDecl            * node ) {
-		return node;
-	}
-
-	virtual const ast::Decl *             visit( const ast::TypeDecl             * node ) {
-		return node;
-	}
-
-	virtual const ast::Decl *             visit( const ast::TypedefDecl          * node ) {
-		return node;
-	}
-
-	virtual const ast::AsmDecl *          visit( const ast::AsmDecl              * node ) {
-		return node;
-	}
-
-	virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl     * node ) {
-		return node;
-	}
-
-	virtual const ast::CompoundStmt *     visit( const ast::CompoundStmt         * node ) {
-		return node;
-	}
-
-	virtual const ast::Stmt *             visit( const ast::ExprStmt             * node ) {
-		return node;
-	}
-
-	virtual const ast::Stmt *             visit( const ast::AsmStmt              * node ) {
-		return node;
-	}
-
-	virtual const ast::Stmt *             visit( const ast::DirectiveStmt        * node ) {
-		return node;
-	}
-
-	virtual const ast::Stmt *             visit( const ast::IfStmt               * node ) {
-		return node;
-	}
-
-	virtual const ast::Stmt *             visit( const ast::WhileStmt            * node ) {
-		return node;
-	}
-
-	virtual const ast::Stmt *             visit( const ast::ForStmt              * node ) {
-		return node;
-	}
-
-	virtual const ast::Stmt *             visit( const ast::SwitchStmt           * node ) {
-		return node;
-	}
-
-	virtual const ast::Stmt *             visit( const ast::CaseStmt             * node ) {
-		return node;
-	}
-
-	virtual const ast::Stmt *             visit( const ast::BranchStmt           * node ) {
-		return node;
-	}
-
-	virtual const ast::Stmt *             visit( const ast::ReturnStmt           * node ) {
-		return node;
-	}
-
-	virtual const ast::Stmt *             visit( const ast::ThrowStmt            * node ) {
-		return node;
-	}
-
-	virtual const ast::Stmt *             visit( const ast::TryStmt              * node ) {
-		return node;
-	}
-
-	virtual const ast::Stmt *             visit( const ast::CatchStmt            * node ) {
-		return node;
-	}
-
-	virtual const ast::Stmt *             visit( const ast::FinallyStmt          * node ) {
-		return node;
-	}
-
-	virtual const ast::Stmt *             visit( const ast::WaitForStmt          * node ) {
-		return node;
-	}
-
-	virtual const ast::Stmt *             visit( const ast::WithStmt             * node ) {
-		return node;
-	}
-
-	virtual const ast::NullStmt *         visit( const ast::NullStmt             * node ) {
-		return node;
-	}
-
-	virtual const ast::Stmt *             visit( const ast::DeclStmt             * node ) {
-		return node;
-	}
-
-	virtual const ast::Stmt *             visit( const ast::ImplicitCtorDtorStmt * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::ApplicationExpr      * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::UntypedExpr          * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::NameExpr             * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::AddressExpr          * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::LabelAddressExpr     * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::CastExpr             * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::KeywordCastExpr      * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::VirtualCastExpr      * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::UntypedMemberExpr    * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::MemberExpr           * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::VariableExpr         * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::ConstantExpr         * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::SizeofExpr           * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::AlignofExpr          * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::UntypedOffsetofExpr  * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::OffsetofExpr         * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::OffsetPackExpr       * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::LogicalExpr          * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::ConditionalExpr      * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::CommaExpr            * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::TypeExpr             * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::AsmExpr              * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::ImplicitCopyCtorExpr * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::ConstructorExpr      * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::CompoundLiteralExpr  * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::RangeExpr            * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::UntypedTupleExpr     * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::TupleExpr            * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::TupleIndexExpr       * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::TupleAssignExpr      * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::StmtExpr             * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::UniqueExpr           * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::UntypedInitExpr      * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::InitExpr             * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::DeletedExpr          * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::DefaultArgExpr       * node ) {
-		return node;
-	}
-
-	virtual const ast::Expr *             visit( const ast::GenericExpr          * node ) {
-		return node;
-	}
-
-	virtual const ast::Type *             visit( const ast::VoidType             * node ) {
-		return node;
-	}
-
-	virtual const ast::Type *             visit( const ast::BasicType            * node ) {
-		return node;
-	}
-
-	virtual const ast::Type *             visit( const ast::PointerType          * node ) {
-		return node;
-	}
-
-	virtual const ast::Type *             visit( const ast::ArrayType            * node ) {
-		return node;
-	}
-
-	virtual const ast::Type *             visit( const ast::ReferenceType        * node ) {
-		return node;
-	}
-
-	virtual const ast::Type *             visit( const ast::QualifiedType        * node ) {
-		return node;
-	}
-
-	virtual const ast::Type *             visit( const ast::FunctionType         * node ) {
-		return node;
-	}
-
-	virtual const ast::Type *             visit( const ast::StructInstType       * node ) {
-		return node;
-	}
-
-	virtual const ast::Type *             visit( const ast::UnionInstType        * node ) {
-		return node;
-	}
-
-	virtual const ast::Type *             visit( const ast::EnumInstType         * node ) {
-		return node;
-	}
-
-	virtual const ast::Type *             visit( const ast::TraitInstType        * node ) {
-		return node;
-	}
-
-	virtual const ast::Type *             visit( const ast::TypeInstType         * node ) {
-		return node;
-	}
-
-	virtual const ast::Type *             visit( const ast::TupleType            * node ) {
-		return node;
-	}
-
-	virtual const ast::Type *             visit( const ast::TypeofType           * node ) {
-		return node;
-	}
-
-	virtual const ast::Type *             visit( const ast::VarArgsType          * node ) {
-		return node;
-	}
-
-	virtual const ast::Type *             visit( const ast::ZeroType             * node ) {
-		return node;
-	}
-
-	virtual const ast::Type *             visit( const ast::OneType              * node ) {
-		return node;
-	}
-
-	virtual const ast::Type *             visit( const ast::GlobalScopeType      * node ) {
-		return node;
-	}
-
-	virtual const ast::Designation *      visit( const ast::Designation          * node ) {
-		return node;
-	}
-
-	virtual const ast::Init *             visit( const ast::SingleInit           * node ) {
-		return node;
-	}
-
-	virtual const ast::Init *             visit( const ast::ListInit             * node ) {
-		return node;
-	}
-
-	virtual const ast::Init *             visit( const ast::ConstructorInit      * node ) {
-		return node;
-	}
-
-	virtual const ast::Attribute *        visit( const ast::Attribute            * node ) {
-		return node;
-	}
-
-	virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution     * node ) {
+	virtual const ast::DeclWithType * visit( const ast::FunctionDecl * node ) {
+		if ( !node->name.empty() ) {
+			os << node->name << ": ";
+		} // if
+		if ( node->linkage != Linkage::Cforall ) {
+			os << Linkage::name( node->linkage ) << " ";
+		} // if
+
+		printAll( node->attributes );
+
+		print( node->storage );
+		print( node->funcSpec );
+
+		if ( node->type ) {
+			node->type->accept( *this );
+		} else {
+			os << "untyped entity ";
+		} // if
+
+		if ( node->stmts ) {
+			os << indent << "... with body" << endl << indent+1;
+			++indent;
+			node->stmts->accept( *this );
+			--indent;
+		} // if
+		return node;
+	}
+
+	virtual const ast::Decl * visit( const ast::StructDecl * node ) {
+		print(node);
+		return node;
+	}
+
+	virtual const ast::Decl * visit( const ast::UnionDecl * node ) {
+		print(node);
+		return node;
+	}
+
+	virtual const ast::Decl * visit( const ast::EnumDecl * node ) {
+		print(node);
+		return node;
+	}
+
+	virtual const ast::Decl * visit( const ast::TraitDecl * node ) {
+		print(node);
+		return node;
+	}
+
+	virtual const ast::Decl * visit( const ast::TypeDecl * node ) {
+		print( node );
+		if ( node->init ) {
+			os << endl << indent << "with type initializer: ";
+			++indent;
+			node->init->accept( *this );
+			--indent;
+		}
+		return node;
+	}
+
+	virtual const ast::Decl * visit( const ast::TypedefDecl * node ) {
+		print( node );
+		return node;
+	}
+
+	virtual const ast::AsmDecl * visit( const ast::AsmDecl * node ) {
+		node->stmt->accept( *this );
+		return node;
+	}
+
+	virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) {
+		os << "Static Assert with condition: ";
+		++indent;
+		node->cond->accept( *this );
+		--indent;
+		os << endl << indent << "and message: ";
+		++indent;
+		node->msg->accept( *this );
+		--indent;
+		os << endl;
+		return node;
+	}
+
+	virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) {
+		os << "CompoundStmt" << endl;
+		++indent;
+		printAll( node->kids );
+		--indent;
+		return node;
+	}
+
+	virtual const ast::Stmt * visit( const ast::ExprStmt * node ) {
+		++indent;
+		os << "Expression Statement:" << endl << indent;
+		node->expr->accept( *this );
+		--indent;
+		return node;
+	}
+
+	virtual const ast::Stmt * visit( const ast::AsmStmt * node ) {
+		os << "Assembler Statement:" << endl;
+		++indent;
+		os << indent << "instruction: " << endl << indent;
+		node->instruction->accept( *this );
+		if ( ! node->output.empty() ) {
+			os << endl << indent+1 << "output: " << endl;
+			printAll( node->output );
+		} // if
+		if ( ! node->input.empty() ) {
+			os << indent+1 << "input: " << endl;
+			printAll( node->input );
+		} // if
+		if ( ! node->clobber.empty() ) {
+			os << indent+1 << "clobber: " << endl;
+			printAll( node->clobber );
+		} // if
+		--indent;
+		return node;
+	}
+
+	virtual const ast::Stmt * visit( const ast::DirectiveStmt * node ) {
+		os << "GCC Directive:" << node->directive << endl;
+		return node;
+	}
+
+	virtual const ast::Stmt * visit( const ast::IfStmt * node ) {
+		os << "If on condition: " << endl;
+		os << indent+1;
+		++indent;
+		node->cond->accept( *this );
+		--indent;
+
+		if ( !node->inits.empty() ) {
+			os << indent << "... with initialization: \n";
+			++indent;
+			for ( const Stmt * stmt : node->inits ) {
+				os << indent;
+				stmt->accept( *this );
+			}
+			--indent;
+			os << endl;
+		}
+
+		os << indent << "... then: " << endl;
+
+		++indent;
+		os << indent;
+		node->thenPart->accept( *this );
+		--indent;
+
+		if ( node->elsePart != 0 ) {
+			os << indent << "... else: " << endl;
+			++indent;
+			os << indent;
+			node->elsePart->accept( *this );
+			--indent;
+		} // if
+		return node;
+	}
+
+	virtual const ast::Stmt * visit( const ast::WhileStmt * node ) {
+		return node;
+	}
+
+	virtual const ast::Stmt * visit( const ast::ForStmt * node ) {
+		return node;
+	}
+
+	virtual const ast::Stmt * visit( const ast::SwitchStmt * node ) {
+		return node;
+	}
+
+	virtual const ast::Stmt * visit( const ast::CaseStmt * node ) {
+		return node;
+	}
+
+	virtual const ast::Stmt * visit( const ast::BranchStmt * node ) {
+		return node;
+	}
+
+	virtual const ast::Stmt * visit( const ast::ReturnStmt * node ) {
+		return node;
+	}
+
+	virtual const ast::Stmt * visit( const ast::ThrowStmt * node ) {
+		return node;
+	}
+
+	virtual const ast::Stmt * visit( const ast::TryStmt * node ) {
+		return node;
+	}
+
+	virtual const ast::Stmt * visit( const ast::CatchStmt * node ) {
+		return node;
+	}
+
+	virtual const ast::Stmt * visit( const ast::FinallyStmt * node ) {
+		return node;
+	}
+
+	virtual const ast::Stmt * visit( const ast::WaitForStmt * node ) {
+		return node;
+	}
+
+	virtual const ast::Stmt * visit( const ast::WithStmt * node ) {
+		return node;
+	}
+
+	virtual const ast::NullStmt * visit( const ast::NullStmt * node ) {
+		return node;
+	}
+
+	virtual const ast::Stmt * visit( const ast::DeclStmt * node ) {
+		return node;
+	}
+
+	virtual const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::UntypedExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::NameExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::AddressExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::CastExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::MemberExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::VariableExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::ConstantExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::SizeofExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::AlignofExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::OffsetofExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::OffsetPackExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::LogicalExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::ConditionalExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::CommaExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::TypeExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::AsmExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::ConstructorExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::RangeExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::UntypedTupleExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::TupleExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::TupleIndexExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::TupleAssignExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::StmtExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::UniqueExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::UntypedInitExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::InitExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::DeletedExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::DefaultArgExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::GenericExpr * node ) {
+		return node;
+	}
+
+	virtual const ast::Type * visit( const ast::VoidType * node ) {
+		return node;
+	}
+
+	virtual const ast::Type * visit( const ast::BasicType * node ) {
+		return node;
+	}
+
+	virtual const ast::Type * visit( const ast::PointerType * node ) {
+		return node;
+	}
+
+	virtual const ast::Type * visit( const ast::ArrayType * node ) {
+		return node;
+	}
+
+	virtual const ast::Type * visit( const ast::ReferenceType * node ) {
+		return node;
+	}
+
+	virtual const ast::Type * visit( const ast::QualifiedType * node ) {
+		return node;
+	}
+
+	virtual const ast::Type * visit( const ast::FunctionType * node ) {
+		return node;
+	}
+
+	virtual const ast::Type * visit( const ast::StructInstType * node ) {
+		return node;
+	}
+
+	virtual const ast::Type * visit( const ast::UnionInstType * node ) {
+		return node;
+	}
+
+	virtual const ast::Type * visit( const ast::EnumInstType * node ) {
+		return node;
+	}
+
+	virtual const ast::Type * visit( const ast::TraitInstType * node ) {
+		return node;
+	}
+
+	virtual const ast::Type * visit( const ast::TypeInstType * node ) {
+		return node;
+	}
+
+	virtual const ast::Type * visit( const ast::TupleType * node ) {
+		return node;
+	}
+
+	virtual const ast::Type * visit( const ast::TypeofType * node ) {
+		return node;
+	}
+
+	virtual const ast::Type * visit( const ast::VarArgsType * node ) {
+		return node;
+	}
+
+	virtual const ast::Type * visit( const ast::ZeroType * node ) {
+		return node;
+	}
+
+	virtual const ast::Type * visit( const ast::OneType * node ) {
+		return node;
+	}
+
+	virtual const ast::Type * visit( const ast::GlobalScopeType * node ) {
+		return node;
+	}
+
+	virtual const ast::Designation * visit( const ast::Designation * node ) {
+		return node;
+	}
+
+	virtual const ast::Init * visit( const ast::SingleInit * node ) {
+		return node;
+	}
+
+	virtual const ast::Init * visit( const ast::ListInit * node ) {
+		return node;
+	}
+
+	virtual const ast::Init * visit( const ast::ConstructorInit * node ) {
+		return node;
+	}
+
+	virtual const ast::Attribute * visit( const ast::Attribute * node ) {
+		return node;
+	}
+
+	virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) {
 		return node;
 	}
@@ -500,6 +661,11 @@
 };
 
-void print( std::ostream & os, const ast::Node * node, Indenter indent ) {
-	Printer printer { os, indent };
+void print( ostream & os, const ast::Node * node, Indenter indent ) {
+	Printer printer { os, indent, false };
+	node->accept(printer);
+}
+
+void printShort( ostream & os, const ast::Node * node, Indenter indent ) {
+	Printer printer { os, indent, true };
 	node->accept(printer);
 }
@@ -508,6 +674,6 @@
 // The size here needs to be explicit but at least the compiler will produce an error
 // if the wrong size is specified
-constexpr std::array<const char*, 3> Printer::Names::FuncSpecifiers;
-constexpr std::array<const char*, 5> Printer::Names::StorageClasses;
-constexpr std::array<const char*, 6> Printer::Names::Qualifiers;
+constexpr array<const char*, 3> Printer::Names::FuncSpecifiers;
+constexpr array<const char*, 5> Printer::Names::StorageClasses;
+constexpr array<const char*, 6> Printer::Names::Qualifiers;
 }
