Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision 8a3467770a0171ca9f928918daee8eb73663ff9a)
+++ src/GenPoly/Box.cc	(revision adc67818491910acdb5cc19b5cb49ba6cefce50f)
@@ -385,15 +385,16 @@
 		for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
 			TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param );
-			layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( &paramType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
-			layoutFnType->get_parameters().push_back( new ObjectDecl( alignofName( &paramType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
+			std::string paramName = mangleType( &paramType );
+			layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( paramName ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
+			layoutFnType->get_parameters().push_back( new ObjectDecl( alignofName( paramName ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
 		}
 	}
 
 	/// Builds a layout function declaration
-	FunctionDecl *buildLayoutFunctionDecl( const std::string &typeName, unsigned int functionNesting, FunctionType *layoutFnType ) {
+	FunctionDecl *buildLayoutFunctionDecl( AggregateDecl *typeDecl, unsigned int functionNesting, FunctionType *layoutFnType ) {
 		// Routines at global scope marked "static" to prevent multiple definitions is separate translation units
 		// because each unit generates copies of the default routines for each aggregate.
 		FunctionDecl *layoutDecl = new FunctionDecl(
-			"__layoutof_" + typeName, functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, layoutFnType, new CompoundStmt( noLabels ), true, false );
+			layoutofName( typeDecl ), functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, layoutFnType, new CompoundStmt( noLabels ), true, false );
 		layoutDecl->fixUniqueId();
 		return layoutDecl;
@@ -462,14 +463,14 @@
 		PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
 		
-		ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
+		ObjectDecl *sizeParam = new ObjectDecl( sizeofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
 		layoutFnType->get_parameters().push_back( sizeParam );
-		ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
+		ObjectDecl *alignParam = new ObjectDecl( alignofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
 		layoutFnType->get_parameters().push_back( alignParam );
-		ObjectDecl *offsetParam = new ObjectDecl( "__offsetof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
+		ObjectDecl *offsetParam = new ObjectDecl( offsetofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
 		layoutFnType->get_parameters().push_back( offsetParam );
 		addOtypeParams( layoutFnType, otypeParams );
 
 		// build function decl
-		FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl->get_name(), functionNesting, layoutFnType );
+		FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl, functionNesting, layoutFnType );
 
 		// calculate struct layout in function body
@@ -523,12 +524,12 @@
 		PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
 		
-		ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
+		ObjectDecl *sizeParam = new ObjectDecl( sizeofName( unionDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
 		layoutFnType->get_parameters().push_back( sizeParam );
-		ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
+		ObjectDecl *alignParam = new ObjectDecl( alignofName( unionDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
 		layoutFnType->get_parameters().push_back( alignParam );
 		addOtypeParams( layoutFnType, otypeParams );
 
 		// build function decl
-		FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl->get_name(), functionNesting, layoutFnType );
+		FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl, functionNesting, layoutFnType );
 
 		// calculate union layout in function body
@@ -747,6 +748,6 @@
 			Type *polyBase = hasPolyBase( parmType, exprTyVars );
 			if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
-				std::string sizeName = sizeofName( polyBase );
-				if ( seenTypes.count( sizeName ) ) return;
+				std::string typeName = mangleType( polyBase );
+				if ( seenTypes.count( typeName ) ) return;
 
 				arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) );
@@ -766,5 +767,5 @@
 				}
 
-				seenTypes.insert( sizeName );
+				seenTypes.insert( typeName );
 			}
 		}
@@ -1124,5 +1125,5 @@
 				addAssign->get_args().push_back( appExpr->get_args().front() );
 			} // if
-			addAssign->get_args().push_back( new NameExpr( sizeofName( polyType ) ) );
+			addAssign->get_args().push_back( new NameExpr( sizeofName( mangleType( polyType ) ) ) );
 			addAssign->get_results().front() = appExpr->get_results().front()->clone();
 			if ( appExpr->get_env() ) {
@@ -1151,5 +1152,5 @@
 							UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
 							multiply->get_args().push_back( appExpr->get_args().back() );
-							multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
+							multiply->get_args().push_back( new SizeofExpr( baseType1->clone() ) );
 							ret->get_args().push_back( appExpr->get_args().front() );
 							ret->get_args().push_back( multiply );
@@ -1157,5 +1158,5 @@
 							UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
 							multiply->get_args().push_back( appExpr->get_args().front() );
-							multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) );
+							multiply->get_args().push_back( new SizeofExpr( baseType2->clone() ) );
 							ret->get_args().push_back( multiply );
 							ret->get_args().push_back( appExpr->get_args().back() );
@@ -1220,5 +1221,5 @@
 							UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) );
 							divide->get_args().push_back( appExpr );
-							divide->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
+							divide->get_args().push_back( new SizeofExpr( baseType1->clone() ) );
 							divide->get_results().push_front( appExpr->get_results().front()->clone() );
 							if ( appExpr->get_env() ) {
@@ -1230,10 +1231,10 @@
 							UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
 							multiply->get_args().push_back( appExpr->get_args().back() );
-							multiply->get_args().push_back( new NameExpr( sizeofName( baseType1 ) ) );
+							multiply->get_args().push_back( new SizeofExpr( baseType1->clone() ) );
 							appExpr->get_args().back() = multiply;
 						} else if ( baseType2 ) {
 							UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
 							multiply->get_args().push_back( appExpr->get_args().front() );
-							multiply->get_args().push_back( new NameExpr( sizeofName( baseType2 ) ) );
+							multiply->get_args().push_back( new SizeofExpr( baseType2->clone() ) );
 							appExpr->get_args().front() = multiply;
 						} // if
@@ -1245,5 +1246,5 @@
 							UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
 							multiply->get_args().push_back( appExpr->get_args().back() );
-							multiply->get_args().push_back( new NameExpr( sizeofName( baseType ) ) );
+							multiply->get_args().push_back( new SizeofExpr( baseType->clone() ) );
 							appExpr->get_args().back() = multiply;
 						} // if
@@ -1572,12 +1573,13 @@
 				if ( (*tyParm)->get_kind() == TypeDecl::Any ) {
 					TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm );
+					std::string parmName = mangleType( &parmType );
 
 					sizeParm = newObj.clone();
-					sizeParm->set_name( sizeofName( &parmType ) );
+					sizeParm->set_name( sizeofName( parmName ) );
 					last = funcType->get_parameters().insert( last, sizeParm );
 					++last;
 
 					alignParm = newObj.clone();
-					alignParm->set_name( alignofName( &parmType ) );
+					alignParm->set_name( alignofName( parmName ) );
 					last = funcType->get_parameters().insert( last, alignParm );
 					++last;
@@ -1596,15 +1598,15 @@
 				Type *polyBase = hasPolyBase( (*fnParm)->get_type(), scopeTyVars );
 				if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
-					std::string sizeName = sizeofName( polyBase );
-					if ( seenTypes.count( sizeName ) ) continue;
+					std::string typeName = mangleType( polyBase );
+					if ( seenTypes.count( typeName ) ) continue;
 
 					ObjectDecl *sizeParm, *alignParm, *offsetParm;
 					sizeParm = newObj.clone();
-					sizeParm->set_name( sizeName );
+					sizeParm->set_name( sizeofName( typeName ) );
 					last = funcType->get_parameters().insert( last, sizeParm );
 					++last;
 
 					alignParm = newObj.clone();
-					alignParm->set_name( alignofName( polyBase ) );
+					alignParm->set_name( alignofName( typeName ) );
 					last = funcType->get_parameters().insert( last, alignParm );
 					++last;
@@ -1614,5 +1616,5 @@
 						if ( ! polyBaseStruct->get_baseStruct()->get_members().empty() ) {
 							offsetParm = newPtr.clone();
-							offsetParm->set_name( offsetofName( polyBase ) );
+							offsetParm->set_name( offsetofName( typeName ) );
 							last = funcType->get_parameters().insert( last, offsetParm );
 							++last;
@@ -1620,5 +1622,5 @@
 					}
 
-					seenTypes.insert( sizeName );
+					seenTypes.insert( typeName );
 				}
 			}
@@ -1872,5 +1874,5 @@
 				Type *polyBase = hasPolyBase( (*fnParm)->get_type(), scopeTyVars );
 				if ( polyBase && ! dynamic_cast< TypeInstType* >( polyBase ) ) {
-					knownLayouts.insert( sizeofName( polyBase ) );
+					knownLayouts.insert( mangleType( polyBase ) );
 				}
 			}
@@ -1889,5 +1891,5 @@
 					Type *declType = objectDecl->get_type();
 					UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );
-					alloc->get_args().push_back( new NameExpr( sizeofName( declType ) ) );
+					alloc->get_args().push_back( new NameExpr( sizeofName( mangleType( declType ) ) ) );
 
 					delete objectDecl->get_init();
@@ -1921,5 +1923,5 @@
 			ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) );
 			UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) );
-			fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) );
+			fieldOffset->get_args().push_back( new NameExpr( offsetofName( mangleType( objectType ) ) ) );
 			fieldOffset->get_args().push_back( fieldIndex );
 			return fieldOffset;
@@ -1995,6 +1997,7 @@
 				if ( findGeneric( *param ) ) {
 					// push size/align vars for a generic parameter back
-					layoutCall->get_args().push_back( new NameExpr( sizeofName( *param ) ) );
-					layoutCall->get_args().push_back( new NameExpr( alignofName( *param ) ) );
+					std::string paramName = mangleType( *param );
+					layoutCall->get_args().push_back( new NameExpr( sizeofName( paramName ) ) );
+					layoutCall->get_args().push_back( new NameExpr( alignofName( paramName ) ) );
 				} else {
 					layoutCall->get_args().push_back( new SizeofExpr( (*param)->clone() ) );
@@ -2040,6 +2043,6 @@
 			} else if ( StructInstType *structTy = dynamic_cast< StructInstType* >( ty ) ) {
 				// check if this type already has a layout generated for it
-				std::string sizeName = sizeofName( ty );
-				if ( knownLayouts.find( sizeName ) != knownLayouts.end() ) return true;
+				std::string typeName = mangleType( ty );
+				if ( knownLayouts.find( typeName ) != knownLayouts.end() ) return true;
 
 				// check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized
@@ -2048,5 +2051,5 @@
 
 				// insert local variables for layout and generate call to layout function
-				knownLayouts.insert( sizeName );  // done early so as not to interfere with the later addition of parameters to the layout call
+				knownLayouts.insert( typeName );  // done early so as not to interfere with the later addition of parameters to the layout call
 				Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
 
@@ -2054,14 +2057,14 @@
 				if ( n_members == 0 ) {
 					// all empty structs have the same layout - size 1, align 1
-					makeVar( sizeName, layoutType, new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) );
-					makeVar( alignofName( ty ), layoutType->clone(), new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) );
+					makeVar( sizeofName( typeName ), layoutType, new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) );
+					makeVar( alignofName( typeName ), layoutType->clone(), new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) );
 					// NOTE zero-length arrays are forbidden in C, so empty structs have no offsetof array
 				} else {
-					ObjectDecl *sizeVar = makeVar( sizeName, layoutType );
-					ObjectDecl *alignVar = makeVar( alignofName( ty ), layoutType->clone() );
-					ObjectDecl *offsetVar = makeVar( offsetofName( ty ), new ArrayType( Type::Qualifiers(), layoutType->clone(), new ConstantExpr( Constant::from( n_members ) ), false, false ) );
+					ObjectDecl *sizeVar = makeVar( sizeofName( typeName ), layoutType );
+					ObjectDecl *alignVar = makeVar( alignofName( typeName ), layoutType->clone() );
+					ObjectDecl *offsetVar = makeVar( offsetofName( typeName ), new ArrayType( Type::Qualifiers(), layoutType->clone(), new ConstantExpr( Constant::from( n_members ) ), false, false ) );
 
 					// generate call to layout function
-					UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( "__layoutof_" + structTy->get_baseStruct()->get_name() ) );
+					UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( layoutofName( structTy->get_baseStruct() ) ) );
 					layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) );
 					layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) );
@@ -2075,6 +2078,6 @@
 			} else if ( UnionInstType *unionTy = dynamic_cast< UnionInstType* >( ty ) ) {
 				// check if this type already has a layout generated for it
-				std::string sizeName = sizeofName( ty );
-				if ( knownLayouts.find( sizeName ) != knownLayouts.end() ) return true;
+				std::string typeName = mangleType( ty );
+				if ( knownLayouts.find( typeName ) != knownLayouts.end() ) return true;
 
 				// check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized
@@ -2083,12 +2086,12 @@
 
 				// insert local variables for layout and generate call to layout function
-				knownLayouts.insert( sizeName );  // done early so as not to interfere with the later addition of parameters to the layout call
+				knownLayouts.insert( typeName );  // done early so as not to interfere with the later addition of parameters to the layout call
 				Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
 
-				ObjectDecl *sizeVar = makeVar( sizeName, layoutType );
-				ObjectDecl *alignVar = makeVar( alignofName( ty ), layoutType->clone() );
+				ObjectDecl *sizeVar = makeVar( sizeofName( typeName ), layoutType );
+				ObjectDecl *alignVar = makeVar( alignofName( typeName ), layoutType->clone() );
 
 				// generate call to layout function
-				UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( "__layoutof_" + unionTy->get_baseUnion()->get_name() ) );
+				UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( layoutofName( unionTy->get_baseUnion() ) ) );
 				layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) );
 				layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) );
@@ -2106,5 +2109,5 @@
 			Type *ty = sizeofExpr->get_type();
 			if ( findGeneric( ty ) ) {
-				Expression *ret = new NameExpr( sizeofName( ty ) );
+				Expression *ret = new NameExpr( sizeofName( mangleType( ty ) ) );
 				delete sizeofExpr;
 				return ret;
@@ -2116,5 +2119,5 @@
 			Type *ty = alignofExpr->get_type();
 			if ( findGeneric( ty ) ) {
-				Expression *ret = new NameExpr( alignofName( ty ) );
+				Expression *ret = new NameExpr( alignofName( mangleType( ty ) ) );
 				delete alignofExpr;
 				return ret;
@@ -2154,7 +2157,7 @@
 			if ( findGeneric( ty ) ) {
 				// pull offset back from generated type information
-				ret = new NameExpr( offsetofName( ty ) );
+				ret = new NameExpr( offsetofName( mangleType( ty ) ) );
 			} else {
-				std::string offsetName = offsetofName( ty );
+				std::string offsetName = offsetofName( mangleType( ty ) );
 				if ( knownOffsets.find( offsetName ) != knownOffsets.end() ) {
 					// use the already-generated offsets for this type
@@ -2196,5 +2199,5 @@
 		void PolyGenericCalculator::doEndScope() {
 			knownLayouts.endScope();
-			knownOffsets.beginScope();
+			knownOffsets.endScope();
 		}
 
Index: src/GenPoly/GenPoly.cc
===================================================================
--- src/GenPoly/GenPoly.cc	(revision 8a3467770a0171ca9f928918daee8eb73663ff9a)
+++ src/GenPoly/GenPoly.cc	(revision adc67818491910acdb5cc19b5cb49ba6cefce50f)
@@ -16,5 +16,4 @@
 #include "GenPoly.h"
 
-#include "SymTab/Mangler.h"
 #include "SynTree/Expression.h"
 #include "SynTree/Type.h"
@@ -218,16 +217,4 @@
 	}
 
-	std::string sizeofName( Type *ty ) {
-		return std::string( "_sizeof_" ) + SymTab::Mangler::mangleType( ty );
-	}
-
-	std::string alignofName( Type *ty ) {
-		return std::string( "_alignof_" ) + SymTab::Mangler::mangleType( ty );
-	}
-
-	std::string offsetofName( Type* ty ) {
-		return std::string( "_offsetof_" ) + SymTab::Mangler::mangleType( ty );
-	}
-
 } // namespace GenPoly
 
Index: src/GenPoly/GenPoly.h
===================================================================
--- src/GenPoly/GenPoly.h	(revision 8a3467770a0171ca9f928918daee8eb73663ff9a)
+++ src/GenPoly/GenPoly.h	(revision adc67818491910acdb5cc19b5cb49ba6cefce50f)
@@ -21,4 +21,6 @@
 #include <iostream>
 #include <utility>
+
+#include "SymTab/Mangler.h"
 
 #include "SynTree/Declaration.h"
@@ -69,12 +71,19 @@
 	void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap );
 
-	/// Gets the name of the sizeof parameter for the type
-	std::string sizeofName( Type *ty );
+	/// Gets the mangled name of this type; alias for SymTab::Mangler::mangleType().
+	inline std::string mangleType( Type *ty ) { return SymTab::Mangler::mangleType( ty ); }
+	
+	/// Gets the name of the sizeof parameter for the type, given its mangled name
+	inline std::string sizeofName( const std::string &name ) { return std::string( "_sizeof_" ) + name; }
 
-	/// Gets the name of the alignof parameter for the type
-	std::string alignofName( Type *ty );
+	/// Gets the name of the alignof parameter for the type, given its mangled name
+	inline std::string alignofName( const std::string &name ) { return std::string( "_alignof_" ) + name; }
 
-	/// Gets the name of the offsetof parameter for the type
-	std::string offsetofName( Type *ty );
+	/// Gets the name of the offsetof parameter for the type, given its mangled name
+	inline std::string offsetofName( const std::string &name ) { return std::string( "_offsetof_" ) + name; }
+
+	/// Gets the name of the layout function for a given aggregate type, given its declaration
+	inline std::string layoutofName( AggregateDecl *decl ) { return std::string( "_layoutof_" ) + decl->get_name(); }
+	
 } // namespace GenPoly
 
Index: src/GenPoly/ScrubTyVars.cc
===================================================================
--- src/GenPoly/ScrubTyVars.cc	(revision 8a3467770a0171ca9f928918daee8eb73663ff9a)
+++ src/GenPoly/ScrubTyVars.cc	(revision adc67818491910acdb5cc19b5cb49ba6cefce50f)
@@ -64,5 +64,5 @@
 		// sizeof( T ) => _sizeof_T parameter, which is the size of T
 		if ( Type *polyType = isPolyType( szeof->get_type() ) ) {
-			Expression *expr = new NameExpr( sizeofName( polyType ) );
+			Expression *expr = new NameExpr( sizeofName( mangleType( polyType ) ) );
 			return expr;
 		} else {
@@ -74,5 +74,5 @@
 		// alignof( T ) => _alignof_T parameter, which is the alignment of T
 		if ( Type *polyType = isPolyType( algnof->get_type() ) ) {
-			Expression *expr = new NameExpr( alignofName( polyType ) );
+			Expression *expr = new NameExpr( alignofName( mangleType( polyType ) ) );
 			return expr;
 		} else {
