Index: src/Common/Eval.cc
===================================================================
--- src/Common/Eval.cc	(revision 5cbacf10c007573bb52e9dbace6bc7d304c98b78)
+++ src/Common/Eval.cc	(revision 5cbacf10c007573bb52e9dbace6bc7d304c98b78)
@@ -0,0 +1,96 @@
+//
+// 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.
+//
+// utility.h --
+//
+// Author           : Richard C. Bilson
+// Created On       : Mon May 18 07:44:20 2015
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Sun May  6 22:24:16 2018
+// Update Count     : 40
+//
+
+#include <utility> // for pair
+
+#include "Common/PassVisitor.h"
+#include "InitTweak/InitTweak.h"
+#include "SynTree/Expression.h"
+
+struct Eval : public WithShortCircuiting {
+	long long int value = 0;
+	bool valid = true;
+
+	void previsit( BaseSyntaxNode * ) { visit_children = false; }
+	void postvisit( BaseSyntaxNode * ) { valid = false; }
+
+	void postvisit( ConstantExpr * expr ) {
+		value = expr->intValue();
+	}
+
+	void postvisit( CastExpr * expr ) {
+		auto arg = eval(expr->arg);
+		valid = arg.second;
+		value = arg.first;
+		// TODO: perform type conversion on value if valid
+	}
+
+	void postvisit( VariableExpr * expr ) {
+		if ( EnumInstType * inst = dynamic_cast<EnumInstType *>(expr->result) ) {
+			if ( EnumDecl * decl = inst->baseEnum ) {
+				if ( decl->valueOf( expr->var, value ) ) { // value filled by valueOf
+					return;
+				}
+			}
+		}
+		valid = false;
+	}
+
+	void postvisit( ApplicationExpr * expr ) {
+		DeclarationWithType * function = InitTweak::getFunction(expr);
+		if ( ! function || function->linkage != LinkageSpec::Intrinsic ) { valid = false; return; }
+		const std::string & fname = function->name;
+		assertf( expr->args.size() == 1 || expr->args.size() == 2, "Intrinsic function with %zd arguments: %s", expr->args.size(), fname.c_str() );
+		std::pair<long long int, bool> arg1, arg2;
+		arg1 = eval(expr->args.front());
+		valid = valid && arg1.second;
+		if ( ! valid ) return;
+		if ( expr->args.size() == 2 ) {
+			arg2 = eval(expr->args.back());
+			valid = valid && arg2.second;
+			if ( ! valid ) return;
+		}
+		if (fname == "?+?") {
+			value = arg1.first + arg2.first;
+		} else if (fname == "?-?") {
+			value = arg1.first - arg2.first;
+		} else if (fname == "?*?") {
+			value = arg1.first * arg2.first;
+		} else if (fname == "?/?") {
+			value = arg1.first / arg2.first;
+		} else if (fname == "?%?") {
+			value = arg1.first % arg2.first;
+		} else {
+			valid = false;
+		}
+		// TODO: implement other intrinsic functions
+	}
+};
+
+std::pair<long long int, bool> eval(Expression * expr) {
+	PassVisitor<Eval> ev;
+	if (expr) {
+		expr->accept(ev);
+		return std::make_pair(ev.pass.value, ev.pass.valid);
+	} else {
+		return std::make_pair(0, false);
+	}
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/Common/module.mk
===================================================================
--- src/Common/module.mk	(revision 05e6eb547b1ef88c13f322a51ab4e52be696d924)
+++ src/Common/module.mk	(revision 5cbacf10c007573bb52e9dbace6bc7d304c98b78)
@@ -19,3 +19,4 @@
        Common/DebugMalloc.cc \
        Common/Assert.cc \
-       Common/Heap.cc
+       Common/Heap.cc \
+       Common/Eval.cc
Index: src/Common/utility.h
===================================================================
--- src/Common/utility.h	(revision 05e6eb547b1ef88c13f322a51ab4e52be696d924)
+++ src/Common/utility.h	(revision 5cbacf10c007573bb52e9dbace6bc7d304c98b78)
@@ -31,4 +31,6 @@
 #include "Common/Indenter.h"
 
+class Expression;
+
 template< typename T >
 static inline T * maybeClone( const T *orig ) {
@@ -456,4 +458,7 @@
 } // ilog2
 
+// -----------------------------------------------------------------------------
+/// evaluates expr as a long long int. If second is false, expr could not be evaluated
+std::pair<long long int, bool> eval(Expression * expr);
 
 // Local Variables: //
Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision 05e6eb547b1ef88c13f322a51ab4e52be696d924)
+++ src/Makefile.in	(revision 5cbacf10c007573bb52e9dbace6bc7d304c98b78)
@@ -169,4 +169,5 @@
 	Common/driver_cfa_cpp-Assert.$(OBJEXT) \
 	Common/driver_cfa_cpp-Heap.$(OBJEXT) \
+	Common/driver_cfa_cpp-Eval.$(OBJEXT) \
 	ControlStruct/driver_cfa_cpp-LabelGenerator.$(OBJEXT) \
 	ControlStruct/driver_cfa_cpp-LabelFixer.$(OBJEXT) \
@@ -494,5 +495,5 @@
 	Concurrency/Waitfor.cc Common/SemanticError.cc \
 	Common/UniqueName.cc Common/DebugMalloc.cc Common/Assert.cc \
-	Common/Heap.cc ControlStruct/LabelGenerator.cc \
+	Common/Heap.cc Common/Eval.cc ControlStruct/LabelGenerator.cc \
 	ControlStruct/LabelFixer.cc ControlStruct/MLEMutator.cc \
 	ControlStruct/Mutate.cc ControlStruct/ForExprMutator.cc \
@@ -683,4 +684,6 @@
 	Common/$(DEPDIR)/$(am__dirstamp)
 Common/driver_cfa_cpp-Heap.$(OBJEXT): Common/$(am__dirstamp) \
+	Common/$(DEPDIR)/$(am__dirstamp)
+Common/driver_cfa_cpp-Eval.$(OBJEXT): Common/$(am__dirstamp) \
 	Common/$(DEPDIR)/$(am__dirstamp)
 ControlStruct/$(am__dirstamp):
@@ -994,4 +997,5 @@
 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-Assert.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-DebugMalloc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-Eval.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-Heap.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-SemanticError.Po@am__quote@
@@ -1359,4 +1363,18 @@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-Heap.obj `if test -f 'Common/Heap.cc'; then $(CYGPATH_W) 'Common/Heap.cc'; else $(CYGPATH_W) '$(srcdir)/Common/Heap.cc'; fi`
 
+Common/driver_cfa_cpp-Eval.o: Common/Eval.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-Eval.o -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-Eval.Tpo -c -o Common/driver_cfa_cpp-Eval.o `test -f 'Common/Eval.cc' || echo '$(srcdir)/'`Common/Eval.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-Eval.Tpo Common/$(DEPDIR)/driver_cfa_cpp-Eval.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='Common/Eval.cc' object='Common/driver_cfa_cpp-Eval.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-Eval.o `test -f 'Common/Eval.cc' || echo '$(srcdir)/'`Common/Eval.cc
+
+Common/driver_cfa_cpp-Eval.obj: Common/Eval.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-Eval.obj -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-Eval.Tpo -c -o Common/driver_cfa_cpp-Eval.obj `if test -f 'Common/Eval.cc'; then $(CYGPATH_W) 'Common/Eval.cc'; else $(CYGPATH_W) '$(srcdir)/Common/Eval.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-Eval.Tpo Common/$(DEPDIR)/driver_cfa_cpp-Eval.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='Common/Eval.cc' object='Common/driver_cfa_cpp-Eval.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-Eval.obj `if test -f 'Common/Eval.cc'; then $(CYGPATH_W) 'Common/Eval.cc'; else $(CYGPATH_W) '$(srcdir)/Common/Eval.cc'; fi`
+
 ControlStruct/driver_cfa_cpp-LabelGenerator.o: ControlStruct/LabelGenerator.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-LabelGenerator.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelGenerator.Tpo -c -o ControlStruct/driver_cfa_cpp-LabelGenerator.o `test -f 'ControlStruct/LabelGenerator.cc' || echo '$(srcdir)/'`ControlStruct/LabelGenerator.cc
Index: src/Validate/HandleAttributes.cc
===================================================================
--- src/Validate/HandleAttributes.cc	(revision 05e6eb547b1ef88c13f322a51ab4e52be696d924)
+++ src/Validate/HandleAttributes.cc	(revision 5cbacf10c007573bb52e9dbace6bc7d304c98b78)
@@ -16,10 +16,7 @@
 #include "HandleAttributes.h"
 
-#include <utility> // for pair
-
 #include "CompilationState.h"
 #include "Common/PassVisitor.h"
 #include "Common/SemanticError.h"
-#include "InitTweak/InitTweak.h"
 #include "ResolvExpr/Resolver.h"
 #include "SynTree/Attribute.h"
@@ -29,76 +26,4 @@
 namespace Validate {
 	namespace {
-		std::pair<long long int, bool> eval(Expression * expr);
-
-		struct Eval : public WithShortCircuiting {
-			long long int value = 0;
-			bool valid = true;
-
-			void previsit( BaseSyntaxNode * ) { visit_children = false; }
-			void postvisit( BaseSyntaxNode * ) { valid = false; }
-
-			void postvisit( ConstantExpr * expr ) {
-				value = expr->intValue();
-			}
-
-			void postvisit( CastExpr * expr ) {
-				auto arg = eval(expr->arg);
-				valid = arg.second;
-				value = arg.first;
-				// TODO: perform type conversion on value if valid
-			}
-
-			void postvisit( VariableExpr * expr ) {
-				if ( EnumInstType * inst = dynamic_cast<EnumInstType *>(expr->result) ) {
-					if ( EnumDecl * decl = inst->baseEnum ) {
-						if ( decl->valueOf( expr->var, value ) ) { // value filled by valueOf
-							return;
-						}
-					}
-				}
-				valid = false;
-			}
-
-			void postvisit( ApplicationExpr * expr ) {
-				DeclarationWithType * function = InitTweak::getFunction(expr);
-				if ( ! function || function->linkage != LinkageSpec::Intrinsic ) { valid = false; return; }
-				const std::string & fname = function->name;
-				assertf( expr->args.size() == 1 || expr->args.size() == 2, "Intrinsic function with %zd arguments: %s", expr->args.size(), fname.c_str() );
-				std::pair<long long int, bool> arg1, arg2;
-				arg1 = eval(expr->args.front());
-				valid = valid && arg1.second;
-				if ( ! valid ) return;
-				if ( expr->args.size() == 2 ) {
-					arg2 = eval(expr->args.back());
-					valid = valid && arg2.second;
-					if ( ! valid ) return;
-				}
-				if (fname == "?+?") {
-					value = arg1.first + arg2.first;
-				} else if (fname == "?-?") {
-					value = arg1.first - arg2.first;
-				} else if (fname == "?*?") {
-					value = arg1.first * arg2.first;
-				} else if (fname == "?/?") {
-					value = arg1.first / arg2.first;
-				} else if (fname == "?%?") {
-					value = arg1.first % arg2.first;
-				} else {
-					valid = false;
-				}
-				// TODO: implement other intrinsic functions
-			}
-		};
-
-		std::pair<long long int, bool> eval(Expression * expr) {
-			PassVisitor<Eval> ev;
-			if (expr) {
-				expr->accept(ev);
-				return std::make_pair(ev.pass.value, ev.pass.valid);
-			} else {
-				return std::make_pair(0, false);
-			}
-		}
-
 		struct HandleAttributes : public WithIndexer {
 			void previsit( ObjectDecl * decl );
