Index: src/AST/Pass.hpp
===================================================================
--- src/AST/Pass.hpp	(revision 8e64cb4eabf6a141f302302ee70e6d1934f832ad)
+++ src/AST/Pass.hpp	(revision 1afda5a28cedbdf19c9bd2fdbf8cef4e296b02bc)
@@ -66,4 +66,8 @@
 //
 // Other Special Members:
+// | beginScope            - A method with no parameters or return value, called each time the
+//                           visitor enters a block.
+// | endScope              - A method with no parameters or return value, called each time the
+//                           visitor leaves a block.
 // | result                - Either a method that takes no parameters or a field. If a method (or
 //                           callable field) get_result calls it, otherwise the value is returned.
Index: src/AST/Pass.impl.hpp
===================================================================
--- src/AST/Pass.impl.hpp	(revision 8e64cb4eabf6a141f302302ee70e6d1934f832ad)
+++ src/AST/Pass.impl.hpp	(revision 1afda5a28cedbdf19c9bd2fdbf8cef4e296b02bc)
@@ -836,10 +836,8 @@
 			if ( enterScope ) {
 				__pass::symtab::enter(core, 0);
-				__pass::scope::enter(core, 0);
 			}
 		}, [this, leaveScope = !this->atFunctionTop]() {
 			if ( leaveScope ) {
 				__pass::symtab::leave(core, 0);
-				__pass::scope::leave(core, 0);
 			}
 		});
Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 8e64cb4eabf6a141f302302ee70e6d1934f832ad)
+++ src/GenPoly/Box.cc	(revision 1afda5a28cedbdf19c9bd2fdbf8cef4e296b02bc)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Dec 13 23:40:34 2019
-// Update Count     : 347
+// Last Modified By : Andrew Beach
+// Last Modified On : Mon Dec 19 16:36:00 2022
+// Update Count     : 348
 //
 
@@ -214,8 +214,5 @@
 		/// sizeof expressions of polymorphic types with the proper variable,
 		/// and strips fields from generic struct declarations.
-		struct Pass3 final : public BoxPass, public WithGuards {
-			template< typename DeclClass >
-			void handleDecl( DeclClass * decl, Type * type );
-
+		struct Pass3 final {
 			void premutate( ObjectDecl * objectDecl );
 			void premutate( FunctionDecl * functionDecl );
@@ -223,7 +220,4 @@
 			void premutate( StructDecl * structDecl );
 			void premutate( UnionDecl * unionDecl );
-			void premutate( TypeDecl * typeDecl );
-			void premutate( PointerType * pointerType );
-			void premutate( FunctionType * funcType );
 		};
 	} // anonymous namespace
@@ -1886,25 +1880,18 @@
 ////////////////////////////////////////// Pass3 ////////////////////////////////////////////////////
 
-		template< typename DeclClass >
-		void Pass3::handleDecl( DeclClass * decl, Type * type ) {
-			GuardScope( scopeTyVars );
-			makeTyVarMap( type, scopeTyVars );
-			ScrubTyVars::scrubAll( decl );
-		}
-
 		void Pass3::premutate( ObjectDecl * objectDecl ) {
-			handleDecl( objectDecl, objectDecl->type );
+			ScrubTyVars::scrubAll( objectDecl );
 		}
 
 		void Pass3::premutate( FunctionDecl * functionDecl ) {
-			handleDecl( functionDecl, functionDecl->type );
+			ScrubTyVars::scrubAll( functionDecl );
 		}
 
 		void Pass3::premutate( TypedefDecl * typedefDecl ) {
-			handleDecl( typedefDecl, typedefDecl->base );
+			ScrubTyVars::scrubAll( typedefDecl );
 		}
 
 		/// Strips the members from a generic aggregate
-		void stripGenericMembers(AggregateDecl * decl) {
+		static void stripGenericMembers( AggregateDecl * decl ) {
 			if ( ! decl->parameters.empty() ) decl->members.clear();
 		}
@@ -1916,18 +1903,4 @@
 		void Pass3::premutate( UnionDecl * unionDecl ) {
 			stripGenericMembers( unionDecl );
-		}
-
-		void Pass3::premutate( TypeDecl * typeDecl ) {
-			addToTyVarMap( typeDecl, scopeTyVars );
-		}
-
-		void Pass3::premutate( PointerType * pointerType ) {
-			GuardScope( scopeTyVars );
-			makeTyVarMap( pointerType, scopeTyVars );
-		}
-
-		void Pass3::premutate( FunctionType * functionType ) {
-			GuardScope( scopeTyVars );
-			makeTyVarMap( functionType, scopeTyVars );
 		}
 	} // anonymous namespace
@@ -1939,3 +1912,2 @@
 // compile-command: "make install" //
 // End: //
-
Index: src/Parser/RunParser.cpp
===================================================================
--- src/Parser/RunParser.cpp	(revision 1afda5a28cedbdf19c9bd2fdbf8cef4e296b02bc)
+++ src/Parser/RunParser.cpp	(revision 1afda5a28cedbdf19c9bd2fdbf8cef4e296b02bc)
@@ -0,0 +1,63 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// RunParser.cpp -- External interface to the parser.
+//
+// Author           : Andrew Beach
+// Created On       : Mon Dec 19 11:00:00 2022
+// Last Modified By : Andrew Beach
+// Last Modified On : Mon Dec 19 11:15:00 2022
+// Update Count     : 0
+//
+
+#include "RunParser.hpp"
+
+#include "Parser/ParseNode.h"               // for DeclarationNode, buildList
+#include "Parser/TypedefTable.h"            // for TypedefTable
+
+// Variables global to the parsing code.
+LinkageSpec::Spec linkage = LinkageSpec::Cforall;
+TypedefTable typedefTable;
+DeclarationNode * parseTree = nullptr;
+
+void parse( FILE * input, LinkageSpec::Spec linkage, bool alwaysExit ) {
+	extern int yyparse( void );
+	extern FILE * yyin;
+	extern int yylineno;
+
+	// Set global information.
+	::linkage = linkage;
+	yyin = input;
+	yylineno = 1;
+
+	int parseStatus = yyparse();
+	fclose( input );
+	if ( alwaysExit || parseStatus != 0 ) {
+		exit( parseStatus );
+	} // if
+} // parse
+
+void dumpParseTree( std::ostream & out ) {
+	parseTree->printList( out );
+	delete parseTree;
+	parseTree = nullptr;
+}
+
+std::list<Declaration *> buildUnit(void) {
+	std::list<Declaration *> translationUnit;
+	buildList( parseTree, translationUnit );
+
+	delete parseTree;
+	parseTree = nullptr;
+
+	return translationUnit;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/Parser/RunParser.hpp
===================================================================
--- src/Parser/RunParser.hpp	(revision 1afda5a28cedbdf19c9bd2fdbf8cef4e296b02bc)
+++ src/Parser/RunParser.hpp	(revision 1afda5a28cedbdf19c9bd2fdbf8cef4e296b02bc)
@@ -0,0 +1,43 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// RunParser.hpp -- External interface to the parser.
+//
+// Author           : Andrew Beach
+// Created On       : Mon Dec 19 10:42:00 2022
+// Last Modified By : Andrew Beach
+// Last Modified On : Mon Dec 19 11:15:00 2022
+// Update Count     : 0
+//
+
+#pragma once
+
+#include <iosfwd>                           // for ostream
+#include <list>                             // for list
+
+#include "SynTree/LinkageSpec.h"            // for Spec
+class Declaration;
+
+// The Parser does not have an enclosing namespace.
+
+/// Parse the contents of the input file, setting the initial linkage to the
+/// value provided. Results are saved to the internal accumulator.
+/// The input file is closed when complete. Exits instead of returning on
+/// error or if alwaysExit is true.
+void parse( FILE * input, LinkageSpec::Spec linkage, bool alwaysExit = false );
+
+/// Drain the internal accumulator of parsed code and print it to the stream.
+void dumpParseTree( std::ostream & );
+
+/// Drain the internal accumulator of parsed code and build a translation
+/// unit from it.
+std::list<Declaration *> buildUnit(void);
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/Parser/module.mk
===================================================================
--- src/Parser/module.mk	(revision 8e64cb4eabf6a141f302302ee70e6d1934f832ad)
+++ src/Parser/module.mk	(revision 1afda5a28cedbdf19c9bd2fdbf8cef4e296b02bc)
@@ -30,4 +30,6 @@
        Parser/parserutility.cc \
        Parser/parserutility.h \
+       Parser/RunParser.cpp \
+       Parser/RunParser.hpp \
        Parser/StatementNode.cc \
        Parser/TypeData.cc \
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 8e64cb4eabf6a141f302302ee70e6d1934f832ad)
+++ src/main.cc	(revision 1afda5a28cedbdf19c9bd2fdbf8cef4e296b02bc)
@@ -59,6 +59,5 @@
 #include "InitTweak/GenInit.h"              // for genInit
 #include "MakeLibCfa.h"                     // for makeLibCfa
-#include "Parser/ParseNode.h"               // for DeclarationNode, buildList
-#include "Parser/TypedefTable.h"            // for TypedefTable
+#include "Parser/RunParser.hpp"             // for buildList, dumpParseTree,...
 #include "ResolvExpr/CandidatePrinter.hpp"  // for printCandidates
 #include "ResolvExpr/Resolver.h"            // for resolve
@@ -109,8 +108,4 @@
 	Stats::Time::StopBlock();
 
-LinkageSpec::Spec linkage = LinkageSpec::Cforall;
-TypedefTable typedefTable;
-DeclarationNode * parseTree = nullptr;					// program parse tree
-
 static bool waiting_for_gdb = false;					// flag to set cfa-cpp to wait for gdb on start
 
@@ -118,5 +113,4 @@
 
 static void parse_cmdline( int argc, char * argv[] );
-static void parse( FILE * input, LinkageSpec::Spec linkage, bool shouldExit = false );
 static void dump( list< Declaration * > & translationUnit, ostream & out = cout );
 static void dump( ast::TranslationUnit && transUnit, ostream & out = cout );
@@ -301,12 +295,9 @@
 
 		if ( parsep ) {
-			parseTree->printList( cout );
-			delete parseTree;
-			return EXIT_SUCCESS;
-		} // if
-
-		buildList( parseTree, translationUnit );
-		delete parseTree;
-		parseTree = nullptr;
+			dumpParseTree( cout );
+			return EXIT_SUCCESS;
+		} // if
+
+		translationUnit = buildUnit();
 
 		if ( astp ) {
@@ -748,20 +739,4 @@
 } // parse_cmdline
 
-static void parse( FILE * input, LinkageSpec::Spec linkage, bool shouldExit ) {
-	extern int yyparse( void );
-	extern FILE * yyin;
-	extern int yylineno;
-
-	::linkage = linkage;								// set globals
-	yyin = input;
-	yylineno = 1;
-	int parseStatus = yyparse();
-
-	fclose( input );
-	if ( shouldExit || parseStatus != 0 ) {
-		exit( parseStatus );
-	} // if
-} // parse
-
 static bool notPrelude( Declaration * decl ) {
 	return ! LinkageSpec::isBuiltin( decl->get_linkage() );
Index: tests/concurrent/pthread/.expect/bounded_buffer.txt
===================================================================
--- tests/concurrent/pthread/.expect/bounded_buffer.txt	(revision 8e64cb4eabf6a141f302302ee70e6d1934f832ad)
+++ tests/concurrent/pthread/.expect/bounded_buffer.txt	(revision 1afda5a28cedbdf19c9bd2fdbf8cef4e296b02bc)
@@ -1,2 +1,2 @@
-producer total value is 23426
-consumer total value is 23426
+producer total value is 24150
+consumer total value is 24150
Index: tests/concurrent/pthread/bounded_buffer.cfa
===================================================================
--- tests/concurrent/pthread/bounded_buffer.cfa	(revision 8e64cb4eabf6a141f302302ee70e6d1934f832ad)
+++ tests/concurrent/pthread/bounded_buffer.cfa	(revision 1afda5a28cedbdf19c9bd2fdbf8cef4e296b02bc)
@@ -63,9 +63,9 @@
 
 void *producer( void *arg ) {
-	Buffer(int) &buf = *(Buffer(int)*)arg;
-	const int NoOfItems = rand() % 40;
+    Buffer(int) &buf = *(Buffer(int)*)arg;
+	const int NoOfItems = prng(*active_thread(), 40);
 	int item;
 	for ( int i = 1; i <= NoOfItems; i += 1 ) {			// produce a bunch of items
-		item = rand() % 100 + 1;						// produce a random number
+		item = prng(*active_thread(), 1, 101);			// produce a random number
 		//sout | "Producer:" | pthread_self() | " value:" | item;
 		insert( buf,item );								// insert element into queue
@@ -101,5 +101,5 @@
     pthread_mutex_init(&consumer_cnt_lock, NULL);
 	// parallelism
-    srandom( 1003 );
+    set_seed( 1003 );
 
 	processor p[5];
