Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision 71806e0f8878eff4daf459af6ea5ef2c730185da)
+++ src/AST/Convert.cpp	(revision e4d7c1c357a5b1b2a17a980a263be977539b988b)
@@ -1764,4 +1764,5 @@
 			{ old->linkage.val },
 			GET_ACCEPT_1(base, Type),
+			old->hide == EnumDecl::EnumHiding::Hide ? ast::EnumDecl::EnumHiding::Hide : ast::EnumDecl::EnumHiding::Visible,
 			old->enumValues
 		);
Index: src/AST/Decl.hpp
===================================================================
--- src/AST/Decl.hpp	(revision 71806e0f8878eff4daf459af6ea5ef2c730185da)
+++ src/AST/Decl.hpp	(revision e4d7c1c357a5b1b2a17a980a263be977539b988b)
@@ -315,10 +315,11 @@
 	// enum (type_optional) Name {...} 
 	ptr<Type> base; // if isTyped == true && base.get() == nullptr, it is a "void" type enum
-
-	EnumDecl( const CodeLocation& loc, const std::string& name, bool isTyped = false, 
+	enum class EnumHiding { Visible, Hide } hide;
+
+	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,
+		Type const * base = nullptr, EnumHiding hide = EnumHiding::Hide,
 		std::unordered_map< std::string, long long > enumValues = std::unordered_map< std::string, long long >() )
-	: AggregateDecl( loc, name, std::move(attrs), linkage ), isTyped(isTyped), base(base), enumValues(enumValues) {}
+	: AggregateDecl( loc, name, std::move(attrs), linkage ), isTyped(isTyped), base(base), hide(hide), enumValues(enumValues) {}
 
 	/// gets the integer value for this enumerator, returning true iff value found
Index: src/AST/Pass.impl.hpp
===================================================================
--- src/AST/Pass.impl.hpp	(revision 71806e0f8878eff4daf459af6ea5ef2c730185da)
+++ src/AST/Pass.impl.hpp	(revision e4d7c1c357a5b1b2a17a980a263be977539b988b)
@@ -686,9 +686,16 @@
 
 	if ( __visit_children() ) {
-		// unlike structs, traits, and unions, enums inject their members into the global scope
-		maybe_accept( node, &EnumDecl::base );
-		maybe_accept( node, &EnumDecl::params     );
-		maybe_accept( node, &EnumDecl::members    );
-		maybe_accept( node, &EnumDecl::attributes );
+		if ( node->hide == ast::EnumDecl::EnumHiding::Hide ) {
+			guard_symtab guard { *this };
+			maybe_accept( node, &EnumDecl::base );
+			maybe_accept( node, &EnumDecl::params     );
+			maybe_accept( node, &EnumDecl::members    );
+			maybe_accept( node, &EnumDecl::attributes );
+		} else {
+			maybe_accept( node, &EnumDecl::base );
+			maybe_accept( node, &EnumDecl::params     );
+			maybe_accept( node, &EnumDecl::members    );
+			maybe_accept( node, &EnumDecl::attributes );
+		}
 	}
 
Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision 71806e0f8878eff4daf459af6ea5ef2c730185da)
+++ src/Parser/DeclarationNode.cc	(revision e4d7c1c357a5b1b2a17a980a263be977539b988b)
@@ -254,5 +254,5 @@
 } // DeclarationNode::newAggregate
 
-DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base) {
+DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base, EnumHiding hiding ) {
 	DeclarationNode * newnode = new DeclarationNode;
 	newnode->type = new TypeData( TypeData::Enum );
@@ -262,4 +262,5 @@
 	newnode->type->enumeration.anon = name == nullptr;
 	newnode->type->enumeration.typed = typed;
+	newnode->type->enumeration.hiding = hiding;
 	if ( base && base->type)  {
 		newnode->type->base = base->type;
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision 71806e0f8878eff4daf459af6ea5ef2c730185da)
+++ src/Parser/ParseNode.h	(revision e4d7c1c357a5b1b2a17a980a263be977539b988b)
@@ -239,5 +239,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, bool typed, DeclarationNode * base = nullptr );
+	static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr, EnumHiding hiding = EnumHiding::Visible );
 	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 71806e0f8878eff4daf459af6ea5ef2c730185da)
+++ src/Parser/TypeData.cc	(revision e4d7c1c357a5b1b2a17a980a263be977539b988b)
@@ -923,4 +923,5 @@
 	buildList( td->enumeration.constants, ret->get_members() );
 	list< Declaration * >::iterator members = ret->get_members().begin();
+	ret->hide = td->enumeration.hiding == EnumHiding::Hide ? EnumDecl::EnumHiding::Hide : EnumDecl::EnumHiding::Visible;
 	for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) {
 		if ( cur->enumInLine ) {
Index: src/Parser/TypeData.h
===================================================================
--- src/Parser/TypeData.h	(revision 71806e0f8878eff4daf459af6ea5ef2c730185da)
+++ src/Parser/TypeData.h	(revision e4d7c1c357a5b1b2a17a980a263be977539b988b)
@@ -60,4 +60,5 @@
 		bool anon;
 		bool typed;
+		EnumHiding hiding;
 	};
 
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 71806e0f8878eff4daf459af6ea5ef2c730185da)
+++ src/Parser/parser.yy	(revision e4d7c1c357a5b1b2a17a980a263be977539b988b)
@@ -2558,8 +2558,8 @@
 		{ typedefTable.makeTypedef( *$3 ); }
 	  hide_opt '{' enumerator_list comma_opt '}'
-	  { $$ = DeclarationNode::newEnum( $3, $7, true, false )->addQualifiers( $2 ); }
+	  { $$ = DeclarationNode::newEnum( $3, $7, true, false, nullptr, $5 )->addQualifiers( $2 ); }
 	| ENUM attribute_list_opt typedef_name				// unqualified type name
 	  hide_opt '{' enumerator_list comma_opt '}'
-		{ $$ = DeclarationNode::newEnum( $3->name, $6, true, false )->addQualifiers( $2 ); }
+		{ $$ = DeclarationNode::newEnum( $3->name, $6, true, false, nullptr, $4 )->addQualifiers( $2 ); }
 	| ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}'
 	 	{
@@ -2580,20 +2580,20 @@
 	  hide_opt '{' enumerator_list comma_opt '}'
 		{
-			$$ = DeclarationNode::newEnum( $6, $11, true, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 );
+			$$ = DeclarationNode::newEnum( $6, $11, true, true, $3, $9 )->addQualifiers( $5 )->addQualifiers( $7 );
 		}
 	| ENUM '(' ')' attribute_list_opt identifier attribute_list_opt
 	  hide_opt '{' enumerator_list comma_opt '}'
 		{
-			$$ = DeclarationNode::newEnum( $5, $9, true, true, nullptr )->addQualifiers( $4 )->addQualifiers( $6 );
+			$$ = DeclarationNode::newEnum( $5, $9, true, true, nullptr, $7 )->addQualifiers( $4 )->addQualifiers( $6 );
 		}
 	| ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt typedef_name attribute_list_opt
 	  hide_opt '{' enumerator_list comma_opt '}'
 		{
-			$$ = DeclarationNode::newEnum( $6->name, $10, true, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 );
+			$$ = DeclarationNode::newEnum( $6->name, $10, true, true, $3, $8 )->addQualifiers( $5 )->addQualifiers( $7 );
 		}
 	| ENUM '(' ')' attribute_list_opt typedef_name attribute_list_opt
 	  hide_opt '{' enumerator_list comma_opt '}'
 		{
-			$$ = DeclarationNode::newEnum( $5->name, $9, true, true, nullptr )->addQualifiers( $4 )->addQualifiers( $6 );
+			$$ = DeclarationNode::newEnum( $5->name, $9, true, true, nullptr, $7 )->addQualifiers( $4 )->addQualifiers( $6 );
 		}
 	| enum_type_nobody
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision 71806e0f8878eff4daf459af6ea5ef2c730185da)
+++ src/SynTree/Declaration.h	(revision e4d7c1c357a5b1b2a17a980a263be977539b988b)
@@ -340,4 +340,5 @@
   	bool isTyped;
 	Type * base;
+	enum EnumHiding { Visible, Hide } hide;
 
 	EnumDecl( const std::string & name,
@@ -345,5 +346,5 @@
 	  bool isTyped = false, LinkageSpec::Spec linkage = LinkageSpec::Cforall,
 	  Type * baseType = nullptr ) 
-	  : Parent( name, attributes, linkage ),isTyped(isTyped), base( baseType ) {}
+	  : Parent( name, attributes, linkage ), isTyped(isTyped), base( baseType ) {}
 	EnumDecl( const EnumDecl & other ) 
 	  : Parent( other ), isTyped( other.isTyped), base( other.base ) {}
