Index: doc/theses/andrew_beach_MMath/Makefile
===================================================================
--- doc/theses/andrew_beach_MMath/Makefile	(revision cde1bf91c0bfca05aacca4df9ecd39e5629690a5)
+++ doc/theses/andrew_beach_MMath/Makefile	(revision af333e3d0cd105b684c355f254d9b8418a0f2a2c)
@@ -31,4 +31,5 @@
 	${GLOSSARY} ${BUILD}/${BASE}
 	${LATEX} ${BASE}
+	${LATEX} ${BASE}
 
 ${DOC}: ${BUILD}/${DOC}
Index: doc/theses/andrew_beach_MMath/cfalab.sty
===================================================================
--- doc/theses/andrew_beach_MMath/cfalab.sty	(revision cde1bf91c0bfca05aacca4df9ecd39e5629690a5)
+++ doc/theses/andrew_beach_MMath/cfalab.sty	(revision af333e3d0cd105b684c355f254d9b8418a0f2a2c)
@@ -27,17 +27,4 @@
 % Cforall with the forall symbol.
 \newsymbolcmd\CFA{\textsf{C}\raisebox{\depth}{\rotatebox{180}{\textsf{A}}}}
-% C++ with kerning. (No standard number support.)
-\newsymbolcmd\CPP{\textrm{C}\kern-.1em\hbox{+\kern-.25em+}}
-
-% This is executed very early in the \begin{document} code.
-\AtEndPreamble{
-  \@ifpackageloaded{hyperref}{
-    % Convert symbols to pdf compatable forms when required.
-    \pdfstringdefDisableCommands{
-      \def\CFA{CFA}
-      \def\CPP{C++}
-    }
-  }{}
-}
 
 % The CFA listings language. Based off of ANCI C and including GCC extensions.
@@ -85,3 +72,13 @@
     \renewcommand\textunderscore{\csuse{cfalab@textunderscore@#1}}}
 
+% This is executed very early in the \begin{document} code.
+\AtEndPreamble{
+  \@ifpackageloaded{hyperref}{
+    % Convert symbols to pdf compatable forms when required.
+    \pdfstringdefDisableCommands{
+      \def\CFA{CFA}
+    }
+  }{}
+}
+
 \endinput
Index: c/theses/andrew_beach_MMath/existing.tex
===================================================================
--- doc/theses/andrew_beach_MMath/existing.tex	(revision cde1bf91c0bfca05aacca4df9ecd39e5629690a5)
+++ 	(revision )
@@ -1,237 +1,0 @@
-\chapter{\CFA{} Existing Features}
-
-\section{Overloading and extern}
-Cforall has overloading, allowing multiple definitions of the same name to
-be defined.
-
-This also adds name mangling so that the assembly symbols are unique for
-different overloads. For compatability with names in C there is also a
-syntax to diable the name mangling. These unmangled names cannot be overloaded
-but act as the interface between C and \CFA code.
-
-The syntax for disabling mangling is:
-\begin{lstlisting}
-extern "C" {
-    ...
-}
-\end{lstlisting}
-
-To re-enable mangling once it is disabled the syntax is:
-\begin{lstlisting}
-extern "Cforall" {
-    ...
-}
-\end{lstlisting}
-
-Both should occur at the declaration level and effect all the declarations
-in \texttt{...}. Neither care about the state of mangling when they begin
-and will return to that state after the group is finished. So re-enabling
-is only used to nest areas of mangled and unmangled declarations.
-
-\section{References}
-\CFA adds references to C. These are auto-dereferencing pointers and use the
-same syntax as pointers except they use ampersand (\codeCFA{\&}) instead of
-the asterisk (\codeCFA{*}). They can also be constaint or mutable, if they
-are mutable they may be assigned to by using the address-of operator
-(\codeCFA\&) which converts them into a pointer.
-
-\section{Constructors and Destructors}
-
-Both constructors and destructors are operators, which means they are just
-functions with special names. The special names are used to define them and
-may be used to call the functions expicately. The \CFA special names are
-constructed by taking the tokens in the operators and putting \texttt{?} where
-the arguments would go. So multiplication is \texttt{?*?} while dereference
-is \texttt{*?}. This also make it easy to tell the difference between
-pre-fix operations (such as \texttt{++?}) and post-fix operations
-(\texttt{?++}).
-
-The special name for contructors is \texttt{?\{\}}, which comes from the
-initialization syntax in C. The special name for destructors is
-\texttt{\^{}?\{\}}. % I don't like the \^{} symbol but $^\wedge$ isn't better.
-
-Any time a type T goes out of scope the destructor matching
-\codeCFA{void ^?\{\}(T \&);} is called. In theory this is also true of
-primitive types such as \codeCFA{int}, but in practice those are no-ops and
-are usually omitted for optimization.
-
-\section{Polymorphism}
-\CFA uses polymorphism to create functions and types that are defined over
-different types. \CFA polymorphic declarations serve the same role as \CPP
-templates or Java generics.
-
-Polymorphic declaractions start with a forall clause that goes before the
-standard (monomorphic) declaration. These declarations have the same syntax
-except that you may use the names introduced by the forall clause in them.
-
-Forall clauses are written \codeCFA{forall( ... )} where \codeCFA{...} becomes
-the list of polymorphic variables (local type names) and assertions, which
-repersent required operations on those types.
-
-\begin{lstlisting}
-forall(dtype T | { void do_once(T &); })
-void do_twice(T & value) {
-    do_once(value);
-    do_once(value);
-}
-\end{lstlisting}
-
-A polymorphic function can be used in the same way normal functions are.
-The polymorphics variables are filled in with concrete types and the
-assertions are checked. An assertion checked by seeing if that name of that
-type (with all the variables replaced with the concrete types) is defined at
-the the call site.
-
-As an example, even if no function named \codeCFA{do\_once} is not defined
-near the definition of \codeCFA{do\_twice} the following code will work.
-\begin{lstlisting}
-int quadruple(int x) {
-    void do_once(int & y) {
-        y = y * 2;
-    }
-    do_twice(x);
-    return x;
-}
-\end{lstlisting}
-This is not the recommended way to implement a quadruple function but it
-does work. The complier will deduce that \codeCFA{do\_twice}'s T is an
-integer from the argument. It will then look for a definition matching the
-assertion which is the \codeCFA{do\_once} defined within the function. That
-function will be passed in as a function pointer to \codeCFA{do\_twice} and
-called within it.
-
-To avoid typing out long lists of assertions again and again there are also
-traits which collect assertions into convenent packages that can then be used
-in assertion lists instead of all of their components.
-\begin{lstlisting}
-trait done_once(dtype T) {
-    void do_once(T &);
-}
-\end{lstlisting}
-
-After this the forall list in the previous example could instead be written
-with the trait instead of the assertion itself.
-\begin{lstlisting}
-forall(dtype T | done_once(T))
-\end{lstlisting}
-
-Traits can have arbitrary number of assertions in them and are usually used to
-create short hands for, and give descriptive names to, commond groupings of
-assertions.
-
-Polymorphic structures and unions may also be defined by putting a forall
-clause before the declaration. The type variables work the same way except
-are now used in field declaractions instead of parameters and local variables.
-
-\begin{lstlisting}
-forall(dtype T)
-struct node {
-    node(T) * next;
-    T * data;
-}
-\end{lstlisting}
-
-The \codeCFA{node(T)} is a use of a polymorphic structure. Polymorphic types
-must be provided their polymorphic parameters.
-
-There are many other features of polymorphism that have not given here but
-these are the ones used by the exception system.
-
-\section{Concurrency}
-
-\CFA has a number of concurrency features, \codeCFA{thread}s,
-\codeCFA{monitor}s and \codeCFA{mutex} parameters, \codeCFA{coroutine}s and
-\codeCFA{generator}s. The two features that interact with the exception system
-are \codeCFA{thread}s and \codeCFA{coroutine}s; they and their supporting
-constructs will be described here.
-
-\subsection{Coroutines}
-Coroutines are routines that do not have to finish execution to hand control
-back to their caller, instead they may suspend their execution at any time
-and resume it later.
-Coroutines are not true concurrency but share some similarities and many of
-the same underpinnings and so are included as part of the \CFA threading
-library.
-
-In \CFA coroutines are created using the \codeCFA{coroutine} keyword which
-works just like \codeCFA{struct} except that the created structure will be
-modified by the compiler to satify the \codeCFA{is\_coroutine} trait.
-
-These structures act as the interface between callers and the coroutine,
-the fields are used to pass information in and out. Here is a simple example
-where the single field is used to pass the next number in a sequence out.
-\begin{lstlisting}
-coroutine CountUp {
-    unsigned int next;
-}
-\end{lstlisting}
-
-The routine part of the coroutine is a main function for the coroutine. It
-takes a reference to a coroutine object and returns nothing. In this function,
-and any functions called by this function, the suspend statement may be used
-to return execution to the coroutine's caller. When control returns to the
-function it continue from that same suspend statement instead of at the top
-of the function.
-\begin{lstlisting}
-void main(CountUp & this) {
-    unsigned int next = 0;
-    while (true) {
-        this.next = next;
-        suspend;
-        next = next + 1;
-    }
-}
-\end{lstlisting}
-
-Control is passed to the coroutine with the resume function. This includes the
-first time when the coroutine is starting up. The resume function takes a
-reference to the coroutine structure and returns the same reference. The
-return value is for easy access to communication variables. For example the
-next value from a count-up can be generated and collected in a single
-expression: \codeCFA{resume(count).next}.
-
-\subsection{Monitors and Mutex}
-
-True concurrency does not garrenty ordering. To get some of that ordering back
-\CFA uses monitors and mutex (mutual exclution) parameters. A monitor is
-another special declaration that contains a lock and is compatable with mutex
-parameters.
-
-Function parameters can have the \codeCFA{mutex} qualifiers on reference
-arguments, for example \codeCFA{void example(a_monitor & mutex arg);}. When the
-function is called it will acquire the lock on all of the mutex parameters.
-
-This means that all functions that mutex on a type are part of a critical
-section and only one will ever run at a time.
-
-\subsection{Threads}
-While coroutines allow new things to be done with a single execution path
-threads actually introduce new paths of execution that continue independently.
-Now for threads to work together their must be some communication between them
-and that means the timing of certain operations does have to be known. There
-or various means of syncronization and mutual exclution provided by \CFA but
-for exceptions only the basic two -- fork and join -- are needed.
-
-Threads are created like coroutines except the keyword is changed:
-\begin{lstlisting}
-thread StringWorker {
-    const char * input;
-    int result;
-};
-
-void main(StringWorker & this) {
-    const char * localCopy = this.input;
-    // ... do some work, perhaps hashing the string ...
-    this.result = result;
-}
-\end{lstlisting}
-The main function will start executing after the fork operation and continue
-executing until it is finished. If another thread joins with this one it will
-wait until main has completed execution. In other words everything the thread
-does is between fork and join.
-
-From the outside this is the creation and destruction of the thread object.
-Fork happens after the constructor is run and join happens before the
-destructor runs. Join also happens during the \codeCFA{join} function which
-can be used to join a thread earlier. If it is used the destructor does not
-join as that has already been completed.
Index: doc/theses/andrew_beach_MMath/thesis.tex
===================================================================
--- doc/theses/andrew_beach_MMath/thesis.tex	(revision cde1bf91c0bfca05aacca4df9ecd39e5629690a5)
+++ doc/theses/andrew_beach_MMath/thesis.tex	(revision af333e3d0cd105b684c355f254d9b8418a0f2a2c)
@@ -50,8 +50,5 @@
 % MAIN BODY
 %----------------------------------------------------------------------
-\input{existing}
-\input{features}
 \input{unwinding}
-\input{future}
 
 %======================================================================
Index: src/SymTab/Mangler.cc
===================================================================
--- src/SymTab/Mangler.cc	(revision cde1bf91c0bfca05aacca4df9ecd39e5629690a5)
+++ src/SymTab/Mangler.cc	(revision af333e3d0cd105b684c355f254d9b8418a0f2a2c)
@@ -10,6 +10,6 @@
 // Created On       : Sun May 17 21:40:29 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Nov 18 12:01:38 2020
-// Update Count     : 64
+// Last Modified On : Sat Feb 15 13:55:12 2020
+// Update Count     : 33
 //
 #include "Mangler.h"
@@ -65,7 +65,7 @@
 				void postvisit( const QualifiedType * qualType );
 
-				std::string get_mangleName() { return mangleName; }
+				std::string get_mangleName() { return mangleName.str(); }
 			  private:
-				std::string mangleName;         ///< Mangled name being constructed
+				std::ostringstream mangleName;  ///< Mangled name being constructed
 				typedef std::map< std::string, std::pair< int, int > > VarMapType;
 				VarMapType varNums;             ///< Map of type variables to indices
@@ -127,10 +127,10 @@
 					isTopLevel = false;
 				} // if
-				mangleName += Encoding::manglePrefix;
+				mangleName << Encoding::manglePrefix;
 				const CodeGen::OperatorInfo * opInfo = CodeGen::operatorLookup( declaration->get_name() );
 				if ( opInfo ) {
-					mangleName += std::to_string( opInfo->outputName.size() ) + opInfo->outputName;
+					mangleName << opInfo->outputName.size() << opInfo->outputName;
 				} else {
-					mangleName += std::to_string( declaration->name.size() ) + declaration->name;
+					mangleName << declaration->name.size() << declaration->name;
 				} // if
 				maybeAccept( declaration->get_type(), *visitor );
@@ -139,7 +139,7 @@
 					// so they need a different name mangling
 					if ( declaration->get_linkage() == LinkageSpec::AutoGen ) {
-						mangleName += Encoding::autogen;
+						mangleName << Encoding::autogen;
 					} else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) {
-						mangleName += Encoding::intrinsic;
+						mangleName << Encoding::intrinsic;
 					} else {
 						// if we add another kind of overridable function, this has to change
@@ -160,5 +160,5 @@
 			void Mangler_old::postvisit( const VoidType * voidType ) {
 				printQualifiers( voidType );
-				mangleName += Encoding::void_t;
+				mangleName << Encoding::void_t;
 			}
 
@@ -166,5 +166,5 @@
 				printQualifiers( basicType );
 				assertf( basicType->kind < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind );
-				mangleName += Encoding::basicTypes[ basicType->kind ];
+				mangleName << Encoding::basicTypes[ basicType->kind ];
 			}
 
@@ -172,5 +172,5 @@
 				printQualifiers( pointerType );
 				// mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers
-				if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName += Encoding::pointer;
+				if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName << Encoding::pointer;
 				maybeAccept( pointerType->base, *visitor );
 			}
@@ -179,5 +179,5 @@
 				// TODO: encode dimension
 				printQualifiers( arrayType );
-				mangleName += Encoding::array + "0";
+				mangleName << Encoding::array << "0";
 				maybeAccept( arrayType->base, *visitor );
 			}
@@ -204,5 +204,5 @@
 			void Mangler_old::postvisit( const FunctionType * functionType ) {
 				printQualifiers( functionType );
-				mangleName += Encoding::function;
+				mangleName << Encoding::function;
 				// turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters,
 				// since qualifiers on outermost parameter type do not differentiate function types, e.g.,
@@ -211,10 +211,10 @@
 				inFunctionType = true;
 				std::list< Type* > returnTypes = getTypes( functionType->returnVals );
-				if (returnTypes.empty()) mangleName += Encoding::void_t;
+				if (returnTypes.empty()) mangleName << Encoding::void_t;
 				else acceptAll( returnTypes, *visitor );
-				mangleName += "_";
+				mangleName << "_";
 				std::list< Type* > paramTypes = getTypes( functionType->parameters );
 				acceptAll( paramTypes, *visitor );
-				mangleName += "_";
+				mangleName << "_";
 			}
 
@@ -222,10 +222,10 @@
 				printQualifiers( refType );
 
-				mangleName += prefix + std::to_string( refType->name.length() ) + refType->name;
+				mangleName << prefix << refType->name.length() << refType->name;
 
 				if ( mangleGenericParams ) {
 					const std::list< Expression* > & params = refType->parameters;
 					if ( ! params.empty() ) {
-						mangleName += "_";
+						mangleName << "_";
 						for ( const Expression * param : params ) {
 							const TypeExpr * paramType = dynamic_cast< const TypeExpr * >( param );
@@ -233,5 +233,5 @@
 							maybeAccept( paramType->type, *visitor );
 						}
-						mangleName += "_";
+						mangleName << "_";
 					}
 				}
@@ -262,5 +262,5 @@
 					// are first found and prefixing with the appropriate encoding for the type class.
 					assertf( varNum->second.second < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second );
-					mangleName += Encoding::typeVariables[varNum->second.second] + std::to_string( varNum->second.first );
+					mangleName << Encoding::typeVariables[varNum->second.second] << varNum->second.first;
 				} // if
 			}
@@ -268,10 +268,10 @@
 			void Mangler_old::postvisit( const TraitInstType * inst ) {
 				printQualifiers( inst );
-				mangleName += std::to_string( inst->name.size() ) + inst->name;
+				mangleName << inst->name.size() << inst->name;
 			}
 
 			void Mangler_old::postvisit( const TupleType * tupleType ) {
 				printQualifiers( tupleType );
-				mangleName += Encoding::tuple + std::to_string( tupleType->types.size() );
+				mangleName << Encoding::tuple << tupleType->types.size();
 				acceptAll( tupleType->types, *visitor );
 			}
@@ -280,13 +280,13 @@
 				printQualifiers( varArgsType );
 				static const std::string vargs = "__builtin_va_list";
-				mangleName += Encoding::type + std::to_string( vargs.size() ) + vargs;
+				mangleName << Encoding::type << vargs.size() << vargs;
 			}
 
 			void Mangler_old::postvisit( const ZeroType * ) {
-				mangleName += Encoding::zero;
+				mangleName << Encoding::zero;
 			}
 
 			void Mangler_old::postvisit( const OneType * ) {
-				mangleName += Encoding::one;
+				mangleName << Encoding::one;
 			}
 
@@ -296,5 +296,5 @@
 					// N marks the start of a qualified type
 					inQualifiedType = true;
-					mangleName += Encoding::qualifiedTypeStart;
+					mangleName << Encoding::qualifiedTypeStart;
 				}
 				maybeAccept( qualType->parent, *visitor );
@@ -303,5 +303,5 @@
 					// E marks the end of a qualified type
 					inQualifiedType = false;
-					mangleName += Encoding::qualifiedTypeEnd;
+					mangleName << Encoding::qualifiedTypeEnd;
 				}
 			}
@@ -315,5 +315,5 @@
 				assertf(false, "Mangler_old should not visit typedecl: %s", toCString(decl));
 				assertf( decl->kind < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
-				mangleName += Encoding::typeVariables[ decl->kind ] + std::to_string( decl->name.length() ) + decl->name;
+				mangleName << Encoding::typeVariables[ decl->kind ] << ( decl->name.length() ) << decl->name;
 			}
 
@@ -330,5 +330,5 @@
 					std::list< std::string > assertionNames;
 					int dcount = 0, fcount = 0, vcount = 0, acount = 0;
-					mangleName += Encoding::forall;
+					mangleName << Encoding::forall;
 					for ( const TypeDecl * i : type->forall ) {
 						switch ( i->kind ) {
@@ -354,27 +354,26 @@
 						} // for
 					} // for
-					mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_";
-					for(const auto & a : assertionNames) mangleName += a;
-//					std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
-					mangleName += "_";
+					mangleName << dcount << "_" << fcount << "_" << vcount << "_" << acount << "_";
+					std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
+					mangleName << "_";
 				} // if
 				if ( ! inFunctionType ) {
 					// these qualifiers do not distinguish the outermost type of a function parameter
 					if ( type->get_const() ) {
-						mangleName += Encoding::qualifiers.at(Type::Const);
+						mangleName << Encoding::qualifiers.at(Type::Const);
 					} // if
 					if ( type->get_volatile() ) {
-						mangleName += Encoding::qualifiers.at(Type::Volatile);
+						mangleName << Encoding::qualifiers.at(Type::Volatile);
 					} // if
 					// Removed due to restrict not affecting function compatibility in GCC
 					// if ( type->get_isRestrict() ) {
-					// 	mangleName += "E";
+					// 	mangleName << "E";
 					// } // if
 					if ( type->get_atomic() ) {
-						mangleName += Encoding::qualifiers.at(Type::Atomic);
+						mangleName << Encoding::qualifiers.at(Type::Atomic);
 					} // if
 				}
 				if ( type->get_mutex() ) {
-					mangleName += Encoding::qualifiers.at(Type::Mutex);
+					mangleName << Encoding::qualifiers.at(Type::Mutex);
 				} // if
 				if ( inFunctionType ) {
@@ -384,5 +383,5 @@
 				}
 			}
-		} // namespace
+		}	// namespace
 	} // namespace Mangler
 } // namespace SymTab
@@ -418,7 +417,7 @@
 			void postvisit( const ast::QualifiedType * qualType );
 
-			std::string get_mangleName() { return mangleName; }
+			std::string get_mangleName() { return mangleName.str(); }
 		  private:
-			std::string mangleName;         ///< Mangled name being constructed
+			std::ostringstream mangleName;  ///< Mangled name being constructed
 			typedef std::map< std::string, std::pair< int, int > > VarMapType;
 			VarMapType varNums;             ///< Map of type variables to indices
@@ -471,10 +470,10 @@
 				isTopLevel = false;
 			} // if
-			mangleName += Encoding::manglePrefix;
+			mangleName << Encoding::manglePrefix;
 			const CodeGen::OperatorInfo * opInfo = CodeGen::operatorLookup( decl->name );
 			if ( opInfo ) {
-				mangleName += std::to_string( opInfo->outputName.size() ) + opInfo->outputName;
+				mangleName << opInfo->outputName.size() << opInfo->outputName;
 			} else {
-				mangleName += std::to_string( decl->name.size() ) + decl->name;
+				mangleName << decl->name.size() << decl->name;
 			} // if
 			maybeAccept( decl->get_type(), *visitor );
@@ -483,7 +482,7 @@
 				// so they need a different name mangling
 				if ( decl->linkage == ast::Linkage::AutoGen ) {
-					mangleName += Encoding::autogen;
+					mangleName << Encoding::autogen;
 				} else if ( decl->linkage == ast::Linkage::Intrinsic ) {
-					mangleName += Encoding::intrinsic;
+					mangleName << Encoding::intrinsic;
 				} else {
 					// if we add another kind of overridable function, this has to change
@@ -504,5 +503,5 @@
 		void Mangler_new::postvisit( const ast::VoidType * voidType ) {
 			printQualifiers( voidType );
-			mangleName += Encoding::void_t;
+			mangleName << Encoding::void_t;
 		}
 
@@ -510,5 +509,5 @@
 			printQualifiers( basicType );
 			assertf( basicType->kind < ast::BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind );
-			mangleName += Encoding::basicTypes[ basicType->kind ];
+			mangleName << Encoding::basicTypes[ basicType->kind ];
 		}
 
@@ -516,5 +515,5 @@
 			printQualifiers( pointerType );
 			// mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers
-			if ( ! pointerType->base.as<ast::FunctionType>() ) mangleName += Encoding::pointer;
+			if ( ! pointerType->base.as<ast::FunctionType>() ) mangleName << Encoding::pointer;
 			maybe_accept( pointerType->base.get(), *visitor );
 		}
@@ -523,5 +522,5 @@
 			// TODO: encode dimension
 			printQualifiers( arrayType );
-			mangleName += Encoding::array + "0";
+			mangleName << Encoding::array << "0";
 			maybeAccept( arrayType->base.get(), *visitor );
 		}
@@ -546,5 +545,5 @@
 		void Mangler_new::postvisit( const ast::FunctionType * functionType ) {
 			printQualifiers( functionType );
-			mangleName += Encoding::function;
+			mangleName << Encoding::function;
 			// turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters,
 			// since qualifiers on outermost parameter type do not differentiate function types, e.g.,
@@ -552,9 +551,9 @@
 			GuardValue( inFunctionType );
 			inFunctionType = true;
-			if (functionType->returns.empty()) mangleName += Encoding::void_t;
+			if (functionType->returns.empty()) mangleName << Encoding::void_t;
 			else accept_each( functionType->returns, *visitor );
-			mangleName += "_";
+			mangleName << "_";
 			accept_each( functionType->params, *visitor );
-			mangleName += "_";
+			mangleName << "_";
 		}
 
@@ -562,9 +561,9 @@
 			printQualifiers( refType );
 
-			mangleName += prefix + std::to_string( refType->name.length() ) + refType->name;
+			mangleName << prefix << refType->name.length() << refType->name;
 
 			if ( mangleGenericParams ) {
 				if ( ! refType->params.empty() ) {
-					mangleName += "_";
+					mangleName << "_";
 					for ( const ast::Expr * param : refType->params ) {
 						auto paramType = dynamic_cast< const ast::TypeExpr * >( param );
@@ -572,5 +571,5 @@
 						maybeAccept( paramType->type.get(), *visitor );
 					}
-					mangleName += "_";
+					mangleName << "_";
 				}
 			}
@@ -601,5 +600,5 @@
 				// are first found and prefixing with the appropriate encoding for the type class.
 				assertf( varNum->second.second < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second );
-				mangleName += Encoding::typeVariables[varNum->second.second] + std::to_string( varNum->second.first );
+				mangleName << Encoding::typeVariables[varNum->second.second] << varNum->second.first;
 			} // if
 		}
@@ -607,10 +606,10 @@
 		void Mangler_new::postvisit( const ast::TraitInstType * inst ) {
 			printQualifiers( inst );
-			mangleName += std::to_string( inst->name.size() ) + inst->name;
+			mangleName << inst->name.size() << inst->name;
 		}
 
 		void Mangler_new::postvisit( const ast::TupleType * tupleType ) {
 			printQualifiers( tupleType );
-			mangleName += Encoding::tuple + std::to_string( tupleType->types.size() );
+			mangleName << Encoding::tuple << tupleType->types.size();
 			accept_each( tupleType->types, *visitor );
 		}
@@ -619,13 +618,13 @@
 			printQualifiers( varArgsType );
 			static const std::string vargs = "__builtin_va_list";
-			mangleName += Encoding::type + std::to_string( vargs.size() ) + vargs;
+			mangleName << Encoding::type << vargs.size() << vargs;
 		}
 
 		void Mangler_new::postvisit( const ast::ZeroType * ) {
-			mangleName += Encoding::zero;
+			mangleName << Encoding::zero;
 		}
 
 		void Mangler_new::postvisit( const ast::OneType * ) {
-			mangleName += Encoding::one;
+			mangleName << Encoding::one;
 		}
 
@@ -635,5 +634,5 @@
 				// N marks the start of a qualified type
 				inQualifiedType = true;
-				mangleName += Encoding::qualifiedTypeStart;
+				mangleName << Encoding::qualifiedTypeStart;
 			}
 			maybeAccept( qualType->parent.get(), *visitor );
@@ -642,5 +641,5 @@
 				// E marks the end of a qualified type
 				inQualifiedType = false;
-				mangleName += Encoding::qualifiedTypeEnd;
+				mangleName << Encoding::qualifiedTypeEnd;
 			}
 		}
@@ -654,5 +653,5 @@
 			assertf(false, "Mangler_new should not visit typedecl: %s", toCString(decl));
 			assertf( decl->kind < ast::TypeDecl::Kind::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
-			mangleName += Encoding::typeVariables[ decl->kind ] + std::to_string( decl->name.length() ) + decl->name;
+			mangleName << Encoding::typeVariables[ decl->kind ] << ( decl->name.length() ) << decl->name;
 		}
 
@@ -670,5 +669,5 @@
 					std::list< std::string > assertionNames;
 					int dcount = 0, fcount = 0, vcount = 0, acount = 0;
-					mangleName += Encoding::forall;
+					mangleName << Encoding::forall;
 					for ( const ast::TypeDecl * decl : ptype->forall ) {
 						switch ( decl->kind ) {
@@ -694,8 +693,7 @@
 						} // for
 					} // for
-					mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_";
-					for(const auto & a : assertionNames) mangleName += a;
-//					std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
-					mangleName += "_";
+					mangleName << dcount << "_" << fcount << "_" << vcount << "_" << acount << "_";
+					std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
+					mangleName << "_";
 				} // if
 			} // if
@@ -703,19 +701,19 @@
 				// these qualifiers do not distinguish the outermost type of a function parameter
 				if ( type->is_const() ) {
-					mangleName += Encoding::qualifiers.at(Type::Const);
+					mangleName << Encoding::qualifiers.at(Type::Const);
 				} // if
 				if ( type->is_volatile() ) {
-					mangleName += Encoding::qualifiers.at(Type::Volatile);
+					mangleName << Encoding::qualifiers.at(Type::Volatile);
 				} // if
 				// Removed due to restrict not affecting function compatibility in GCC
 				// if ( type->get_isRestrict() ) {
-				// 	mangleName += "E";
+				// 	mangleName << "E";
 				// } // if
 				if ( type->is_atomic() ) {
-					mangleName += Encoding::qualifiers.at(Type::Atomic);
+					mangleName << Encoding::qualifiers.at(Type::Atomic);
 				} // if
 			}
 			if ( type->is_mutex() ) {
-				mangleName += Encoding::qualifiers.at(Type::Mutex);
+				mangleName << Encoding::qualifiers.at(Type::Mutex);
 			} // if
 			if ( inFunctionType ) {
