Index: src/ResolvExpr/ResolveTypeof.cc
===================================================================
--- src/ResolvExpr/ResolveTypeof.cc	(revision 4894239fc9c15905847850e8ebfb6a2a288a5cdf)
+++ src/ResolvExpr/ResolveTypeof.cc	(revision c1e66d966aadf6846330871033458d4a398bd576)
@@ -24,7 +24,8 @@
 #include "AST/Type.hpp"
 #include "AST/TypeEnvironment.hpp"
-#include "Common/PassVisitor.h"   // for PassVisitor
-#include "Common/utility.h"       // for copy
-#include "InitTweak/InitTweak.h"  // for isConstExpr
+#include "Common/PassVisitor.h"    // for PassVisitor
+#include "Common/SemanticError.h"  // for SemanticError
+#include "Common/utility.h"        // for copy
+#include "InitTweak/InitTweak.h"   // for isConstExpr
 #include "RenameVars.h"
 #include "Resolver.h"  // for resolveInVoidContext
@@ -50,11 +51,11 @@
 		}
 #endif
-	}
+}  // namespace
 
 class ResolveTypeof_old : public WithShortCircuiting {
    public:
-		ResolveTypeof_old( const SymTab::Indexer &indexer ) : indexer( indexer ) {}
-		void premutate( TypeofType *typeofType );
-		Type * postmutate( TypeofType *typeofType );
+    ResolveTypeof_old(const SymTab::Indexer &indexer) : indexer(indexer) {}
+    void premutate(TypeofType *typeofType);
+    Type *postmutate(TypeofType *typeofType);
 
    private:
@@ -62,14 +63,12 @@
 };
 
-	Type * resolveTypeof( Type *type, const SymTab::Indexer &indexer ) {
-		PassVisitor<ResolveTypeof_old> mutator( indexer );
-		return type->acceptMutator( mutator );
-	}
-
-	void ResolveTypeof_old::premutate( TypeofType * ) {
-		visit_children = false;
-	}
-
-    Type * ResolveTypeof_old::postmutate( TypeofType *typeofType ) {
+Type *resolveTypeof(Type *type, const SymTab::Indexer &indexer) {
+    PassVisitor<ResolveTypeof_old> mutator(indexer);
+    return type->acceptMutator(mutator);
+}
+
+void ResolveTypeof_old::premutate(TypeofType *) { visit_children = false; }
+
+Type *ResolveTypeof_old::postmutate(TypeofType *typeofType) {
 #if 0
 		std::cerr << "resolving typeof: ";
@@ -78,5 +77,5 @@
 #endif
     // pass on null expression
-		if ( ! typeofType->expr ) return typeofType;
+    if (!typeofType->expr) return typeofType;
 
     bool isBasetypeof = typeofType->is_basetypeof;
@@ -84,5 +83,5 @@
 
     Type* newType;
-		if ( TypeExpr* tyExpr = dynamic_cast<TypeExpr*>(typeofType->expr) ) {
+    if ( TypeExpr* tyExpr = dynamic_cast<TypeExpr*>( typeofType->expr ) ) {
         // typeof wrapping type
         newType = tyExpr->type;
@@ -91,6 +90,6 @@
     } else {
         // typeof wrapping expression
-			Expression * newExpr = resolveInVoidContext( typeofType->expr, indexer );
-			assert( newExpr->result && ! newExpr->result->isVoid() );
+        Expression *newExpr = resolveInVoidContext(typeofType->expr, indexer);
+        assert(newExpr->result && !newExpr->result->isVoid());
         newType = newExpr->result;
         newExpr->result = nullptr;
@@ -100,16 +99,17 @@
 
     // clear qualifiers for base, combine with typeoftype quals in any case
-    if ( isBasetypeof ) {
-			// replace basetypeof(<enum>) by int
-			if ( dynamic_cast<EnumInstType*>(newType) ) {
-				Type* newerType =
-					new BasicType{ newType->get_qualifiers(), BasicType::SignedInt,
-					newType->attributes };
-				delete newType;
-				newType = newerType;
-			}
-			newType->get_qualifiers().val
-				= ( newType->get_qualifiers().val & ~Type::Qualifiers::Mask ) | oldQuals;
-		} else {
+    if (isBasetypeof) {
+        // replace basetypeof(<enum>) by int
+        if (dynamic_cast<EnumInstType *>(newType)) {
+            Type *newerType =
+                new BasicType{newType->get_qualifiers(), BasicType::SignedInt,
+                              newType->attributes};
+            delete newType;
+            newType = newerType;
+        }
+        newType->get_qualifiers().val =
+            (newType->get_qualifiers().val & ~Type::Qualifiers::Mask) |
+            oldQuals;
+    } else {
         newType->get_qualifiers().val |= oldQuals;
     }
@@ -120,17 +120,16 @@
 namespace {
 struct ResolveTypeof_new : public ast::WithShortCircuiting {
-    const ResolveContext & context;
-
-		ResolveTypeof_new( const ResolveContext & context ) :
-			context( context ) {}
-
-		void previsit( const ast::TypeofType * ) { visit_children = false; }
-
-        const ast::Type * postvisit( const ast::TypeofType * typeofType ) {
+    const ResolveContext &context;
+
+    ResolveTypeof_new(const ResolveContext &context) : context(context) {}
+
+    void previsit(const ast::TypeofType *) { visit_children = false; }
+
+    const ast::Type *postvisit(const ast::TypeofType *typeofType) {
         // pass on null expression
-            if ( ! typeofType->expr ) return typeofType;
-
-            ast::ptr< ast::Type > newType;
-            if ( auto tyExpr = typeofType->expr.as< ast::TypeExpr >() ) {
+        if (!typeofType->expr) return typeofType;
+
+        ast::ptr<ast::Type> newType;
+        if (auto tyExpr = typeofType->expr.as<ast::TypeExpr>()) {
             // typeof wrapping type
             newType = tyExpr->type;
@@ -138,22 +137,23 @@
             // typeof wrapping expression
             ast::TypeEnvironment dummy;
-            ast::ptr< ast::Expr > newExpr =
-                resolveInVoidContext( typeofType->expr, context, dummy );
-            assert( newExpr->result && ! newExpr->result->isVoid() );
+            ast::ptr<ast::Expr> newExpr =
+                resolveInVoidContext(typeofType->expr, context, dummy);
+            assert(newExpr->result && !newExpr->result->isVoid());
             newType = newExpr->result;
         }
 
         // clear qualifiers for base, combine with typeoftype quals regardless
-        if ( typeofType->kind == ast::TypeofType::Basetypeof ) {
+        if (typeofType->kind == ast::TypeofType::Basetypeof) {
             // replace basetypeof(<enum>) by int
-				if ( newType.as< ast::EnumInstType >() ) {
-					newType = new ast::BasicType{
-						ast::BasicType::SignedInt, newType->qualifiers, copy(newType->attributes) };
+            if (newType.as<ast::EnumInstType>()) {
+                newType = new ast::BasicType{ast::BasicType::SignedInt,
+                                             newType->qualifiers,
+                                             copy(newType->attributes)};
             }
-				reset_qualifiers(
-					newType,
-					( newType->qualifiers & ~ast::CV::EquivQualifiers ) | typeofType->qualifiers );
+            reset_qualifiers(newType,
+                             (newType->qualifiers & ~ast::CV::EquivQualifiers) |
+                                 typeofType->qualifiers);
         } else {
-				add_qualifiers( newType, typeofType->qualifiers );
+            add_qualifiers(newType, typeofType->qualifiers);
         }
 
@@ -161,38 +161,79 @@
     }
 };
-} // anonymous namespace
-
-const ast::Type * resolveTypeof( const ast::Type * type , const ResolveContext & context ) {
-	ast::Pass< ResolveTypeof_new > mutator( context );
-	return type->accept( mutator );
+}  // anonymous namespace
+
+const ast::Type *resolveTypeof(const ast::Type *type,
+                               const ResolveContext &context) {
+    ast::Pass<ResolveTypeof_new> mutator(context);
+    return type->accept(mutator);
 }
 
 struct FixArrayDimension {
-	const ResolveContext & context;
-	FixArrayDimension(const ResolveContext & context) : context( context ) {}
-
-	const ast::ArrayType * previsit (const ast::ArrayType * arrayType) {
-		if (!arrayType->dimension) return arrayType;
-		auto mutType = mutate(arrayType);
-		auto globalSizeType = context.global.sizeType;
-		ast::ptr<ast::Type> sizetype = globalSizeType ? globalSizeType : new ast::BasicType(ast::BasicType::LongUnsignedInt);
-		mutType->dimension = findSingleExpression(arrayType->dimension, sizetype, context );
-
-		if (InitTweak::isConstExpr(mutType->dimension)) {
-			mutType->isVarLen = ast::LengthFlag::FixedLen;
-		}
-		else {
-			mutType->isVarLen = ast::LengthFlag::VariableLen;
-		}
-		return mutType;
-	}
+    const ResolveContext &context;
+    FixArrayDimension(const ResolveContext &context) : context(context) {}
+
+    const ast::ArrayType *previsit(const ast::ArrayType *arrayType) {
+        if (!arrayType->dimension) return arrayType;
+        auto mutType = mutate(arrayType);
+        auto globalSizeType = context.global.sizeType;
+        ast::ptr<ast::Type> sizetype =
+            globalSizeType
+                ? globalSizeType
+                : new ast::BasicType(ast::BasicType::LongUnsignedInt);
+        mutType->dimension =
+            findSingleExpression(arrayType->dimension, sizetype, context);
+
+        if (InitTweak::isConstExpr(mutType->dimension)) {
+            mutType->isVarLen = ast::LengthFlag::FixedLen;
+        } else {
+            mutType->isVarLen = ast::LengthFlag::VariableLen;
+        }
+        return mutType;
+    }
 };
 
-const ast::Type * fixArrayType( const ast::Type * type, const ResolveContext & context ) {
-	ast::Pass<FixArrayDimension> visitor(context);
-	return type->accept(visitor);
-}
-
-const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ResolveContext & context ) {
+struct FixEnumeratedArray {
+    const ResolveContext &context;
+    const ast::ListInit *init;
+    FixEnumeratedArray(const ResolveContext &context, const ast::ListInit *init)
+        : context(context), init(init) {}
+
+    const ast::ArrayType *previsit(const ast::ArrayType *arrayType) {
+        return arrayType;
+    }
+
+    // Enum Defined as inline field of array needs initalizer to define its
+    // members
+    const ast::EnumDecl *previsit(const ast::EnumDecl *enumDecl) {
+        auto mutType = mutate(enumDecl);
+        for (auto designation : init->designations) {
+            std::deque<ast::ptr<ast::Expr>> designatorList =
+                designation->designators;
+            if (designatorList.size() != 1) {
+                SemanticError(mutType,
+                              "Multiple Initialization in enumerated array is "
+                              "not supported.");
+            }
+            ast::ptr<ast::Expr> designator = designatorList.at(0);
+            ast::ptr<ast::NameExpr> designatorAsName =
+                designator.as<ast::NameExpr>();
+            ast::ObjectDecl *memberDecl =
+                new ast::ObjectDecl(enumDecl->location, designatorAsName->name,
+                                    new ast::EnumInstType("", ast::CV::Const));
+            mutType->members.push_back(memberDecl);
+            // mutType->members.push_back( )
+        }
+        return mutType;
+    }
+};
+
+const ast::Type *fixArrayType(const ast::Type *type,
+                              const ResolveContext &context) {
+    ast::Pass<FixArrayDimension> visitor(context);
+    return type->accept(visitor);
+}
+
+const ast::ObjectDecl *fixObjectType(const ast::ObjectDecl *decl,
+                                     const ResolveContext &context) {
     if (decl->isTypeFixed) {
         return decl;
@@ -219,59 +260,56 @@
 const ast::ObjectDecl *fixObjectInit(const ast::ObjectDecl *decl,
                                      const ResolveContext &context) {
-    if (decl->isTypeFixed) {
+    if ( decl->isTypeFixed ) {
         return decl;
     }
 
-    auto mutDecl = mutate(decl);
-
-    if ( auto mutListInit = mutDecl->init.as<ast::ListInit>() ) {
-        // std::list<ast::Designation *> newDesignations;        
-
-        for ( size_t k = 0; k < mutListInit->designations.size(); k++ ) {
-            const ast::Designation *des = mutListInit->designations[k].get();
-            // Desination here
-            ast::Designation * newDesination = new ast::Designation(des->location);
-
-            if (des->designators.size() == 0) continue;
-
-            // The designator I want to replace
-            const ast::Expr * designator = des->designators.at(0);
-            // Stupid flag variable for development, to be removed
-            bool mutated = false;
-            if ( const ast::NameExpr * designatorName = dynamic_cast<const ast::NameExpr *>(designator) ) {
-                auto candidates = context.symtab.lookupId(designatorName->name);
-                // Does not work for the overloading case currently
-                // assert( candidates.size() == 1 );
-                if ( candidates.size() != 1 ) return mutDecl;
-                auto candidate = candidates.at(0);
-                if ( const ast::EnumInstType * enumInst = dynamic_cast<const ast::EnumInstType *>(candidate.id->get_type())) {
-                    // determine that is an enumInst, swap it with its const value
-                    assert( candidates.size() == 1 );
-                    const ast::EnumDecl * baseEnum = enumInst->base;
-                    // Need to iterate over all enum value to find the initializer to swap
-                    for ( size_t m = 0; m < baseEnum->members.size(); ++m ) {
-                        const ast::ObjectDecl * mem = baseEnum->members.at(m).as<const ast::ObjectDecl>();
-                        if ( baseEnum->members.at(m)->name == designatorName->name ) {
-                            assert(mem);
-                            if ( mem->init ) {
-                                const ast::SingleInit * memInit = mem->init.as<const ast::SingleInit>();
-                                ast::Expr * initValue = shallowCopy( memInit->value.get() );
-                                newDesination->designators.push_back( initValue );
-                                mutated = true;
-                            }
-                            break;
-                        }
-                    }
+    auto mutDecl = mutate( decl );
+
+    if ( const ast::ListInit * listInit = mutDecl->init.as<ast::ListInit>() ) {
+        ast::ListInit * mutListInit = mutate( listInit );
+        // ListInit::designations is std::vector<ptr<Designation>>
+        // ((ast::ListInit)mutDecl->init).designations = newDesignations
+        std::vector<ast::ptr<ast::Designation>> newDesignations;
+        
+        // The loop iterates over ListInit::designations and push member to newDesignations
+        for ( ast::ptr<ast::Designation> des : listInit->designations ) {
+            ast::Designation * newDesignation = mutate( des.get() );
+            
+            std::deque<ast::ptr<ast::Expr>> newDesignators;
+            for ( const ast::Expr *designator : des->designators ) {
+                if ( const ast::NameExpr *designatorName = dynamic_cast<const ast::NameExpr *>(designator) ) {
+                    auto candidates = context.symtab.lookupId(designatorName->name);
+                    if ( candidates.size() == 0 ) {
+                        newDesignators.push_back(designator);
+                    } else {
+                        auto candidate = candidates.at(0);
+                        if ( const ast::EnumInstType *enumInst = dynamic_cast<const ast::EnumInstType *>(candidate.id->get_type()) ) {
+                            const ast::EnumDecl * baseEnum = enumInst->base;
+                            // // Need to iterate over all enum value to find the
+                            // // initializer to swap
+                            for (size_t m = 0; m < baseEnum->members.size(); ++m) {
+                                const ast::ObjectDecl *mem = baseEnum->members.at(m).as<const ast::ObjectDecl>();
+                                if (baseEnum->members.at(m)->name == designatorName->name) {
+                                    assert(mem);
+                                    newDesignators.push_back( ast::ConstantExpr::from_int(des->location,  m ));
+                                }
+                            } // for
+                            assert(newDesignators.size() > 0);
+                        } else {
+                            newDesignators.push_back(designator);
+                        } //if
+                    }  
                 } else {
-                    newDesination->designators.push_back( des->designators.at(0) );
-                }
-            } else {
-                newDesination->designators.push_back( des->designators.at(0) );
-            }
-            if ( mutated ) {
-                mutListInit = ast::mutate_field_index(mutListInit, &ast::ListInit::designations, k, newDesination);
-            }
-        }
-    }
+                    newDesignators.push_back(designator);
+                } // if
+            } // for
+            
+            newDesignation->designators = newDesignators;
+            newDesignations.push_back( newDesignation );
+        } // for
+        // mutListInit->designations = newDesignations;
+        ast::mutate_field( mutListInit, &ast::ListInit::designations, newDesignations );
+        ast::mutate_field( mutDecl, &ast::ObjectDecl::init, mutListInit );
+    } // if
     return mutDecl;
 }
