Index: src/SymTab/Mangler.cc
===================================================================
--- src/SymTab/Mangler.cc	(revision b9c432fc0d6c9c1f4962af0e77cf031cf584dbf1)
+++ src/SymTab/Mangler.cc	(revision 1a3eab86f23dc0bb8709ff1a369ab2a3e9b1663e)
@@ -35,5 +35,5 @@
 		namespace {
 			/// Mangles names to a unique C identifier
-			struct Mangler : public WithShortCircuiting, public WithVisitorRef<Mangler> {
+			struct Mangler : public WithShortCircuiting, public WithVisitorRef<Mangler>, public WithGuards {
 				Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams );
 				Mangler( const Mangler & ) = delete;
@@ -70,4 +70,5 @@
 				bool typeMode;                  ///< Produce a unique mangled name for a type
 				bool mangleGenericParams;       ///< Include generic parameters in name mangling if true
+				bool inFunctionType = false;    ///< Include type qualifiers if false.
 
 				void mangleDecl( DeclarationWithType *declaration );
@@ -189,6 +190,10 @@
 
 			void Mangler::postvisit( ReferenceType * refType ) {
+				// don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload.
+				// Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.),
+				// by pretending every reference type is a function parameter.
+				GuardValue( inFunctionType );
+				inFunctionType = true;
 				printQualifiers( refType );
-				mangleName << "R";
 				maybeAccept( refType->base, *visitor );
 			}
@@ -206,4 +211,9 @@
 				printQualifiers( functionType );
 				mangleName << "F";
+				// 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.,
+				// void (*)(const int) and void (*)(int) are the same type, but void (*)(const int *) and void (*)(int *) are different
+				GuardValue( inFunctionType );
+				inFunctionType = true;
 				std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() );
 				acceptAll( returnTypes, *visitor );
@@ -304,5 +314,4 @@
 				// skip if not including qualifiers
 				if ( typeMode ) return;
-
 				if ( ! type->get_forall().empty() ) {
 					std::list< std::string > assertionNames;
@@ -337,24 +346,33 @@
 					mangleName << "_";
 				} // if
-				if ( type->get_const() ) {
-					mangleName << "C";
-				} // if
-				if ( type->get_volatile() ) {
-					mangleName << "V";
-				} // if
+				if ( ! inFunctionType ) {
+					// these qualifiers do not distinguish the outermost type of a function parameter
+					if ( type->get_const() ) {
+						mangleName << "C";
+					} // if
+					if ( type->get_volatile() ) {
+						mangleName << "V";
+					} // if
+					// Removed due to restrict not affecting function compatibility in GCC
+					// if ( type->get_isRestrict() ) {
+					// 	mangleName << "E";
+					// } // if
+					if ( type->get_atomic() ) {
+						mangleName << "A";
+					} // if
+				}
 				if ( type->get_mutex() ) {
 					mangleName << "M";
 				} // if
-				// Removed due to restrict not affecting function compatibility in GCC
-		//		if ( type->get_isRestrict() ) {
-		//			mangleName << "E";
-		//		} // if
 				if ( type->get_lvalue() ) {
 					// mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues
 					mangleName << "L";
 				}
-				if ( type->get_atomic() ) {
-					mangleName << "A";
-				} // if
+
+				if ( inFunctionType ) {
+					// turn off inFunctionType so that types can be differentiated for nested qualifiers
+					GuardValue( inFunctionType );
+					inFunctionType = false;
+				}
 			}
 		}	// namespace
