Index: src/Parser/StatementNode.cc
===================================================================
--- src/Parser/StatementNode.cc	(revision 9fd9d01543f319adc37ab11817b20515dcb04170)
+++ src/Parser/StatementNode.cc	(revision bb7422a92c2e0bb9b901b7099d87e5736fed1d23)
@@ -10,21 +10,18 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Sat May 16 14:59:41 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Mar 29 08:51:23 2023
-// Update Count     : 454
+// Last Modified By : Andrew Beach
+// Last Modified On : Tue Apr  4 11:40:00 2023
+// Update Count     : 427
 //
 
 #include <cassert>                 // for assert, strict_dynamic_cast, assertf
-#include <list>                    // for list
 #include <memory>                  // for unique_ptr
 #include <string>                  // for string
 
+#include "AST/Label.hpp"           // for Label
+#include "AST/Stmt.hpp"            // for Stmt, AsmStmt, BranchStmt, CaseCla...
 #include "Common/SemanticError.h"  // for SemanticError
 #include "Common/utility.h"        // for maybeMoveBuild, maybeBuild
 #include "ParseNode.h"             // for StatementNode, ExpressionNode, bui...
-#include "SynTree/Expression.h"    // for Expression, ConstantExpr
-#include "SynTree/Label.h"         // for Label, noLabels
-#include "SynTree/Declaration.h"
-#include "SynTree/Statement.h"     // for Statement, BranchStmt, CaseStmt
 #include "parserutility.h"         // for notZeroExpr
 
@@ -32,5 +29,4 @@
 
 using namespace std;
-
 
 StatementNode::StatementNode( DeclarationNode * decl ) {
@@ -38,5 +34,6 @@
 	DeclarationNode * agg = decl->extractAggregate();
 	if ( agg ) {
-		StatementNode * nextStmt = new StatementNode( new DeclStmt( maybeBuild( decl ) ) );
+		StatementNode * nextStmt = new StatementNode(
+			new ast::DeclStmt( decl->location, maybeBuild( decl ) ) );
 		set_next( nextStmt );
 		if ( decl->get_next() ) {
@@ -51,5 +48,7 @@
 		agg = decl;
 	} // if
-	stmt.reset( new DeclStmt( maybeMoveBuild( agg ) ) );
+	// Local copy to avoid accessing the pointer after it is moved from.
+	CodeLocation declLocation = agg->location;
+	stmt.reset( new ast::DeclStmt( declLocation, maybeMoveBuild( agg ) ) );
 } // StatementNode::StatementNode
 
@@ -59,40 +58,49 @@
 	for ( StatementNode * curr = prev; curr != nullptr; curr = (StatementNode *)curr->get_next() ) {
 		StatementNode * node = strict_dynamic_cast< StatementNode * >(curr);
-		assert( dynamic_cast< CaseStmt * >(node->stmt.get()) );
+		assert( nullptr == node->stmt.get() );
+		assert( dynamic_cast<ast::CaseClause *>( node->clause.get() ) );
 		prev = curr;
 	} // for
 	// convert from StatementNode list to Statement list
 	StatementNode * node = dynamic_cast< StatementNode * >(prev);
-	list< Statement * > stmts;
+	std::vector<ast::ptr<ast::Stmt>> stmts;
 	buildMoveList( stmt, stmts );
 	// splice any new Statements to end of current Statements
-	CaseStmt * caseStmt = dynamic_cast< CaseStmt * >(node->stmt.get());
-	caseStmt->get_statements().splice( caseStmt->get_statements().end(), stmts );
+	auto caseStmt = strict_dynamic_cast<ast::CaseClause *>( node->clause.get() );
+	for ( auto const & newStmt : stmts ) {
+		caseStmt->stmts.emplace_back( newStmt );
+	}
+	stmts.clear();
 	return this;
 } // StatementNode::append_last_case
 
-Statement * build_expr( ExpressionNode * ctl ) {
-	Expression * e = maybeMoveBuild( ctl );
-
-	if ( e ) return new ExprStmt( e );
-	else return new NullStmt();
+ast::Stmt * build_expr( CodeLocation const & location, ExpressionNode * ctl ) {
+	if ( ast::Expr * e = maybeMoveBuild( ctl ) ) {
+		return new ast::ExprStmt( location, e );
+	} else {
+		return new ast::NullStmt( location );
+	}
 } // build_expr
 
-Expression * build_if_control( CondCtl * ctl, list< Statement * > & init ) {
-	if ( ctl->init != 0 ) {
-		buildMoveList( ctl->init, init );
-	} // if
-
-	Expression * cond = nullptr;
+static ast::Expr * build_if_control( CondCtl * ctl,
+		std::vector<ast::ptr<ast::Stmt>> & inits ) {
+	assert( inits.empty() );
+	if ( nullptr != ctl->init ) {
+		buildMoveList( ctl->init, inits );
+	} // if
+
+	ast::Expr * cond = nullptr;
 	if ( ctl->condition ) {
 		// compare the provided condition against 0
 		cond = notZeroExpr( maybeMoveBuild( ctl->condition ) );
 	} else {
-		for ( Statement * stmt : init ) {
+		for ( ast::ptr<ast::Stmt> & stmt : inits ) {
 			// build the && of all of the declared variables compared against 0
-			DeclStmt * declStmt = strict_dynamic_cast< DeclStmt * >( stmt );
-			DeclarationWithType * dwt = strict_dynamic_cast< DeclarationWithType * >( declStmt->decl );
-			Expression * nze = notZeroExpr( new VariableExpr( dwt ) );
-			cond = cond ? new LogicalExpr( cond, nze, true ) : nze;
+			//auto declStmt = strict_dynamic_cast<ast::DeclStmt *>( stmt );
+			auto declStmt = stmt.strict_as<ast::DeclStmt>();
+			//ast::DeclWithType * dwt = strict_dynamic_cast<ast::DeclWithType *>( declStmt->decl );
+			auto dwt = declStmt->decl.strict_as<ast::DeclWithType>();
+			ast::Expr * nze = notZeroExpr( new ast::VariableExpr( dwt->location, dwt ) );
+			cond = cond ? new ast::LogicalExpr( dwt->location, cond, nze, ast::AndExpr ) : nze;
 		}
 	}
@@ -101,131 +109,216 @@
 } // build_if_control
 
-Statement * build_if( CondCtl * ctl, StatementNode * then, StatementNode * else_ ) {
-	list< Statement * > astinit;						// maybe empty
-	Expression * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
-
-	Statement * astthen, * astelse = nullptr;
-	list< Statement * > aststmt;
-	buildMoveList< Statement, StatementNode >( then, aststmt );
+ast::Stmt * build_if( const CodeLocation & location, CondCtl * ctl, StatementNode * then, StatementNode * else_ ) {
+	std::vector<ast::ptr<ast::Stmt>> astinit;						// maybe empty
+	ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
+
+	std::vector<ast::ptr<ast::Stmt>> aststmt;
+	buildMoveList( then, aststmt );
 	assert( aststmt.size() == 1 );
-	astthen = aststmt.front();
-
+	ast::Stmt const * astthen = aststmt.front().release();
+
+	ast::Stmt const * astelse = nullptr;
 	if ( else_ ) {
-		list< Statement * > aststmt;
-		buildMoveList< Statement, StatementNode >( else_, aststmt );
+		std::vector<ast::ptr<ast::Stmt>> aststmt;
+		buildMoveList( else_, aststmt );
 		assert( aststmt.size() == 1 );
-		astelse = aststmt.front();
-	} // if
-
-	return new IfStmt( astcond, astthen, astelse, astinit );
+		astelse = aststmt.front().release();
+	} // if
+
+	return new ast::IfStmt( location, astcond, astthen, astelse,
+		std::move( astinit )
+	);
 } // build_if
 
-Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ) {
-	list< Statement * > aststmt;
-	buildMoveList< Statement, StatementNode >( stmt, aststmt );
-	if ( ! isSwitch ) {									// choose statement
-		for ( Statement * stmt : aststmt ) {
-			CaseStmt * caseStmt = strict_dynamic_cast< CaseStmt * >( stmt );
-			if ( ! caseStmt->stmts.empty() ) {			// code after "case" => end of case list
-				CompoundStmt * block = strict_dynamic_cast< CompoundStmt * >( caseStmt->stmts.front() );
-				block->kids.push_back( new BranchStmt( "", BranchStmt::Break ) );
+// Temporary work around. Split StmtClause off from StatementNode.
+template<typename clause_t>
+static void buildMoveClauseList( StatementNode * firstNode,
+		std::vector<ast::ptr<clause_t>> & output ) {
+	SemanticErrorException errors;
+	std::back_insert_iterator<std::vector<ast::ptr<clause_t>>>
+		out( output );
+	StatementNode * cur = firstNode;
+
+	while ( cur ) {
+		try {
+			auto clause = cur->clause.release();
+			if ( auto result = dynamic_cast<clause_t *>( clause ) ) {
+				*out++ = result;
+			} else {
+				assertf(false, __PRETTY_FUNCTION__ );
+				SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." );
+			} // if
+		} catch( SemanticErrorException & e ) {
+			errors.append( e );
+		} // try
+		ParseNode * temp = cur->get_next();
+		// Should not return nullptr, then it is non-homogeneous:
+		cur = dynamic_cast<StatementNode *>( temp );
+		if ( !cur && temp ) {
+			SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." );
+		} // if
+	} // while
+	if ( ! errors.isEmpty() ) {
+		throw errors;
+	} // if
+	// Usually in the wrapper.
+	delete firstNode;
+}
+
+ast::Stmt * build_switch( const CodeLocation & location, bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ) {
+	std::vector<ast::ptr<ast::CaseClause>> aststmt;
+	buildMoveClauseList( stmt, aststmt );
+	// If it is not a switch it is a choose statement.
+	if ( ! isSwitch ) {
+		for ( ast::ptr<ast::CaseClause> & stmt : aststmt ) {
+			// Code after "case" is the end of case list.
+			if ( !stmt->stmts.empty() ) {
+				auto mutStmt = ast::mutate( stmt.get() );
+				// I believe the stmts are actually always one block.
+				auto stmts = mutStmt->stmts.front().get_and_mutate();
+				auto block = strict_dynamic_cast<ast::CompoundStmt *>( stmts );
+				block->kids.push_back( new ast::BranchStmt( block->location,
+					ast::BranchStmt::Break,
+					ast::Label( block->location ) ) );
+				stmt = mutStmt;
 			} // if
 		} // for
 	} // if
 	// aststmt.size() == 0 for switch (...) {}, i.e., no declaration or statements
-	return new SwitchStmt( maybeMoveBuild( ctl ), aststmt );
+	return new ast::SwitchStmt( location,
+		maybeMoveBuild( ctl ), std::move( aststmt ) );
 } // build_switch
 
-Statement * build_case( ExpressionNode * ctl ) {
-	return new CaseStmt( maybeMoveBuild( ctl ), {} ); // stmt starts empty and then added to
+ast::CaseClause * build_case( ExpressionNode * ctl ) {
+	// stmt starts empty and then added to
+	auto expr = maybeMoveBuild( ctl );
+	return new ast::CaseClause( expr->location, expr, {} );
 } // build_case
 
-Statement * build_default() {
-	return new CaseStmt( nullptr, {}, true );			// stmt starts empty and then added to
+ast::CaseClause * build_default( const CodeLocation & location ) {
+	// stmt starts empty and then added to
+	return new ast::CaseClause( location, nullptr, {} );
 } // build_default
 
-Statement * build_while( CondCtl * ctl, StatementNode * stmt, StatementNode * else_ ) {
-	list< Statement * > astinit;						// maybe empty
-	Expression * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
-
-	list< Statement * > aststmt;						// loop body, compound created if empty
-	buildMoveList< Statement, StatementNode >( stmt, aststmt );
+ast::Stmt * build_while( const CodeLocation & location, CondCtl * ctl, StatementNode * stmt, StatementNode * else_ ) {
+	std::vector<ast::ptr<ast::Stmt>> astinit;						// maybe empty
+	ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
+
+	std::vector<ast::ptr<ast::Stmt>> aststmt;						// loop body, compound created if empty
+	buildMoveList( stmt, aststmt );
 	assert( aststmt.size() == 1 );
 
-	list< Statement * > astelse;						// else clause, maybe empty
-	buildMoveList< Statement, StatementNode >( else_, astelse );
-
-	return new WhileDoStmt( astcond, aststmt.front(), astelse.front(), astinit, false );
+	std::vector<ast::ptr<ast::Stmt>> astelse;						// else clause, maybe empty
+	buildMoveList( else_, astelse );
+	assert( astelse.size() <= 1 );
+
+	return new ast::WhileDoStmt( location,
+		astcond,
+		aststmt.front(),
+		astelse.empty() ? nullptr : astelse.front().release(),
+		std::move( astinit ),
+		false
+	);
 } // build_while
 
-Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ ) {
-	list< Statement * > aststmt;						// loop body, compound created if empty
-	buildMoveList< Statement, StatementNode >( stmt, aststmt );
+ast::Stmt * build_do_while( const CodeLocation & location, ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ ) {
+	std::vector<ast::ptr<ast::Stmt>> aststmt;						// loop body, compound created if empty
+	buildMoveList( stmt, aststmt );
 	assert( aststmt.size() == 1 );						// compound created if empty
 
-	list< Statement * > astelse;						// else clause, maybe empty
-	buildMoveList< Statement, StatementNode >( else_, astelse );
+	std::vector<ast::ptr<ast::Stmt>> astelse;						// else clause, maybe empty
+	buildMoveList( else_, astelse );
+	assert( astelse.size() <= 1 );
 
 	// do-while cannot have declarations in the contitional, so init is always empty
-	return new WhileDoStmt( notZeroExpr( maybeMoveBuild( ctl ) ), aststmt.front(), astelse.front(), {}, true );
+	return new ast::WhileDoStmt( location,
+		notZeroExpr( maybeMoveBuild( ctl ) ),
+		aststmt.front(),
+		astelse.empty() ? nullptr : astelse.front().release(),
+		{},
+		true
+	);
 } // build_do_while
 
-Statement * build_for( ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ ) {
-	list< Statement * > astinit;						// maybe empty
+ast::Stmt * build_for( const CodeLocation & location, ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ ) {
+	std::vector<ast::ptr<ast::Stmt>> astinit;						// maybe empty
 	buildMoveList( forctl->init, astinit );
 
-	Expression * astcond = nullptr;						// maybe empty
+	ast::Expr * astcond = nullptr;						// maybe empty
 	astcond = notZeroExpr( maybeMoveBuild( forctl->condition ) );
 
-	Expression * astincr = nullptr;						// maybe empty
+	ast::Expr * astincr = nullptr;						// maybe empty
 	astincr = maybeMoveBuild( forctl->change );
 	delete forctl;
 
-	list< Statement * > aststmt;						// loop body, compound created if empty
-	buildMoveList< Statement, StatementNode >( stmt, aststmt );
+	std::vector<ast::ptr<ast::Stmt>> aststmt;						// loop body, compound created if empty
+	buildMoveList( stmt, aststmt );
 	assert( aststmt.size() == 1 );
 
-	list< Statement * > astelse;						// else clause, maybe empty
-	buildMoveList< Statement, StatementNode >( else_, astelse );
-
-	return new ForStmt( astinit, astcond, astincr, aststmt.front(), astelse.front() );
+	std::vector<ast::ptr<ast::Stmt>> astelse;						// else clause, maybe empty
+	buildMoveList( else_, astelse );
+	assert( astelse.size() <= 1 );
+
+	return new ast::ForStmt( location,
+		std::move( astinit ),
+		astcond,
+		astincr,
+		aststmt.front(),
+		astelse.empty() ? nullptr : astelse.front().release()
+	);
 } // build_for
 
-Statement * build_branch( BranchStmt::Type kind ) {
-	Statement * ret = new BranchStmt( "", kind );
+ast::Stmt * build_branch( const CodeLocation & location, ast::BranchStmt::Kind kind ) {
+	return new ast::BranchStmt( location,
+		kind,
+		ast::Label( location )
+	);
+} // build_branch
+
+ast::Stmt * build_branch( const CodeLocation & location, string * identifier, ast::BranchStmt::Kind kind ) {
+	ast::Stmt * ret = new ast::BranchStmt( location,
+		kind,
+		ast::Label( location, *identifier )
+	);
+	delete identifier; 									// allocated by lexer
 	return ret;
 } // build_branch
 
-Statement * build_branch( string * identifier, BranchStmt::Type kind ) {
-	Statement * ret = new BranchStmt( * identifier, kind );
-	delete identifier;									// allocated by lexer
-	return ret;
-} // build_branch
-
-Statement * build_computedgoto( ExpressionNode * ctl ) {
-	return new BranchStmt( maybeMoveBuild( ctl ), BranchStmt::Goto );
+ast::Stmt * build_computedgoto( ExpressionNode * ctl ) {
+	ast::Expr * expr = maybeMoveBuild( ctl );
+	return new ast::BranchStmt( expr->location, expr );
 } // build_computedgoto
 
-Statement * build_return( ExpressionNode * ctl ) {
-	list< Expression * > exps;
+ast::Stmt * build_return( const CodeLocation & location, ExpressionNode * ctl ) {
+	std::vector<ast::ptr<ast::Expr>> exps;
 	buildMoveList( ctl, exps );
-	return new ReturnStmt( exps.size() > 0 ? exps.back() : nullptr );
+	return new ast::ReturnStmt( location,
+		exps.size() > 0 ? exps.back().release() : nullptr
+	);
 } // build_return
 
-Statement * build_throw( ExpressionNode * ctl ) {
-	list< Expression * > exps;
+static ast::Stmt * build_throw_stmt(
+		const CodeLocation & location,
+		ExpressionNode * ctl,
+		ast::ExceptionKind kind ) {
+	std::vector<ast::ptr<ast::Expr>> exps;
 	buildMoveList( ctl, exps );
 	assertf( exps.size() < 2, "CFA internal error: leaking memory" );
-	return new ThrowStmt( ThrowStmt::Terminate, !exps.empty() ? exps.back() : nullptr );
+	return new ast::ThrowStmt( location,
+		kind,
+		!exps.empty() ? exps.back().release() : nullptr,
+		(ast::Expr *)nullptr
+	);
+}
+
+ast::Stmt * build_throw( const CodeLocation & loc, ExpressionNode * ctl ) {
+	return build_throw_stmt( loc, ctl, ast::Terminate );
 } // build_throw
 
-Statement * build_resume( ExpressionNode * ctl ) {
-	list< Expression * > exps;
-	buildMoveList( ctl, exps );
-	assertf( exps.size() < 2, "CFA internal error: leaking memory" );
-	return new ThrowStmt( ThrowStmt::Resume, !exps.empty() ? exps.back() : nullptr );
+ast::Stmt * build_resume( const CodeLocation & loc, ExpressionNode * ctl ) {
+	return build_throw_stmt( loc, ctl, ast::Resume );
 } // build_resume
 
-Statement * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) {
+ast::Stmt * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) {
 	(void)ctl;
 	(void)target;
@@ -233,85 +326,97 @@
 } // build_resume_at
 
-Statement * build_try( StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ) {
-	list< CatchStmt * > aststmt;
-	buildMoveList< CatchStmt, StatementNode >( catch_, aststmt );
-	CompoundStmt * tryBlock = strict_dynamic_cast< CompoundStmt * >( maybeMoveBuild( try_ ) );
-	FinallyStmt * finallyBlock = dynamic_cast< FinallyStmt * >( maybeMoveBuild( finally_ ) );
-	return new TryStmt( tryBlock, aststmt, finallyBlock );
+ast::Stmt * build_try( const CodeLocation & location, StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ) {
+	std::vector<ast::ptr<ast::CatchClause>> aststmt;
+	buildMoveClauseList( catch_, aststmt );
+	ast::CompoundStmt * tryBlock = strict_dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( try_ ) );
+	ast::FinallyClause * finallyBlock = nullptr;
+	if ( finally_ ) {
+		finallyBlock = dynamic_cast<ast::FinallyClause *>( finally_->clause.release() );
+	}
+	return new ast::TryStmt( location,
+		tryBlock,
+		std::move( aststmt ),
+		finallyBlock
+	);
 } // build_try
 
-Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) {
-	list< Statement * > aststmt;
-	buildMoveList< Statement, StatementNode >( body, aststmt );
+ast::CatchClause * build_catch( const CodeLocation & location, ast::ExceptionKind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) {
+	std::vector<ast::ptr<ast::Stmt>> aststmt;
+	buildMoveList( body, aststmt );
 	assert( aststmt.size() == 1 );
-	return new CatchStmt( kind, maybeMoveBuild( decl ), maybeMoveBuild( cond ), aststmt.front() );
+	return new ast::CatchClause( location,
+		kind,
+		maybeMoveBuild( decl ),
+		maybeMoveBuild( cond ),
+		aststmt.front().release()
+	);
 } // build_catch
 
-Statement * build_finally( StatementNode * stmt ) {
-	list< Statement * > aststmt;
-	buildMoveList< Statement, StatementNode >( stmt, aststmt );
+ast::FinallyClause * build_finally( const CodeLocation & location, StatementNode * stmt ) {
+	std::vector<ast::ptr<ast::Stmt>> aststmt;
+	buildMoveList( stmt, aststmt );
 	assert( aststmt.size() == 1 );
-	return new FinallyStmt( dynamic_cast< CompoundStmt * >( aststmt.front() ) );
+	return new ast::FinallyClause( location,
+		aststmt.front().strict_as<ast::CompoundStmt>()
+	);
 } // build_finally
 
-SuspendStmt * build_suspend( StatementNode * then, SuspendStmt::Type type ) {
-	auto node = new SuspendStmt();
-
-	node->type = type;
-
-	list< Statement * > stmts;
-	buildMoveList< Statement, StatementNode >( then, stmts );
+ast::SuspendStmt * build_suspend( const CodeLocation & location, StatementNode * then, ast::SuspendStmt::Type type ) {
+	std::vector<ast::ptr<ast::Stmt>> stmts;
+	buildMoveList( then, stmts );
+	ast::CompoundStmt const * then2 = nullptr;
 	if(!stmts.empty()) {
 		assert( stmts.size() == 1 );
-		node->then = dynamic_cast< CompoundStmt * >( stmts.front() );
+		then2 = stmts.front().strict_as<ast::CompoundStmt>();
 	}
-
+	auto node = new ast::SuspendStmt( location, then2, ast::SuspendStmt::None );
+	node->type = type;
 	return node;
 } // build_suspend
 
-WaitForStmt * build_waitfor( WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) {
-	WaitForStmt::Target target;
-	target.function = maybeBuild( targetExpr );
+ast::WaitForStmt * build_waitfor( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) {
+	auto clause = new ast::WaitForClause( location );
+	clause->target_func = maybeBuild( targetExpr );
+	clause->stmt = maybeMoveBuild( stmt );
+	clause->cond = notZeroExpr( maybeMoveBuild( when ) );
 
 	ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() );
 	targetExpr->set_next( nullptr );
-	buildMoveList< Expression >( next, target.arguments );
+	buildMoveList( next, clause->target_args );
 
 	delete targetExpr;
 
-	existing->clauses.insert( existing->clauses.begin(), WaitForStmt::Clause{
-		std::move( target ),
-		maybeMoveBuild( stmt ),
-		notZeroExpr( maybeMoveBuild( when ) )
-	});
+	existing->clauses.insert( existing->clauses.begin(), clause );
 
 	return existing;
 } // build_waitfor
 
-WaitForStmt * build_waitfor_else( WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ) {
-	existing->orelse.statement  = maybeMoveBuild( stmt );
-	existing->orelse.condition  = notZeroExpr( maybeMoveBuild( when ) );
-
+ast::WaitForStmt * build_waitfor_else( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ) {
+	existing->else_stmt = maybeMoveBuild( stmt );
+	existing->else_cond = notZeroExpr( maybeMoveBuild( when ) );
+
+	(void)location;
 	return existing;
 } // build_waitfor_else
 
-WaitForStmt * build_waitfor_timeout( WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) {
-	existing->timeout.time      = maybeMoveBuild( timeout );
-	existing->timeout.statement = maybeMoveBuild( stmt );
-	existing->timeout.condition = notZeroExpr( maybeMoveBuild( when ) );
-
+ast::WaitForStmt * build_waitfor_timeout( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) {
+	existing->timeout_time = maybeMoveBuild( timeout );
+	existing->timeout_stmt = maybeMoveBuild( stmt );
+	existing->timeout_cond = notZeroExpr( maybeMoveBuild( when ) );
+
+	(void)location;
 	return existing;
 } // build_waitfor_timeout
 
-Statement * build_with( ExpressionNode * exprs, StatementNode * stmt ) {
-	list< Expression * > e;
+ast::Stmt * build_with( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) {
+	std::vector<ast::ptr<ast::Expr>> e;
 	buildMoveList( exprs, e );
-	Statement * s = maybeMoveBuild( stmt );
-	return new DeclStmt( new WithStmt( e, s ) );
+	ast::Stmt * s = maybeMoveBuild( stmt );
+	return new ast::DeclStmt( location, new ast::WithStmt( location, std::move( e ), s ) );
 } // build_with
 
-Statement * build_compound( StatementNode * first ) {
-	CompoundStmt * cs = new CompoundStmt();
-	buildMoveList( first, cs->get_kids() );
+ast::Stmt * build_compound( const CodeLocation & location, StatementNode * first ) {
+	auto cs = new ast::CompoundStmt( location );
+	buildMoveList( first, cs->kids );
 	return cs;
 } // build_compound
@@ -321,11 +426,9 @@
 // statement and wrap it into a compound statement to insert additional code. Hence, all control structures have a
 // conical form for code generation.
-StatementNode * maybe_build_compound( StatementNode * first ) {
+StatementNode * maybe_build_compound( const CodeLocation & location, StatementNode * first ) {
 	// Optimization: if the control-structure statement is a compound statement, do not wrap it.
 	// e.g., if (...) {...} do not wrap the existing compound statement.
-	if ( ! dynamic_cast<CompoundStmt *>( first->stmt.get() ) ) { // unique_ptr
-		CompoundStmt * cs = new CompoundStmt();
-		buildMoveList( first, cs->get_kids() );
-		return new StatementNode( cs );
+	if ( !dynamic_cast<ast::CompoundStmt *>( first->stmt.get() ) ) { // unique_ptr
+		return new StatementNode( build_compound( location, first ) );
 	} // if
 	return first;
@@ -333,23 +436,32 @@
 
 // Question
-Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {
-	list< Expression * > out, in;
-	list< ConstantExpr * > clob;
+ast::Stmt * build_asm( const CodeLocation & location, bool voltile, ast::Expr * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {
+	std::vector<ast::ptr<ast::Expr>> out, in;
+	std::vector<ast::ptr<ast::ConstantExpr>> clob;
 
 	buildMoveList( output, out );
 	buildMoveList( input, in );
 	buildMoveList( clobber, clob );
-	return new AsmStmt( voltile, instruction, out, in, clob, gotolabels ? gotolabels->labels : noLabels );
+	return new ast::AsmStmt( location,
+		voltile,
+		instruction,
+		std::move( out ),
+		std::move( in ),
+		std::move( clob ),
+		gotolabels ? gotolabels->labels : std::vector<ast::Label>()
+	);
 } // build_asm
 
-Statement * build_directive( string * directive ) {
-	return new DirectiveStmt( *directive );
+ast::Stmt * build_directive( const CodeLocation & location, string * directive ) {
+	auto stmt = new ast::DirectiveStmt( location, *directive );
+	delete directive;
+	return stmt;
 } // build_directive
 
-Statement * build_mutex( ExpressionNode * exprs, StatementNode * stmt ) {
-	list< Expression * > expList;
+ast::Stmt * build_mutex( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) {
+	std::vector<ast::ptr<ast::Expr>> expList;
 	buildMoveList( exprs, expList );
-	Statement * body = maybeMoveBuild( stmt );
-	return new MutexStmt( body, expList );
+	ast::Stmt * body = maybeMoveBuild( stmt );
+	return new ast::MutexStmt( location, body, std::move( expList ) );
 } // build_mutex
 
