Index: src/AST/Label.hpp
===================================================================
--- src/AST/Label.hpp	(revision a16e246a825b05d29de91873c84e14d5e15adb57)
+++ src/AST/Label.hpp	(revision 94b1f71803b1e664d37eb2283a4777a322d527d0)
@@ -39,5 +39,5 @@
 
 	operator std::string () const { return name; }
-	bool empty() { return name.empty(); }
+	bool empty() const { return name.empty(); }
 };
 
Index: src/AST/Print.cpp
===================================================================
--- src/AST/Print.cpp	(revision a16e246a825b05d29de91873c84e14d5e15adb57)
+++ src/AST/Print.cpp	(revision 94b1f71803b1e664d37eb2283a4777a322d527d0)
@@ -118,19 +118,30 @@
 	}
 
+	void print( const std::vector<ast::Label> & labels ) {
+		if ( labels.empty() ) return;
+		os << indent << "... Labels: {";
+		bool isFirst = true;
+		for ( const Label & l : labels ) {
+			if ( isFirst ) { isFirst = false; } else { os << ","; }
+			os << l;
+		}
+		os << "}" << endl;
+	}
+
 	void print( const ast::Expr::InferUnion & inferred, unsigned level = 0 ) {
 		switch ( inferred.mode ) {
 		case ast::Expr::InferUnion::Empty: return;
 		case ast::Expr::InferUnion::Slots: {
-			os << indent << "with " << inferred.data.resnSlots.size() << " pending inference slots" 
-			   << std::endl;
+			os << indent << "with " << inferred.data.resnSlots.size() 
+			   << " pending inference slots" << endl;
 			return;
 		}
 		case ast::Expr::InferUnion::Params: {
-			os << indent << "with inferred parameters " << level << ":" << std::endl;
+			os << indent << "with inferred parameters " << level << ":" << endl;
 			++indent;
 			for ( const auto & i : inferred.data.inferParams ) {
 				os << indent;
 				short_print( Decl::fromId( i.second.decl ) );
-				os << std::endl;
+				os << endl;
 				print( i.second.expr->inferred, level+1 );
 			}
@@ -143,5 +154,5 @@
 	void print( const ast::ParameterizedType::ForallList & forall ) {
 		if ( forall.empty() ) return;	
-		os << "forall" << std::endl;
+		os << "forall" << endl;
 		++indent;
 		printAll( forall );
@@ -152,5 +163,5 @@
 	void print( const std::vector<ptr<Attribute>> & attrs ) {
 		if ( attrs.empty() ) return;
-		os << "with attributes" << std::endl;
+		os << "with attributes" << endl;
 		++indent;
 		printAll( attrs );
@@ -160,5 +171,5 @@
 	void print( const std::vector<ptr<Expr>> & params ) {
 		if ( params.empty() ) return;
-		os << std::endl << indent << "... with parameters" << std::endl;
+		os << endl << indent << "... with parameters" << endl;
 		++indent;
 		printAll( params );
@@ -226,5 +237,5 @@
 
 		if ( node->env ) {
-			os << std::endl << indent << "... with environment:" << std::endl;
+			os << endl << indent << "... with environment:" << endl;
 			++indent;
 			node->env->accept( *this );
@@ -233,5 +244,5 @@
 
 		if ( node->extension ) {
-			os << std::endl << indent << "... with extension";
+			os << endl << indent << "... with extension";
 		}
 	}
@@ -378,5 +389,5 @@
 
 	virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) {
-		os << "CompoundStmt" << endl;
+		os << "Compound Statement:" << endl;
 		++indent;
 		printAll( node->kids );
@@ -396,16 +407,16 @@
 		os << "Assembler Statement:" << endl;
 		++indent;
-		os << indent << "instruction: " << endl << indent;
-		node->instruction->accept( *this );
+		os << indent-1 << "instruction:" << endl << indent;
+		safe_print( node->instruction );
 		if ( ! node->output.empty() ) {
-			os << endl << indent+1 << "output: " << endl;
+			os << endl << indent << "output:" << endl;
 			printAll( node->output );
 		} // if
 		if ( ! node->input.empty() ) {
-			os << indent+1 << "input: " << endl;
+			os << indent << "input:" << endl;
 			printAll( node->input );
 		} // if
 		if ( ! node->clobber.empty() ) {
-			os << indent+1 << "clobber: " << endl;
+			os << indent << "clobber:" << endl;
 			printAll( node->clobber );
 		} // if
@@ -415,21 +426,21 @@
 
 	virtual const ast::Stmt * visit( const ast::DirectiveStmt * node ) {
-		os << "GCC Directive:" << node->directive << endl;
+		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;
+		os << "If on condition:" << endl;
+		++indent;
+		os << indent;
 		safe_print( node->cond );
 		--indent;
 
-		if ( !node->inits.empty() ) {
-			os << indent << "... with initialization: \n";
-			++indent;
-			for ( const Stmt * stmt : node->inits ) {
+		if ( ! node->inits.empty() ) {
+			os << indent << "... with initialization:" << endl;
+			++indent;
+			for ( const ast::Stmt * stmt : node->inits ) {
 				os << indent;
-				stmt->accept( *this );
+				safe_print( stmt );
 			}
 			--indent;
@@ -437,5 +448,5 @@
 		}
 
-		os << indent << "... then: " << endl;
+		os << indent << "... then:" << endl;
 
 		++indent;
@@ -445,5 +456,5 @@
 
 		if ( node->elsePart != 0 ) {
-			os << indent << "... else: " << endl;
+			os << indent << "... else:" << endl;
 			++indent;
 			os << indent;
@@ -455,24 +466,128 @@
 
 	virtual const ast::Stmt * visit( const ast::WhileStmt * node ) {
+		if ( node->isDoWhile ) { os << "Do-"; }
+		os << "While on condition:" << endl;
+		++indent;
+		safe_print( node->cond );
+		os << indent-1 << "... with body:" << endl;
+		safe_print( node->body );
+
+		if ( ! node->inits.empty() ) {
+			os << indent-1 << "... with inits:" << endl;
+			printAll( node->inits );
+		}
+		--indent;
+
 		return node;
 	}
 
 	virtual const ast::Stmt * visit( const ast::ForStmt * node ) {
+		os << "For Statement" << endl;
+
+		if ( ! node->inits.empty() ) {
+			os << indent << "... initialization:" << endl;
+			++indent;
+			for ( const ast::Stmt * stmt : node->inits ) {
+				os << indent+1;
+				safe_print( stmt );
+			}
+			--indent;
+		}
+
+		if ( node->cond ) {
+			os << indent << "... condition:" << endl;
+			++indent;
+			os << indent;
+			node->cond->accept( *this );
+			--indent;
+		}
+
+		if ( node->inc ) {
+			os << indent << "... increment:" << endl;
+			++indent;
+			os << indent;
+			node->inc->accept( *this );
+			--indent;
+		}
+
+		if ( node->body ) {
+			os << indent << "... with body:" << endl;
+			++indent;
+			os << indent;
+			node->body->accept( *this );
+			--indent;
+		}
+		os << endl;
+		print( node->labels );
+
 		return node;
 	}
 
 	virtual const ast::Stmt * visit( const ast::SwitchStmt * node ) {
+		os << "Switch on condition: ";
+		safe_print( node->cond );
+		os << endl;
+
+		++indent;
+		for ( const ast::Stmt * stmt : node->stmts ) {
+			stmt->accept( *this );
+		}
+		--indent;
+
 		return node;
 	}
 
 	virtual const ast::Stmt * visit( const ast::CaseStmt * node ) {
+		if ( node->isDefault() ) {
+			os << indent << "Default ";
+		} else {
+			os << indent << "Case ";
+			safe_print( node->cond );
+		} // if
+		os << endl;
+
+		++indent;
+		for ( const ast::Stmt * stmt : node->stmts ) {
+			os << indent;
+			stmt->accept( *this );
+		}
+		--indent;
+
 		return node;
 	}
 
 	virtual const ast::Stmt * visit( const ast::BranchStmt * node ) {
+		os << "Branch (" << node->kindName() << ")" << endl;
+		++indent;
+		if ( ! node->target.empty() ) {
+			os << indent << "with target: " << node->target << endl;
+		}
+
+		if ( ! node->originalTarget.empty() ) {
+			os << indent << "with original target: " << node->originalTarget << endl;
+		}
+
+		if ( node->computedTarget ) {
+			os << indent << "with computed target: ";
+			node->computedTarget->accept( *this );
+			os << endl;
+		}
+		--indent;
+
 		return node;
 	}
 
 	virtual const ast::Stmt * visit( const ast::ReturnStmt * node ) {
+		os << "Return Statement, returning";
+		if ( node->expr ) {
+			++indent;
+			os << ":" << endl << indent;
+			node->expr->accept( *this );
+			--indent;
+		} else {
+			os << " void";
+		}
+		os << endl;
+
 		return node;
 	}
@@ -503,4 +618,7 @@
 
 	virtual const ast::NullStmt * visit( const ast::NullStmt * node ) {
+		os << "Null Statement" << endl;
+		print( node->labels );
+
 		return node;
 	}
@@ -516,9 +634,9 @@
 	virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) {
 		++indent;
-		os << "Application of" << std::endl << indent;
+		os << "Application of" << endl << indent;
 		safe_print( node->func );
-		os << std::endl;
+		os << endl;
 		if ( ! node->args.empty() ) {
-			os << indent << "... to arguments" << std::endl;
+			os << indent << "... to arguments" << endl;
 			printAll( node->args );
 		}
@@ -531,8 +649,8 @@
 	virtual const ast::Expr * visit( const ast::UntypedExpr * node ) {
 		++indent;
-		os << "Applying untyped:" << std::endl;
+		os << "Applying untyped:" << endl;
 		os << indent;
 		safe_print( node->func );
-		os << std::endl << indent-1 << "...to:" << std::endl;
+		os << endl << indent-1 << "...to:" << endl;
 		printAll( node->args );
 		--indent;
@@ -550,5 +668,5 @@
 
 	virtual const ast::Expr * visit( const ast::AddressExpr * node ) {
-		os << "Address of:" << std::endl;
+		os << "Address of:" << endl;
 		++indent;
 		os << indent;
@@ -568,7 +686,7 @@
 	virtual const ast::Expr * visit( const ast::CastExpr * node ) {
 		++indent;
-		os << (node->isGenerated ? "Generated" : "Explicit") << " cast of:" << std::endl << indent;
+		os << (node->isGenerated ? "Generated" : "Explicit") << " cast of:" << endl << indent;
 		safe_print( node->arg );
-		os << std::endl << indent-1 << "... to:";
+		os << endl << indent-1 << "... to:";
 		if ( ! node->result ) {
 			os << " ";
@@ -577,5 +695,5 @@
 			os << " nothing";
 		} else {
-			os << std::endl << indent;
+			os << endl << indent;
 			node->result->accept( *this );
 		} // if
@@ -588,8 +706,8 @@
 	virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) {
 		++indent;
-		os << "Keyword Cast of:" << std::endl << indent;
+		os << "Keyword Cast of:" << endl << indent;
 		safe_print( node->arg );
 		--indent;
-		os << std::endl << indent << "... to: " << node->targetString();
+		os << endl << indent << "... to: " << node->targetString();
 		postprint( node );
 
@@ -599,11 +717,11 @@
 	virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) {
 		++indent;
-		os << "Virtual Cast of:" << std::endl << indent;
+		os << "Virtual Cast of:" << endl << indent;
 		safe_print( node->arg );
-		os << std::endl << indent-1 << "... to:";
+		os << endl << indent-1 << "... to:";
 		if ( ! node->result ) {
 			os << " unknown";
 		} else {
-			os << std::endl << indent;
+			os << endl << indent;
 			node->result->accept( *this );
 		}
@@ -616,7 +734,7 @@
 	virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) {
 		++indent;
-		os << "Untyped Member Expression, with field: " << std::endl << indent;
+		os << "Untyped Member Expression, with field: " << endl << indent;
 		safe_print( node->member );
-		os << indent-1 << "... from aggregate:" << std::endl << indent;
+		os << indent-1 << "... from aggregate:" << endl << indent;
 		safe_print( node->aggregate );
 		--indent;
@@ -628,7 +746,7 @@
 	virtual const ast::Expr * visit( const ast::MemberExpr * node ) {
 		++indent;
-		os << "Member Expression, with field:" << std::endl << indent;
+		os << "Member Expression, with field:" << endl << indent;
 		safe_print( node->member );
-		os << std::endl << indent-1 << "... from aggregate:" << std::endl << indent;
+		os << endl << indent-1 << "... from aggregate:" << endl << indent;
 		safe_print( node->aggregate );
 		--indent;
@@ -722,9 +840,9 @@
 	virtual const ast::Expr * visit( const ast::ConditionalExpr * node ) {
 		++indent;
-		os << "Conditional expression on:" << std::endl << indent;
+		os << "Conditional expression on:" << endl << indent;
 		safe_print( node->arg1 );
-		os << indent-1 << "First alternative:" << std::endl << indent;
+		os << indent-1 << "First alternative:" << endl << indent;
 		safe_print( node->arg2 );
-		os << indent-1 << "Second alternative:" << std::endl << indent;
+		os << indent-1 << "Second alternative:" << endl << indent;
 		safe_print( node->arg3 );
 		--indent;
@@ -736,7 +854,7 @@
 	virtual const ast::Expr * visit( const ast::CommaExpr * node ) {
 		++indent;
-		os << "Comma Expression:" << std::endl << indent;
+		os << "Comma Expression:" << endl << indent;
 		safe_print( node->arg1 );
-		os << std::endl << indent;
+		os << endl << indent;
 		safe_print( node->arg2 );
 		--indent;
@@ -754,5 +872,5 @@
 
 	virtual const ast::Expr * visit( const ast::AsmExpr * node ) {
-		os << "Asm Expression:" << std::endl;
+		os << "Asm Expression:" << endl;
 		++indent;
 		if ( node->inout ) node->inout->accept( *this );
@@ -766,9 +884,9 @@
 	virtual const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) {
 		++indent;
-		os << "Implicit Copy Constructor Expression:" << std::endl << indent;
+		os << "Implicit Copy Constructor Expression:" << endl << indent;
 		safe_print( node->callExpr );
-		os << std::endl << indent-1 << "... with temporaries:" << std::endl;
+		os << endl << indent-1 << "... with temporaries:" << endl;
 		printAll( node->tempDecls );
-		os << std::endl << indent-1 << "... with return temporaries:" << std::endl;
+		os << endl << indent-1 << "... with return temporaries:" << endl;
 		printAll( node->returnDecls );
 		--indent;
@@ -779,5 +897,5 @@
 
 	virtual const ast::Expr * visit( const ast::ConstructorExpr * node ) {
-		os <<  "Constructor Expression:" << std::endl << indent+1;
+		os <<  "Constructor Expression:" << endl << indent+1;
 		indent += 2;
 		safe_print( node->callExpr );
@@ -790,5 +908,5 @@
 	virtual const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) {
 		++indent;
-		os << "Compound Literal Expression: " << std::endl << indent;
+		os << "Compound Literal Expression: " << endl << indent;
 		safe_print( node->result );
 		os << indent;
@@ -811,5 +929,5 @@
 
 	virtual const ast::Expr * visit( const ast::UntypedTupleExpr * node ) {
-		os << "Untyped Tuple:" << std::endl;
+		os << "Untyped Tuple:" << endl;
 		++indent;
 		printAll( node->exprs );
@@ -821,5 +939,5 @@
 
 	virtual const ast::Expr * visit( const ast::TupleExpr * node ) {
-		os << "Tuple:" << std::endl;
+		os << "Tuple:" << endl;
 		++indent;
 		printAll( node->exprs );
@@ -831,9 +949,9 @@
 
 	virtual const ast::Expr * visit( const ast::TupleIndexExpr * node ) {
-		os << "Tuple Index Expression, with tuple:" << std::endl;
+		os << "Tuple Index Expression, with tuple:" << endl;
 		++indent;
 		os << indent;
 		safe_print( node->tuple );
-		os << indent << "with index: " << node->index << std::endl;
+		os << indent << "with index: " << node->index << endl;
 		--indent;
 		postprint( node );
@@ -843,5 +961,5 @@
 
 	virtual const ast::Expr * visit( const ast::TupleAssignExpr * node ) {
-		os << "Tuple Assignment Expression, with stmt expr:" << std::endl;
+		os << "Tuple Assignment Expression, with stmt expr:" << endl;
 		++indent;
 		os << indent;
@@ -855,5 +973,5 @@
 	virtual const ast::Expr * visit( const ast::StmtExpr * node ) {
 		++indent;
-		os << "Statement Expression:" << std::endl << indent;
+		os << "Statement Expression:" << endl << indent;
 		safe_print( node->stmts );
 		if ( ! node->returnDecls.empty() ) {
@@ -873,5 +991,5 @@
 	virtual const ast::Expr * visit( const ast::UniqueExpr * node ) {
 		++indent;
-		os << "Unique Expression with id: " << node->id << std::endl << indent;
+		os << "Unique Expression with id: " << node->id << endl << indent;
 		safe_print( node->expr );
 		if ( node->object ) {
@@ -887,5 +1005,5 @@
 	virtual const ast::Expr * visit( const ast::UntypedInitExpr * node ) {
 		++indent;
-		os << "Untyped Init Expression" << std::endl << indent;
+		os << "Untyped Init Expression" << endl << indent;
 		safe_print( node->expr );
 		if ( ! node->initAlts.empty() ) {
@@ -903,5 +1021,5 @@
 	virtual const ast::Expr * visit( const ast::InitExpr * node ) {
 		++indent;
-		os << "Init Expression" << std::endl << indent;
+		os << "Init Expression" << endl << indent;
 		safe_print( node->expr );
 		os << indent << "... with designation: ";
@@ -914,7 +1032,7 @@
 	virtual const ast::Expr * visit( const ast::DeletedExpr * node ) {
 		++indent;
-		os << "Deleted Expression" << std::endl << indent;
+		os << "Deleted Expression" << endl << indent;
 		safe_print( node->expr );
-		os << std::endl << indent << "... deleted by: ";
+		os << endl << indent << "... deleted by: ";
 		safe_print( node->deleteStmt );
 		--indent;
@@ -925,5 +1043,5 @@
 	virtual const ast::Expr * visit( const ast::DefaultArgExpr * node ) {
 		++indent;
-		os << "Default Argument Expression" << std::endl << indent;
+		os << "Default Argument Expression" << endl << indent;
 		safe_print( node->expr );
 		--indent;
@@ -934,7 +1052,7 @@
 	virtual const ast::Expr * visit( const ast::GenericExpr * node ) {
 		++indent;
-		os << "C11 _Generic Expression" << std::endl << indent;
+		os << "C11 _Generic Expression" << endl << indent;
 		safe_print( node->control );
-		os << std::endl << indent << "... with associations:" << std::endl;
+		os << endl << indent << "... with associations:" << endl;
 		for ( const auto & assoc : node->associations ) {
 			os << indent;
@@ -942,5 +1060,5 @@
 				os << "... type: ";
 				assoc.type->accept( *this );
-				os << std::endl << indent << "... expression: ";
+				os << endl << indent << "... expression: ";
 				safe_print( assoc.expr );
 			} else {
@@ -948,5 +1066,5 @@
 				safe_print( assoc.expr );
 			}
-			os << std::endl;
+			os << endl;
 		}
 		--indent;
@@ -1025,9 +1143,9 @@
 		preprint( node );
 		++indent;
-		os << "Qualified Type:" << std::endl << indent;
+		os << "Qualified Type:" << endl << indent;
 		safe_print( node->parent );
-		os << std::endl << indent;
+		os << endl << indent;
 		safe_print( node->child );
-		os << std::endl;
+		os << endl;
 		--indent;
 
@@ -1038,22 +1156,22 @@
 		preprint( node );
 		
-		os << "function" << std::endl;
+		os << "function" << endl;
 		if ( ! node->params.empty() ) {
-			os << indent << "... with parameters" << std::endl;
+			os << indent << "... with parameters" << endl;
 			++indent;
 			printAll( node->params );
 			if ( node->isVarArgs ) {
-				os << indent << "and a variable number of other arguments" << std::endl;
+				os << indent << "and a variable number of other arguments" << endl;
 			}
 			--indent;
 		} else if ( node->isVarArgs ) {
-			os << indent+1 << "accepting unspecified arguments" << std::endl;
+			os << indent+1 << "accepting unspecified arguments" << endl;
 		}
 
 		os << indent << "... returning";
 		if ( node->returns.empty() ) {
-			os << " nothing" << std::endl;
+			os << " nothing" << endl;
 		} else {
-			os << std::endl;
+			os << endl;
 			++indent;
 			printAll( node->returns );
@@ -1116,5 +1234,5 @@
 	virtual const ast::Type * visit( const ast::TupleType * node ) {
 		preprint( node );
-		os << "tuple of types" << std::endl;
+		os << "tuple of types" << endl;
 		++indent;
 		printAll( node->types );
@@ -1159,10 +1277,10 @@
 	virtual const ast::Designation * visit( const ast::Designation * node ) {
 		if ( node->designators.empty() ) return node;
-		os << "... designated by: " << std::endl;
+		os << "... designated by: " << endl;
 		++indent;
 		for ( const ast::Expr * d : node->designators ) {
 			os << indent;
 			d->accept( *this );
-			os << std::endl;
+			os << endl;
 		}
 		--indent;
@@ -1177,5 +1295,5 @@
 
 	virtual const ast::Init * visit( const ast::ListInit * node ) {
-		os << "Compound initializer: " << std::endl;
+		os << "Compound initializer: " << endl;
 		++indent;
 		for ( auto p : group_iterate( node->designations, node->initializers ) ) {
@@ -1184,5 +1302,5 @@
 			os << indent;
 			init->accept( *this );
-			os << std::endl;
+			os << endl;
 			if ( ! d->designators.empty() ) {
 				os << indent;
@@ -1195,5 +1313,5 @@
 
 	virtual const ast::Init * visit( const ast::ConstructorInit * node ) {
-		os << "Constructor initializer: " << std::endl;
+		os << "Constructor initializer: " << endl;
 		if ( node->ctor ) {
 			os << indent << "... initially constructed with ";
@@ -1223,5 +1341,5 @@
 		os << "Attribute with name: " << node->name;
 		if ( node->params.empty() ) return node;
-		os << " with parameters: " << std::endl;
+		os << " with parameters: " << endl;
 		++indent;
 		printAll( node->params );
@@ -1231,5 +1349,5 @@
 
 	virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) {
-		os << indent << "Types:" << std::endl;
+		os << indent << "Types:" << endl;
 		for ( const auto& i : *node ) {
 			os << indent+1 << i.first << " -> ";
@@ -1237,7 +1355,7 @@
 			safe_print( i.second );
 			indent -= 2;
-			os << std::endl;
-		}
-		os << indent << "Non-types:" << std::endl;
+			os << endl;
+		}
+		os << indent << "Non-types:" << endl;
 		for ( auto i = node->beginVar(); i != node->endVar(); ++i ) {
 			os << indent+1 << i->first << " -> ";
@@ -1245,5 +1363,5 @@
 			safe_print( i->second );
 			indent -= 2;
-			os << std::endl;
+			os << endl;
 		}
 		return node;
Index: src/AST/Stmt.hpp
===================================================================
--- src/AST/Stmt.hpp	(revision a16e246a825b05d29de91873c84e14d5e15adb57)
+++ src/AST/Stmt.hpp	(revision 94b1f71803b1e664d37eb2283a4777a322d527d0)
@@ -244,5 +244,5 @@
 	  computedTarget(computedTarget), kind(Goto) {}
 
-	const char * kindName() { return kindNames[kind]; }
+	const char * kindName() const { return kindNames[kind]; }
 
 	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
