Index: src/AST/Expr.cpp
===================================================================
--- src/AST/Expr.cpp	(revision e6491ca99dda0765fbc62f8668f0c6c71710b020)
+++ src/AST/Expr.cpp	(revision 857b5f94b11520c80efa84eab7d4104469b9e9da)
@@ -283,16 +283,13 @@
 : Expr( loc, new BasicType{ BasicKind::LongUnsignedInt } ), type( t ) {}
 
-// --- CountExpr
-
-CountExpr::CountExpr( const CodeLocation & loc, const Expr * e )
-: Expr( loc, new BasicType( BasicKind::LongUnsignedInt) ), expr(e), type( nullptr ) {}
-
-CountExpr::CountExpr( const CodeLocation & loc, const Type * t )
-: Expr( loc, new BasicType( BasicKind::LongUnsignedInt) ), expr(nullptr), type( t ) {}
-
 // --- AlignofExpr
 
 AlignofExpr::AlignofExpr( const CodeLocation & loc, const Type * t )
 : Expr( loc, new BasicType{ BasicKind::LongUnsignedInt } ), type( t ) {}
+
+// --- CountofExpr
+
+CountofExpr::CountofExpr( const CodeLocation & loc, const Type * t )
+: Expr( loc, new BasicType( BasicKind::LongUnsignedInt) ), type( t ) {}
 
 // --- OffsetofExpr
Index: src/AST/Expr.hpp
===================================================================
--- src/AST/Expr.hpp	(revision e6491ca99dda0765fbc62f8668f0c6c71710b020)
+++ src/AST/Expr.hpp	(revision 857b5f94b11520c80efa84eab7d4104469b9e9da)
@@ -490,18 +490,4 @@
 };
 
-class CountExpr final : public Expr {
-public:
-	ptr<Expr> expr;
-	ptr<Type> type;
-
-	CountExpr( const CodeLocation & loc, const Expr * t );
-	CountExpr( const CodeLocation & loc, const Type * t );
-
-	const Expr * accept( Visitor & v )const override { return v.visit( this ); }
-private:
-	CountExpr * clone() const override { return new CountExpr( *this ); }
-	MUTATE_FRIEND
-};
-
 /// alignof expression, e.g. `alignof(int)`, `alignof 3+4`
 class AlignofExpr final : public Expr {
@@ -514,4 +500,17 @@
 private:
 	AlignofExpr * clone() const override { return new AlignofExpr{ *this }; }
+	MUTATE_FRIEND
+};
+
+/// countof expression, e.g. `countof(AnEnum)`, `countof pred(Head)`
+class CountofExpr final : public Expr {
+public:
+	ptr<Type> type;
+
+	CountofExpr( const CodeLocation & loc, const Type * t );
+
+	const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
+private:
+	CountofExpr * clone() const override { return new CountofExpr( *this ); }
 	MUTATE_FRIEND
 };
Index: src/AST/Fwd.hpp
===================================================================
--- src/AST/Fwd.hpp	(revision e6491ca99dda0765fbc62f8668f0c6c71710b020)
+++ src/AST/Fwd.hpp	(revision 857b5f94b11520c80efa84eab7d4104469b9e9da)
@@ -86,6 +86,6 @@
 class ConstantExpr;
 class SizeofExpr;
-class CountExpr;
 class AlignofExpr;
+class CountofExpr;
 class UntypedOffsetofExpr;
 class OffsetofExpr;
Index: src/AST/Pass.hpp
===================================================================
--- src/AST/Pass.hpp	(revision e6491ca99dda0765fbc62f8668f0c6c71710b020)
+++ src/AST/Pass.hpp	(revision 857b5f94b11520c80efa84eab7d4104469b9e9da)
@@ -173,6 +173,6 @@
 	const ast::Expr *             visit( const ast::ConstantExpr         * ) override final;
 	const ast::Expr *             visit( const ast::SizeofExpr           * ) override final;
-	const ast::Expr *             visit( const ast::CountExpr            * ) override final;
 	const ast::Expr *             visit( const ast::AlignofExpr          * ) override final;
+	const ast::Expr *             visit( const ast::CountofExpr          * ) override final;
 	const ast::Expr *             visit( const ast::UntypedOffsetofExpr  * ) override final;
 	const ast::Expr *             visit( const ast::OffsetofExpr         * ) override final;
Index: src/AST/Pass.impl.hpp
===================================================================
--- src/AST/Pass.impl.hpp	(revision e6491ca99dda0765fbc62f8668f0c6c71710b020)
+++ src/AST/Pass.impl.hpp	(revision 857b5f94b11520c80efa84eab7d4104469b9e9da)
@@ -1350,23 +1350,4 @@
 
 //--------------------------------------------------------------------------
-// CountExpr
-template< typename core_t >
-const ast::Expr * ast::Pass< core_t >::visit( const ast::CountExpr * node ) {
-	VISIT_START( node );
-	if ( __visit_children() ) {
-		{
-			guard_symtab guard { *this };
-			maybe_accept( node, &CountExpr::result );
-		}
-		if ( node->type ) {
-			maybe_accept( node, &CountExpr::type );
-		} else {
-			maybe_accept( node, &CountExpr::expr );
-		}
-	}
-	VISIT_END( Expr, node );
-}
-
-//--------------------------------------------------------------------------
 // AlignofExpr
 template< typename core_t >
@@ -1380,4 +1361,21 @@
 		}
 		maybe_accept( node, &AlignofExpr::type );
+	}
+
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
+// CountofExpr
+template< typename core_t >
+const ast::Expr * ast::Pass< core_t >::visit( const ast::CountofExpr * node ) {
+	VISIT_START( node );
+
+	if ( __visit_children() ) {
+		{
+			guard_symtab guard { *this };
+			maybe_accept( node, &CountofExpr::result );
+		}
+		maybe_accept( node, &CountofExpr::type );
 	}
 
Index: src/AST/Print.cpp
===================================================================
--- src/AST/Print.cpp	(revision e6491ca99dda0765fbc62f8668f0c6c71710b020)
+++ src/AST/Print.cpp	(revision 857b5f94b11520c80efa84eab7d4104469b9e9da)
@@ -1207,9 +1207,8 @@
 	}
 
-	virtual const ast::Expr * visit( const ast::CountExpr * node ) override final {
+	virtual const ast::Expr * visit( const ast::CountofExpr * node ) override final {
 		os << "Count Expression on: ";
 		++indent;
-		if ( node->type ) node->type->accept( *this );
-		else safe_print( node->expr );
+		safe_print( node->type );
 		--indent;
 		postprint( node );
Index: src/AST/Visitor.hpp
===================================================================
--- src/AST/Visitor.hpp	(revision e6491ca99dda0765fbc62f8668f0c6c71710b020)
+++ src/AST/Visitor.hpp	(revision 857b5f94b11520c80efa84eab7d4104469b9e9da)
@@ -76,6 +76,6 @@
     virtual const ast::Expr *             visit( const ast::ConstantExpr         * ) = 0;
     virtual const ast::Expr *             visit( const ast::SizeofExpr           * ) = 0;
-    virtual const ast::Expr *             visit( const ast::CountExpr            * ) = 0;
     virtual const ast::Expr *             visit( const ast::AlignofExpr          * ) = 0;
+    virtual const ast::Expr *             visit( const ast::CountofExpr          * ) = 0;
     virtual const ast::Expr *             visit( const ast::UntypedOffsetofExpr  * ) = 0;
     virtual const ast::Expr *             visit( const ast::OffsetofExpr         * ) = 0;
Index: src/Common/CodeLocationTools.cpp
===================================================================
--- src/Common/CodeLocationTools.cpp	(revision e6491ca99dda0765fbc62f8668f0c6c71710b020)
+++ src/Common/CodeLocationTools.cpp	(revision 857b5f94b11520c80efa84eab7d4104469b9e9da)
@@ -154,6 +154,6 @@
     macro(ConstantExpr, Expr) \
     macro(SizeofExpr, Expr) \
-    macro(CountExpr, Expr ) \
     macro(AlignofExpr, Expr) \
+    macro(CountofExpr, Expr ) \
     macro(UntypedOffsetofExpr, Expr) \
     macro(OffsetofExpr, Expr) \
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision e6491ca99dda0765fbc62f8668f0c6c71710b020)
+++ src/Parser/parser.yy	(revision 857b5f94b11520c80efa84eab7d4104469b9e9da)
@@ -946,7 +946,7 @@
 		}
 	| COUNTOF unary_expression
-		{ $$ = new ExpressionNode( new ast::CountExpr( yylloc, maybeMoveBuild( $2 ) ) ); }
+		{ $$ = new ExpressionNode( new ast::CountofExpr( yylloc, new ast::TypeofType( maybeMoveBuild( $2 ) ) ) ); }
 	| COUNTOF '(' type_no_function ')'
-		{ $$ = new ExpressionNode( new ast::CountExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
+		{ $$ = new ExpressionNode( new ast::CountofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
 	;
 
Index: src/ResolvExpr/CandidateFinder.cpp
===================================================================
--- src/ResolvExpr/CandidateFinder.cpp	(revision e6491ca99dda0765fbc62f8668f0c6c71710b020)
+++ src/ResolvExpr/CandidateFinder.cpp	(revision 857b5f94b11520c80efa84eab7d4104469b9e9da)
@@ -672,4 +672,5 @@
 		void postvisit( const ast::SizeofExpr * sizeofExpr );
 		void postvisit( const ast::AlignofExpr * alignofExpr );
+		void postvisit( const ast::CountofExpr * countExpr );
 		void postvisit( const ast::AddressExpr * addressExpr );
 		void postvisit( const ast::LabelAddressExpr * labelExpr );
@@ -697,5 +698,4 @@
 		void postvisit( const ast::UntypedInitExpr * initExpr );
 		void postvisit( const ast::QualifiedNameExpr * qualifiedExpr );
-		void postvisit( const ast::CountExpr * countExpr );
 
 		void postvisit( const ast::InitExpr * ) {
@@ -941,5 +941,4 @@
 		}
 	}
-	
 
 	/// Adds aggregate member interpretations
@@ -1269,5 +1268,5 @@
 					? conversionCost( fromType, toType, cand->expr->get_lvalue(), symtab, cand->env )
 					: castCost( fromType, toType, cand->expr->get_lvalue(), symtab, cand->env );
-			
+
 			// Redefine enum cast
 			auto argAsEnum = fromType.as<ast::EnumInstType>();
@@ -1493,20 +1492,13 @@
 	}
 
-	void Finder::postvisit( const ast::CountExpr * countExpr ) {
-		const ast::UntypedExpr * untyped = nullptr;
-		if ( countExpr->type ) {
-			auto enumInst = countExpr->type.as<ast::EnumInstType>();
-			if ( enumInst ) {
-				addCandidate( ast::ConstantExpr::from_ulong(countExpr->location, enumInst->base->members.size()), tenv );
-				return;
-			}
-			auto untypedFirst = ast::UntypedExpr::createCall( countExpr->location, "lowerBound", {} );
-			auto castFirst = new ast::CastExpr( countExpr->location, untypedFirst , countExpr->type );
-			untyped = ast::UntypedExpr::createCall(
-				countExpr->location, "Countof", { castFirst }
-			);
-		}
-		if (!untyped) untyped = ast::UntypedExpr::createCall(
-				countExpr->location, "Countof", { countExpr->expr }
+	void Finder::postvisit( const ast::CountofExpr * countExpr ) {
+		if ( auto enumInst = countExpr->type.as<ast::EnumInstType>() ) {
+			addCandidate( ast::ConstantExpr::from_ulong( countExpr->location, enumInst->base->members.size()), tenv );
+			return;
+		}
+		auto untypedFirst = ast::UntypedExpr::createCall( countExpr->location, "lowerBound", {} );
+		auto castFirst = new ast::CastExpr( countExpr->location, untypedFirst , countExpr->type );
+		const ast::UntypedExpr * untyped = ast::UntypedExpr::createCall(
+			countExpr->location, "Countof", { castFirst }
 		);
 		CandidateFinder finder( context, tenv );
@@ -1514,8 +1506,8 @@
 		CandidateList winners = findMinCost( finder.candidates );
 		if ( winners.size() == 0 ) {
-			SemanticError( countExpr->expr, "Countof is not implemented for operand: " );
-		}
-		if ( winners.size() !=  1 ) {
-			SemanticError( countExpr->expr, "Ambiguous expression in countof operand: " );
+			SemanticError( countExpr, "Countof is not implemented: " );
+		}
+		if ( winners.size() != 1 ) {
+			SemanticError( countExpr, "Ambiguous expression in countof: " );
 		}
 		CandidateRef & choice = winners.front();
