Index: src/AST/Expr.cpp
===================================================================
--- src/AST/Expr.cpp	(revision 90e683bd043dbecee5fc34eec99bc3d53f59d082)
+++ src/AST/Expr.cpp	(revision 301e9f747c630e38dbcd276c1902135e0f3737aa)
@@ -26,4 +26,5 @@
 #include "Stmt.hpp"
 #include "Type.hpp"
+#include "Util.hpp"                // for TranslationDeps
 #include "TypeSubstitution.hpp"
 #include "Common/Utility.hpp"
@@ -281,20 +282,20 @@
 
 SizeofExpr::SizeofExpr( const CodeLocation & loc, const Type * t )
-: Expr( loc, new BasicType{ BasicKind::LongUnsignedInt } ), type( t ) {}
+: Expr( loc, ast::TranslationDeps::getSizeType() ), type( t ) {}
 
 // --- AlignofExpr
 
 AlignofExpr::AlignofExpr( const CodeLocation & loc, const Type * t )
-: Expr( loc, new BasicType{ BasicKind::LongUnsignedInt } ), type( t ) {}
+: Expr( loc, ast::TranslationDeps::getSizeType() ), type( t ) {}
 
 // --- CountofExpr
 
 CountofExpr::CountofExpr( const CodeLocation & loc, const Type * t )
-: Expr( loc, new BasicType( BasicKind::LongUnsignedInt) ), type( t ) {}
+: Expr( loc, ast::TranslationDeps::getSizeType() ), type( t ) {}
 
 // --- OffsetofExpr
 
 OffsetofExpr::OffsetofExpr( const CodeLocation & loc, const Type * ty, const DeclWithType * mem )
-: Expr( loc, new BasicType{ BasicKind::LongUnsignedInt } ), type( ty ), member( mem ) {
+: Expr( loc, ast::TranslationDeps::getSizeType() ), type( ty ), member( mem ) {
 	assert( type );
 	assert( member );
@@ -305,5 +306,5 @@
 OffsetPackExpr::OffsetPackExpr( const CodeLocation & loc, const StructInstType * ty )
 : Expr( loc, new ArrayType{
-	new BasicType{ BasicKind::LongUnsignedInt }, nullptr, FixedLen, DynamicDim }
+	ast::TranslationDeps::getSizeType(), nullptr, FixedLen, DynamicDim }
 ), type( ty ) {
 	assert( type );
Index: src/AST/Type.hpp
===================================================================
--- src/AST/Type.hpp	(revision 90e683bd043dbecee5fc34eec99bc3d53f59d082)
+++ src/AST/Type.hpp	(revision 301e9f747c630e38dbcd276c1902135e0f3737aa)
@@ -344,5 +344,5 @@
 struct TypeEnvKey;
 
-/// instance of named type alias (typedef or variable)
+/// instance of named type alias (typedef, variable, or even, just after parsing, the name of a struct)
 class TypeInstType final : public BaseInstType {
 public:
Index: src/AST/Util.cpp
===================================================================
--- src/AST/Util.cpp	(revision 90e683bd043dbecee5fc34eec99bc3d53f59d082)
+++ src/AST/Util.cpp	(revision 301e9f747c630e38dbcd276c1902135e0f3737aa)
@@ -22,4 +22,6 @@
 #include "Common/Utility.hpp"
 #include "GenPoly/ScopedSet.hpp"
+#include "Decl.hpp"
+#include "Type.hpp"
 
 #include <vector>
@@ -382,3 +384,30 @@
 }
 
+namespace {
+	const TranslationUnit * transUnit = 0;
+}
+
+void TranslationDeps::evolve( TranslationUnit & u ) {
+	transUnit = &u;
+}
+
+const ast::Type * TranslationDeps::getSizeType() {
+	static const ast::Type * zd_abstract = new TypeInstType{ "size_t", TypeDecl::Kind::Dtype };
+	static const ast::Type * ld_concrete = new BasicType( BasicKind::LongUnsignedInt );
+	if ( ! transUnit ) {
+		// early state
+		// as if `size_t` in program text were freshly parsed
+		return zd_abstract;
+	} else if ( transUnit->global.sizeType ) {
+		// late state, normal run
+		// whatever size_t was defined as
+		return transUnit->global.sizeType;
+	} else {
+		// late state, no prelude (-n)
+		// placeholder: cfa-cpp is being used experimentally, stay out of the way
+		return ld_concrete;
+	}
+}
+
+
 } // namespace ast
Index: src/AST/Util.hpp
===================================================================
--- src/AST/Util.hpp	(revision 90e683bd043dbecee5fc34eec99bc3d53f59d082)
+++ src/AST/Util.hpp	(revision 301e9f747c630e38dbcd276c1902135e0f3737aa)
@@ -16,4 +16,6 @@
 #pragma once
 
+#include "Fwd.hpp"
+
 namespace ast {
 
@@ -22,5 +24,29 @@
 /// Check anything that should always be true of the AST between passes.
 /// Insert this whenever you want additional debugging checks.
-void checkInvariants( TranslationUnit & transUnit );
+void checkInvariants( TranslationUnit & );
+
+/// Maintains an AST-module state for contextual information needed in
+/// ast::* implementations, notably constructors:
+///    early: while parsing, use bootstrap versions
+///    late: once a whole TranslationUnit exists, use its answers
+/// When the program is in the later state, ast::* construcors effectively get
+/// the benefit of WithTranslationUnit, without having to pass them one.
+class TranslationDeps {
+
+    TranslationDeps() = delete;
+
+    friend class SizeofExpr;
+    friend class AlignofExpr;
+    friend class CountofExpr;
+    friend class OffsetofExpr;
+    friend class OffsetPackExpr;
+
+    /// Appropriate return type for built-in expressions that report on sizes
+    static const Type * getSizeType();
+
+  public:
+    /// Transition from early to late states
+    static void evolve( TranslationUnit & );
+};
 
 }
