Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision 3d2b7bc8ab86d81a629447f35c464695613e0057)
+++ src/Common/PassVisitor.h	(revision f6e3e345e94a983a197c49451c099ac2783fca51)
@@ -66,4 +66,5 @@
 	virtual void visit( TypedefDecl * typeDecl ) override final;
 	virtual void visit( AsmDecl * asmDecl ) override final;
+	virtual void visit( StaticAssertDecl * assertDecl ) override final;
 
 	virtual void visit( CompoundStmt * compoundStmt ) override final;
@@ -161,4 +162,5 @@
 	virtual Declaration * mutate( TypedefDecl * typeDecl ) override final;
 	virtual AsmDecl * mutate( AsmDecl * asmDecl ) override final;
+	virtual StaticAssertDecl * mutate( StaticAssertDecl * assertDecl ) override final;
 
 	virtual CompoundStmt * mutate( CompoundStmt * compoundStmt ) override final;
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 3d2b7bc8ab86d81a629447f35c464695613e0057)
+++ src/Common/PassVisitor.impl.h	(revision f6e3e345e94a983a197c49451c099ac2783fca51)
@@ -685,4 +685,26 @@
 
 //--------------------------------------------------------------------------
+// StaticAssertDecl
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( StaticAssertDecl * node ) {
+	VISIT_START( node );
+
+	maybeAccept_impl( node->condition, *this );
+	maybeAccept_impl( node->message  , *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+StaticAssertDecl * PassVisitor< pass_type >::mutate( StaticAssertDecl * node ) {
+	MUTATE_START( node );
+
+	maybeMutate_impl( node->condition, *this );
+	maybeMutate_impl( node->message  , *this );
+
+	MUTATE_END( StaticAssertDecl, node );
+}
+
+//--------------------------------------------------------------------------
 // CompoundStmt
 template< typename pass_type >
@@ -1490,5 +1512,4 @@
 	indexerScopedAccept( node->result, *this );
 	maybeAccept_impl   ( node->type  , *this );
-	maybeAccept_impl   ( node->member, *this );
 
 	VISIT_END( node );
@@ -1502,5 +1523,4 @@
 	indexerScopedMutate( node->result, *this );
 	maybeMutate_impl   ( node->type  , *this );
-	maybeMutate_impl   ( node->member, *this );
 
 	MUTATE_END( Expression, node );
Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision 3d2b7bc8ab86d81a629447f35c464695613e0057)
+++ src/Parser/DeclarationNode.cc	(revision f6e3e345e94a983a197c49451c099ac2783fca51)
@@ -71,4 +71,7 @@
 	attr.expr = nullptr;
 	attr.type = nullptr;
+
+	assert.condition = nullptr;
+	assert.message = nullptr;
 }
 
@@ -88,4 +91,7 @@
 	// asmName, no delete, passed to next stage
 	delete initializer;
+
+	delete assert.condition;
+	delete assert.message;
 }
 
@@ -117,4 +123,7 @@
 	newnode->attr.expr = maybeClone( attr.expr );
 	newnode->attr.type = maybeClone( attr.type );
+
+	newnode->assert.condition = maybeClone( assert.condition );
+	newnode->assert.message = maybeClone( assert.message );
 	return newnode;
 } // DeclarationNode::clone
@@ -434,4 +443,12 @@
 	return newnode;
 }
+
+DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, Expression * message ) {
+	DeclarationNode * newnode = new DeclarationNode;
+	newnode->assert.condition = condition;
+	newnode->assert.message = message;
+	return newnode;
+}
+
 
 void appendError( string & dst, const string & src ) {
@@ -1052,4 +1069,8 @@
 	} // if
 
+	if ( assert.condition ) {
+		return new StaticAssertDecl( maybeBuild< Expression >( assert.condition ), strict_dynamic_cast< ConstantExpr * >( maybeClone( assert.message ) ) );
+	}
+
 	// SUE's cannot have function specifiers, either
 	//
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision 3d2b7bc8ab86d81a629447f35c464695613e0057)
+++ src/Parser/ParseNode.h	(revision f6e3e345e94a983a197c49451c099ac2783fca51)
@@ -246,4 +246,5 @@
 	static DeclarationNode * newAttribute( std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
 	static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
+	static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
 
 	DeclarationNode();
@@ -313,4 +314,10 @@
 	Attr_t attr;
 
+	struct StaticAssert_t {
+		ExpressionNode * condition;
+		Expression * message;
+	};
+	StaticAssert_t assert;
+
 	BuiltinType builtin;
 
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 3d2b7bc8ab86d81a629447f35c464695613e0057)
+++ src/Parser/parser.yy	(revision f6e3e345e94a983a197c49451c099ac2783fca51)
@@ -1308,5 +1308,5 @@
 static_assert:
 	STATICASSERT '(' constant_expression ',' string_literal ')' ';' // C11
-		{ SemanticError( yylloc, "Static assert is currently unimplemented." ); $$ = nullptr; }	// FIX ME
+		{ $$ = DeclarationNode::newStaticAssert( $3, $5 ); }
 
 // C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function
Index: src/SynTree/Declaration.cc
===================================================================
--- src/SynTree/Declaration.cc	(revision 3d2b7bc8ab86d81a629447f35c464695613e0057)
+++ src/SynTree/Declaration.cc	(revision f6e3e345e94a983a197c49451c099ac2783fca51)
@@ -81,4 +81,27 @@
 
 
+StaticAssertDecl::StaticAssertDecl( Expression * condition, ConstantExpr * message ) : Declaration( "", Type::StorageClasses(), LinkageSpec::C ), condition( condition ), message( message )  {
+}
+
+StaticAssertDecl::StaticAssertDecl( const StaticAssertDecl & other ) : Declaration( other ), condition( maybeClone( other.condition ) ), message( maybeClone( other.message ) )  {
+}
+
+StaticAssertDecl::~StaticAssertDecl() {
+	delete condition;
+	delete message;
+}
+
+void StaticAssertDecl::print( std::ostream &os, Indenter indent ) const {
+	os << "Static Assert with condition: ";
+	condition->print( os, indent+1 );
+	os << std::endl << indent << "and message: ";
+	message->print( os, indent+1 );
+os << std::endl;
+}
+
+void StaticAssertDecl::printShort( std::ostream &os, Indenter indent ) const {
+	print( os, indent );
+}
+
 // Local Variables: //
 // tab-width: 4 //
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision 3d2b7bc8ab86d81a629447f35c464695613e0057)
+++ src/SynTree/Declaration.h	(revision f6e3e345e94a983a197c49451c099ac2783fca51)
@@ -365,4 +365,20 @@
 };
 
+class StaticAssertDecl : public Declaration {
+public:
+	Expression * condition;
+	ConstantExpr * message;   // string literal
+
+	StaticAssertDecl( Expression * condition, ConstantExpr * message );
+	StaticAssertDecl( const StaticAssertDecl & other );
+	virtual ~StaticAssertDecl();
+
+	virtual StaticAssertDecl * clone() const override { return new StaticAssertDecl( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual StaticAssertDecl * acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
+	virtual void printShort( std::ostream &os, Indenter indent = {} ) const override;
+};
+
 std::ostream & operator<<( std::ostream & os, const TypeDecl::Data & data );
 
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision 3d2b7bc8ab86d81a629447f35c464695613e0057)
+++ src/SynTree/Mutator.h	(revision f6e3e345e94a983a197c49451c099ac2783fca51)
@@ -34,4 +34,5 @@
 	virtual Declaration * mutate( TypedefDecl * typeDecl ) = 0;
 	virtual AsmDecl * mutate( AsmDecl * asmDecl ) = 0;
+	virtual StaticAssertDecl * mutate( StaticAssertDecl * assertDecl ) = 0;
 
 	virtual CompoundStmt * mutate( CompoundStmt * compoundStmt ) = 0;
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision 3d2b7bc8ab86d81a629447f35c464695613e0057)
+++ src/SynTree/SynTree.h	(revision f6e3e345e94a983a197c49451c099ac2783fca51)
@@ -38,4 +38,5 @@
 class TypedefDecl;
 class AsmDecl;
+class StaticAssertDecl;
 
 class Statement;
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision 3d2b7bc8ab86d81a629447f35c464695613e0057)
+++ src/SynTree/Visitor.h	(revision f6e3e345e94a983a197c49451c099ac2783fca51)
@@ -36,4 +36,5 @@
 	virtual void visit( TypedefDecl * typeDecl ) = 0;
 	virtual void visit( AsmDecl * asmDecl ) = 0;
+	virtual void visit( StaticAssertDecl * assertDecl ) = 0;
 
 	virtual void visit( CompoundStmt * compoundStmt ) = 0;
