Index: src/SynTree/TopLvalue.cc
===================================================================
--- src/SynTree/TopLvalue.cc	(revision 4615ac81401b8a87620dad09deac63435bd06109)
+++ src/SynTree/TopLvalue.cc	(revision 4615ac81401b8a87620dad09deac63435bd06109)
@@ -0,0 +1,132 @@
+//
+// 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.
+//
+// TopLvalue.cc -- Check and force that lvalue is only at the top of types.
+//
+// Author           : Andrew Beach
+// Created On       : Wed Jul 31 15:49:00 2019
+// Last Modified By : Andrew Beach
+// Last Modified On : Wed Aug  7 15:36:00 2019
+// Update Count     : 0
+//
+
+#include <iostream>
+
+#include "Common/PassVisitor.h"
+
+namespace {
+	class TopLvalue : public WithGuards {
+		bool inType = false;
+	public:
+		void previsit( const BaseSyntaxNode * ) {
+			if ( inType ) {
+				GuardValue( inType );
+				inType = false;
+			}
+		}
+
+		void previsit( const Type * type ) {
+			if ( inType ) {
+				assert( !type->get_lvalue() );
+			} else {
+				GuardValue( inType );
+				inType = true;
+			}
+		}
+
+	};
+
+	class ClearLvalue : public WithGuards {
+		bool inType = false;
+	public:
+		void previsit( BaseSyntaxNode * ) {
+			if ( inType ) {
+				GuardValue( inType );
+				inType = false;
+			}
+		}
+
+		void previsit( Type * type ) {
+			if ( !inType ) {
+				GuardValue( inType );
+				inType = true;
+			} else if ( type->get_lvalue() ) {
+				type->set_lvalue( false );
+			}
+		}
+	};
+
+	class TopLvaluePrint : public WithGuards, public WithShortCircuiting {
+		bool failed = false;
+		bool inType = false;
+		bool typeTop = false;
+	public:
+		bool failedAny = false;
+		void previsit() {
+			if ( failed ) {
+				visit_children = false;
+			} else if ( typeTop ) {
+				GuardValue( typeTop );
+				typeTop = false;
+			}
+		}
+
+		void previsit( const BaseSyntaxNode * ) {
+			previsit();
+			if ( inType ) {
+				GuardValue( inType );
+				inType = false;
+			}
+		}
+
+		void previsit( const Type * type ) {
+			previsit();
+			if ( inType ) {
+				if ( type->get_lvalue() ) {
+					failed = true;
+					failedAny = true;
+					visit_children = false;
+					std::cout << type->location << std::endl;
+				}
+				//assert( !type->get_lvalue() );
+			} else {
+				GuardValue( inType );
+				inType = true;
+				typeTop = true;
+			}
+		}
+
+		void postvisit( const Type * type ) {
+			if ( typeTop ) {
+				if ( failed ) {
+					std::cout << type->location << std::endl;
+					type->print( std::cout );
+					//assert( !failed );
+					failed = false;
+				}
+				typeTop = false;
+			}
+		}
+	};
+}
+
+void assertTopLvalue( const std::list< Declaration * > & translationUnit ) {
+	PassVisitor< TopLvaluePrint > visitor;
+	acceptAll( translationUnit, visitor );
+	assert( !visitor.pass.failedAny );
+}
+
+void clearInnerLvalue( std::list< Declaration * > & translationUnit ) {
+	PassVisitor< ClearLvalue > visitor;
+	acceptAll( translationUnit, visitor );
+}
+
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/SynTree/TopLvalue.h
===================================================================
--- src/SynTree/TopLvalue.h	(revision 4615ac81401b8a87620dad09deac63435bd06109)
+++ src/SynTree/TopLvalue.h	(revision 4615ac81401b8a87620dad09deac63435bd06109)
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+// TopLvalue.h -- Check and force that lvalue is only at the top of types.
+//
+// Author           : Andrew Beach
+// Created On       : Wed Jul 31 16:04:00 2019
+// Last Modified By : Andrew Beach
+// Last Modified On : Wed Aug  7 15:26:00 2019
+// Update Count     : 0
+//
+
+#include <list>
+class Declaration;
+
+void assertTopLvalue( const std::list< Declaration * > & translationUnit );
+/* Assert that all lvalue qualifiers are set on the top level.
+ *
+ * Does not return if the test fails.
+ */
+
+void clearInnerLvalue( std::list< Declaration * > & translationUnit );
+/* Make all types that are not at the top level rvalues (not-lvalues).
+ */
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
+
Index: src/SynTree/module.mk
===================================================================
--- src/SynTree/module.mk	(revision 357390f08744bdb5b92d74978a73be3712f711ed)
+++ src/SynTree/module.mk	(revision 4615ac81401b8a87620dad09deac63435bd06109)
@@ -49,5 +49,6 @@
       SynTree/TypeSubstitution.cc \
       SynTree/Attribute.cc \
-      SynTree/DeclReplacer.cc
+      SynTree/DeclReplacer.cc \
+      SynTree/TopLvalue.cc
 
 SRC += $(SRC_SYNTREE)
