Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision b4cd03b740cf2cfe5905750f3587883e5a51a654)
+++ src/CodeGen/CodeGenerator.cc	(revision 4789f44f209a3abbeda0761c6adc954c88a1bff8)
@@ -453,4 +453,8 @@
 	}
 
+	void CodeGenerator::visit( UntypedOffsetofExpr *offsetofExpr ) {
+		assert( false );
+	}
+
 	void CodeGenerator::visit( OffsetofExpr *offsetofExpr ) {
 		// use GCC builtin
Index: src/CodeGen/CodeGenerator.h
===================================================================
--- src/CodeGen/CodeGenerator.h	(revision b4cd03b740cf2cfe5905750f3587883e5a51a654)
+++ src/CodeGen/CodeGenerator.h	(revision 4789f44f209a3abbeda0761c6adc954c88a1bff8)
@@ -61,4 +61,5 @@
 		virtual void visit( SizeofExpr *sizeofExpr );
 		virtual void visit( AlignofExpr *alignofExpr );
+		virtual void visit( UntypedOffsetofExpr *offsetofExpr );
 		virtual void visit( OffsetofExpr *offsetofExpr );
 		virtual void visit( LogicalExpr *logicalExpr );
Index: src/GenPoly/Box.cc
===================================================================
--- src/GenPoly/Box.cc	(revision b4cd03b740cf2cfe5905750f3587883e5a51a654)
+++ src/GenPoly/Box.cc	(revision 4789f44f209a3abbeda0761c6adc954c88a1bff8)
@@ -123,5 +123,6 @@
 		};
 
-		/// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference
+		/// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference;
+		/// also fixes offsetof expressions.
 		class MemberExprFixer : public PolyMutator {
 		  public:
@@ -136,4 +137,5 @@
 			virtual Type *mutate( FunctionType *funcType );
 			virtual Expression *mutate( MemberExpr *memberExpr );
+			virtual Expression *mutate( OffsetofExpr *offsetofExpr );
 		};
 
@@ -1283,4 +1285,39 @@
 		}
 
+		/// Finds the member in the base list that matches the given declaration; returns its index, or -1 if not present
+		long findMember( DeclarationWithType *memberDecl, std::list< Declaration* > &baseDecls ) {
+			long i = 0;
+			for(std::list< Declaration* >::const_iterator decl = baseDecls.begin(); decl != baseDecls.end(); ++decl, ++i ) {
+				if ( memberDecl->get_name() != (*decl)->get_name() ) continue;
+
+				if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) {
+					if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) return i;
+					else continue;
+				} else return i;
+			}
+			return -1;
+		}
+
+		/// Returns an index expression into the offset array for a type
+		Expression *makeOffsetIndex( Type *objectType, long i ) {
+			std::stringstream offset_namer;
+			offset_namer << i;
+			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( fieldIndex );
+			return fieldOffset;
+		}
+
+		/// Returns an expression dereferenced n times
+		Expression *makeDerefdVar( Expression *derefdVar, long n ) {
+			for ( int i = 1; i < n; ++i ) {
+				UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
+				derefExpr->get_args().push_back( derefdVar );
+				derefdVar = derefExpr;
+			}
+			return derefdVar;
+		}
+		
 		Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) {
 			// mutate, exiting early if no longer MemberExpr
@@ -1301,49 +1338,47 @@
 			if ( ! objectType ) return memberExpr;
 
-			// get base aggregate for type so members can be looked up
-			AggregateDecl *memberBase = 0;
 			if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) {
-				memberBase = structType->get_baseStruct();
+				// look up offset index
+				long i = findMember( memberExpr->get_member(), structType->get_baseStruct()->get_members() );
+				if ( i == -1 ) return memberExpr;
+
+				// replace member expression with pointer to base plus offset
+				UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) );
+				fieldLoc->get_args().push_back( makeDerefdVar( varExpr->clone(), varDepth ) );
+				fieldLoc->get_args().push_back( makeOffsetIndex( objectType, i ) );
+
+				delete memberExpr;
+				return fieldLoc;
 			} else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ) ) {
-				memberBase = unionType->get_baseUnion();
+				// union members are all at offset zero, so build appropriately-dereferenced variable
+				Expression *derefdVar = makeDerefdVar( varExpr->clone(), varDepth );
+				delete memberExpr;
+				return derefdVar;
 			} else return memberExpr;
-
-			// look up numeric index of member in base aggregate
-			DeclarationWithType *memberDecl = memberExpr->get_member();
-			std::list< Declaration* > &baseDecls = memberBase->get_members();
-			std::list< Declaration* >::const_iterator decl = baseDecls.begin();
-			unsigned long i = 0;
-			for( ; decl != baseDecls.end(); ++decl, ++i ) {
-				if ( memberDecl->get_name() != (*decl)->get_name() ) continue;
-
-				if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) {
-					if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) break;
-					else continue;
-				} else break;
-			}
-			if ( decl == baseDecls.end() ) return memberExpr;
-
-			// replace member expression with pointer to base plus offset
-			// get offset for field
-			std::stringstream offset_namer;
-			offset_namer << i;
-			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( fieldIndex );
-			// build appropriately-dereferenced variable
-			Expression *derefdVar = varExpr->clone();
-			for ( int i = 1; i < varDepth; ++i ) {
-				UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
-				derefExpr->get_args().push_back( derefdVar );
-				derefdVar = derefExpr;
-			}
-			// add offset to deref'd variable
-			UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) );
-			fieldLoc->get_args().push_back( derefdVar );
-			fieldLoc->get_args().push_back( fieldOffset );
-
-			delete memberExpr;
-			return fieldLoc;
+		}
+
+		Expression *MemberExprFixer::mutate( OffsetofExpr *offsetofExpr ) {
+			// mutate, exiting early if no longer OffsetofExpr
+			Expression *expr = Mutator::mutate( offsetofExpr );
+			offsetofExpr = dynamic_cast< OffsetofExpr* >( expr );
+			if ( ! offsetofExpr ) return expr;
+
+			// only mutate expressions for polymorphic structs/unions
+			Type *ty = isPolyType( offsetofExpr->get_type(), scopeTyVars );
+			if ( ! ty ) return offsetofExpr;
+
+			if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) {
+				// replace offsetof expression by index into offset array
+				long i = findMember( offsetofExpr->get_member(), structType->get_baseStruct()->get_members() );
+				if ( i == -1 ) return offsetofExpr;
+
+				Expression *offsetInd = makeOffsetIndex( ty, i );
+				delete offsetofExpr;
+				return offsetInd;
+			} else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( ty ) ) {
+				// all union members are at offset zero
+				delete offsetofExpr;
+				return new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), std::string("0") ) );
+			} else return offsetofExpr;
 		}
 
Index: src/InitTweak/InitModel.h
===================================================================
--- src/InitTweak/InitModel.h	(revision b4cd03b740cf2cfe5905750f3587883e5a51a654)
+++ src/InitTweak/InitModel.h	(revision 4789f44f209a3abbeda0761c6adc954c88a1bff8)
@@ -73,4 +73,5 @@
 			void visit( SizeofExpr * ) { throw 0; }
 			void visit( AlignofExpr * ) { throw 0; }
+			void visit( UntypedOffsetofExpr * ) { throw 0; }
 			void visit( OffsetofExpr * ) { throw 0; }
 			void visit( AttrExpr * ) { throw 0; }
Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision b4cd03b740cf2cfe5905750f3587883e5a51a654)
+++ src/Parser/ExpressionNode.cc	(revision 4789f44f209a3abbeda0761c6adc954c88a1bff8)
@@ -606,5 +606,12 @@
 	  case OperatorNode::OffsetOf:
 		{
-			assert( false );
+			assert( args.size() == 2 );
+			
+			if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args() ) ) {
+				NameExpr *member = dynamic_cast<NameExpr *>( args.back() );
+				assert( member != 0 );
+
+				return new UntypedOffsetofExpr( arg->get_decl()->buildType(), member->get_name() );
+			} else assert( false );
 		}
 	  case OperatorNode::Attr:
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision b4cd03b740cf2cfe5905750f3587883e5a51a654)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 4789f44f209a3abbeda0761c6adc954c88a1bff8)
@@ -811,4 +811,27 @@
 	}
 
+	template< typename StructOrUnionType >
+	void AlternativeFinder::addOffsetof( StructOrUnionType *aggInst, const std::string &name ) {
+		std::list< Declaration* > members;
+		aggInst->lookup( name, members );
+		for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
+			if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
+				alternatives.push_back( Alternative( new OffsetofExpr( aggInst->clone(), dwt->clone() ), env, Cost::zero ) );
+				renameTypes( alternatives.back().expr );
+			} else {
+				assert( false );
+			}
+		}
+	}
+	
+	void AlternativeFinder::visit( UntypedOffsetofExpr *offsetofExpr ) {
+		AlternativeFinder funcFinder( indexer, env );
+		if ( StructInstType *structInst = dynamic_cast< StructInstType* >( offsetofExpr->get_type() ) ) {
+			addOffsetof( structInst, offsetofExpr->get_member() );
+		} else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( offsetofExpr->get_type() ) ) {
+			addOffsetof( unionInst, offsetofExpr->get_member() );
+		}
+	}
+	
 	void AlternativeFinder::visit( OffsetofExpr *offsetofExpr ) {
 		alternatives.push_back( Alternative( offsetofExpr->clone(), env, Cost::zero ) );
Index: src/ResolvExpr/AlternativeFinder.h
===================================================================
--- src/ResolvExpr/AlternativeFinder.h	(revision b4cd03b740cf2cfe5905750f3587883e5a51a654)
+++ src/ResolvExpr/AlternativeFinder.h	(revision 4789f44f209a3abbeda0761c6adc954c88a1bff8)
@@ -57,4 +57,5 @@
 		virtual void visit( SizeofExpr *sizeofExpr );
 		virtual void visit( AlignofExpr *alignofExpr );
+		virtual void visit( UntypedOffsetofExpr *offsetofExpr );
 		virtual void visit( OffsetofExpr *offsetofExpr );
 		virtual void visit( AttrExpr *attrExpr );
@@ -68,5 +69,8 @@
 
 	  private:
+		/// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member
 		template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const std::string &name );
+		/// Adds alternatives for offsetof expressions, given the base type and name of the member
+		template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name );
 		bool instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave );
 		template< typename OutputIterator >
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision b4cd03b740cf2cfe5905750f3587883e5a51a654)
+++ src/SymTab/Indexer.cc	(revision 4789f44f209a3abbeda0761c6adc954c88a1bff8)
@@ -225,4 +225,9 @@
 			maybeAccept( alignofExpr->get_expr(), *this );
 		}
+	}
+
+	void Indexer::visit( UntypedOffsetofExpr *offsetofExpr ) {
+		acceptAllNewScope( offsetofExpr->get_results(), *this );
+		maybeAccept( offsetofExpr->get_type(), *this );
 	}
 
Index: src/SymTab/Indexer.h
===================================================================
--- src/SymTab/Indexer.h	(revision b4cd03b740cf2cfe5905750f3587883e5a51a654)
+++ src/SymTab/Indexer.h	(revision 4789f44f209a3abbeda0761c6adc954c88a1bff8)
@@ -55,4 +55,5 @@
 		virtual void visit( SizeofExpr *sizeofExpr );
 		virtual void visit( AlignofExpr *alignofExpr );
+		virtual void visit( UntypedOffsetofExpr *offsetofExpr );
 		virtual void visit( OffsetofExpr *offsetofExpr );
 		virtual void visit( AttrExpr *attrExpr );
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision b4cd03b740cf2cfe5905750f3587883e5a51a654)
+++ src/SynTree/Expression.cc	(revision 4789f44f209a3abbeda0761c6adc954c88a1bff8)
@@ -163,4 +163,29 @@
 }
 
+UntypedOffsetofExpr::UntypedOffsetofExpr( Type *type_, const std::string &member_, Expression *_aname ) :
+		Expression( _aname ), type(type_), member(member_) {
+	add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
+}
+
+UntypedOffsetofExpr::UntypedOffsetofExpr( const UntypedOffsetofExpr &other ) :
+	Expression( other ), type( maybeClone( other.type ) ), member( other.member ) {}
+
+UntypedOffsetofExpr::~UntypedOffsetofExpr() {
+	delete type;
+}
+
+void UntypedOffsetofExpr::print( std::ostream &os, int indent) const {
+	os << std::string( indent, ' ' ) << "Untyped Offsetof Expression on member " << member << " of ";
+
+	if ( type ) {
+		type->print(os, indent + 2);
+	} else {
+		os << "<NULL>";
+	}
+
+	os << std::endl;
+	Expression::print( os, indent );
+}
+
 OffsetofExpr::OffsetofExpr( Type *type_, DeclarationWithType *member_, Expression *_aname ) :
 		Expression( _aname ), type(type_), member(member_) {
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision b4cd03b740cf2cfe5905750f3587883e5a51a654)
+++ src/SynTree/Expression.h	(revision 4789f44f209a3abbeda0761c6adc954c88a1bff8)
@@ -319,4 +319,25 @@
 };
 
+/// UntypedOffsetofExpr represents an offsetof expression before resolution
+class UntypedOffsetofExpr : public Expression {
+  public:
+	UntypedOffsetofExpr( Type *type, const std::string &member, Expression *_aname = 0 );
+	UntypedOffsetofExpr( const UntypedOffsetofExpr &other );
+	virtual ~UntypedOffsetofExpr();
+
+	std::string get_member() const { return member; }
+	void set_member( const std::string &newValue ) { member = newValue; }
+	Type *get_type() const { return type; }
+	void set_type( Type *newValue ) { type = newValue; }
+
+	virtual UntypedOffsetofExpr *clone() const { return new UntypedOffsetofExpr( *this ); }
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const;
+  private:
+	Type *type;
+	std::string member;
+};
+
 /// OffsetofExpr represents an offsetof expression
 class OffsetofExpr : public Expression {
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision b4cd03b740cf2cfe5905750f3587883e5a51a654)
+++ src/SynTree/Mutator.cc	(revision 4789f44f209a3abbeda0761c6adc954c88a1bff8)
@@ -261,4 +261,10 @@
 }
 
+Expression *Mutator::mutate( UntypedOffsetofExpr *offsetofExpr ) {
+	mutateAll( offsetofExpr->get_results(), *this );
+	offsetofExpr->set_type( maybeMutate( offsetofExpr->get_type(), *this ) );
+	return offsetofExpr;
+}
+
 Expression *Mutator::mutate( OffsetofExpr *offsetofExpr ) {
 	mutateAll( offsetofExpr->get_results(), *this );
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision b4cd03b740cf2cfe5905750f3587883e5a51a654)
+++ src/SynTree/Mutator.h	(revision 4789f44f209a3abbeda0761c6adc954c88a1bff8)
@@ -65,4 +65,5 @@
 	virtual Expression* mutate( SizeofExpr *sizeofExpr );
 	virtual Expression* mutate( AlignofExpr *alignofExpr );
+	virtual Expression* mutate( UntypedOffsetofExpr *offsetofExpr );
 	virtual Expression* mutate( OffsetofExpr *offsetofExpr );
 	virtual Expression* mutate( AttrExpr *attrExpr );
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision b4cd03b740cf2cfe5905750f3587883e5a51a654)
+++ src/SynTree/SynTree.h	(revision 4789f44f209a3abbeda0761c6adc954c88a1bff8)
@@ -70,4 +70,5 @@
 class SizeofExpr;
 class AlignofExpr;
+class UntypedOffsetofExpr;
 class OffsetofExpr;
 class AttrExpr;
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision b4cd03b740cf2cfe5905750f3587883e5a51a654)
+++ src/SynTree/Visitor.cc	(revision 4789f44f209a3abbeda0761c6adc954c88a1bff8)
@@ -219,4 +219,9 @@
 }
 
+void Visitor::visit( UntypedOffsetofExpr *offsetofExpr ) {
+	acceptAll( offsetofExpr->get_results(), *this );
+	maybeAccept( offsetofExpr->get_type(), *this );
+}
+
 void Visitor::visit( OffsetofExpr *offsetofExpr ) {
 	acceptAll( offsetofExpr->get_results(), *this );
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision b4cd03b740cf2cfe5905750f3587883e5a51a654)
+++ src/SynTree/Visitor.h	(revision 4789f44f209a3abbeda0761c6adc954c88a1bff8)
@@ -65,4 +65,5 @@
 	virtual void visit( SizeofExpr *sizeofExpr );
 	virtual void visit( AlignofExpr *alignofExpr );
+	virtual void visit( UntypedOffsetofExpr *offsetofExpr );
 	virtual void visit( OffsetofExpr *offsetofExpr );
 	virtual void visit( AttrExpr *attrExpr );
Index: src/Tuples/FlattenTuple.cc
===================================================================
--- src/Tuples/FlattenTuple.cc	(revision b4cd03b740cf2cfe5905750f3587883e5a51a654)
+++ src/Tuples/FlattenTuple.cc	(revision 4789f44f209a3abbeda0761c6adc954c88a1bff8)
@@ -37,21 +37,22 @@
 	}
 
-	void FlattenTuple::CollectArgs::visit( UntypedExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
-	void FlattenTuple::CollectArgs::visit( NameExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
-	void FlattenTuple::CollectArgs::visit( CastExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
-	void FlattenTuple::CollectArgs::visit( AddressExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
-	void FlattenTuple::CollectArgs::visit( UntypedMemberExpr *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
-	void FlattenTuple::CollectArgs::visit( MemberExpr        *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
-	void FlattenTuple::CollectArgs::visit( VariableExpr      *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
-	void FlattenTuple::CollectArgs::visit( ConstantExpr      *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
-	void FlattenTuple::CollectArgs::visit( SizeofExpr        *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
-	void FlattenTuple::CollectArgs::visit( AlignofExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
-	void FlattenTuple::CollectArgs::visit( OffsetofExpr      *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
-	void FlattenTuple::CollectArgs::visit( AttrExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
-	void FlattenTuple::CollectArgs::visit( LogicalExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
-	void FlattenTuple::CollectArgs::visit( ConditionalExpr   *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
-	void FlattenTuple::CollectArgs::visit( CommaExpr         *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
-	void FlattenTuple::CollectArgs::visit( TypeExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
-	void FlattenTuple::CollectArgs::visit( UntypedValofExpr  *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+	void FlattenTuple::CollectArgs::visit( UntypedExpr         *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+	void FlattenTuple::CollectArgs::visit( NameExpr            *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+	void FlattenTuple::CollectArgs::visit( CastExpr            *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+	void FlattenTuple::CollectArgs::visit( AddressExpr         *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+	void FlattenTuple::CollectArgs::visit( UntypedMemberExpr   *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+	void FlattenTuple::CollectArgs::visit( MemberExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+	void FlattenTuple::CollectArgs::visit( VariableExpr        *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+	void FlattenTuple::CollectArgs::visit( ConstantExpr        *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+	void FlattenTuple::CollectArgs::visit( SizeofExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+	void FlattenTuple::CollectArgs::visit( AlignofExpr         *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+	void FlattenTuple::CollectArgs::visit( UntypedOffsetofExpr *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+	void FlattenTuple::CollectArgs::visit( OffsetofExpr        *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+	void FlattenTuple::CollectArgs::visit( AttrExpr            *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+	void FlattenTuple::CollectArgs::visit( LogicalExpr         *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+	void FlattenTuple::CollectArgs::visit( ConditionalExpr     *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+	void FlattenTuple::CollectArgs::visit( CommaExpr           *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+	void FlattenTuple::CollectArgs::visit( TypeExpr            *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
+	void FlattenTuple::CollectArgs::visit( UntypedValofExpr    *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
 
 	void FlattenTuple::CollectArgs::visit( TupleExpr *tupleExpr) {
Index: src/Tuples/FlattenTuple.h
===================================================================
--- src/Tuples/FlattenTuple.h	(revision b4cd03b740cf2cfe5905750f3587883e5a51a654)
+++ src/Tuples/FlattenTuple.h	(revision 4789f44f209a3abbeda0761c6adc954c88a1bff8)
@@ -43,4 +43,5 @@
 			virtual void visit( SizeofExpr * );
 			virtual void visit( AlignofExpr * );
+			virtual void visit( UntypedOffsetofExpr * );
 			virtual void visit( OffsetofExpr * );
 			virtual void visit( AttrExpr * );
