Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/AST/Convert.cpp	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -310,4 +310,5 @@
 			node->name,
 			get<Attribute>().acceptL( node->attributes ),
+			false, // Temporary
 			LinkageSpec::Spec( node->linkage.val ),
 			get<Type>().accept1(node->base)
@@ -731,4 +732,17 @@
 	}
 
+	const ast::Expr * visit( const ast::QualifiedNameExpr * node ) override final {
+		auto temp = new QualifiedNameExpr(
+				get<Declaration>().accept1(node->type_decl),
+				node->name
+		);
+		temp->var = get<DeclarationWithType>().accept1(node->var);
+		auto expr = visitBaseExpr( node,
+			temp
+		);
+		this->node = expr;
+		return nullptr;
+	}
+
 	const ast::Expr * visit( const ast::AddressExpr * node ) override final {
 		auto expr = visitBaseExpr( node,
@@ -1740,4 +1754,5 @@
 			old->location,
 			old->name,
+			old->isTyped,
 			GET_ACCEPT_V(attributes, Attribute),
 			{ old->linkage.val },
@@ -2266,4 +2281,17 @@
 	}
 
+	/// xxx - type_decl should be DeclWithType in the final design
+	/// type_decl is set to EnumDecl as a temporary fix
+	virtual void visit( const QualifiedNameExpr * old ) override final {
+		this->node = visitBaseExpr( old,
+			new ast::QualifiedNameExpr (
+				old->location,
+				GET_ACCEPT_1(type_decl, Decl),
+				GET_ACCEPT_1(var, DeclWithType),
+				old->name
+			)
+		);
+	}
+
 	virtual void visit( const CastExpr * old ) override final {
 		this->node = visitBaseExpr( old,
Index: src/AST/Decl.hpp
===================================================================
--- src/AST/Decl.hpp	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/AST/Decl.hpp	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -312,10 +312,12 @@
 class EnumDecl final : public AggregateDecl {
 public:
+	bool isTyped;
 	ptr<Type> base;
 
-	EnumDecl( const CodeLocation& loc, const std::string& name,
-		std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall, Type const * base = nullptr,
+	EnumDecl( const CodeLocation& loc, const std::string& name, bool isTyped = false, 
+		std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall,
+		Type const * base = nullptr,
 		std::unordered_map< std::string, long long > enumValues = std::unordered_map< std::string, long long >() )
-	: AggregateDecl( loc, name, std::move(attrs), linkage ), base(base), enumValues(enumValues) {}
+	: AggregateDecl( loc, name, std::move(attrs), linkage ), isTyped(isTyped), base(base), enumValues(enumValues) {}
 
 	/// gets the integer value for this enumerator, returning true iff value found
@@ -327,5 +329,4 @@
 	const char * typeString() const override { return aggrString( Enum ); }
 
-	bool isTyped() {return base && base.get();}
 
 private:
Index: src/AST/Expr.hpp
===================================================================
--- src/AST/Expr.hpp	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/AST/Expr.hpp	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -254,4 +254,19 @@
 };
 
+class QualifiedNameExpr final : public Expr {
+public:
+	ptr<Decl> type_decl;
+	ptr<DeclWithType> var;
+	std::string name;
+
+	QualifiedNameExpr( const CodeLocation & loc, const Decl * d, const DeclWithType * r, const std::string & n ) 
+	: Expr( loc ), type_decl( d ), var(r), name( n ) {}
+
+	const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
+private:
+	QualifiedNameExpr * clone() const override { return new QualifiedNameExpr{ *this }; }
+	MUTATE_FRIEND
+};
+
 /// A reference to a named variable.
 class VariableExpr final : public Expr {
Index: src/AST/Fwd.hpp
===================================================================
--- src/AST/Fwd.hpp	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/AST/Fwd.hpp	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -67,4 +67,5 @@
 class UntypedExpr;
 class NameExpr;
+class QualifiedNameExpr;
 class AddressExpr;
 class LabelAddressExpr;
Index: src/AST/Pass.hpp
===================================================================
--- src/AST/Pass.hpp	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/AST/Pass.hpp	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -167,4 +167,5 @@
 	const ast::Expr *             visit( const ast::UntypedExpr          * ) override final;
 	const ast::Expr *             visit( const ast::NameExpr             * ) override final;
+	const ast::Expr *			  visit( const ast::QualifiedNameExpr	 * ) override final;
 	const ast::Expr *             visit( const ast::AddressExpr          * ) override final;
 	const ast::Expr *             visit( const ast::LabelAddressExpr     * ) override final;
Index: src/AST/Pass.impl.hpp
===================================================================
--- src/AST/Pass.impl.hpp	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/AST/Pass.impl.hpp	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -1199,4 +1199,17 @@
 
 //--------------------------------------------------------------------------
+// QualifiedNameExpr
+template< typename core_t >
+const ast::Expr * ast::Pass< core_t >::visit( const ast::QualifiedNameExpr * node ) {
+	VISIT_START( node );
+	if ( __visit_children() ) {
+		guard_symtab guard { *this };
+		maybe_accept( node, &QualifiedNameExpr::var );
+		maybe_accept( node, &QualifiedNameExpr::type_decl );
+	}
+	VISIT_END( Expr, node );
+}
+
+//--------------------------------------------------------------------------
 // CastExpr
 template< typename core_t >
Index: src/AST/Print.cpp
===================================================================
--- src/AST/Print.cpp	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/AST/Print.cpp	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -899,4 +899,15 @@
 		postprint( node );
 
+		return node;
+	}
+
+	virtual const ast::Expr * visit( const ast::QualifiedNameExpr * node ) override final {
+		os << "QualifiedNameExpr: " << std::endl;
+		os << ++indent << "Type: ";
+		safe_print( node->type_decl );
+		os << std::endl;
+		os <<  indent << "Name: " << node->name  << std::endl;
+		--indent;
+		postprint( node );
 		return node;
 	}
Index: src/AST/Visitor.hpp
===================================================================
--- src/AST/Visitor.hpp	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/AST/Visitor.hpp	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -59,4 +59,5 @@
     virtual const ast::Expr *             visit( const ast::UntypedExpr          * ) = 0;
     virtual const ast::Expr *             visit( const ast::NameExpr             * ) = 0;
+    virtual const ast::Expr *             visit( const ast::QualifiedNameExpr    * ) = 0;
     virtual const ast::Expr *             visit( const ast::AddressExpr          * ) = 0;
     virtual const ast::Expr *             visit( const ast::LabelAddressExpr     * ) = 0;
Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/CodeGen/CodeGenerator.cc	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -277,5 +277,6 @@
 		std::list< Declaration* > &memb = enumDecl->get_members();
 		if (enumDecl->base && ! memb.empty()) {
-			unsigned long long last_val = -1;
+			unsigned long long last_val = -1; // if the first enum value has no explicit initializer, 
+			// as other 
 			for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
 				ObjectDecl * obj = dynamic_cast< ObjectDecl* >( *i );
@@ -695,8 +696,4 @@
 			output << opInfo->symbol;
 		} else {
-			// if (dynamic_cast<EnumInstType *>(variableExpr->get_var()->get_type())
-			// && dynamic_cast<EnumInstType *>(variableExpr->get_var()->get_type())->baseEnum->base) {
-			// 	output << '(' <<genType(dynamic_cast<EnumInstType *>(variableExpr->get_var()->get_type())->baseEnum->base, "", options) << ')';
-			// }
 			output << mangleName( variableExpr->get_var() );
 		} // if
@@ -917,4 +914,9 @@
 	}
 
+	// QualifiedNameExpr should not reach to CodeGen. 
+	// FixQualifiedName Convert QualifiedNameExpr to VariableExpr
+	void CodeGenerator::postvisit( QualifiedNameExpr * expr ) {
+		output << "/* label */" << mangleName(expr->var);
+	}
 
 	// *** Statements
Index: src/CodeGen/CodeGenerator.h
===================================================================
--- src/CodeGen/CodeGenerator.h	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/CodeGen/CodeGenerator.h	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -103,4 +103,5 @@
 		void postvisit( DefaultArgExpr * );
 		void postvisit( GenericExpr * );
+		void postvisit( QualifiedNameExpr *);
 
 		//*** Statements
Index: src/Common/CodeLocationTools.cpp
===================================================================
--- src/Common/CodeLocationTools.cpp	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/Common/CodeLocationTools.cpp	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -137,4 +137,5 @@
     macro(UntypedExpr, Expr) \
     macro(NameExpr, Expr) \
+	macro(QualifiedNameExpr, Expr) \
     macro(AddressExpr, Expr) \
     macro(LabelAddressExpr, Expr) \
Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/Common/PassVisitor.h	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -133,4 +133,6 @@
 	virtual void visit( NameExpr * nameExpr ) override final;
 	virtual void visit( const NameExpr * nameExpr ) override final;
+	virtual void visit ( QualifiedNameExpr * qualifiedNameExpr ) override final;
+	virtual void visit ( const QualifiedNameExpr * qualifiedNameExpr ) override final;
 	virtual void visit( CastExpr * castExpr ) override final;
 	virtual void visit( const CastExpr * castExpr ) override final;
@@ -325,5 +327,5 @@
 	virtual Expression * mutate( TupleExpr * tupleExpr ) override final;
 	virtual Expression * mutate( TupleIndexExpr * tupleExpr ) override final;
-	virtual Expression * mutate( TupleAssignExpr * assignExpr ) override final;
+	virtual Expression * mutate( TupleAssignExpr * assignExpr ) override final; 
 	virtual Expression * mutate( StmtExpr *  stmtExpr ) override final;
 	virtual Expression * mutate( UniqueExpr *  uniqueExpr ) override final;
@@ -333,4 +335,5 @@
 	virtual Expression * mutate( DefaultArgExpr * argExpr ) override final;
 	virtual Expression * mutate( GenericExpr * genExpr ) override final;
+	virtual Expression * mutate( QualifiedNameExpr * qualifiedNameExpr ) override final;
 
 	virtual Type * mutate( VoidType * basicType ) override final;
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/Common/PassVisitor.impl.h	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -1927,4 +1927,40 @@
 
 //--------------------------------------------------------------------------
+// QualifiedNameExpr
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( QualifiedNameExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl( node->type_decl, *this );
+	maybeAccept_impl( node->var, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( const QualifiedNameExpr * node ) {
+	VISIT_START( node );
+
+	indexerScopedAccept( node->result, *this );
+	maybeAccept_impl( node->type_decl, *this );
+	maybeAccept_impl( node->var, *this );
+
+	VISIT_END( node );
+}
+
+template< typename pass_type >
+Expression * PassVisitor< pass_type >::mutate( QualifiedNameExpr * node ) {
+	MUTATE_START( node );
+
+    indexerScopedMutate( node->env   , *this );
+    indexerScopedMutate( node->result, *this );
+	maybeMutate_impl( node->type_decl, *this );
+	maybeAccept_impl( node->var, *this );
+
+	MUTATE_END( Expression, node );
+}
+
+//--------------------------------------------------------------------------
 // CastExpr
 template< typename pass_type >
Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/Parser/DeclarationNode.cc	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -254,5 +254,5 @@
 } // DeclarationNode::newAggregate
 
-DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body, DeclarationNode * base) {
+DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base) {
 	DeclarationNode * newnode = new DeclarationNode;
 	newnode->type = new TypeData( TypeData::Enum );
@@ -261,9 +261,9 @@
 	newnode->type->enumeration.body = body;
 	newnode->type->enumeration.anon = name == nullptr;
+	newnode->type->enumeration.typed = typed;
 	if ( base && base->type)  {
 		newnode->type->base = base->type;
 	} // if
 
-	// Check: if base has TypeData
 	return newnode;
 } // DeclarationNode::newEnum
@@ -285,8 +285,8 @@
 
 DeclarationNode * DeclarationNode::newEnumValueGeneric( const string * name, InitializerNode * init ) {
-	if ( init ) { // list init {} or a singleInit
-		if ( init->get_expression() ) { // singleInit
+	if ( init ) {
+		if ( init->get_expression() ) {
 			return newEnumConstant( name, init->get_expression() );
-		} else { // TODO: listInit
+		} else {
 			DeclarationNode * newnode = newName( name );
 			newnode->initializer = init;
@@ -294,5 +294,5 @@
 		} // if
 	} else {
-		return newName( name ); // Not explicitly inited enum value;
+		return newName( name );
 	} // if
 } // DeclarationNode::newEnumValueGeneric
Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/Parser/ExpressionNode.cc	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -509,4 +509,28 @@
 } // build_varref
 
+QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name ) {
+	Declaration * newDecl = maybeBuild< Declaration >(decl_node);
+	if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) {
+		const Type * t = newDeclWithType->get_type();
+		if ( t ) {
+			if ( const TypeInstType * typeInst = dynamic_cast<const TypeInstType *>( t ) ) {
+				newDecl= new EnumDecl( typeInst->name );
+			}
+		}
+	}
+	auto ret =  new QualifiedNameExpr( newDecl, name->name );
+	if ( auto e = dynamic_cast<EnumDecl*>(newDecl) ) {
+		auto enumInst = new EnumInstType( Type::Qualifiers(), e );
+		auto obj = new ObjectDecl( name->name, Type::StorageClasses(), LinkageSpec::Cforall, nullptr, enumInst, nullptr );
+		ret->set_var( obj );
+	}
+	return ret;
+}
+
+QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl_node, const NameExpr * name ) {
+	EnumDecl * newDecl = const_cast< EnumDecl * >( decl_node );
+	return new QualifiedNameExpr( newDecl, name->name );
+}
+
 DimensionExpr * build_dimensionref( const string * name ) {
 	DimensionExpr * expr = new DimensionExpr( *name );
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/Parser/ParseNode.h	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -183,4 +183,6 @@
 
 NameExpr * build_varref( const std::string * name );
+QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name );
+QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl, const NameExpr * name );
 DimensionExpr * build_dimensionref( const std::string * name );
 
@@ -235,5 +237,5 @@
 	static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
 	static DeclarationNode * newAggregate( AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
-	static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, DeclarationNode * base = nullptr );
+	static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr );
 	static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
 	static DeclarationNode * newEnumValueGeneric( const std::string * name, InitializerNode * init );
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/Parser/TypeData.cc	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -546,5 +546,4 @@
 		return buildAggInst( td );
 	  case TypeData::EnumConstant:
-		// the name gets filled in later -- by SymTab::Validate
 		return new EnumInstType( buildQualifiers( td ), "" );
 	  case TypeData::SymbolicInst:
@@ -921,14 +920,16 @@
 	assert( td->kind == TypeData::Enum );
 	Type * baseType = td->base ? typebuild(td->base) : nullptr;
-	EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes, linkage, baseType );
+	EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes, td->enumeration.typed, linkage, baseType );
 	buildList( td->enumeration.constants, ret->get_members() );
 	list< Declaration * >::iterator members = ret->get_members().begin();
 	for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) {
-		if ( cur->has_enumeratorValue() ) {
+		if ( ret->isTyped && !ret->base && cur->has_enumeratorValue() ) {
+			SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." );
+		} else if ( cur->has_enumeratorValue() ) {
 			ObjectDecl * member = dynamic_cast< ObjectDecl * >(* members);
 			member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ) ) );
 		} else if ( !cur->initializer ) {
 			if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isWholeNumber())) {
-				SemanticError( td->location, "A non whole number enum value decl must be explicitly initialized." );
+				SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." );
 			}
 		}
Index: src/Parser/TypeData.h
===================================================================
--- src/Parser/TypeData.h	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/Parser/TypeData.h	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -59,4 +59,5 @@
 		bool body;
 		bool anon;
+		bool typed;
 	};
 
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/Parser/parser.yy	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -637,5 +637,5 @@
 		{ $$ = new ExpressionNode( new StmtExpr( dynamic_cast<CompoundStmt *>(maybeMoveBuild<Statement>($2) ) ) ); }
 	| type_name '.' identifier							// CFA, nested type
-		{ SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
+		{ $$ = new ExpressionNode( build_qualified_expr( $1, build_varref( $3 ) ) ); }
 	| type_name '.' '[' field_name_list ']'				// CFA, nested type / tuple field selector
 		{ SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
@@ -2538,14 +2538,12 @@
 enum_type:
 	ENUM attribute_list_opt '{' enumerator_list comma_opt '}'
-		{ $$ = DeclarationNode::newEnum( nullptr, $4, true )->addQualifiers( $2 ); }
+		{ $$ = DeclarationNode::newEnum( nullptr, $4, true, false )->addQualifiers( $2 ); }
 	| ENUM attribute_list_opt identifier
 		{ typedefTable.makeTypedef( *$3 ); }
 	  '{' enumerator_list comma_opt '}'
-		{ $$ = DeclarationNode::newEnum( $3, $6, true )->addQualifiers( $2 ); }
+		{ $$ = DeclarationNode::newEnum( $3, $6, true, false )->addQualifiers( $2 ); }
 	| ENUM attribute_list_opt typedef_name				// unqualified type name
 	  '{' enumerator_list comma_opt '}'
-		{ $$ = DeclarationNode::newEnum( $3->name, $5, true )->addQualifiers( $2 ); }
-	| ENUM '(' ')' attribute_list_opt '{' enumerator_list comma_opt '}'
-		{ SemanticError( yylloc, "Unvalued enumerated type is currently unimplemented." ); $$ = nullptr; }
+		{ $$ = DeclarationNode::newEnum( $3->name, $5, true, false )->addQualifiers( $2 ); }
 	| ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}'
 	 	{
@@ -2553,5 +2551,9 @@
 			{ SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
 
-			$$ = DeclarationNode::newEnum( nullptr, $7, true, $3 )->addQualifiers( $5 );
+			$$ = DeclarationNode::newEnum( nullptr, $7, true, true, $3 )->addQualifiers( $5 );
+		}
+	| ENUM '(' ')' attribute_list_opt '{' enumerator_list comma_opt '}'
+		{
+			$$ = DeclarationNode::newEnum( nullptr, $6, true, true )->addQualifiers( $4 );
 		}
 	| ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt
@@ -2562,11 +2564,18 @@
 	  '{' enumerator_list comma_opt '}'
 		{
-			$$ = DeclarationNode::newEnum( $6, $10, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 );
-		}
+			$$ = DeclarationNode::newEnum( $6, $10, true, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 );
+		}
+	| ENUM '(' ')' attribute_list_opt identifier attribute_list_opt
+	  '{' enumerator_list comma_opt '}'
+		{
+			$$ = DeclarationNode::newEnum( $5, $8, true, true, nullptr )->addQualifiers( $4 )->addQualifiers( $6 );
+		}	
 	| ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt typedef_name attribute_list_opt '{' enumerator_list comma_opt '}'
 		{
-			if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
-			typedefTable.makeTypedef( *$6->name );
-			$$ = DeclarationNode::newEnum( $6->name, $9, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 );
+			$$ = DeclarationNode::newEnum( $6->name, $9, true, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 );
+		}
+	| ENUM '(' ')' attribute_list_opt typedef_name attribute_list_opt '{' enumerator_list comma_opt '}'
+		{
+			$$ = DeclarationNode::newEnum( $5->name, $8, true, true, nullptr )->addQualifiers( $4 )->addQualifiers( $6 );
 		}
 	| enum_type_nobody
@@ -2575,7 +2584,7 @@
 enum_type_nobody:										// enum - {...}
 	ENUM attribute_list_opt identifier
-		{ typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false )->addQualifiers( $2 ); }
-	| ENUM attribute_list_opt type_name					// qualified type name
-		{ typedefTable.makeTypedef( *$3->type->symbolic.name );	$$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false )->addQualifiers( $2 ); }
+		{ typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false, false )->addQualifiers( $2 ); }
+	| ENUM attribute_list_opt type_name	
+		{ typedefTable.makeTypedef( *$3->type->symbolic.name );	$$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false, false )->addQualifiers( $2 ); }
 	;
 
Index: src/ResolvExpr/CandidateFinder.cpp
===================================================================
--- src/ResolvExpr/CandidateFinder.cpp	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/ResolvExpr/CandidateFinder.cpp	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -864,4 +864,9 @@
 		}
 
+		void postvisit( const ast::QualifiedNameExpr * qualifiedNameExpr ) {
+			auto mangleName = Mangle::mangle(qualifiedNameExpr->var);
+			addCandidate( qualifiedNameExpr, tenv );
+		}
+
 		void postvisit( const ast::UntypedExpr * untypedExpr ) {
 			std::vector< CandidateFinder > argCandidates =
@@ -897,15 +902,15 @@
 						}
 
-						if (argType.as<ast::PointerType>()) funcFinder.otypeKeys.insert(Mangle::Encoding::pointer);
-						else if (const ast::EnumInstType * enumInst = argType.as<ast::EnumInstType>()) {
-							const ast::EnumDecl * enumDecl = enumInst->base;
-							if ( const ast::Type* enumType = enumDecl->base ) {
-								// instance of enum (T) is a instance of type (T)
-								funcFinder.otypeKeys.insert(Mangle::mangle(enumType, Mangle::NoGenericParams | Mangle::Type));
-							} else {
-								// instance of an untyped enum is techically int
-								funcFinder.otypeKeys.insert(Mangle::mangle(enumDecl, Mangle::NoGenericParams | Mangle::Type));
-							}
-						}
+						if (argType.as<ast::PointerType>()) funcFinder.otypeKeys.insert(Mangle::Encoding::pointer);						
+						// else if (const ast::EnumInstType * enumInst = argType.as<ast::EnumInstType>()) {
+						// 	const ast::EnumDecl * enumDecl = enumInst->base; // Here
+						// 	if ( const ast::Type* enumType = enumDecl->base ) {
+						// 		// instance of enum (T) is a instance of type (T) 
+						// 		funcFinder.otypeKeys.insert(Mangle::mangle(enumType, Mangle::NoGenericParams | Mangle::Type));
+						// 	} else {
+						// 		// instance of an untyped enum is techically int
+						// 		funcFinder.otypeKeys.insert(Mangle::mangle(enumDecl, Mangle::NoGenericParams | Mangle::Type));
+						// 	}
+						// }
 						else funcFinder.otypeKeys.insert(Mangle::mangle(argType, Mangle::NoGenericParams | Mangle::Type));
 					}
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/ResolvExpr/ConversionCost.cc	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -340,5 +340,5 @@
 		} else if ( const EnumInstType * enumInst = dynamic_cast< const EnumInstType * >( dest ) ) {
 			const EnumDecl * base_enum = enumInst->baseEnum;
-			if ( const Type * base = base_enum->base ) { // if the base enum has a base (if it is typed)
+			if ( const Type * base = base_enum->base ) {
 				if ( const BasicType * enumBaseAstBasic = dynamic_cast< const BasicType *> (base) ) {
 					conversionCostFromBasicToBasic(basicType, enumBaseAstBasic);
@@ -634,5 +634,7 @@
 	} else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
 		const ast::EnumDecl * enumDecl = enumInst->base.get();
-		if ( const ast::Type * enumType = enumDecl->base.get() ) {
+		if ( enumDecl->isTyped && !enumDecl->base.get() ) {
+			cost = Cost::infinity; 
+		} else if ( const ast::Type * enumType = enumDecl->base.get() ) {
 			if ( const ast::BasicType * enumTypeAsBasic = dynamic_cast<const ast::BasicType *>(enumType) ) {
 				conversionCostFromBasicToBasic( basicType, enumTypeAsBasic );
@@ -716,5 +718,5 @@
 	const ast::EnumDecl * baseEnum = enumInstType->base;
 	if ( const ast::Type * baseType = baseEnum->base ) {
-		cost = costCalc( baseType, dst, srcIsLvalue, symtab, env );
+		costCalc( baseType, dst, srcIsLvalue, symtab, env );
 	} else {
 		(void)enumInstType;
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/ResolvExpr/Resolver.cc	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -1478,7 +1478,7 @@
 			// enum type is still incomplete at this point. Use `int` instead.
 
-			if (dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() )->base->base) {
+			if ( auto enumBase = dynamic_cast< const ast::EnumInstType * >
+				( objectDecl->get_type() )->base->base ) {
 				objectDecl = fixObjectType( objectDecl, context );
-				const ast::Type * enumBase =  (dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() )->base->base.get());
 				currentObject = ast::CurrentObject{ 
 					objectDecl->location, 
@@ -1493,5 +1493,5 @@
 		}
 		else {
-			if (!objectDecl->isTypeFixed) {
+			if ( !objectDecl->isTypeFixed ) {
 				auto newDecl = fixObjectType(objectDecl, context);
 				auto mutDecl = mutate(newDecl);
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/ResolvExpr/Unify.cc	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -165,4 +165,18 @@
 		ast::Type * newFirst  = shallowCopy( first  );
 		ast::Type * newSecond = shallowCopy( second );
+		if ( auto temp = dynamic_cast<const ast::EnumInstType *>(first) ) {
+			if ( !dynamic_cast< const ast::EnumInstType * >( second ) ) {
+				const ast::EnumDecl * baseEnum = dynamic_cast<const ast::EnumDecl *>(temp->base.get());
+				if ( auto t = baseEnum->base.get() ) {
+					newFirst = ast::shallowCopy( t );
+				}
+			}
+		} else if ( auto temp = dynamic_cast<const ast::EnumInstType *>(second) ) {
+			const ast::EnumDecl * baseEnum = dynamic_cast<const ast::EnumDecl *>(temp->base.get());
+			if ( auto t = baseEnum->base.get() ) {
+				newSecond = ast::shallowCopy( t );
+			}
+		}
+
 		newFirst ->qualifiers = {};
 		newSecond->qualifiers = {};
@@ -975,5 +989,5 @@
 				if ( isTuple && isTuple2 ) {
 					++it; ++jt;  // skip ttype parameters before break
-				} else if ( isTuple ) {
+				} else if ( isTuple ) { 
 					// bundle remaining params into tuple
 					pty2 = tupleFromExprs( param2, jt, params2.end(), pty->qualifiers );
Index: src/SymTab/Mangler.cc
===================================================================
--- src/SymTab/Mangler.cc	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/SymTab/Mangler.cc	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -65,4 +65,6 @@
 				void postvisit( const QualifiedType * qualType );
 
+				void postvisit( const QualifiedNameExpr * qualNameExpr );
+
 				std::string get_mangleName() { return mangleName; }
 			  private:
@@ -305,4 +307,8 @@
 					mangleName += Encoding::qualifiedTypeEnd;
 				}
+			}
+
+			void Mangler_old::postvisit( const QualifiedNameExpr * qual ) {
+				maybeAccept( qual->var, *visitor );
 			}
 
@@ -417,4 +423,5 @@
 			void postvisit( const ast::OneType * oneType );
 			void postvisit( const ast::QualifiedType * qualType );
+			void postvisit( const ast::QualifiedNameExpr * qualNameExpr );
 
 			std::string get_mangleName() { return mangleName; }
@@ -645,4 +652,7 @@
 				mangleName += Encoding::qualifiedTypeEnd;
 			}
+		}
+		void Mangler_new::postvisit( const ast::QualifiedNameExpr * qual ) {
+			maybeAccept( qual->var.get(), *visitor );
 		}
 
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/SymTab/Validate.cc	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -857,10 +857,11 @@
 		} else if ( UnionInstType * aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) {
 			declsToAddBefore.push_back( new UnionDecl( aggDecl->name, noAttributes, tyDecl->linkage ) );
-		} else if ( EnumInstType * enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) {
+		} else if ( EnumInstType * enumInst = dynamic_cast< EnumInstType * >( designatorType ) ) {
 			// declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage, enumDecl->baseEnum->base ) );
-			if (enumDecl->baseEnum) {
-				declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage, enumDecl->baseEnum->base ) );
+			if ( enumInst->baseEnum ) {
+				const EnumDecl * enumDecl = enumInst->baseEnum;
+				declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, enumDecl->isTyped, tyDecl->linkage, enumDecl->base ) );
 			} else {
-				declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage ) );
+				declsToAddBefore.push_back( new EnumDecl( enumInst->name, noAttributes, tyDecl->linkage ) );
 			}
 		} // if
Index: src/SymTab/ValidateType.cc
===================================================================
--- src/SymTab/ValidateType.cc	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/SymTab/ValidateType.cc	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -82,4 +82,6 @@
 	void postvisit( QualifiedType * qualType );
 
+	void postvisit( QualifiedNameExpr * qualExpr );
+
 	void postvisit( EnumDecl * enumDecl );
 	void postvisit( StructDecl * structDecl );
@@ -157,4 +159,9 @@
 	// linking only makes sense for the 'oldest ancestor' of the qualified type
 	qualType->parent->accept( * visitor );
+}
+
+void LinkReferenceToTypes_old::postvisit( QualifiedNameExpr * qualExpr ) {
+	const EnumDecl * st = local_indexer->lookupEnum( qualExpr->type_decl->name );
+	qualExpr->type_decl = const_cast<EnumDecl *>(st);
 }
 
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/SynTree/Declaration.h	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -145,5 +145,4 @@
 	virtual void printShort( std::ostream & os, Indenter indent = {} ) const override;
 
-	// TODO: Move to the right place
 	void checkAssignedValue() const;
 };
@@ -338,18 +337,21 @@
 	typedef AggregateDecl Parent;
   public:
+  	bool isTyped;
+	Type * base;
+
 	EnumDecl( const std::string & name,
 	 const std::list< Attribute * > & attributes = std::list< class Attribute * >(),
-	  LinkageSpec::Spec linkage = LinkageSpec::Cforall,
-	  Type * baseType = nullptr ) : Parent( name, attributes, linkage ) , base( baseType ){}
-	EnumDecl( const EnumDecl & other ) : Parent( other ), base( other.base ) {}
-
+	  bool isTyped = false, LinkageSpec::Spec linkage = LinkageSpec::Cforall,
+	  Type * baseType = nullptr ) 
+	  : Parent( name, attributes, linkage ),isTyped(isTyped), base( baseType ) {}
+	EnumDecl( const EnumDecl & other ) 
+	  : Parent( other ), isTyped( other.isTyped), base( other.base ) {}
 	bool valueOf( Declaration * enumerator, long long int & value );
-
 	virtual EnumDecl * clone() const override { return new EnumDecl( *this ); }
 	virtual void accept( Visitor & v ) override { v.visit( this ); }
 	virtual void accept( Visitor & v ) const override { v.visit( this ); }
 	virtual Declaration * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
-	Type * base;
-	std::unordered_map< std::string, long long int > enumValues;
+
+	std::unordered_map< std::string, long long int > enumValues; // This attribute is unused
 	virtual void print( std::ostream & os, Indenter indent = {} ) const override final;
   private:
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/SynTree/Expression.h	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -163,4 +163,36 @@
 };
 
+// [Qualifier].name; Qualifier is the type_name from the parser
+class QualifiedNameExpr : public Expression {
+  public:
+	Declaration * type_decl;
+	std::string name;
+	DeclarationWithType * var;
+
+	QualifiedNameExpr( Declaration * decl, std::string name): Expression(), type_decl(decl), name(name) {}
+	QualifiedNameExpr( const QualifiedNameExpr & other): Expression(other), type_decl(other.type_decl), name(other.name), var(other.var) {}
+	DeclarationWithType * get_var() const { return var; }
+	void set_var( DeclarationWithType * newValue ) { var = newValue; }
+
+	virtual ~QualifiedNameExpr() {
+		delete var;
+		delete type_decl;
+	}
+
+	virtual QualifiedNameExpr * clone() const override {
+		return new QualifiedNameExpr( * this );
+	}
+	virtual void accept( Visitor & v ) override { v.visit(this); }
+	virtual void accept( Visitor & v ) const override { v.visit(this); }
+	virtual Expression * acceptMutator( Mutator & m ) override { 
+		return m.mutate( this ); 
+	}
+	
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override {
+		type_decl->print( os, indent );
+		os << name << std::endl;
+	}
+};
+
 /// VariableExpr represents an expression that simply refers to the value of a named variable.
 /// Does not take ownership of var.
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/SynTree/Mutator.h	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -98,4 +98,5 @@
 	virtual Expression * mutate( DefaultArgExpr * argExpr ) = 0;
 	virtual Expression * mutate( GenericExpr * genExpr ) = 0;
+	virtual Expression * mutate( QualifiedNameExpr * qualifiedNameExpr ) = 0;
 
 	virtual Type * mutate( VoidType * basicType ) = 0;
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/SynTree/SynTree.h	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -103,4 +103,5 @@
 class DefaultArgExpr;
 class GenericExpr;
+class QualifiedNameExpr;
 
 class Type;
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/SynTree/Type.h	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -345,5 +345,4 @@
 	Type * parent;
 	Type * child;
-
 	QualifiedType( const Type::Qualifiers & tq, Type * parent, Type * child );
 	QualifiedType( const QualifiedType & tq );
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/SynTree/Visitor.h	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -101,4 +101,6 @@
 	virtual void visit( NameExpr * node ) { visit( const_cast<const NameExpr *>(node) ); }
 	virtual void visit( const NameExpr * nameExpr ) = 0;
+	virtual void visit( QualifiedNameExpr * node ) { visit( const_cast<const QualifiedNameExpr*>(node) );}
+	virtual void visit( const QualifiedNameExpr* qualifiednameExpr ) = 0;
 	virtual void visit( CastExpr * node ) { visit( const_cast<const CastExpr *>(node) ); }
 	virtual void visit( const CastExpr * castExpr ) = 0;
Index: src/Validate/Autogen.cpp
===================================================================
--- src/Validate/Autogen.cpp	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/Validate/Autogen.cpp	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -235,4 +235,11 @@
 	// Must visit children (enum constants) to add them to the symbol table.
 	if ( !enumDecl->body ) return;
+
+	// if ( auto enumBaseType = enumDecl->base ) {
+	// 	if ( auto enumBaseTypeAsStructInst = dynamic_cast<const ast::StructInstType *>(enumBaseType.get()) ) {
+	// 		const ast::StructDecl * structDecl = enumBaseTypeAsStructInst->base.get();
+	// 		this->previsit( structDecl );
+	// 	}
+	// }
 
 	ast::EnumInstType enumInst( enumDecl->name );
Index: src/Validate/FixQualifiedTypes.cpp
===================================================================
--- src/Validate/FixQualifiedTypes.cpp	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/Validate/FixQualifiedTypes.cpp	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -19,4 +19,6 @@
 #include "AST/TranslationUnit.hpp"
 #include "Validate/NoIdSymbolTable.hpp"
+#include "SymTab/Mangler.h"            // for Mangler
+#include "AST/LinkageSpec.hpp"			   // for Linkage
 
 namespace Validate {
@@ -89,4 +91,32 @@
 		}
 	}
+
+	ast::Expr const * postvisit( ast::QualifiedNameExpr const * t) {
+		assert( location );
+		if ( t->type_decl ) {
+        	auto enumName = t->type_decl->name;
+        	const ast::EnumDecl * enumDecl = symtab.lookupEnum( enumName );
+			for ( ast::ptr<ast::Decl> const & member : enumDecl->members ) {
+				if ( auto memberAsObj = member.as<ast::ObjectDecl>() ) {
+					if ( memberAsObj->name == t->name ) {
+						return new ast::VariableExpr( t->location, memberAsObj );
+					}
+				} else {
+					assertf( false, "unhandled qualified child type");
+				}
+			}
+
+
+        	auto var = new ast::ObjectDecl( t->var->location, t->name,
+			 new ast::EnumInstType(enumDecl, ast::CV::Const), nullptr, {}, ast::Linkage::Cforall );
+			var->scopeLevel = 1; // 1 for now; should copy the scopeLevel of the enumValue
+			var->mangleName = Mangle::mangle( var );
+			return new ast::VariableExpr( t->location, var );
+        	// return ret;
+        }
+
+		return t;
+	}
+
 };
 
Index: src/Validate/LinkReferenceToTypes.cpp
===================================================================
--- src/Validate/LinkReferenceToTypes.cpp	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/Validate/LinkReferenceToTypes.cpp	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -46,4 +46,5 @@
 	void postvisit( ast::UnionDecl const * decl );
 	ast::TraitDecl const * postvisit( ast::TraitDecl const * decl );
+	ast::QualifiedNameExpr const * previsit( ast::QualifiedNameExpr const * decl);
 
 private:
@@ -292,4 +293,37 @@
 }
 
+ast::QualifiedNameExpr const * LinkTypesCore::previsit( ast::QualifiedNameExpr const * decl ) {
+	// Try to lookup type
+	if ( auto objDecl = decl->type_decl.as<ast::ObjectDecl>() ) {
+		if ( auto inst = objDecl->type.as<ast::TypeInstType>()) {
+			if ( auto enumDecl = symtab.lookupEnum ( inst->name ) ) {
+				auto mut = ast::mutate( decl );
+				mut->type_decl = enumDecl;
+				auto enumInst = new ast::EnumInstType( enumDecl );
+				enumInst->name = decl->name;
+				// Adding result; addCandidate() use result
+				mut->result = enumInst;
+				decl = mut;
+			}
+		}
+	} else if ( auto enumDecl = decl->type_decl.as<ast::EnumDecl>() ) {
+		auto mut = ast::mutate( decl );
+		auto enumInst = new ast::EnumInstType( enumDecl );
+		enumInst->name = decl->name;
+		// Adding result; addCandidate() use result
+		mut->result = enumInst;
+		decl = mut;
+	}
+	// ast::EnumDecl const * decl = symtab.lookupEnum( type->name );
+	// // It's not a semantic error if the enum is not found, just an implicit forward declaration.
+	// if ( decl ) {
+	// 	// Just linking in the node.
+	// 	auto mut = ast::mutate( type );
+	// 	mut->base = const_cast<ast::EnumDecl *>( decl );
+	// 	type = mut;
+	// }
+	return decl;
+}
+
 } // namespace
 
Index: src/Validate/ReplaceTypedef.cpp
===================================================================
--- src/Validate/ReplaceTypedef.cpp	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ src/Validate/ReplaceTypedef.cpp	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -183,5 +183,5 @@
 	} else if ( auto enumType = dynamic_cast<ast::EnumInstType const *>( designatorType ) ) {
 		declsToAddBefore.push_back( new ast::EnumDecl(
-			decl->location, enumType->name, {}, decl->linkage,
+			decl->location, enumType->name, false, {}, decl->linkage,
 			( (enumType->base) ? enumType->base->base : nullptr )
 			) );
Index: tests/enum_tests/.expect/pointerEnum.cfa
===================================================================
--- tests/enum_tests/.expect/pointerEnum.cfa	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
+++ tests/enum_tests/.expect/pointerEnum.cfa	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -0,0 +1,1 @@
+v: 1
Index: tests/enum_tests/.expect/qualifiedEnum.cfa
===================================================================
--- tests/enum_tests/.expect/qualifiedEnum.cfa	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
+++ tests/enum_tests/.expect/qualifiedEnum.cfa	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -0,0 +1,1 @@
+l :0
Index: tests/enum_tests/.expect/voidEnum.txt
===================================================================
--- tests/enum_tests/.expect/voidEnum.txt	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
+++ tests/enum_tests/.expect/voidEnum.txt	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -0,0 +1,3 @@
+Not Equal
+0
+1
Index: tests/enum_tests/funcEnum.cfa
===================================================================
--- tests/enum_tests/funcEnum.cfa	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
+++ tests/enum_tests/funcEnum.cfa	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -0,0 +1,15 @@
+#include <stdio.h>
+void my_int_func(int x)
+{
+    printf( "%d\n", x );
+}
+ 
+int main()
+{
+    void (*foo)(int);
+    enum( void (*)(int) ) { FF = &my_int_func }; 
+    /* the ampersand is actually optional */
+    foo = &my_int_func;
+    foo(5);
+    return 0;
+}
Index: tests/enum_tests/pointerEnum.cfa
===================================================================
--- tests/enum_tests/pointerEnum.cfa	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
+++ tests/enum_tests/pointerEnum.cfa	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -0,0 +1,14 @@
+#include <fstream.hfa>
+
+struct E {
+    int x;
+};
+struct E e = {1};
+enum(E *) {
+    First = &e,
+};
+
+int main() {
+    E * v = First;
+    sout | "v: " | e.x;
+}
Index: tests/enum_tests/qualifiedEnum.cfa
===================================================================
--- tests/enum_tests/qualifiedEnum.cfa	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
+++ tests/enum_tests/qualifiedEnum.cfa	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -0,0 +1,13 @@
+#include <fstream.hfa>
+
+enum Level {
+  LOW,
+  MEDIUM,
+  HIGH
+};
+
+int main() {
+    enum Level l = Level.LOW;
+    sout | "l :" | l;
+    return 0;
+}
Index: tests/enum_tests/structEnum.cfa
===================================================================
--- tests/enum_tests/structEnum.cfa	(revision 1c893aef63e3cbbf67a354696e988219eb19aff6)
+++ tests/enum_tests/structEnum.cfa	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -2,29 +2,37 @@
 
 struct Point {
-    int x;
-    char y;
+     int x;
+     char y;
 };
 
 enum(Point) PointEnum {
-    first={
-        100,
-        'c'
-    },
-    second={
-        200,
-        'a'
-    }
+     first={
+         100,
+         'c'
+     },
+     second={
+         200,
+         'a'
+     }
 };
+
+PointEnum foo(PointEnum in) {
+     return in;
+}
 
 // The only valid usage
 struct Point apple = first;
 // Failed due to Qualified name is currently unimplemented.
-// struct Point banana = PointEnum.first;
 
 int main() {
-    printf("%d %c\n", apple.x, apple.y);
-    // Failed; enumInstType is now not a real type and not instantiated.
-    // Not sure if we want that
-    // printf("%d %c\n", second.x, second.y);
-    return 0;
+     PointEnum vals = second;
+     PointEnum val2;
+     // The failing line: assignment
+     // val2 = vals;
+
+     printf("%d %c\n", apple.x, apple.y);
+     // Failed; enumInstType is now not a real type and not instantiated.
+     // Not sure if we want that
+     // printf("%d %c\n", second.x, second.y);
+     return 0;
 }
Index: tests/enum_tests/voidEnum.cfa
===================================================================
--- tests/enum_tests/voidEnum.cfa	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
+++ tests/enum_tests/voidEnum.cfa	(revision dc56b9d88cf82f868f003d67991e756cbbd93bf1)
@@ -0,0 +1,26 @@
+#include <fstream.hfa>
+
+enum() voidEnum {
+    a, b, c
+    /*** 
+    * ,d = 10 // Disable; 
+    * //error: Enumerator of enum(void) cannot have an explicit initial value.
+    */
+};
+
+// void foo (const enum voidEnum & t){}
+
+int main() {
+    enum voidEnum v_1 = a;
+    enum voidEnum v_2 = b;
+    // foo(b);
+    // enum voidEnum v_3 = 10;
+    // Error as int cannot convert to void enum
+    if ( v_1 == v_2 ) {
+        sout | "Equal" | nl;
+    } else {
+        sout | "Not Equal" | nl;
+    }
+    sout | a | nl;
+    sout | b | nl;
+}
