Index: src/AST/Decl.cpp
===================================================================
--- src/AST/Decl.cpp	(revision 4e0168a377ffa27413e536c47c0454d91422bc2a)
+++ src/AST/Decl.cpp	(revision 90be0cf4038a0d324a55f8ab409c9aa1b4ba02e2)
@@ -169,38 +169,4 @@
 }
 
-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 "";
-	}
-}
-
-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;
-}
-
 bool EnumDecl::isTyped() const { return base; }
 
Index: src/AST/Decl.hpp
===================================================================
--- src/AST/Decl.hpp	(revision 4e0168a377ffa27413e536c47c0454d91422bc2a)
+++ src/AST/Decl.hpp	(revision 90be0cf4038a0d324a55f8ab409c9aa1b4ba02e2)
@@ -302,5 +302,7 @@
 };
 
+/// Enumeration attribute kind.
 enum class EnumAttribute{ Value, Posn, Label };
+
 /// enum declaration `enum Foo { ... };`
 class EnumDecl final : public AggregateDecl {
@@ -328,10 +330,4 @@
 	const char * typeString() const override { return aggrString( Enum ); }
 
-	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;
 	bool isTyped() const;
 	bool isOpaque() const;
Index: src/ResolvExpr/CandidateFinder.cpp
===================================================================
--- src/ResolvExpr/CandidateFinder.cpp	(revision 4e0168a377ffa27413e536c47c0454d91422bc2a)
+++ src/ResolvExpr/CandidateFinder.cpp	(revision 90be0cf4038a0d324a55f8ab409c9aa1b4ba02e2)
@@ -2136,4 +2136,18 @@
 }
 
+/// If the target enum is a child, get the offset from the base to the target.
+static unsigned findChildOffset(
+		const ast::EnumDecl * decl, const ast::EnumDecl * target ) {
+	unsigned offset = 0;
+	for ( auto inlined : decl->inlinedDecl ) {
+		auto childDecl = inlined->base;
+		if ( childDecl == target ) {
+			return offset;
+		}
+		offset += childDecl->members.size();
+	}
+	SemanticError( decl, "Cannot find the target enum." );
+}
+
 const ast::Expr * CandidateFinder::makeEnumOffsetCast( const ast::EnumInstType * src, 
 	const ast::EnumInstType * dst, const ast::Expr * expr, Cost minCost ) {
@@ -2147,9 +2161,9 @@
 		ast::CastExpr * castToDst;
 		if (c<minCost) {
-			unsigned offset = dstDecl->calChildOffset(dstChild.get());
+			unsigned offset = findChildOffset( dstDecl, dstChild.get()->base );
 			if (offset > 0) {
 				auto untyped = ast::UntypedExpr::createCall(
-					expr->location, 
-					"?+?", 
+					expr->location,
+					"?+?",
 					{ new ast::CastExpr( expr->location,
 						expr,
Index: src/ResolvExpr/CommonType.cpp
===================================================================
--- src/ResolvExpr/CommonType.cpp	(revision 4e0168a377ffa27413e536c47c0454d91422bc2a)
+++ src/ResolvExpr/CommonType.cpp	(revision 90be0cf4038a0d324a55f8ab409c9aa1b4ba02e2)
@@ -636,4 +636,14 @@
 	void postvisit( const ast::UnionInstType * ) {}
 
+	/// Is the target enum a child of the base enum?
+	static bool isChildEnum(
+			const ast::EnumDecl * decl, const ast::EnumDecl * target ) {
+		if ( decl == target ) return true;
+		for ( auto inlined : decl->inlinedDecl ) {
+			if ( isChildEnum( inlined->base, target ) ) return true;
+		}
+		return false;
+	}
+
 	void postvisit( const ast::EnumInstType * param ) {
 		auto argAsEnumInst = dynamic_cast<const ast::EnumInstType *>(type2);
@@ -641,5 +651,7 @@
 			const ast::EnumDecl* paramDecl = param->base;
 			const ast::EnumDecl* argDecl = argAsEnumInst->base;
-			if (argDecl->isSubTypeOf(paramDecl)) result = param;
+			if ( isChildEnum( paramDecl, argDecl ) ) {
+				result = param;
+			}
 		} else if ( param->base && !param->base->isCfa ) {
 			auto basicType = new ast::BasicType( ast::BasicKind::UnsignedInt );
Index: src/Validate/ImplementEnumFunc.cpp
===================================================================
--- src/Validate/ImplementEnumFunc.cpp	(revision 4e0168a377ffa27413e536c47c0454d91422bc2a)
+++ src/Validate/ImplementEnumFunc.cpp	(revision 90be0cf4038a0d324a55f8ab409c9aa1b4ba02e2)
@@ -78,6 +78,6 @@
 	std::vector<ast::ptr<ast::Init>> genValueInit() const;
 	ast::ObjectDecl* genAttrArrayProto(
-		const ast::EnumAttribute attr, const CodeLocation& location,
-		std::vector<ast::ptr<ast::Init>>& inits) const;
+		const CodeLocation& location, const std::string& prefix,
+		const ast::Type * type, std::vector<ast::ptr<ast::Init>>& inits ) const;
 };
 
@@ -351,11 +351,8 @@
 
 ast::ObjectDecl* EnumAttrFuncGenerator::genAttrArrayProto(
-	const ast::EnumAttribute attr, const CodeLocation& location,
-	std::vector<ast::ptr<ast::Init>>& inits) const {
+		const CodeLocation& location, const std::string& prefix,
+		const ast::Type * type, std::vector<ast::ptr<ast::Init>>& inits ) const {
 	ast::ArrayType* arrT = new ast::ArrayType(
-		attr == ast::EnumAttribute::Value
-			? decl->base
-			: new ast::PointerType(
-				new ast::BasicType(ast::BasicKind::Char, ast::CV::Const)),
+		type,
 		ast::ConstantExpr::from_int(decl->location, decl->members.size()),
 		ast::LengthFlag::FixedLen, ast::DimensionFlag::DynamicDim);
@@ -363,5 +360,5 @@
 	ast::ObjectDecl* objDecl =
 		new ast::ObjectDecl(
-			decl->location, decl->getUnmangeldArrayName( attr ),
+			decl->location, prefix + decl->name,
 			arrT, new ast::ListInit( location, std::move( inits ) ),
 			ast::Storage::Static, ast::Linkage::AutoGen );
@@ -417,26 +414,20 @@
 void EnumAttrFuncGenerator::genTypedEnumFunction(const ast::EnumAttribute attr) {
 	if (attr == ast::EnumAttribute::Value) {
-		if (decl->isTyped()) {
-			// TypedEnum's backing arrays
-			std::vector<ast::ptr<ast::Init>> inits = genValueInit();
-			ast::ObjectDecl* arrayProto =
-				genAttrArrayProto(attr, getLocation(), inits);
-			forwards.push_back(arrayProto);
-
-			ast::FunctionDecl* funcProto = genValueProto();
-			produceForwardDecl(funcProto);
-			genValueOrLabelBody(funcProto, arrayProto);
-			produceDecl(funcProto);
-		}  
-		// else {
-		// 	ast::FunctionDecl* funcProto = genQuasiValueProto();
-		// 	produceForwardDecl(funcProto);
-		// 	// genQuasiValueBody(funcProto);
-		// 	produceDecl(funcProto);
-		// }
+		if ( !decl->isTyped() ) return;
+		std::vector<ast::ptr<ast::Init>> inits = genValueInit();
+		ast::ObjectDecl* arrayProto =
+			genAttrArrayProto( getLocation(), "values_", decl->base, inits );
+		forwards.push_back(arrayProto);
+
+		ast::FunctionDecl* funcProto = genValueProto();
+		produceForwardDecl(funcProto);
+		genValueOrLabelBody(funcProto, arrayProto);
+		produceDecl(funcProto);
 	} else if (attr == ast::EnumAttribute::Label) {
 		std::vector<ast::ptr<ast::Init>> inits = genLabelInit();
+		const ast::Type * type = new ast::PointerType(
+			new ast::BasicType( ast::BasicKind::Char, ast::CV::Const ) );
 		ast::ObjectDecl* arrayProto =
-			genAttrArrayProto(attr, getLocation(), inits);
+			genAttrArrayProto( getLocation(), "labels_", type, inits );
 		forwards.push_back(arrayProto);
 		ast::FunctionDecl* funcProto = genLabelProto();
@@ -445,4 +436,5 @@
 		produceDecl(funcProto);
 	} else {
+		assert( attr == ast::EnumAttribute::Posn );
 		ast::FunctionDecl* funcProto = genPosnProto();
 		produceForwardDecl(funcProto);
