Index: src/CodeGen/OperatorTable.cc
===================================================================
--- src/CodeGen/OperatorTable.cc	(revision 9cbdc13d9cce278a2500603b5411d55641c59504)
+++ src/CodeGen/OperatorTable.cc	(revision 49ae2bc61cd203a75f4b8322e30ede41a6c617cd)
@@ -9,121 +9,129 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Feb 18 15:55:01 2020
-// Update Count     : 55
+// Last Modified By : Andrew Beach
+// Last Modified On : Fri Nov  3 16:00:00 2023
+// Update Count     : 56
 //
 
-#include <algorithm>  // for any_of
-#include <map>        // for map, _Rb_tree_const_iterator, map<>::const_iterator
-#include <utility>    // for pair
-using namespace std;
+#include "OperatorTable.h"
 
-#include "OperatorTable.h"
-#include "Common/utility.h"
+#include <cassert>         // for assert
+#include <unordered_map>   // for unordered_map
 
 namespace CodeGen {
-	const OperatorInfo CodeGen::tableValues[] = {
-		// inputName symbol   outputName                     friendlyName                  type
-		{	"?[?]",   "",     "_operator_index",             "Index",                      OT_INDEX          },
-		{	"?{}",    "=",    "_constructor",                "Constructor",                OT_CTOR           },
-		{	"^?{}",   "",     "_destructor",                 "Destructor",                 OT_DTOR           },
-		{	"?()",    "",     "_operator_call",              "Call Operator",              OT_CALL           },
-		{	"?++",    "++",   "_operator_postincr",          "Postfix Increment",          OT_POSTFIXASSIGN  },
-		{	"?--",    "--",   "_operator_postdecr",          "Postfix Decrement",          OT_POSTFIXASSIGN  },
-		{	"*?",     "*",    "_operator_deref",             "Dereference",                OT_PREFIX         },
-		{	"+?",     "+",    "_operator_unaryplus",         "Plus",                       OT_PREFIX         },
-		{	"-?",     "-",    "_operator_unaryminus",        "Minus",                      OT_PREFIX         },
-		{	"~?",     "~",    "_operator_bitnot",            "Bitwise Not",                OT_PREFIX         },
-		{	"!?",     "!",    "_operator_lognot",            "Logical Not",                OT_PREFIX         },
-		{	"++?",    "++",   "_operator_preincr",           "Prefix Increment",           OT_PREFIXASSIGN   },
-		{	"--?",    "--",   "_operator_predecr",           "Prefix Decrement",           OT_PREFIXASSIGN   },
-		{	"?\\?",   "\\",   "_operator_exponential",       "Exponentiation",             OT_INFIX          },
-		{	"?*?",    "*",    "_operator_multiply",          "Multiplication",             OT_INFIX          },
-		{	"?/?",    "/",    "_operator_divide",            "Division",                   OT_INFIX          },
-		{	"?%?",    "%",    "_operator_modulus",           "Modulo",                     OT_INFIX          },
-		{	"?+?",    "+",    "_operator_add",               "Addition",                   OT_INFIX          },
-		{	"?-?",    "-",    "_operator_subtract",          "Substraction",               OT_INFIX          },
-		{	"?<<?",   "<<",   "_operator_shiftleft",         "Shift Left",                 OT_INFIX          },
-		{	"?>>?",   ">>",   "_operator_shiftright",        "Shift Right",                OT_INFIX          },
-		{	"?<?",    "<",    "_operator_less",              "Less-than",                  OT_INFIX          },
-		{	"?>?",    ">",    "_operator_greater",           "Greater-than",               OT_INFIX          },
-		{	"?<=?",   "<=",   "_operator_lessequal",         "Less-than-or-Equal",         OT_INFIX          },
-		{	"?>=?",   ">=",   "_operator_greaterequal",      "Greater-than-or-Equal",      OT_INFIX          },
-		{	"?==?",   "==",   "_operator_equal",             "Equality",                   OT_INFIX          },
-		{	"?!=?",   "!=",   "_operator_notequal",          "Not-Equal",                  OT_INFIX          },
-		{	"?&?",    "&",    "_operator_bitand",            "Bitwise And",                OT_INFIX          },
-		{	"?^?",    "^",    "_operator_bitxor",            "Bitwise Xor",                OT_INFIX          },
-		{	"?|?",    "|",    "_operator_bitor",             "Bitwise Or",                 OT_INFIX          },
-		{	"?=?",    "=",    "_operator_assign",            "Assignment",                 OT_INFIXASSIGN    },
-		{	"?\\=?",  "\\=",  "_operator_expassign",         "Exponentiation Assignment",  OT_INFIXASSIGN    },
-		{	"?*=?",   "*=",   "_operator_multassign",        "Multiplication Assignment",  OT_INFIXASSIGN    },
-		{	"?/=?",   "/=",   "_operator_divassign",         "Division Assignment",        OT_INFIXASSIGN    },
-		{	"?%=?",   "%=",   "_operator_modassign",         "Modulo Assignment",          OT_INFIXASSIGN    },
-		{	"?+=?",   "+=",   "_operator_addassign",         "Addition Assignment",        OT_INFIXASSIGN    },
-		{	"?-=?",   "-=",   "_operator_subassign",         "Substrction Assignment",     OT_INFIXASSIGN    },
-		{	"?<<=?",  "<<=",  "_operator_shiftleftassign",   "Shift Left Assignment",      OT_INFIXASSIGN    },
-		{	"?>>=?",  ">>=",  "_operator_shiftrightassign",  "Shift Right Assignment",     OT_INFIXASSIGN    },
-		{	"?&=?",   "&=",   "_operator_bitandassign",      "Bitwise And Assignment",     OT_INFIXASSIGN    },
-		{	"?^=?",   "^=",   "_operator_bitxorassign",      "Bitwise Xor Assignment",     OT_INFIXASSIGN    },
-		{	"?|=?",   "|=",   "_operator_bitorassign",       "Bitwise Or Assignment",      OT_INFIXASSIGN    },
-	}; // tableValues
 
-	std::map< std::string, OperatorInfo > CodeGen::table;
+static const OperatorInfo tableValues[] = {
+	//  inputName symbol  outputName                     friendlyName                  type
+	{	"?[?]",   "",     "_operator_index",             "Index",                      OT_INDEX          },
+	{	"?{}",    "=",    "_constructor",                "Constructor",                OT_CTOR           },
+	{	"^?{}",   "",     "_destructor",                 "Destructor",                 OT_DTOR           },
+	{	"?()",    "",     "_operator_call",              "Call Operator",              OT_CALL           },
+	{	"?++",    "++",   "_operator_postincr",          "Postfix Increment",          OT_POSTFIXASSIGN  },
+	{	"?--",    "--",   "_operator_postdecr",          "Postfix Decrement",          OT_POSTFIXASSIGN  },
+	{	"*?",     "*",    "_operator_deref",             "Dereference",                OT_PREFIX         },
+	{	"+?",     "+",    "_operator_unaryplus",         "Plus",                       OT_PREFIX         },
+	{	"-?",     "-",    "_operator_unaryminus",        "Minus",                      OT_PREFIX         },
+	{	"~?",     "~",    "_operator_bitnot",            "Bitwise Not",                OT_PREFIX         },
+	{	"!?",     "!",    "_operator_lognot",            "Logical Not",                OT_PREFIX         },
+	{	"++?",    "++",   "_operator_preincr",           "Prefix Increment",           OT_PREFIXASSIGN   },
+	{	"--?",    "--",   "_operator_predecr",           "Prefix Decrement",           OT_PREFIXASSIGN   },
+	{	"?\\?",   "\\",   "_operator_exponential",       "Exponentiation",             OT_INFIX          },
+	{	"?*?",    "*",    "_operator_multiply",          "Multiplication",             OT_INFIX          },
+	{	"?/?",    "/",    "_operator_divide",            "Division",                   OT_INFIX          },
+	{	"?%?",    "%",    "_operator_modulus",           "Modulo",                     OT_INFIX          },
+	{	"?+?",    "+",    "_operator_add",               "Addition",                   OT_INFIX          },
+	{	"?-?",    "-",    "_operator_subtract",          "Substraction",               OT_INFIX          },
+	{	"?<<?",   "<<",   "_operator_shiftleft",         "Shift Left",                 OT_INFIX          },
+	{	"?>>?",   ">>",   "_operator_shiftright",        "Shift Right",                OT_INFIX          },
+	{	"?<?",    "<",    "_operator_less",              "Less-than",                  OT_INFIX          },
+	{	"?>?",    ">",    "_operator_greater",           "Greater-than",               OT_INFIX          },
+	{	"?<=?",   "<=",   "_operator_lessequal",         "Less-than-or-Equal",         OT_INFIX          },
+	{	"?>=?",   ">=",   "_operator_greaterequal",      "Greater-than-or-Equal",      OT_INFIX          },
+	{	"?==?",   "==",   "_operator_equal",             "Equality",                   OT_INFIX          },
+	{	"?!=?",   "!=",   "_operator_notequal",          "Not-Equal",                  OT_INFIX          },
+	{	"?&?",    "&",    "_operator_bitand",            "Bitwise And",                OT_INFIX          },
+	{	"?^?",    "^",    "_operator_bitxor",            "Bitwise Xor",                OT_INFIX          },
+	{	"?|?",    "|",    "_operator_bitor",             "Bitwise Or",                 OT_INFIX          },
+	{	"?=?",    "=",    "_operator_assign",            "Assignment",                 OT_INFIXASSIGN    },
+	{	"?\\=?",  "\\=",  "_operator_expassign",         "Exponentiation Assignment",  OT_INFIXASSIGN    },
+	{	"?*=?",   "*=",   "_operator_multassign",        "Multiplication Assignment",  OT_INFIXASSIGN    },
+	{	"?/=?",   "/=",   "_operator_divassign",         "Division Assignment",        OT_INFIXASSIGN    },
+	{	"?%=?",   "%=",   "_operator_modassign",         "Modulo Assignment",          OT_INFIXASSIGN    },
+	{	"?+=?",   "+=",   "_operator_addassign",         "Addition Assignment",        OT_INFIXASSIGN    },
+	{	"?-=?",   "-=",   "_operator_subassign",         "Substrction Assignment",     OT_INFIXASSIGN    },
+	{	"?<<=?",  "<<=",  "_operator_shiftleftassign",   "Shift Left Assignment",      OT_INFIXASSIGN    },
+	{	"?>>=?",  ">>=",  "_operator_shiftrightassign",  "Shift Right Assignment",     OT_INFIXASSIGN    },
+	{	"?&=?",   "&=",   "_operator_bitandassign",      "Bitwise And Assignment",     OT_INFIXASSIGN    },
+	{	"?^=?",   "^=",   "_operator_bitxorassign",      "Bitwise Xor Assignment",     OT_INFIXASSIGN    },
+	{	"?|=?",   "|=",   "_operator_bitorassign",       "Bitwise Or Assignment",      OT_INFIXASSIGN    },
+}; // tableValues
 
-	CodeGen::CodeGen() {
-		enum { numOps = sizeof( tableValues ) / sizeof( OperatorInfo ) };
-		for ( int i = 0; i < numOps; i += 1 ) {
-			table[ tableValues[i].inputName ] = tableValues[i];
-		} // for
+enum { numOps = sizeof( tableValues ) / sizeof( OperatorInfo ) };
+
+const OperatorInfo * operatorLookup( const std::string & inputName ) {
+	// Static information set up:
+	static std::unordered_map<std::string, const OperatorInfo *> inputTable;
+	if ( inputTable.empty() ) for ( const OperatorInfo & op : tableValues ) {
+		inputTable[ op.inputName ] = &op;
 	}
 
-	const OperatorInfo * operatorLookup( const string & funcName ) {
-		if ( funcName.find_first_of( "?^*+-!", 0, 1 ) == string::npos ) return nullptr; // prefilter
-		const OperatorInfo * ret = &CodeGen::table.find( funcName )->second; // must be in the table
-		assert( ret );
-		return ret;
+	if ( inputName.find_first_of( "?^*+-!", 0, 1 ) == std::string::npos ) return nullptr; // prefilter
+	const OperatorInfo * ret = inputTable.find( inputName )->second;
+	// This can only happen if an invalid identifier name has been used.
+	assert( ret );
+	return ret;
+}
+
+bool isOperator( const std::string & inputName ) {
+	return operatorLookup( inputName ) != nullptr;
+}
+
+std::string operatorFriendlyName( const std::string & inputName ) {
+	const OperatorInfo * info = operatorLookup( inputName );
+	if ( info ) return info->friendlyName;
+	return "";
+}
+
+// This is only used in the demangler, so it is smaller (and only maybe slow).
+const OperatorInfo * operatorLookupByOutput( const std::string & outputName ) {
+	if ( '_' != outputName[0] ) return nullptr;
+	for ( const OperatorInfo & op : tableValues ) {
+		if ( outputName == op.outputName ) {
+			return &op;
+		}
 	}
+	return nullptr;
+}
 
-	bool isOperator( const string & funcName ) {
-		return operatorLookup( funcName ) != nullptr;
-	}
+bool isConstructor( const std::string & inputName ) {
+	const OperatorInfo * info = operatorLookup( inputName );
+	if ( info ) return info->type == OT_CTOR;
+	return false;
+}
 
-	string operatorFriendlyName( const string & funcName ) {
-		const OperatorInfo * info = operatorLookup( funcName );
-		if ( info ) return info->friendlyName;
-		return "";
-	}
+bool isDestructor( const std::string & inputName ) {
+	const OperatorInfo * info = operatorLookup( inputName );
+	if ( info ) return info->type == OT_DTOR;
+	return false;
+}
 
-	bool isConstructor( const string & funcName ) {
-		const OperatorInfo * info = operatorLookup( funcName );
-		if ( info ) return info->type == OT_CTOR;
-		return false;
-	}
+bool isCtorDtor( const std::string & inputName ) {
+	const OperatorInfo * info = operatorLookup( inputName );
+	if ( info ) return info->type <= OT_CONSTRUCTOR;
+	return false;
+}
 
-	bool isDestructor( const string & funcName ) {
-		const OperatorInfo * info = operatorLookup( funcName );
-		if ( info ) return info->type == OT_DTOR;
-		return false;
-	}
+bool isAssignment( const std::string & inputName ) {
+	const OperatorInfo * info = operatorLookup( inputName );
+	if ( info ) return info->type > OT_CONSTRUCTOR && info->type <= OT_ASSIGNMENT;
+	return false;
+}
 
-	bool isCtorDtor( const string & funcName ) {
-		const OperatorInfo * info = operatorLookup( funcName );
-		if ( info ) return info->type <= OT_CONSTRUCTOR;
-		return false;
-	}
+bool isCtorDtorAssign( const std::string & inputName ) {
+	const OperatorInfo * info = operatorLookup( inputName );
+	if ( info ) return info->type <= OT_ASSIGNMENT;
+	return false;
+}
 
-	bool isAssignment( const string & funcName ) {
-		const OperatorInfo * info = operatorLookup( funcName );
-		if ( info ) return info->type > OT_CONSTRUCTOR && info->type <= OT_ASSIGNMENT;
-		return false;
-	}
-
-	bool isCtorDtorAssign( const string & funcName ) {
-		const OperatorInfo * info = operatorLookup( funcName );
-		if ( info ) return info->type <= OT_ASSIGNMENT;
-		return false;
-	}
-
-	CodeGen codegen;									// initialize singleton package
 } // namespace CodeGen
 
Index: src/CodeGen/OperatorTable.h
===================================================================
--- src/CodeGen/OperatorTable.h	(revision 9cbdc13d9cce278a2500603b5411d55641c59504)
+++ src/CodeGen/OperatorTable.h	(revision 49ae2bc61cd203a75f4b8322e30ede41a6c617cd)
@@ -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 : Sun Feb 16 08:13:34 2020
-// Update Count     : 26
+// Last Modified By : Andrew Beach
+// Last Modified On : Fri Nov  3 14:53:00 2023
+// Update Count     : 27
 //
 
@@ -17,50 +17,54 @@
 
 #include <string>
-#include <map>
 
 namespace CodeGen {
-	enum OperatorType {
-		OT_CTOR,
-		OT_DTOR,
-		OT_CONSTRUCTOR = OT_DTOR,
-		OT_PREFIXASSIGN,
-		OT_POSTFIXASSIGN,
-		OT_INFIXASSIGN,
-		OT_ASSIGNMENT = OT_INFIXASSIGN,
-		OT_CALL,
-		OT_PREFIX,
-		OT_INFIX,
-		OT_POSTFIX,
-		OT_INDEX,
-		OT_LABELADDRESS,
-		OT_CONSTANT
-	};
 
-	struct OperatorInfo {
-		std::string inputName;
-		std::string symbol;
-		std::string outputName;
-		std::string friendlyName;
-		OperatorType type;
-	};
+enum OperatorType {
+	OT_CTOR,
+	OT_DTOR,
+	OT_CONSTRUCTOR = OT_DTOR,
+	OT_PREFIXASSIGN,
+	OT_POSTFIXASSIGN,
+	OT_INFIXASSIGN,
+	OT_ASSIGNMENT = OT_INFIXASSIGN,
+	OT_CALL,
+	OT_PREFIX,
+	OT_INFIX,
+	OT_POSTFIX,
+	OT_INDEX,
+	OT_LABELADDRESS,
+	OT_CONSTANT
+};
 
-	class CodeGen {
-		friend const OperatorInfo * operatorLookup( const std::string & funcName );
+struct OperatorInfo {
+	// The Cforall special function name.
+	std::string inputName;
+	// The string used when the operator is used as an operator.
+	std::string symbol;
+	// The base name used in the mangled name.
+	std::string outputName;
+	// Human-readable name of the operator.
+	std::string friendlyName;
+	// The type of operator shows how it is used as an operator.
+	OperatorType type;
+};
 
-		static const OperatorInfo tableValues[];
-		static std::map< std::string, OperatorInfo > table;
-	  public:
-		CodeGen();
-	}; // CodeGen
+// Look up the operator (by inputName), return nullptr if no such operator.
+const OperatorInfo * operatorLookup( const std::string & inputName );
+// Is there an operator with this name?
+bool isOperator( const std::string & inputName );
+// Get the friendlyName of the operator with the inputName
+std::string operatorFriendlyName( const std::string & inputName );
+// Get the OperatorInfo with the given outputName, if one exists.
+const OperatorInfo * operatorLookupByOutput( const std::string & outputName );
 
-	bool isOperator( const std::string & funcName );
-	const OperatorInfo * operatorLookup( const std::string & funcName );
-	std::string operatorFriendlyName( const std::string & funcName );
+// Is the operator a constructor, destructor or any form of assignment.
+// (Last two are "or" combinations of the first three.)
+bool isConstructor( const std::string & );
+bool isDestructor( const std::string & );
+bool isAssignment( const std::string & );
+bool isCtorDtor( const std::string & );
+bool isCtorDtorAssign( const std::string & );
 
-	bool isConstructor( const std::string & );
-	bool isDestructor( const std::string & );
-	bool isAssignment( const std::string & );
-	bool isCtorDtor( const std::string & );
-	bool isCtorDtorAssign( const std::string & );
 } // namespace CodeGen
 
