Index: src/AST/Init.cpp
===================================================================
--- src/AST/Init.cpp	(revision 9131e5492fda2590328dd083e16ce74d99e1d810)
+++ src/AST/Init.cpp	(revision 9131e5492fda2590328dd083e16ce74d99e1d810)
@@ -0,0 +1,45 @@
+//
+// 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.
+//
+// Init.cpp --
+//
+// Author           : Aaron B. Moss
+// Created On       : Fri May 10 10:30:00 2019
+// Last Modified By : Aaron B. Moss
+// Created On       : Fri May 10 10:30:00 2019
+// Update Count     : 1
+//
+
+#include "Init.hpp"
+
+#include <cassert>
+#include <utility>  // for move
+#include <vector>
+
+namespace ast {
+
+ListInit::ListInit( const CodeLocation& loc, std::vector<ptr<Init>>&& is, 
+	std::vector<ptr<Designation>>&& ds, bool mc)
+: Init( loc, mc ), initializers( std::move(is) ), designations( std::move(ds) ) {
+	// handle common case where ListInit is created without designations by making an 
+	// equivalent-length empty list
+	if ( designations.empty() ) {
+		for ( unsigned i = 0; i < initializers.size(); ++i ) {
+			designations.emplace_back( new Designation{ loc } );
+		}
+	}
+	
+	assertf( initializers.size() == designations.size(), "Created ListInit with mismatching "
+		"initializers (%zd) and designations (%zd)", initializers.size(), designations.size() );
+}
+
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/AST/Init.hpp
===================================================================
--- src/AST/Init.hpp	(revision 14cebb7a6317d810134980f9a9d8ebf49152dad4)
+++ src/AST/Init.hpp	(revision 9131e5492fda2590328dd083e16ce74d99e1d810)
@@ -0,0 +1,119 @@
+//
+// 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.
+//
+// Init.hpp --
+//
+// Author           : Aaron B. Moss
+// Created On       : Fri May 10 10:30:00 2019
+// Last Modified By : Aaron B. Moss
+// Created On       : Fri May 10 10:30:00 2019
+// Update Count     : 1
+//
+
+#pragma once
+
+#include <utility>        // for move
+#include <vector>
+
+#include "ParseNode.hpp"
+#include "Node.hpp"       // for ptr
+#include "Visitor.hpp"
+
+namespace ast {
+
+class Expr;
+class Stmt;
+
+/// List of designator (NameExpr, VariableExpr, and ConstantExpr) expressions that specify an 
+/// object being initialized
+class Designation final : public ParseNode {
+public:
+	std::vector<ptr<Expr>> designators;
+
+	Designation( const CodeLocation& loc, std::vector<ptr<Expr>>&& ds = {} ) 
+	: ParseNode( loc ), designators( std::move(ds) ) {}
+
+	Designation* accept( Visitor& v ) override { return v.visit( this ); }
+private:
+	Designation* clone() const override { return new Designation{ *this }; }
+};
+
+/// Object initializer base class
+class Init : public ParseNode {
+public:
+	bool maybeConstructed;
+
+	Init( const CodeLocation& loc, bool mc ) : ParseNode( loc ), maybeConstructed( mc ) {}
+
+	virtual Init* accept( Visitor& v ) override = 0;
+private:
+	virtual Init* clone() const override = 0;
+};
+
+/// Initializer for a common object: `int x = 4`
+class SingleInit final : public Init {
+public:
+	/// value to initialize to. Must be compile-time constant.
+	ptr<Expr> value;
+
+	SingleInit( const CodeLocation& loc, Expr* val, bool mc = false ) 
+	: Init( loc, mc ), value( val ) {}
+
+	Init* accept( Visitor& v ) override { return v.visit( this ); }
+private:
+	SingleInit* clone() const override { return new SingleInit{ *this }; }
+};
+
+/// Initializer recursively composed of a list of initializers.
+/// Used to initialize an array or aggregate: `int a[] = { 1, 2, 3 }`
+class ListInit final : public Init {
+public:
+	/// list of initializers
+	std::vector<ptr<Init>> initializers;
+	/// list of designators; order/length is consistent with initializers
+	std::vector<ptr<Designation>> designations;
+
+	ListInit( const CodeLocation& loc, std::vector<ptr<Init>>&& is, 
+		std::vector<ptr<Designation>>&& ds = {}, bool mc = false );
+	
+	using iterator = std::vector<ptr<Init>>::iterator;
+	using const_iterator = std::vector<ptr<Init>>::const_iterator;
+	iterator begin() { return initializers.begin(); }
+	iterator end() { return initializers.end(); }
+	const_iterator begin() const { return initializers.begin(); }
+	const_iterator end() const { return initializers.end(); }
+
+	Init* accept( Visitor& v ) override { return v.visit( this ); }
+private:
+	ListInit* clone() const override { return new ListInit{ *this }; }
+};
+
+/// Either a constructor expression or a C-style initializer.
+/// Should not be necessary to create manually; instead set `maybeConstructed` true on `SingleInit` 
+/// or `ListInit` if the object should be constructed.
+class ConstructorInit final : public Init {
+public:
+	ptr<Stmt> ctor;
+	ptr<Stmt> dtor;
+	/// C-style initializer made up of SingleInit/ListInit nodes to use as a fallback if an 
+	/// appropriate constructor definition is not found by the resolver.
+	ptr<Init> init;
+
+	ConstructorInit( const CodeLocation& loc, Stmt* ctor, Stmt* dtor, Init* init )
+	: Init( loc, true ), ctor( ctor ), dtor( dtor ), init( init ) {}
+
+	Init* accept( Visitor& v ) override { return v.visit( this ); }
+private:
+	ConstructorInit* clone() const override { return new ConstructorInit{ *this }; }
+};
+
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
