Index: src/AST/Decl.cpp
===================================================================
--- src/AST/Decl.cpp	(revision 822332e90fec6c4a9a05fd800863fb5009a81bcd)
+++ src/AST/Decl.cpp	(revision 348f8992a1804b5bc5ecd4646bcdffd6293aa9f0)
@@ -170,11 +170,36 @@
 
 const std::string EnumDecl::getUnmangeldArrayName( const ast::EnumAttribute attr ) const {
-		switch( attr ) {
-			case ast::EnumAttribute::Value: return "values_" + name ;
-			case ast::EnumAttribute::Label: return "labels_" + name;
-			default: /* Posn does not generate array */ 
-				return "";
+	switch( attr ) {
+		case ast::EnumAttribute::Value: return "values_" + name ;
+		case ast::EnumAttribute::Label: return "labels_" + name;
+		default: /* Posn does not generate array */ 
+			return "";
+	}
+}
+
+unsigned EnumDecl::calChildOffset(const std::string & target) const{
+	unsigned offset = 0;
+	for (auto childEnum: inlinedDecl) {
+		auto childDecl = childEnum->base;
+		if (childDecl->name == target) {
+			return offset;
 		}
-	}
+		offset += childDecl->members.size();
+	}
+    std::cerr << "Cannot find the target enum" << std::endl;
+	return 0;
+}
+
+unsigned EnumDecl::calChildOffset(const ast::EnumInstType * target) const{
+	return calChildOffset(target->base->name);
+}
+
+bool EnumDecl::isSubTypeOf(const ast::EnumDecl * other) const {
+	if (name == other->name) return true;
+	for (auto inlined: other->inlinedDecl) {
+		if (isSubTypeOf(inlined->base)) return true;
+	}
+	return false;
+}
 
 }
Index: src/AST/Decl.hpp
===================================================================
--- src/AST/Decl.hpp	(revision 822332e90fec6c4a9a05fd800863fb5009a81bcd)
+++ src/AST/Decl.hpp	(revision 348f8992a1804b5bc5ecd4646bcdffd6293aa9f0)
@@ -75,4 +75,5 @@
 	bool isDeleted = false;
 	bool isTypeFixed = false;
+	bool isHidden = false;
 
 	DeclWithType( const CodeLocation& loc, const std::string& name, Storage::Classes storage,
@@ -313,4 +314,6 @@
 	ptr<Type> base;
 	enum class EnumHiding { Visible, Hide } hide;
+	std::vector< ast::ptr<ast::EnumInstType>> inlinedDecl; // child enums
+
 	EnumDecl( const CodeLocation& loc, const std::string& name, bool isTyped = false,
 		std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall,
@@ -328,4 +331,9 @@
 
 	const std::string getUnmangeldArrayName( const EnumAttribute attr ) const;
+
+	unsigned calChildOffset(const std::string & childEnum) const;
+	unsigned calChildOffset(const ast::EnumInstType * childEnum) const;
+
+	bool isSubTypeOf(const ast::EnumDecl *) const;
 private:
 	EnumDecl * clone() const override { return new EnumDecl{ *this }; }
Index: src/AST/Expr.hpp
===================================================================
--- src/AST/Expr.hpp	(revision 822332e90fec6c4a9a05fd800863fb5009a81bcd)
+++ src/AST/Expr.hpp	(revision 348f8992a1804b5bc5ecd4646bcdffd6293aa9f0)
@@ -256,8 +256,12 @@
 public:
 	ptr<Decl> type_decl;
-	std::string name;
+	const std::string type_name;
+	const std::string name;
 
 	QualifiedNameExpr( const CodeLocation & loc, const Decl * d, const std::string & n )
-	: Expr( loc ), type_decl( d ), name( n ) {}
+	: Expr( loc ), type_decl( d ), type_name(""), name( n ) {}
+
+	QualifiedNameExpr( const CodeLocation & loc, const std::string & type_name, const std::string & name)
+	: Expr( loc ), type_name( type_name ), name( name ) {}
 
 	const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
Index: src/AST/Pass.impl.hpp
===================================================================
--- src/AST/Pass.impl.hpp	(revision 822332e90fec6c4a9a05fd800863fb5009a81bcd)
+++ src/AST/Pass.impl.hpp	(revision 348f8992a1804b5bc5ecd4646bcdffd6293aa9f0)
@@ -560,16 +560,9 @@
 
 	if ( __visit_children() ) {
-		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 );
-		}
+		maybe_accept( node, &EnumDecl::base        );
+		maybe_accept( node, &EnumDecl::params      );
+		maybe_accept( node, &EnumDecl::members     );
+		maybe_accept( node, &EnumDecl::attributes  );
+		maybe_accept( node, &EnumDecl::inlinedDecl );
 	}
 
Index: src/AST/SymbolTable.cpp
===================================================================
--- src/AST/SymbolTable.cpp	(revision 822332e90fec6c4a9a05fd800863fb5009a81bcd)
+++ src/AST/SymbolTable.cpp	(revision 348f8992a1804b5bc5ecd4646bcdffd6293aa9f0)
@@ -159,4 +159,16 @@
 }
 
+std::vector<SymbolTable::IdData> SymbolTable::lookupIdIgnoreHidden( const std::string &id ) const {
+	std::vector<IdData> out;
+	std::vector<IdData> lookupResult = lookupId(id);
+	for ( auto candidate: lookupResult) {
+		if ( candidate.id ) {
+			if (candidate.id->isHidden) continue;
+		}
+		out.push_back(candidate);
+	}
+	return out;
+}
+
 std::vector<SymbolTable::IdData> SymbolTable::specialLookupId( SymbolTable::SpecialFunctionKind kind, const std::string & otypeKey ) const {
 	static Stats::Counters::CounterGroup * special_stats = Stats::Counters::build<Stats::Counters::CounterGroup>("Special Lookups");
Index: src/AST/SymbolTable.hpp
===================================================================
--- src/AST/SymbolTable.hpp	(revision 822332e90fec6c4a9a05fd800863fb5009a81bcd)
+++ src/AST/SymbolTable.hpp	(revision 348f8992a1804b5bc5ecd4646bcdffd6293aa9f0)
@@ -121,4 +121,6 @@
 	/// Gets all declarations with the given ID
 	std::vector<IdData> lookupId( const std::string &id ) const;
+	/// Gets all declarations with the given ID, ignoring hidden members from enumeration
+	std::vector<IdData> lookupIdIgnoreHidden( const std::string &id ) const;
 	/// Gets special functions associated with a type; if no key is given, returns everything
 	std::vector<IdData> specialLookupId( SpecialFunctionKind kind, const std::string & otypeKey = "" ) const;
Index: src/AST/Util.cpp
===================================================================
--- src/AST/Util.cpp	(revision 822332e90fec6c4a9a05fd800863fb5009a81bcd)
+++ src/AST/Util.cpp	(revision 348f8992a1804b5bc5ecd4646bcdffd6293aa9f0)
@@ -352,8 +352,6 @@
 	void previsit( EnumDecl const * decl ) {
 		enumDecls.insert( decl );
-		if ( ast::EnumDecl::EnumHiding::Visible == decl->hide ) {
-			for ( auto & member : decl->members ) {
-				typedDecls.insert( member.strict_as<ast::DeclWithType>() );
-			}
+		for ( auto & member : decl->members ) {
+			typedDecls.insert( member.strict_as<ast::DeclWithType>() );
 		}
 		beginScope();
