Index: src/GenPoly/Box.cpp
===================================================================
--- src/GenPoly/Box.cpp	(revision 6b95febeb9e053e47da842259eeb662a3ecde74e)
+++ src/GenPoly/Box.cpp	(revision 58eb9250e6207108d230dd7d6311b0c3a9103779)
@@ -42,12 +42,24 @@
 
 /// The layout type is used to represent sizes, alignments and offsets.
-ast::BasicType * makeLayoutType() {
-	return new ast::BasicType( ast::BasicKind::LongUnsignedInt );
+const ast::Type * getLayoutType( const ast::TranslationUnit & transUnit ) {
+	assert( transUnit.global.sizeType.get() );
+	return transUnit.global.sizeType;
 }
 
 /// Fixed version of layout type (just adding a 'C' in C++ style).
-ast::BasicType * makeLayoutCType() {
-	return new ast::BasicType( ast::BasicKind::LongUnsignedInt,
-		ast::CV::Qualifiers( ast::CV::Const ) );
+const ast::Type * getLayoutCType( const ast::TranslationUnit & transUnit ) {
+	// Hack for optimization: don't want to clone every time, but don't want
+	// to hardcode a global-translation-unit assumption here either.  So
+	// cache it: will be fast if there is a single translation unit, but
+	// still correct otherwise.
+	static ast::ptr<ast::Type> lastLayoutType = nullptr;
+	static ast::ptr<ast::Type> lastLayoutCType = nullptr;
+	const ast::Type * curLayoutType = getLayoutType( transUnit );
+	if (lastLayoutType != curLayoutType ) {
+		lastLayoutCType = ast::deepCopy( curLayoutType );
+		add_qualifiers(
+			lastLayoutCType, ast::CV::Qualifiers{ ast::CV::Const } );
+	}
+	return lastLayoutCType;
 }
 
@@ -55,4 +67,5 @@
 /// Adds layout-generation functions to polymorphic types.
 struct LayoutFunctionBuilder final :
+		public ast::WithConstTranslationUnit,
 		public ast::WithDeclsToAdd,
 		public ast::WithShortCircuiting,
@@ -77,5 +90,6 @@
 void addSTypeParams(
 		ast::vector<ast::DeclWithType> & params,
-		ast::vector<ast::TypeDecl> const & sizedParams ) {
+		ast::vector<ast::TypeDecl> const & sizedParams,
+		const ast::TranslationUnit & transUnit ) {
 	for ( ast::ptr<ast::TypeDecl> const & sizedParam : sizedParams ) {
 		ast::TypeInstType inst( sizedParam );
@@ -84,10 +98,10 @@
 			sizedParam->location,
 			sizeofName( paramName ),
-			makeLayoutCType()
+			getLayoutCType( transUnit )
 		) );
 		auto alignParam = new ast::ObjectDecl(
 			sizedParam->location,
 			alignofName( paramName ),
-			makeLayoutCType()
+			getLayoutCType( transUnit )
 		);
 		alignParam->attributes.push_back( new ast::Attribute( "unused" ) );
@@ -96,6 +110,6 @@
 }
 
-ast::Type * makeLayoutOutType() {
-	return new ast::PointerType( makeLayoutType() );
+ast::Type * getLayoutOutType( const ast::TranslationUnit & transUnit ) {
+	return new ast::PointerType( getLayoutType( transUnit ) );
 }
 
@@ -110,14 +124,15 @@
 		CodeLocation const & location, ast::AggregateDecl const * aggr,
 		ast::vector<ast::TypeDecl> const & sizedParams,
-		bool isInFunction, bool isStruct ) {
+		bool isInFunction, bool isStruct,
+		const ast::TranslationUnit & transUnit ) {
 	ast::ObjectDecl * sizeParam = new ast::ObjectDecl(
 		location,
 		sizeofName( aggr->name ),
-		makeLayoutOutType()
+		getLayoutOutType( transUnit )
 	);
 	ast::ObjectDecl * alignParam = new ast::ObjectDecl(
 		location,
 		alignofName( aggr->name ),
-		makeLayoutOutType()
+		getLayoutOutType( transUnit )
 	);
 	ast::ObjectDecl * offsetParam = nullptr;
@@ -127,9 +142,9 @@
 			location,
 			offsetofName( aggr->name ),
-			makeLayoutOutType()
+			getLayoutOutType( transUnit )
 		);
 		params.push_back( offsetParam );
 	}
-	addSTypeParams( params, sizedParams );
+	addSTypeParams( params, sizedParams, transUnit );
 
 	// Routines at global scope marked "static" to prevent multiple
@@ -218,5 +233,5 @@
 	// Build layout function signature.
 	LayoutData layout = buildLayoutFunction(
-		location, decl, sizedParams, isInFunction(), true );
+		location, decl, sizedParams, isInFunction(), true, transUnit() );
 	ast::FunctionDecl * layoutDecl = layout.function;
 	// Also return these or extract them from the parameter list?
@@ -292,5 +307,5 @@
 	// Build layout function signature.
 	LayoutData layout = buildLayoutFunction(
-		location, decl, sizedParams, isInFunction(), false );
+		location, decl, sizedParams, isInFunction(), false, transUnit() );
 	ast::FunctionDecl * layoutDecl = layout.function;
 	// Also return these or extract them from the parameter list?
@@ -1390,5 +1405,6 @@
 /// * Move polymorphic returns in function types to pointer-type parameters.
 /// * Adds type size and assertion parameters to parameter lists.
-struct DeclAdapter final {
+struct DeclAdapter final :
+		public ast::WithConstTranslationUnit {
 	ast::FunctionDecl const * previsit( ast::FunctionDecl const * decl );
 	ast::FunctionDecl const * postvisit( ast::FunctionDecl const * decl );
@@ -1398,8 +1414,9 @@
 
 ast::ObjectDecl * makeObj(
-		CodeLocation const & location, std::string const & name ) {
+		CodeLocation const & location, std::string const & name,
+		const ast::TranslationUnit & transUnit ) {
 	// The size/align parameters may be unused, so add the unused attribute.
 	return new ast::ObjectDecl( location, name,
-		makeLayoutCType(),
+		getLayoutCType( transUnit ),
 		nullptr, ast::Storage::Classes(), ast::Linkage::C, nullptr,
 		{ new ast::Attribute( "unused" ) } );
@@ -1441,8 +1458,10 @@
 			std::string paramName = Mangle::mangleType( &paramType );
 
-			auto sizeParam = makeObj( typeParam->location, sizeofName( paramName ) );
+			auto sizeParam = makeObj(
+				typeParam->location, sizeofName( paramName ), transUnit() );
 			layoutParams.emplace_back( sizeParam );
 
-			auto alignParam = makeObj( typeParam->location, alignofName( paramName ) );
+			auto alignParam = makeObj(
+				typeParam->location, alignofName( paramName ), transUnit() );
 			layoutParams.emplace_back( alignParam );
 		}
@@ -1576,5 +1595,6 @@
 /// * Inserts dynamic calculation of polymorphic type layouts where needed.
 struct PolyGenericCalculator final :
-		public ast::WithConstTypeSubstitution,
+		public ast::WithConstTranslationUnit,
+ 		public ast::WithConstTypeSubstitution,
 		public ast::WithDeclsToAdd,
 		public ast::WithGuards,
@@ -1693,5 +1713,5 @@
 
 	ast::ObjectDecl * sizeDecl = new ast::ObjectDecl( decl->location,
-		sizeofName( typeName ), makeLayoutCType(),
+		sizeofName( typeName ), getLayoutCType( transUnit() ),
 		new ast::SingleInit( decl->location,
 			new ast::SizeofExpr( decl->location, deepCopy( base ) )
@@ -1699,5 +1719,5 @@
 	);
 	ast::ObjectDecl * alignDecl = new ast::ObjectDecl( decl->location,
-		alignofName( typeName ), makeLayoutCType(),
+		alignofName( typeName ), getLayoutCType( transUnit() ),
 		new ast::SingleInit( decl->location,
 			new ast::AlignofExpr( decl->location, deepCopy( base ) )
@@ -1987,5 +2007,5 @@
 	auto offsetArray = makeVar( expr->location, offsetName,
 		new ast::ArrayType(
-			makeLayoutType(),
+			getLayoutType( transUnit() ),
 			ast::ConstantExpr::from_ulong( expr->location, inits.size() ),
 			ast::FixedLen,
@@ -2071,9 +2091,9 @@
 			// All empty structures have the same layout (size 1, align 1).
 			makeVar( location,
-				sizeofName( typeName ), makeLayoutType(),
+				sizeofName( typeName ), getLayoutType( transUnit() ),
 				new ast::SingleInit( location,
 						ast::ConstantExpr::from_ulong( location, 1 ) ) );
 			makeVar( location,
-				alignofName( typeName ), makeLayoutType(),
+				alignofName( typeName ), getLayoutType( transUnit() ),
 				new ast::SingleInit( location,
 						ast::ConstantExpr::from_ulong( location, 1 ) ) );
@@ -2081,11 +2101,11 @@
 		} else {
 			ast::ObjectDecl const * sizeofVar = makeVar( location,
-				sizeofName( typeName ), makeLayoutType(), nullptr );
+				sizeofName( typeName ), getLayoutType( transUnit() ), nullptr );
 			ast::ObjectDecl const * alignofVar = makeVar( location,
-				alignofName( typeName ), makeLayoutType(), nullptr );
+				alignofName( typeName ), getLayoutType( transUnit() ), nullptr );
 			ast::ObjectDecl const * offsetofVar = makeVar( location,
 				offsetofName( typeName ),
 				new ast::ArrayType(
-					makeLayoutType(),
+					getLayoutType( transUnit() ),
 					ast::ConstantExpr::from_int( location, memberCount ),
 					ast::FixedLen,
@@ -2133,7 +2153,7 @@
 
 		ast::ObjectDecl * sizeofVar = makeVar( location,
-			sizeofName( typeName ), makeLayoutType() );
+			sizeofName( typeName ), getLayoutType( transUnit() ) );
 		ast::ObjectDecl * alignofVar = makeVar( location,
-			alignofName( typeName ), makeLayoutType() );
+			alignofName( typeName ), getLayoutType( transUnit() ) );
 
 		ast::UntypedExpr * layoutCall = new ast::UntypedExpr( location,
