Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 11947341ab0cf19717b538b36ae3ec940382743f)
+++ src/CodeGen/CodeGenerator.cc	(revision 25a054f2026506f0b8d821cfc29790b22ca54608)
@@ -443,12 +443,21 @@
 	}
 
-	void CodeGenerator::visit( AlignofExpr *sizeofExpr ) {
+	void CodeGenerator::visit( AlignofExpr *alignofExpr ) {
 		// use GCC extension to avoid bumping std to C11
 		output << "__alignof__(";
-		if ( sizeofExpr->get_isType() ) {
-			output << genType( sizeofExpr->get_type(), "" );
-		} else {
-			sizeofExpr->get_expr()->accept( *this );
-		} // if
+		if ( alignofExpr->get_isType() ) {
+			output << genType( alignofExpr->get_type(), "" );
+		} else {
+			alignofExpr->get_expr()->accept( *this );
+		} // if
+		output << ")";
+	}
+
+	void CodeGenerator::visit( OffsetofExpr *offsetofExpr ) {
+		// use GCC builtin
+		output << "__builtin_offsetof(";
+		output << genType( offsetofExpr->get_type(), "" );
+		output << ", ";
+		offsetofExpr->get_member()->accept( *this );
 		output << ")";
 	}
Index: src/CodeGen/CodeGenerator.h
===================================================================
--- src/CodeGen/CodeGenerator.h	(revision 11947341ab0cf19717b538b36ae3ec940382743f)
+++ src/CodeGen/CodeGenerator.h	(revision 25a054f2026506f0b8d821cfc29790b22ca54608)
@@ -61,4 +61,5 @@
 		virtual void visit( SizeofExpr *sizeofExpr );
 		virtual void visit( AlignofExpr *alignofExpr );
+		virtual void visit( OffsetofExpr *offsetofExpr );
 		virtual void visit( LogicalExpr *logicalExpr );
 		virtual void visit( ConditionalExpr *conditionalExpr );
Index: src/InitTweak/InitModel.h
===================================================================
--- src/InitTweak/InitModel.h	(revision 11947341ab0cf19717b538b36ae3ec940382743f)
+++ src/InitTweak/InitModel.h	(revision 25a054f2026506f0b8d821cfc29790b22ca54608)
@@ -73,4 +73,5 @@
 			void visit( SizeofExpr * ) { throw 0; }
 			void visit( AlignofExpr * ) { throw 0; }
+			void visit( OffsetofExpr * ) { throw 0; }
 			void visit( AttrExpr * ) { throw 0; }
 			void visit( LogicalExpr * ) { throw 0; }
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 11947341ab0cf19717b538b36ae3ec940382743f)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 25a054f2026506f0b8d821cfc29790b22ca54608)
@@ -811,4 +811,8 @@
 	}
 
+	void AlternativeFinder::visit( OffsetofExpr *offsetofExpr ) {
+		alternatives.push_back( Alternative( offsetofExpr->clone(), env, Cost::zero ) );
+	}
+
 	void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) {
 		// assume no polymorphism
Index: src/ResolvExpr/AlternativeFinder.h
===================================================================
--- src/ResolvExpr/AlternativeFinder.h	(revision 11947341ab0cf19717b538b36ae3ec940382743f)
+++ src/ResolvExpr/AlternativeFinder.h	(revision 25a054f2026506f0b8d821cfc29790b22ca54608)
@@ -56,5 +56,6 @@
 		virtual void visit( ConstantExpr *constantExpr ); 
 		virtual void visit( SizeofExpr *sizeofExpr );
-		virtual void visit( AlignofExpr *sizeofExpr );
+		virtual void visit( AlignofExpr *alignofExpr );
+		virtual void visit( OffsetofExpr *offsetofExpr );
 		virtual void visit( AttrExpr *attrExpr );
 		virtual void visit( LogicalExpr *logicalExpr );
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision 11947341ab0cf19717b538b36ae3ec940382743f)
+++ src/SymTab/Indexer.cc	(revision 25a054f2026506f0b8d821cfc29790b22ca54608)
@@ -225,4 +225,10 @@
 			maybeAccept( alignofExpr->get_expr(), *this );
 		}
+	}
+
+	void Indexer::visit( OffsetofExpr *offsetofExpr ) {
+		acceptAllNewScope( offsetofExpr->get_results(), *this );
+		maybeAccept( offsetofExpr->get_type(), *this );
+		maybeAccept( offsetofExpr->get_member(), *this );
 	}
 
Index: src/SymTab/Indexer.h
===================================================================
--- src/SymTab/Indexer.h	(revision 11947341ab0cf19717b538b36ae3ec940382743f)
+++ src/SymTab/Indexer.h	(revision 25a054f2026506f0b8d821cfc29790b22ca54608)
@@ -55,4 +55,5 @@
 		virtual void visit( SizeofExpr *sizeofExpr );
 		virtual void visit( AlignofExpr *alignofExpr );
+		virtual void visit( OffsetofExpr *offsetofExpr );
 		virtual void visit( AttrExpr *attrExpr );
 		virtual void visit( LogicalExpr *logicalExpr );
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision 11947341ab0cf19717b538b36ae3ec940382743f)
+++ src/SynTree/Expression.cc	(revision 25a054f2026506f0b8d821cfc29790b22ca54608)
@@ -163,4 +163,38 @@
 }
 
+OffsetofExpr::OffsetofExpr( Type *type_, DeclarationWithType *member_, Expression *_aname ) :
+		Expression( _aname ), type(type_), member(member_) {
+	add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) );
+}
+
+OffsetofExpr::OffsetofExpr( const OffsetofExpr &other ) :
+	Expression( other ), type( maybeClone( other.type ) ), member( maybeClone( other.member ) ) {}
+
+OffsetofExpr::~OffsetofExpr() {
+	delete type;
+	delete member;
+}
+
+void OffsetofExpr::print( std::ostream &os, int indent) const {
+	os << std::string( indent, ' ' ) << "Offsetof Expression on member ";
+
+	if ( member ) {
+		os << member->get_name();
+	} else {
+		os << "<NULL>";
+	}
+
+	os << " of ";
+
+	if ( type ) {
+		type->print(os, indent + 2);
+	} else {
+		os << "<NULL>";
+	}
+
+	os << std::endl;
+	Expression::print( os, indent );
+}
+
 AttrExpr::AttrExpr( Expression *attr, Expression *expr_, Expression *_aname ) :
 		Expression( _aname ), attr( attr ), expr(expr_), type(0), isType(false) {
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 11947341ab0cf19717b538b36ae3ec940382743f)
+++ src/SynTree/Expression.h	(revision 25a054f2026506f0b8d821cfc29790b22ca54608)
@@ -319,4 +319,25 @@
 };
 
+/// OffsetofExpr represents an offsetof expression
+class OffsetofExpr : public Expression {
+  public:
+	OffsetofExpr( Type *type, DeclarationWithType *member, Expression *_aname = 0 );
+	OffsetofExpr( const OffsetofExpr &other );
+	virtual ~OffsetofExpr();
+
+	Type *get_type() const { return type; }
+	void set_type( Type *newValue ) { type = newValue; }
+	DeclarationWithType *get_member() const { return member; }
+	void set_member( DeclarationWithType *newValue ) { member = newValue; }
+
+	virtual OffsetofExpr *clone() const { return new OffsetofExpr( *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;
+	DeclarationWithType *member;
+};
+
 /// AttrExpr represents an @attribute expression (like sizeof, but user-defined)
 class AttrExpr : public Expression {
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision 11947341ab0cf19717b538b36ae3ec940382743f)
+++ src/SynTree/Mutator.cc	(revision 25a054f2026506f0b8d821cfc29790b22ca54608)
@@ -261,4 +261,11 @@
 }
 
+Expression *Mutator::mutate( OffsetofExpr *offsetofExpr ) {
+	mutateAll( offsetofExpr->get_results(), *this );
+	offsetofExpr->set_type( maybeMutate( offsetofExpr->get_type(), *this ) );
+	offsetofExpr->set_member( maybeMutate( offsetofExpr->get_member(), *this ) );
+	return offsetofExpr;
+}
+
 Expression *Mutator::mutate( AttrExpr *attrExpr ) {
 	mutateAll( attrExpr->get_results(), *this );
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision 11947341ab0cf19717b538b36ae3ec940382743f)
+++ src/SynTree/Mutator.h	(revision 25a054f2026506f0b8d821cfc29790b22ca54608)
@@ -65,4 +65,5 @@
 	virtual Expression* mutate( SizeofExpr *sizeofExpr );
 	virtual Expression* mutate( AlignofExpr *alignofExpr );
+	virtual Expression* mutate( OffsetofExpr *offsetofExpr );
 	virtual Expression* mutate( AttrExpr *attrExpr );
 	virtual Expression* mutate( LogicalExpr *logicalExpr );
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision 11947341ab0cf19717b538b36ae3ec940382743f)
+++ src/SynTree/SynTree.h	(revision 25a054f2026506f0b8d821cfc29790b22ca54608)
@@ -70,4 +70,5 @@
 class SizeofExpr;
 class AlignofExpr;
+class OffsetofExpr;
 class AttrExpr;
 class LogicalExpr;
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision 11947341ab0cf19717b538b36ae3ec940382743f)
+++ src/SynTree/Visitor.cc	(revision 25a054f2026506f0b8d821cfc29790b22ca54608)
@@ -219,4 +219,10 @@
 }
 
+void Visitor::visit( OffsetofExpr *offsetofExpr ) {
+	acceptAll( offsetofExpr->get_results(), *this );
+	maybeAccept( offsetofExpr->get_type(), *this );
+	maybeAccept( offsetofExpr->get_member(), *this );
+}
+
 void Visitor::visit( AttrExpr *attrExpr ) {
 	acceptAll( attrExpr->get_results(), *this );
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision 11947341ab0cf19717b538b36ae3ec940382743f)
+++ src/SynTree/Visitor.h	(revision 25a054f2026506f0b8d821cfc29790b22ca54608)
@@ -65,4 +65,5 @@
 	virtual void visit( SizeofExpr *sizeofExpr );
 	virtual void visit( AlignofExpr *alignofExpr );
+	virtual void visit( OffsetofExpr *offsetofExpr );
 	virtual void visit( AttrExpr *attrExpr );
 	virtual void visit( LogicalExpr *logicalExpr );
Index: src/Tuples/FlattenTuple.cc
===================================================================
--- src/Tuples/FlattenTuple.cc	(revision 11947341ab0cf19717b538b36ae3ec940382743f)
+++ src/Tuples/FlattenTuple.cc	(revision 25a054f2026506f0b8d821cfc29790b22ca54608)
@@ -47,4 +47,5 @@
 	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 );  }
Index: src/Tuples/FlattenTuple.h
===================================================================
--- src/Tuples/FlattenTuple.h	(revision 11947341ab0cf19717b538b36ae3ec940382743f)
+++ src/Tuples/FlattenTuple.h	(revision 25a054f2026506f0b8d821cfc29790b22ca54608)
@@ -43,4 +43,5 @@
 			virtual void visit( SizeofExpr * );
 			virtual void visit( AlignofExpr * );
+			virtual void visit( OffsetofExpr * );
 			virtual void visit( AttrExpr * );
 			virtual void visit( LogicalExpr * );
