Index: src/CodeTools/TrackLoc.cc
===================================================================
--- src/CodeTools/TrackLoc.cc	(revision dba6db9a6025d74a9abed179c7aefcec1d0d09ab)
+++ src/CodeTools/TrackLoc.cc	(revision dba6db9a6025d74a9abed179c7aefcec1d0d09ab)
@@ -0,0 +1,191 @@
+//
+// 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.
+//
+// TrackLoc.cc --
+//
+// Author           : Andrew Beach
+// Created On       : Tues May 2 15:46:00 2017
+// Last Modified By : Andrew Beach
+// Last Modified On : Wed May 3 14:43:00 2017
+// Update Count     : 0
+//
+
+#include "TrackLoc.h"
+
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <cstdlib>
+
+#include "Common/utility.h"
+#include "Common/VectorMap.h"
+#include "GenPoly/GenPoly.h"
+#include "Parser/LinkageSpec.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Initializer.h"
+#include "SynTree/Visitor.h"
+
+namespace CodeTools {
+
+    std::ostream & operator<<(std::ostream & out, CodeLocation const & loc) {
+        return out << loc.filename << '[' << loc.linenumber << ']';
+    }
+
+	class LocationPrinter : public Visitor {
+		unsigned int printLevel;
+		unsigned int currentLevel;
+
+		CodeLocation *parent;
+		CodeLocation *lastNode;
+
+    public:
+        LocationPrinter(unsigned int printLevel) :
+            Visitor(), printLevel(printLevel), currentLevel(0),
+			parent(nullptr), lastNode(nullptr)
+        {}
+
+        void print(char const * name, BaseSyntaxNode *node) {
+            for (unsigned int i = 0 ; i < currentLevel ; ++i) {
+				std::cout << "    ";
+			}
+            if (2 <= printLevel) {
+				std::cout << name << '@';
+			}
+			std::cout << node->location << std::endl;
+        }
+
+		void atNode(char const * name, BaseSyntaxNode *node) {
+			if (-1 == node->location.linenumber) {
+				if (nullptr != parent) {
+					node->location.linenumber = parent->linenumber;
+					node->location.filename = parent->filename;
+				} else if (nullptr != lastNode) {
+					node->location.linenumber = lastNode->linenumber;
+					node->location.filename = lastNode->filename;
+				} else {
+					std::cerr << "Top level node has no CodeLocation " <<
+								 name << std::endl;
+					exit(EXIT_FAILURE);
+				}
+			}
+			if (0 < printLevel) {
+				print(name, node);
+			}
+			lastNode = &node->location;
+		}
+
+#define VISIT_FUNCTION(SyntaxNodeType)				\
+		virtual void visit(SyntaxNodeType *node) {	\
+			atNode(#SyntaxNodeType, node);			\
+			++currentLevel;							\
+			CodeLocation * myParent = parent;		\
+			parent = &node->location;				\
+			Visitor::visit(node);					\
+			parent = myParent;						\
+			--currentLevel;							\
+		}
+
+		VISIT_FUNCTION(ObjectDecl)
+		VISIT_FUNCTION(FunctionDecl)
+		VISIT_FUNCTION(StructDecl)
+		VISIT_FUNCTION(UnionDecl)
+		VISIT_FUNCTION(EnumDecl)
+		VISIT_FUNCTION(TraitDecl)
+		VISIT_FUNCTION(TypeDecl)
+		VISIT_FUNCTION(TypedefDecl)
+		VISIT_FUNCTION(AsmDecl)
+
+		VISIT_FUNCTION(CompoundStmt)
+		VISIT_FUNCTION(ExprStmt)
+		VISIT_FUNCTION(AsmStmt)
+		VISIT_FUNCTION(IfStmt)
+		VISIT_FUNCTION(WhileStmt)
+		VISIT_FUNCTION(ForStmt)
+		VISIT_FUNCTION(SwitchStmt)
+		VISIT_FUNCTION(CaseStmt)
+		VISIT_FUNCTION(BranchStmt)
+		VISIT_FUNCTION(ReturnStmt)
+		VISIT_FUNCTION(TryStmt)
+		VISIT_FUNCTION(CatchStmt)
+		VISIT_FUNCTION(FinallyStmt)
+		VISIT_FUNCTION(NullStmt)
+		VISIT_FUNCTION(DeclStmt)
+		VISIT_FUNCTION(ImplicitCtorDtorStmt)
+
+		VISIT_FUNCTION(ApplicationExpr)
+		VISIT_FUNCTION(UntypedExpr)
+		VISIT_FUNCTION(NameExpr)
+		VISIT_FUNCTION(CastExpr)
+		VISIT_FUNCTION(AddressExpr)
+		VISIT_FUNCTION(LabelAddressExpr)
+		VISIT_FUNCTION(UntypedMemberExpr)
+		VISIT_FUNCTION(MemberExpr)
+		VISIT_FUNCTION(VariableExpr)
+		VISIT_FUNCTION(ConstantExpr)
+		VISIT_FUNCTION(SizeofExpr)
+		VISIT_FUNCTION(AlignofExpr)
+		VISIT_FUNCTION(UntypedOffsetofExpr)
+		VISIT_FUNCTION(OffsetofExpr)
+		VISIT_FUNCTION(OffsetPackExpr)
+		VISIT_FUNCTION(AttrExpr)
+		VISIT_FUNCTION(LogicalExpr)
+		VISIT_FUNCTION(ConditionalExpr)
+		VISIT_FUNCTION(CommaExpr)
+		VISIT_FUNCTION(TypeExpr)
+		VISIT_FUNCTION(AsmExpr)
+		VISIT_FUNCTION(ImplicitCopyCtorExpr)
+		VISIT_FUNCTION(ConstructorExpr)
+		VISIT_FUNCTION(CompoundLiteralExpr)
+		VISIT_FUNCTION(UntypedValofExpr)
+		VISIT_FUNCTION(RangeExpr)
+		VISIT_FUNCTION(UntypedTupleExpr)
+		VISIT_FUNCTION(TupleExpr)
+		VISIT_FUNCTION(TupleIndexExpr)
+		VISIT_FUNCTION(MemberTupleExpr)
+		VISIT_FUNCTION(TupleAssignExpr)
+		VISIT_FUNCTION(StmtExpr)
+		VISIT_FUNCTION(UniqueExpr)
+
+		VISIT_FUNCTION(VoidType)
+		VISIT_FUNCTION(BasicType)
+		VISIT_FUNCTION(PointerType)
+		VISIT_FUNCTION(ArrayType)
+		VISIT_FUNCTION(FunctionType)
+		VISIT_FUNCTION(StructInstType)
+		VISIT_FUNCTION(UnionInstType)
+		VISIT_FUNCTION(EnumInstType)
+		VISIT_FUNCTION(TraitInstType)
+		VISIT_FUNCTION(TypeInstType)
+		VISIT_FUNCTION(TupleType)
+		VISIT_FUNCTION(TypeofType)
+		VISIT_FUNCTION(AttrType)
+		VISIT_FUNCTION(VarArgsType)
+		VISIT_FUNCTION(ZeroType)
+		VISIT_FUNCTION(OneType)
+
+		VISIT_FUNCTION(SingleInit)
+		VISIT_FUNCTION(ListInit)
+		VISIT_FUNCTION(ConstructorInit)
+
+		//VISIT_FUNCTION(Subrange)
+
+		//VISIT_FUNCTION(Constant)
+
+	}; // LocationPrinter
+
+	void fillLocations( std::list< Declaration * > & translationUnit,
+			unsigned int printLevel) {
+		LocationPrinter printer(printLevel);
+		acceptAll( translationUnit, printer );
+	}
+
+} // namespace CodeTools
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/CodeTools/TrackLoc.h
===================================================================
--- src/CodeTools/TrackLoc.h	(revision dba6db9a6025d74a9abed179c7aefcec1d0d09ab)
+++ src/CodeTools/TrackLoc.h	(revision dba6db9a6025d74a9abed179c7aefcec1d0d09ab)
@@ -0,0 +1,37 @@
+//
+// 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.
+//
+// TrackLoc.h -- Track CodeLocation information in a translation unit's declarations.
+//
+// Author           : Andrew Beach
+// Created On       : Tues May 2 15:40:00 2017
+// Last Modified By : Andrew Beach
+// Last Modified On : Wed May 3 14:42:00 2017
+// Update Count     : 0
+//
+
+#ifndef TRACKLOC_H
+#define TRACKLOC_H
+
+#include "SynTree/SynTree.h"
+
+namespace CodeTools {
+
+	/// Fill in an approximate CodeLocation for each syntax node.
+	// printLevel: how much printing while filling in the node locations.
+	// 0 - No Printing, 1 - Print Location, 2 - Print Node Type and Location
+	void fillLocations( std::list< Declaration * > &translationUnit,
+			unsigned int printLevel = 0 );
+
+}  // namespace CodeTools
+
+#endif // TRACKLOC_H
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
