Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision f8b961b2dbd5821dc28db05e5097a385b8179c88)
+++ src/CodeGen/CodeGenerator.cc	(revision 4753415975c6f56302c712e83f72751cbf46c6ad)
@@ -442,4 +442,15 @@
 		output << ")";
 	}
+
+	void CodeGenerator::visit( AlignofExpr *sizeofExpr ) {
+		// 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
+		output << ")";
+	}
   
 	void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
Index: src/CodeGen/CodeGenerator.h
===================================================================
--- src/CodeGen/CodeGenerator.h	(revision f8b961b2dbd5821dc28db05e5097a385b8179c88)
+++ src/CodeGen/CodeGenerator.h	(revision 4753415975c6f56302c712e83f72751cbf46c6ad)
@@ -60,4 +60,5 @@
 		virtual void visit( ConstantExpr *constantExpr ); 
 		virtual void visit( SizeofExpr *sizeofExpr );
+		virtual void visit( AlignofExpr *alignofExpr );
 		virtual void visit( LogicalExpr *logicalExpr );
 		virtual void visit( ConditionalExpr *conditionalExpr );
Index: src/InitTweak/InitModel.h
===================================================================
--- src/InitTweak/InitModel.h	(revision f8b961b2dbd5821dc28db05e5097a385b8179c88)
+++ src/InitTweak/InitModel.h	(revision 4753415975c6f56302c712e83f72751cbf46c6ad)
@@ -72,4 +72,5 @@
 			void visit( ConstantExpr * );
 			void visit( SizeofExpr * ) { throw 0; }
+			void visit( AlignofExpr * ) { throw 0; }
 			void visit( AttrExpr * ) { throw 0; }
 			void visit( LogicalExpr * ) { throw 0; }
Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision f8b961b2dbd5821dc28db05e5097a385b8179c88)
+++ src/Parser/ExpressionNode.cc	(revision 4753415975c6f56302c712e83f72751cbf46c6ad)
@@ -586,8 +586,13 @@
 		}
 	  case OperatorNode::AlignOf:
+		{
+			if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
+				return new AlignofExpr( arg->get_decl()->buildType());
+			} else {
+				return new AlignofExpr( args.front());
+			} // if
+		}
 	  case OperatorNode::SizeOf:
 		{
-/// 	bool isSizeOf = ( op->get_type() == OperatorNode::SizeOf );
-
 			if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
 				return new SizeofExpr( arg->get_decl()->buildType());
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision f8b961b2dbd5821dc28db05e5097a385b8179c88)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 4753415975c6f56302c712e83f72751cbf46c6ad)
@@ -792,4 +792,23 @@
 	}
 
+	void AlternativeFinder::visit( AlignofExpr *alignofExpr ) {
+		if ( alignofExpr->get_isType() ) {
+			alternatives.push_back( Alternative( alignofExpr->clone(), env, Cost::zero ) );
+		} else {
+			// find all alternatives for the argument to sizeof
+			AlternativeFinder finder( indexer, env );
+			finder.find( alignofExpr->get_expr() );
+			// find the lowest cost alternative among the alternatives, otherwise ambiguous
+			AltList winners;
+			findMinCost( finder.alternatives.begin(), finder.alternatives.end(), back_inserter( winners ) );
+			if ( winners.size() != 1 ) {
+				throw SemanticError( "Ambiguous expression in alignof operand: ", alignofExpr->get_expr() );
+			} // if
+			// return the lowest cost alternative for the argument
+			Alternative &choice = winners.front();
+			alternatives.push_back( Alternative( new AlignofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
+		} // if
+	}
+
 	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 f8b961b2dbd5821dc28db05e5097a385b8179c88)
+++ src/ResolvExpr/AlternativeFinder.h	(revision 4753415975c6f56302c712e83f72751cbf46c6ad)
@@ -56,4 +56,5 @@
 		virtual void visit( ConstantExpr *constantExpr ); 
 		virtual void visit( SizeofExpr *sizeofExpr );
+		virtual void visit( AlignofExpr *sizeofExpr );
 		virtual void visit( AttrExpr *attrExpr );
 		virtual void visit( LogicalExpr *logicalExpr );
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision f8b961b2dbd5821dc28db05e5097a385b8179c88)
+++ src/SymTab/Indexer.cc	(revision 4753415975c6f56302c712e83f72751cbf46c6ad)
@@ -215,4 +215,13 @@
 		} else {
 			maybeAccept( sizeofExpr->get_expr(), *this );
+		}
+	}
+
+	void Indexer::visit( AlignofExpr *alignofExpr ) {
+		acceptAllNewScope( alignofExpr->get_results(), *this );
+		if ( alignofExpr->get_isType() ) {
+			maybeAccept( alignofExpr->get_type(), *this );
+		} else {
+			maybeAccept( alignofExpr->get_expr(), *this );
 		}
 	}
Index: src/SymTab/Indexer.h
===================================================================
--- src/SymTab/Indexer.h	(revision f8b961b2dbd5821dc28db05e5097a385b8179c88)
+++ src/SymTab/Indexer.h	(revision 4753415975c6f56302c712e83f72751cbf46c6ad)
@@ -54,4 +54,5 @@
 		virtual void visit( ConstantExpr *constantExpr ); 
 		virtual void visit( SizeofExpr *sizeofExpr );
+		virtual void visit( AlignofExpr *alignofExpr );
 		virtual void visit( AttrExpr *attrExpr );
 		virtual void visit( LogicalExpr *logicalExpr );
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision f8b961b2dbd5821dc28db05e5097a385b8179c88)
+++ src/SynTree/Expression.cc	(revision 4753415975c6f56302c712e83f72751cbf46c6ad)
@@ -122,4 +122,35 @@
 void SizeofExpr::print( std::ostream &os, int indent) const {
 	os << std::string( indent, ' ' ) << "Sizeof Expression on: ";
+
+	if (isType)
+		type->print(os, indent + 2);
+	else
+		expr->print(os, indent + 2);
+
+	os << std::endl;
+	Expression::print( os, indent );
+}
+
+AlignofExpr::AlignofExpr( Expression *expr_, Expression *_aname ) :
+		Expression( _aname ), expr(expr_), type(0), isType(false) {
+	add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) );
+}
+
+AlignofExpr::AlignofExpr( Type *type_, Expression *_aname ) :
+		Expression( _aname ), expr(0), type(type_), isType(true) {
+	add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) );
+}
+
+AlignofExpr::AlignofExpr( const AlignofExpr &other ) :
+	Expression( other ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) {
+}
+
+AlignofExpr::~AlignofExpr() {
+	delete expr;
+	delete type;
+}
+
+void AlignofExpr::print( std::ostream &os, int indent) const {
+	os << std::string( indent, ' ' ) << "Alignof Expression on: ";
 
 	if (isType)
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision f8b961b2dbd5821dc28db05e5097a385b8179c88)
+++ src/SynTree/Expression.h	(revision 4753415975c6f56302c712e83f72751cbf46c6ad)
@@ -23,4 +23,5 @@
 #include "Constant.h"
 
+/// Expression is the root type for all expressions
 class Expression {
   public:
@@ -47,7 +48,6 @@
 };
 
-// ParamEntry contains the i.d. of a declaration and a type that is derived from that declaration,
-// but subject to decay-to-pointer and type parameter renaming
-
+/// ParamEntry contains the i.d. of a declaration and a type that is derived from that declaration,
+/// but subject to decay-to-pointer and type parameter renaming
 struct ParamEntry {
 	ParamEntry(): decl( 0 ), actualType( 0 ), formalType( 0 ), expr( 0 ) {}
@@ -65,7 +65,6 @@
 typedef std::map< UniqueId, ParamEntry > InferredParams;
 
-// ApplicationExpr represents the application of a function to a set of parameters.  This is the
-// result of running an UntypedExpr through the expression analyzer.
-
+/// ApplicationExpr represents the application of a function to a set of parameters.  This is the
+/// result of running an UntypedExpr through the expression analyzer.
 class ApplicationExpr : public Expression {
   public:
@@ -89,8 +88,7 @@
 };
 
-// UntypedExpr represents the application of a function to a set of parameters, but where the
-// particular overload for the function name has not yet been determined.  Most operators are
-// converted into functional form automatically, to permit operator overloading.
-
+/// UntypedExpr represents the application of a function to a set of parameters, but where the
+/// particular overload for the function name has not yet been determined.  Most operators are
+/// converted into functional form automatically, to permit operator overloading.
 class UntypedExpr : public Expression {
   public:
@@ -118,5 +116,5 @@
 };
 
-// this class contains a name whose meaning is still not determined
+/// NameExpr contains a name whose meaning is still not determined
 class NameExpr : public Expression {
   public:
@@ -139,5 +137,5 @@
 // function-call format.
 
-// AddressExpr represents a address-of expression, e.g. &e
+/// AddressExpr represents a address-of expression, e.g. &e
 class AddressExpr : public Expression {
   public:
@@ -174,5 +172,5 @@
 };
 
-// CastExpr represents a type cast expression, e.g. (int)e
+/// CastExpr represents a type cast expression, e.g. (int)e
 class CastExpr : public Expression {
   public:
@@ -193,5 +191,5 @@
 };
 
-// UntypedMemberExpr represents a member selection operation, e.g. q.p before processing by the expression analyzer
+/// UntypedMemberExpr represents a member selection operation, e.g. q.p before processing by the expression analyzer
 class UntypedMemberExpr : public Expression {
   public:
@@ -214,5 +212,5 @@
 };
 
-// MemberExpr represents a member selection operation, e.g. q.p after processing by the expression analyzer
+/// MemberExpr represents a member selection operation, e.g. q.p after processing by the expression analyzer
 class MemberExpr : public Expression {
   public:
@@ -235,5 +233,5 @@
 };
 
-// VariableExpr represents an expression that simply refers to the value of a named variable
+/// VariableExpr represents an expression that simply refers to the value of a named variable
 class VariableExpr : public Expression {
   public:
@@ -253,5 +251,5 @@
 };
 
-// ConstantExpr represents an expression that simply refers to the value of a constant 
+/// ConstantExpr represents an expression that simply refers to the value of a constant 
 class ConstantExpr : public Expression {
   public:
@@ -271,5 +269,5 @@
 };
 
-// SizeofExpr represents a sizeof expression (could be sizeof(int) or sizeof 3+4)
+/// SizeofExpr represents a sizeof expression (could be sizeof(int) or sizeof 3+4)
 class SizeofExpr : public Expression {
   public:
@@ -296,5 +294,30 @@
 };
 
-// AttrExpr represents an @attribute expression (like sizeof, but user-defined)
+/// AlignofExpr represents an alignof expression
+class AlignofExpr : public Expression {
+  public:
+	AlignofExpr( Expression *expr, Expression *_aname = 0 );
+	AlignofExpr( const AlignofExpr &other );
+	AlignofExpr( Type *type, Expression *_aname = 0 );
+	virtual ~AlignofExpr();
+
+	Expression *get_expr() const { return expr; }
+	void set_expr( Expression *newValue ) { expr = newValue; }
+	Type *get_type() const { return type; }
+	void set_type( Type *newValue ) { type = newValue; }
+	bool get_isType() const { return isType; }
+	void set_isType( bool newValue ) { isType = newValue; }
+
+	virtual AlignofExpr *clone() const { return new AlignofExpr( *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:
+	Expression *expr;
+	Type *type;
+	bool isType;
+};
+
+/// AttrExpr represents an @attribute expression (like sizeof, but user-defined)
 class AttrExpr : public Expression {
   public:
@@ -324,5 +347,5 @@
 };
 
-// LogicalExpr represents a short-circuit boolean expression (&& or ||)
+/// LogicalExpr represents a short-circuit boolean expression (&& or ||)
 class LogicalExpr : public Expression {
   public:
@@ -347,5 +370,5 @@
 };
 
-// ConditionalExpr represents the three-argument conditional ( p ? a : b )
+/// ConditionalExpr represents the three-argument conditional ( p ? a : b )
 class ConditionalExpr : public Expression {
   public:
@@ -371,5 +394,5 @@
 };
 
-// CommaExpr represents the sequence operator ( a, b )
+/// CommaExpr represents the sequence operator ( a, b )
 class CommaExpr : public Expression {
   public:
@@ -392,5 +415,5 @@
 };
 
-// TupleExpr represents a tuple expression ( [a, b, c] )
+/// TupleExpr represents a tuple expression ( [a, b, c] )
 class TupleExpr : public Expression {
   public:
@@ -410,5 +433,5 @@
 };
 
-// SolvedTupleExpr represents a TupleExpr whose components have been type-resolved. It is effectively a shell for the code generator to work on
+/// SolvedTupleExpr represents a TupleExpr whose components have been type-resolved. It is effectively a shell for the code generator to work on
 class SolvedTupleExpr : public Expression {
   public:
@@ -428,5 +451,5 @@
 };
 
-// TypeExpr represents a type used in an expression (e.g. as a type generator parameter)
+/// TypeExpr represents a type used in an expression (e.g. as a type generator parameter)
 class TypeExpr : public Expression {
   public:
@@ -446,5 +469,5 @@
 };
 
-// AsmExpr represents a GCC 'asm constraint operand' used in an asm statement: [output] "=f" (result)
+/// AsmExpr represents a GCC 'asm constraint operand' used in an asm statement: [output] "=f" (result)
 class AsmExpr : public Expression {
   public:
@@ -472,5 +495,5 @@
 };
 
-// ValofExpr represents a GCC 'lambda expression'
+/// ValofExpr represents a GCC 'lambda expression'
 class UntypedValofExpr : public Expression {
   public:
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision f8b961b2dbd5821dc28db05e5097a385b8179c88)
+++ src/SynTree/Mutator.cc	(revision 4753415975c6f56302c712e83f72751cbf46c6ad)
@@ -251,4 +251,14 @@
 }
 
+Expression *Mutator::mutate( AlignofExpr *alignofExpr ) {
+	mutateAll( alignofExpr->get_results(), *this );
+	if ( alignofExpr->get_isType() ) {
+		alignofExpr->set_type( maybeMutate( alignofExpr->get_type(), *this ) );
+	} else {
+		alignofExpr->set_expr( maybeMutate( alignofExpr->get_expr(), *this ) );
+	}
+	return alignofExpr;
+}
+
 Expression *Mutator::mutate( AttrExpr *attrExpr ) {
 	mutateAll( attrExpr->get_results(), *this );
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision f8b961b2dbd5821dc28db05e5097a385b8179c88)
+++ src/SynTree/Mutator.h	(revision 4753415975c6f56302c712e83f72751cbf46c6ad)
@@ -64,4 +64,5 @@
 	virtual Expression* mutate( ConstantExpr *constantExpr ); 
 	virtual Expression* mutate( SizeofExpr *sizeofExpr );
+	virtual Expression* mutate( AlignofExpr *alignofExpr );
 	virtual Expression* mutate( AttrExpr *attrExpr );
 	virtual Expression* mutate( LogicalExpr *logicalExpr );
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision f8b961b2dbd5821dc28db05e5097a385b8179c88)
+++ src/SynTree/SynTree.h	(revision 4753415975c6f56302c712e83f72751cbf46c6ad)
@@ -69,4 +69,5 @@
 class ConstantExpr;
 class SizeofExpr;
+class AlignofExpr;
 class AttrExpr;
 class LogicalExpr;
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision f8b961b2dbd5821dc28db05e5097a385b8179c88)
+++ src/SynTree/Visitor.cc	(revision 4753415975c6f56302c712e83f72751cbf46c6ad)
@@ -210,4 +210,13 @@
 }
 
+void Visitor::visit( AlignofExpr *alignofExpr ) {
+	acceptAll( alignofExpr->get_results(), *this );
+	if ( alignofExpr->get_isType() ) {
+		maybeAccept( alignofExpr->get_type(), *this );
+	} else {
+		maybeAccept( alignofExpr->get_expr(), *this );
+	}
+}
+
 void Visitor::visit( AttrExpr *attrExpr ) {
 	acceptAll( attrExpr->get_results(), *this );
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision f8b961b2dbd5821dc28db05e5097a385b8179c88)
+++ src/SynTree/Visitor.h	(revision 4753415975c6f56302c712e83f72751cbf46c6ad)
@@ -64,4 +64,5 @@
 	virtual void visit( ConstantExpr *constantExpr ); 
 	virtual void visit( SizeofExpr *sizeofExpr );
+	virtual void visit( AlignofExpr *alignofExpr );
 	virtual void visit( AttrExpr *attrExpr );
 	virtual void visit( LogicalExpr *logicalExpr );
Index: src/Tuples/FlattenTuple.cc
===================================================================
--- src/Tuples/FlattenTuple.cc	(revision f8b961b2dbd5821dc28db05e5097a385b8179c88)
+++ src/Tuples/FlattenTuple.cc	(revision 4753415975c6f56302c712e83f72751cbf46c6ad)
@@ -46,4 +46,5 @@
 	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( 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 f8b961b2dbd5821dc28db05e5097a385b8179c88)
+++ src/Tuples/FlattenTuple.h	(revision 4753415975c6f56302c712e83f72751cbf46c6ad)
@@ -42,4 +42,5 @@
 			virtual void visit( ConstantExpr * ); 
 			virtual void visit( SizeofExpr * );
+			virtual void visit( AlignofExpr * );
 			virtual void visit( AttrExpr * );
 			virtual void visit( LogicalExpr * );
