Index: src/AST/Bitfield.hpp
===================================================================
--- src/AST/Bitfield.hpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
+++ src/AST/Bitfield.hpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
@@ -0,0 +1,70 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Bitfield.hpp --
+//
+// Author           : Aaron B. Moss
+// Created On       : Thu May 9 10:00:00 2019
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Thu May 9 10:00:00 2019
+// Update Count     : 1
+//
+
+#pragma once
+
+#include <strings.h>  // for ffs
+
+/// Make a type a bitfield.
+/// Include in type definition to add operators. Used to simulate inheritance because union 
+/// does not allow it. Requires type to have `unsigned val` field
+/// @param BFType  Name of containing type
+#define MakeBitfield( BFType )                                         \
+	constexpr BFType() : val( 0 ) {}                                   \
+	constexpr BFType( unsigned int v ) : val( v ) {}                   \
+	bool operator[]( unsigned int i ) const { return val & (1 << i); } \
+	bool any() const { return val != 0; }                              \
+	void reset() { val = 0; }                                          \
+	int ffs() { return ::ffs( val ) - 1; }                             \
+	BFType operator&=( BFType other ) {                                \
+		val &= other.val; return *this;                                \
+	}                                                                  \
+	BFType operator&( BFType other ) const {                           \
+		BFType q = other;                                              \
+		q &= *this;                                                    \
+		return q;                                                      \
+	}                                                                  \
+	BFType operator|=( BFType other ) {                                \
+		val |= other.val; return *this;                                \
+	}                                                                  \
+	BFType operator|( BFType other ) const {                           \
+		BFType q = other;                                              \
+		q |= *this;                                                    \
+		return q;                                                      \
+	}                                                                  \
+	BFType operator-=( BFType other ) {                                \
+		val &= ~other.val; return *this;                               \
+	}
+
+/// Adds default printing operator to a bitfield type.
+/// Include in definition to add print function, requires other bitfield operators.
+/// @param N  Number of bits in bitfield
+#define MakeBitfieldPrint( N )                                         \
+	static const char* Names[];                                        \
+	void print( std::ostream & os ) const {                            \
+		if ( (*this).any() ) {                                         \
+			for ( unsigned int i = 0; i < N; i += 1 ) {                \
+				if ( (*this)[i] ) {                                    \
+					os << Names[i] << ' ';                             \
+				}                                                      \
+			}                                                          \
+		}                                                              \
+	}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/AST/Decl.cpp
===================================================================
--- src/AST/Decl.cpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
+++ src/AST/Decl.cpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
@@ -0,0 +1,47 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Decl.cpp --
+//
+// Author           : Aaron B. Moss
+// Created On       : Thu May 9 10:00:00 2019
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Thu May 9 10:00:00 2019
+// Update Count     : 1
+//
+
+#include <unordered_map>
+
+#include "Decl.hpp"
+
+#include "Fwd.hpp"   // for UniqueId
+#include "Node.hpp"  // for readonly
+
+namespace ast {
+// To canonicalize declarations
+static UniqueId lastUniqueId = 0;
+
+using IdMapType = std::unordered_map< UniqueId, readonly<Decl> >;
+static IdMapType idMap;
+
+void Decl::fixUniqueId() {
+	if ( uniqueId ) return;  // ensure only set once
+	uniqueId = ++lastUniqueId;
+	idMap[ uniqueId ] = this;
+}
+
+readonly<Decl> Decl::fromId( UniqueId id ) {
+	IdMapType::const_iterator i = idMap.find( id );
+	if ( i != idMap.end() ) return i->second;
+	return {};
+}
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/AST/Decl.hpp
===================================================================
--- src/AST/Decl.hpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
+++ src/AST/Decl.hpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
@@ -0,0 +1,84 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Decl.hpp --
+//
+// Author           : Aaron B. Moss
+// Created On       : Thu May 9 10:00:00 2019
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Thu May 9 10:00:00 2019
+// Update Count     : 1
+//
+
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "Fwd.hpp"             // for UniqueId
+#include "LinkageSpec.hpp"
+#include "Node.hpp"            // for ptr, readonly
+#include "ParseNode.hpp"
+#include "StorageClasses.hpp"
+#include "Visitor.hpp"
+
+namespace ast {
+class Attribute;
+class Expr;
+
+/// Base declaration class
+class Decl : public ParseNode {
+public:
+	std::string name;
+	Storage::Classes storage;
+	Linkage::Spec linkage;
+	UniqueId uniqueId = 0;
+	bool extension = false;
+
+	Decl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 
+		Linkage::Spec linkage )
+	: ParseNode( loc ), name( name ), storage( storage ), linkage( linkage ) {}
+
+	Decl* set_extension( bool ex ) { extension = ex; return this; }
+
+	/// Ensures this node has a unique ID
+	void fixUniqueId();
+	/// Get canonical declaration for unique ID
+	static readonly<Decl> fromId( UniqueId id );
+
+	virtual Decl* accept( Visitor& v ) override = 0;
+private:
+	virtual Decl* clone() const override = 0;
+};
+
+/// Typed declaration base class
+class DeclWithType : public Decl {
+public:
+	/// Represents the type with all types and typedefs expanded.
+	/// This field is generated by SymTab::Validate::Pass2
+	std::string mangleName;
+	/// Stores the scope level at which the variable was declared. 
+	/// Used to access shadowed identifiers.
+	int scopeLevel = 0;
+
+	std::vector<ptr<Attribute>> attributes;
+	Function::Specs funcSpecs;
+	ptr<Expr> asmName;
+	bool isDeleted = false;
+
+	DeclWithType( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 
+		Linkage::Spec linkage, std::vector<ptr<Attribute>>&& attrs, Function::Specs fs )
+	: Decl( loc, name, storage, linkage ), mangleName(), attributes( std::move(attrs) ), 
+		funcSpecs(fs), asmName() {}
+};
+
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/AST/DeclReplacer.cpp
===================================================================
--- src/AST/DeclReplacer.cpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
+++ src/AST/DeclReplacer.cpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
@@ -0,0 +1,22 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// DeclReplacer.cpp --
+//
+// Author           : Aaron B. Moss
+// Created On       : Wed May 8 13:00:00 2019
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Wed May 8 13:00:00 2019
+// Update Count     : 1
+//
+
+#error unimplemented
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/AST/DeclReplacer.hpp
===================================================================
--- src/AST/DeclReplacer.hpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
+++ src/AST/DeclReplacer.hpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
@@ -0,0 +1,40 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// DeclReplacer.hpp --
+//
+// Author           : Aaron B. Moss
+// Created On       : Wed May 8 13:00:00 2019
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Wed May 8 13:00:00 2019
+// Update Count     : 1
+//
+
+#pragma once
+
+#include <unordered_map>
+
+#include "Node.hpp"
+
+namespace ast {
+	class DeclWithType;
+	class TypeDecl;
+
+	namespace DeclReplacer {
+		using DeclMap = std::unordered_map< DeclWithType*, DeclWithType* >;
+		using TypeMap = std::unordered_map< TypeDecl*, TypeDecl* >;
+
+		void replace( Node* node, const DeclMap& declMap );
+		void replace( Node* node, const TypeMap& typeMap );
+		void replace( Node* node, const DeclMap& declMap, const TypeMap& typeMap );
+	}
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/AST/Label.hpp
===================================================================
--- src/AST/Label.hpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
+++ src/AST/Label.hpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
@@ -0,0 +1,56 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Label.hpp --
+//
+// Author           : Aaron B. Moss
+// Created On       : Wed May 8 13:00:00 2019
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Wed May 8 13:00:00 2019
+// Update Count     : 1
+//
+
+#pragma once
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include "Node.hpp"
+#include "Common/CodeLocation.h"
+
+namespace ast {
+
+	class Attribute;
+
+	/// Named labels for statements
+	class Label {
+	public:
+		CodeLocation location;
+		std::string name;
+		std::vector< ptr<Attribute> > attributes;
+
+		Label( CodeLocation loc, const std::string& name = "", 
+			const std::vector<ptr<Attribute>>& attrs = std::vector<ptr<Attribute>>{} )
+		: location( loc ), name( name ), attributes( attrs ) {}
+
+		operator std::string () const { return name; }
+		bool empty() { return name.empty(); }
+	};
+
+	inline bool operator== ( const Label& l1, const Label& l2 ) { return l1.name == l2.name; }
+	inline bool operator!= ( const Label& l1, const Label& l2 ) { return !(l1 == l2); }
+	inline bool operator<  ( const Label& l1, const Label& l2 ) { return l1.name < l2.name; }
+
+	inline std::ostream& operator<< ( std::ostream& out, const Label& l ) { return out << l.name; }
+	
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/AST/LinkageSpec.cpp
===================================================================
--- src/AST/LinkageSpec.cpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
+++ src/AST/LinkageSpec.cpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
@@ -0,0 +1,62 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// LinkageSpec.hpp --
+//
+// Author           : Aaron B. Moss
+// Created On       : Thu May 9 10:00:00 2019
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Thu May 9 10:00:00 2019
+// Update Count     : 1
+//
+
+#include "LinkageSpec.hpp"
+
+#include <cassert>
+#include <memory>   // for unique_ptr
+#include <string>
+
+#include "Common/CodeLocation.h"
+#include "Common/SemanticError.h"
+
+namespace ast {
+	namespace Linkage {
+		Spec update( CodeLocation loc, Spec spec, const std::string * cmd ) {
+			assert( cmd );
+			std::unique_ptr<const std::string> guard( cmd ); // allocated by lexer
+			if ( *cmd == "\"Cforall\"" ) {
+				spec.is_mangled = true;
+				return spec;
+			} else if ( *cmd == "\"C\"" ) {
+				spec.is_mangled = false;
+				return spec;
+			} else {
+				SemanticError( loc, "Invalid linkage specifier " + *cmd );
+			}
+		}
+	
+
+		std::string name( Spec spec ) {
+			switch ( spec ) {
+			case Intrinsic:  return "intrinsic";
+			case C:          return "C";
+			case Cforall:    return "Cforall";
+			case AutoGen:    return "autogenerated cfa";
+			case Compiler:   return "compiler built-in";
+			case BuiltinCFA: return "cfa built-in";
+			case BuiltinC:   return "c built-in";
+			default:         return "<unnamed linkage spec>";
+			}
+		}
+
+	}
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/AST/LinkageSpec.hpp
===================================================================
--- src/AST/LinkageSpec.hpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
+++ src/AST/LinkageSpec.hpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
@@ -0,0 +1,80 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// LinkageSpec.hpp --
+//
+// Author           : Aaron B. Moss
+// Created On       : Thu May 9 10:00:00 2019
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Thu May 9 10:00:00 2019
+// Update Count     : 1
+//
+
+#pragma once
+
+#include <string>
+
+#include "Bitfield.hpp"
+#include "Common/CodeLocation.h"
+
+namespace ast {
+
+	namespace Linkage {
+
+		/// Bitflags for linkage specifiers
+		enum {
+			Mangle       = 1 << 0,
+			Generate     = 1 << 1,
+			Overrideable = 1 << 2,
+			Builtin      = 1 << 3,
+			GccBuiltin   = 1 << 4
+		};
+
+		/// Bitflag type for storage classes
+		union Spec {
+			unsigned int val;
+			struct {
+				bool is_mangled      : 1;
+				bool is_generatable  : 1;
+				bool is_overrideable : 1;
+				bool is_builtin      : 1;
+				bool is_gcc_builtin  : 1;
+			};
+
+			MakeBitfield( Spec )
+		};
+
+		/// If `cmd` = "C" returns `spec` with `is_mangled = false`.
+		/// If `cmd` = "Cforall" returns `spec` with `is_mangled = true`. 
+		Spec update( CodeLocation loc, Spec spec, const std::string * cmd );
+
+		/// A human-readable name for this spec
+		std::string name( Spec spec );
+
+		// Pre-defined flag combinations
+		
+		/// C built-in defined in prelude
+		constexpr Spec Intrinsic  = { Mangle | Generate | Overrideable | Builtin };
+		/// Ordinary Cforall
+		constexpr Spec Cforall    = { Mangle | Generate };
+		/// C code: not overloadable, not mangled
+		constexpr Spec C          = { Generate };
+		/// Built by translator (e.g. struct assignment)
+		constexpr Spec AutoGen    = { Mangle | Generate | Overrideable };
+		/// GCC internal
+		constexpr Spec Compiler   = { Mangle | Builtin | GccBuiltin };
+		/// Mangled builtins
+		constexpr Spec BuiltinCFA = { Mangle | Generate | Builtin };
+		/// Non-mangled builtins
+		constexpr Spec BuiltinC   = { Generate | Builtin };
+	}
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/AST/Node.hpp
===================================================================
--- src/AST/Node.hpp	(revision f47f8876561ac211c0d7f0c72e79060c8ab30298)
+++ src/AST/Node.hpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
@@ -1,11 +1,42 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Node.hpp --
+//
+// Author           : Thierry Delisle
+// Created On       : Wed May 8 10:27:04 2019
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Wed May 8 11:00:00 2019
+// Update Count     : 2
+//
+
 #pragma once
 
-#include <memory>
+#include <cassert>
+#include <iosfwd>
 
 namespace ast {
+
+class Visitor;
+
+/// Base class for all AST nodes.
+/// Keeps both strong and weak reference counts.
 class Node {
 public:
+	// override defaults to ensure assignment doesn't 
+	// change/share reference counts
+	Node() = default;
+	Node(const Node&) : strong_ref(0), weak_ref(0) {}
+	Node(Node&&) : strong_ref(0), weak_ref(0) {}
+	Node& operator= (const Node&) = delete;
+	Node& operator= (Node&&) = delete;
 	virtual ~Node() = default;
 
+	virtual Node* accept( Visitor& v ) = 0;
+
+	/// Types of node references
 	enum class ref_type {
 		strong,
@@ -35,4 +66,7 @@
 
 private:
+	/// Make a copy of this node; should be overridden in subclass with more precise return type
+	virtual Node* clone() const = 0;
+
 	mutable size_t strong_ref = 0;
 	mutable size_t weak_ref = 0;
@@ -58,4 +92,6 @@
 }
 
+std::ostream& operator<< ( std::ostream& out, const Node* node );
+
 // Base class for the smart pointer types
 // should never really be used.
@@ -76,5 +112,4 @@
 	ptr_base( ptr_base<node_t, o_ref_t> && o ) : node(o.node) {
 		if( node ) node->increment(ref_t);
-		if( node ) node->decrement(o_ref_t);
 	}
 
@@ -89,5 +124,4 @@
 		if(o.node == node) return *this;
 		assign(o.node);
-		if( node ) node->decrement(o_ref_t);
 		return *this;
 	}
@@ -112,8 +146,16 @@
 };
 
+/// Owning pointer to node
 template< typename node_t >
 using ptr = ptr_base< node_t, Node::ref_type::strong >;
 
+/// Observing pointer to node
 template< typename node_t >
 using readonly = ptr_base< node_t, Node::ref_type::weak >;
 }
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/AST/ParseNode.hpp
===================================================================
--- src/AST/ParseNode.hpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
+++ src/AST/ParseNode.hpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
@@ -0,0 +1,44 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// ParseNode.hpp --
+//
+// Author           : Aaron B. Moss
+// Created On       : Wed May 8 11:00:00 2019
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Wed May 8 11:00:00 2019
+// Update Count     : 1
+//
+
+#pragma once
+
+#include "Node.hpp"
+
+#include "Common/CodeLocation.h"
+
+namespace ast {
+
+	/// AST node with an included source location
+	class ParseNode : public Node {
+	public:
+		CodeLocation location;
+
+		// Default constructor is deliberately omitted, all ParseNodes must have a location.
+		// Escape hatch if needed is to explicitly pass a default-constructed location, but 
+		// this should be used sparingly.
+
+		ParseNode( const CodeLocation& loc ) : Node(), location(loc) {}
+
+		ParseNode( const ParseNode& o ) = default;
+	};
+
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/AST/Stmt.cpp
===================================================================
--- src/AST/Stmt.cpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
+++ src/AST/Stmt.cpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
@@ -0,0 +1,32 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Stmt.cpp --
+//
+// Author           : Aaron B. Moss
+// Created On       : Wed May 8 13:00:00 2019
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Wed May 8 13:00:00 2019
+// Update Count     : 1
+//
+
+#include "Stmt.hpp"
+
+#include "DeclReplacer.hpp"
+
+// --- CompoundStmt
+
+namespace ast {
+	CompoundStmt::CompoundStmt( const CompoundStmt& o ) : Stmt(o), kids(o.kids) {
+		assert(!"implemented");
+	}
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/AST/Stmt.hpp
===================================================================
--- src/AST/Stmt.hpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
+++ src/AST/Stmt.hpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
@@ -0,0 +1,97 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Stmt.hpp --
+//
+// Author           : Aaron B. Moss
+// Created On       : Wed May 8 13:00:00 2019
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Wed May 8 13:00:00 2019
+// Update Count     : 1
+//
+
+#pragma once
+
+#include <list>
+#include <utility>                // for move
+#include <vector>
+
+#include "Label.hpp"
+#include "Node.hpp"               // for node, ptr
+#include "ParseNode.hpp"
+#include "Visitor.hpp"
+#include "Common/CodeLocation.h"
+
+namespace ast {
+
+class Expr;
+
+/// Base statement node
+class Stmt : public ParseNode {
+public:
+	std::vector<Label> labels;
+
+	Stmt( const CodeLocation& loc, std::vector<Label>&& labels = {} )
+	: ParseNode(loc), labels(std::move(labels)) {}
+
+	Stmt(const Stmt& o) : ParseNode(o), labels(o.labels) {}
+
+	virtual Stmt* accept( Visitor& v ) override = 0;
+private:
+	virtual Stmt* clone() const override = 0;
+};
+
+/// Compound statement `{ ... }`
+class CompoundStmt final : public Stmt {
+public:
+	std::list<ptr<Stmt>> kids;
+
+	CompoundStmt(const CodeLocation& loc, std::list<ptr<Stmt>>&& ks = {} )
+	: Stmt(loc), kids(std::move(ks)) {}
+
+	CompoundStmt( const CompoundStmt& o );
+	CompoundStmt( CompoundStmt&& o ) = default;
+
+	void push_back( Stmt* s ) { kids.emplace_back( s ); }
+	void push_front( Stmt* s ) { kids.emplace_front( s ); }
+
+	CompoundStmt* accept( Visitor& v ) override { return v.visit( this ); }
+private:
+	CompoundStmt* clone() const override { return new CompoundStmt{ *this }; }
+};
+
+/// Empty statment `;`
+class NullStmt final : public Stmt {
+public:
+	NullStmt( const CodeLocation& loc, std::vector<Label>&& labels = {} )
+	: Stmt(loc, std::move(labels)) {}
+
+	NullStmt* accept( Visitor& v ) override { return v.visit( this ); }
+private:
+	NullStmt* clone() const override { return new NullStmt{ *this }; }
+};
+
+/// Expression wrapped by statement
+class ExprStmt final : public Stmt {
+public:
+	ptr<Expr> expr;
+
+	ExprStmt( const CodeLocation& loc, Expr* e ) : Stmt(loc), expr(e) {}
+
+	Stmt* accept( Visitor& v ) override { return v.visit( this ); }
+private:
+	ExprStmt* clone() const override { return new ExprStmt{ *this }; }
+};
+
+
+
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/AST/StorageClasses.hpp
===================================================================
--- src/AST/StorageClasses.hpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
+++ src/AST/StorageClasses.hpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
@@ -0,0 +1,56 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// StorageClasses.hpp --
+//
+// Author           : Aaron B. Moss
+// Created On       : Thu May 9 10:00:00 2019
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Thu May 9 10:00:00 2019
+// Update Count     : 1
+//
+
+#pragma once
+
+#include "Bitfield.hpp"
+
+namespace ast {
+
+	namespace Storage {
+
+		/// Bitflags for storage classes
+		enum {
+			Extern      = 1 << 0,
+			Static      = 1 << 1,
+			Auto        = 1 << 2,
+			Register    = 1 << 3,
+			ThreadLocal = 1 << 4,
+			NumClasses       = 5
+		};
+
+		/// Bitflag type for storage classes
+		union Classes {
+			unsigned int val;
+			struct {
+				bool is_extern      : 1;
+				bool is_static      : 1;
+				bool is_auto        : 1;
+				bool is_register    : 1;
+				bool is_threadlocal : 1;
+			};
+
+			MakeBitfield( Classes )
+			MakeBitfieldPrint( NumClasses )
+		};
+
+	}
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/AST/Type.hpp
===================================================================
--- src/AST/Type.hpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
+++ src/AST/Type.hpp	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
@@ -0,0 +1,32 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Type.hpp --
+//
+// Author           : Aaron B. Moss
+// Created On       : Thu May 9 10:00:00 2019
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Thu May 9 10:00:00 2019
+// Update Count     : 1
+//
+
+#pragma once
+
+#include "Node.hpp"
+
+namespace ast {
+
+class Type : public Node {
+
+};
+
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/AST/porting.md
===================================================================
--- src/AST/porting.md	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
+++ src/AST/porting.md	(revision 2bb4a01b67c9bef5d552f56c14abeca79a2985d2)
@@ -0,0 +1,95 @@
+# Porting notes for new AST #
+
+## Pointer Types ##
+* raw pointer `T*` is used for construction, but not storage
+* strong pointer `ast::ptr<T>` is used for an ownership relationship
+* weak pointer `ast::readonly<T>` is used for an observation relationship
+
+## Visitors ##
+* `Visitor` and `Mutator` are combined into a single `ast::Visitor` class
+  * Base nodes now override `Node* accept( Visitor& v ) = 0` with, e.g. `Stmt* accept( Visitor& v ) override = 0`
+* `PassVisitor` is replaced with `ast::Pass`
+
+## Structural Changes ##
+`CodeLocation` has been devolved from `BaseSyntaxNode` to `ast::ParseNode`
+* excludes `ast::Type` from carrying location information
+* `CodeLocation` is a mandatory constructor field for `ast::ParseNode`
+  * all subclass constructors must fill it; by convention, from their first argument
+
+`N->print(std::ostream&)` is a visitor now, port these methods to `ast::Print` class
+* **TODO** write this visitor
+* **TODO** write `std::ostream& operator<< ( std::ostream& out, const Node* node )` in `Node.hpp` in terms of `ast::Print`
+* `Declaration::printShort` should also be integrated
+
+`clone` is private to `Node` now
+* still needs to be overriden to return appropriate type
+  * e.g. `private: virtual Stmt* clone() const override = 0;`
+
+All leaves of the `Node` inheritance tree are now declared `final`
+* e.g. `class CompoundStmt final : public Stmt`
+* allows compiler to optimize virtual calls to static calls if given static type
+
+Pulled `FuncSpecifiers` and `StorageClasses` out of `Type` into their own headers
+* Made `BFCommon` a `MakeBitfield` macro in its own header
+  * added default and field-init constructors to macro
+
+Prefer move semantics for containers passed to node constructors
+
+## Code Style ##
+
+### Files ###
+* Headers have a `.hpp` suffix
+* Source code has a `.cpp` suffix
+* All source has the project-standard leading and trailing comments
+* prefer `#pragma once` over `#ifdef` guards
+* namespaces that cover entire files don't get indented
+
+### Documentation ###
+* class, method, and field comments should use doxygen-style `///` prefix
+  * should be included on all classes
+  * should be included on any method declaration that doesn't have an obvious behaviour from either naming convention (e.g. constructor, print operator, implement visitor pattern) or an inline implementation
+* use explanatory comments with `//` wherever appropriate
+  * older comments should be maintained in porting process wherever possible
+
+### Naming ###
+* Preserve names from previous AST whenever reasonable, and get team consensus on any changes.
+* Strong justification required for private fields
+  * No `get_` prefix on getters
+* Notable changes:
+  * for concision and consistency with subclasses:
+    * `Declaration` => `ast::Decl`
+	* `DeclarationWithType` => `ast::DeclWithType`  
+	* `Expression` => `ast::Expr`
+	* `Initializer` => `ast::Init`
+    * `Statement` => `ast::Stmt`
+  * because they don't really belong to `Type` (and for consistency with `Linkage::Spec`):
+    * `Type::StorageClasses` => `ast::Storage::Classes`
+	  * `Type::Extern` etc. => `ast::Storage::Extern` etc.
+	* `LinkageSpec::Spec` => `ast::Linkage::Spec`
+	  * `LinkageSpec::Mangle` etc. => `ast::Linkage::Mangle` etc.
+	  * `LinkageSpec::linkageUpdate` => `ast::Linkage::update`
+	  * `LinkageSpec::linkageName` => `ast::Linkage::name`
+	  * `LinkageSpec::isMangled(Spec)` etc. => `Spec.is_mangled` etc.
+	  * `LinkageSpec::Intrinsic` etc. => `ast::Linkage::Intrinsic` etc.
+
+## Specific Nodes ##
+`Decl`
+* `storageClasses` => `storage`
+* `declFromId()` => `fromId()`
+  * not 100% sure about the return type here...
+
+`DeclWithType`
+* When `SymTab::Validate::Pass2` is rewritten, update comment on `mangleName` with new name of pass
+
+`Expr`
+* Merged `inferParams`/`resnSlots` into union, as suggested by comment
+
+`Label`
+* `get_statement()` exclusively used for code location, replaced with `CodeLocation` field
+
+`CompoundStmt`
+* **TODO** port copy operator
+  * Needs to be an almost-shallow clone, where the declarations are cloned only if needed
+  * **TODO** port DeclReplacer
+* Still a `std::list` for children, rather than `std::vector`
+  * allows more-efficient splicing for purposes of later code generation
