Index: src/CodeGen/GenType.cc
===================================================================
--- src/CodeGen/GenType.cc	(revision 82dd287be3d478bfc671d7f0679e11c94f8b8500)
+++ src/CodeGen/GenType.cc	(revision cff1143e2baa13d1597cb90a47cb8f47aa3cc8db)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Jun  8 14:36:02 2015
-// Update Count     : 9
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed Jul 08 16:08:24 2015
+// Update Count     : 10
 //
 
@@ -93,10 +93,11 @@
 			os << "_Atomic ";
 		} // if
-		if ( isVarLen ) {
-			os << "*";
-		} // if
 		if ( dimension != 0 ) {
 			CodeGenerator cg( os );
 			dimension->accept( cg );
+		} else if ( isVarLen ) {
+			// no dimension expression on a VLA
+			// means it came in with the * token
+			os << "*";
 		} // if
 		os << "]";
Index: src/ControlStruct/LabelFixer.cc
===================================================================
--- src/ControlStruct/LabelFixer.cc	(revision 82dd287be3d478bfc671d7f0679e11c94f8b8500)
+++ src/ControlStruct/LabelFixer.cc	(revision cff1143e2baa13d1597cb90a47cb8f47aa3cc8db)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Wed Jun 24 16:24:34 2015
-// Update Count     : 141
+// Last Modified On : Wed Jul 08 12:36:46 2015
+// Update Count     : 145
 //
 
@@ -61,8 +61,16 @@
 
 	void LabelFixer::visit( FunctionDecl *functionDecl ) {
+		// need to go into a nested function in a fresh state
+		std::map < Label, Entry *> oldLabelTable = labelTable;
+		labelTable.clear();
+
 		maybeAccept( functionDecl->get_statements(), *this );
 
 		MLEMutator mlemut( resolveJumps(), generator );
 		functionDecl->acceptMutator( mlemut );
+
+		// and remember the outer function's labels when
+		// returning to it
+		labelTable = oldLabelTable;
 	}
 
Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision 82dd287be3d478bfc671d7f0679e11c94f8b8500)
+++ src/Makefile.in	(revision cff1143e2baa13d1597cb90a47cb8f47aa3cc8db)
@@ -160,4 +160,5 @@
 	SymTab/cfa_cpp-FixFunction.$(OBJEXT) \
 	SymTab/cfa_cpp-ImplementationType.$(OBJEXT) \
+	SymTab/cfa_cpp-TypeEquality.$(OBJEXT) \
 	SynTree/cfa_cpp-Type.$(OBJEXT) \
 	SynTree/cfa_cpp-VoidType.$(OBJEXT) \
@@ -365,9 +366,10 @@
 	SymTab/Indexer.cc SymTab/Mangler.cc SymTab/Validate.cc \
 	SymTab/FixFunction.cc SymTab/ImplementationType.cc \
-	SynTree/Type.cc SynTree/VoidType.cc SynTree/BasicType.cc \
-	SynTree/PointerType.cc SynTree/ArrayType.cc \
-	SynTree/FunctionType.cc SynTree/ReferenceToType.cc \
-	SynTree/TupleType.cc SynTree/TypeofType.cc SynTree/AttrType.cc \
-	SynTree/Constant.cc SynTree/Expression.cc SynTree/TupleExpr.cc \
+	SymTab/TypeEquality.cc SynTree/Type.cc SynTree/VoidType.cc \
+	SynTree/BasicType.cc SynTree/PointerType.cc \
+	SynTree/ArrayType.cc SynTree/FunctionType.cc \
+	SynTree/ReferenceToType.cc SynTree/TupleType.cc \
+	SynTree/TypeofType.cc SynTree/AttrType.cc SynTree/Constant.cc \
+	SynTree/Expression.cc SynTree/TupleExpr.cc \
 	SynTree/CommaExpr.cc SynTree/TypeExpr.cc \
 	SynTree/ApplicationExpr.cc SynTree/AddressExpr.cc \
@@ -666,4 +668,6 @@
 SymTab/cfa_cpp-ImplementationType.$(OBJEXT): SymTab/$(am__dirstamp) \
 	SymTab/$(DEPDIR)/$(am__dirstamp)
+SymTab/cfa_cpp-TypeEquality.$(OBJEXT): SymTab/$(am__dirstamp) \
+	SymTab/$(DEPDIR)/$(am__dirstamp)
 SynTree/$(am__dirstamp):
 	@$(MKDIR_P) SynTree
@@ -823,4 +827,5 @@
 	-rm -f SymTab/cfa_cpp-Indexer.$(OBJEXT)
 	-rm -f SymTab/cfa_cpp-Mangler.$(OBJEXT)
+	-rm -f SymTab/cfa_cpp-TypeEquality.$(OBJEXT)
 	-rm -f SymTab/cfa_cpp-Validate.$(OBJEXT)
 	-rm -f SynTree/cfa_cpp-AddressExpr.$(OBJEXT)
@@ -931,4 +936,5 @@
 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/cfa_cpp-Indexer.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/cfa_cpp-Mangler.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/cfa_cpp-TypeEquality.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/cfa_cpp-Validate.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/cfa_cpp-AddressExpr.Po@am__quote@
@@ -1910,4 +1916,18 @@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/cfa_cpp-ImplementationType.obj `if test -f 'SymTab/ImplementationType.cc'; then $(CYGPATH_W) 'SymTab/ImplementationType.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/ImplementationType.cc'; fi`
+
+SymTab/cfa_cpp-TypeEquality.o: SymTab/TypeEquality.cc
+@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/cfa_cpp-TypeEquality.o -MD -MP -MF SymTab/$(DEPDIR)/cfa_cpp-TypeEquality.Tpo -c -o SymTab/cfa_cpp-TypeEquality.o `test -f 'SymTab/TypeEquality.cc' || echo '$(srcdir)/'`SymTab/TypeEquality.cc
+@am__fastdepCXX_TRUE@	$(am__mv) SymTab/$(DEPDIR)/cfa_cpp-TypeEquality.Tpo SymTab/$(DEPDIR)/cfa_cpp-TypeEquality.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='SymTab/TypeEquality.cc' object='SymTab/cfa_cpp-TypeEquality.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/cfa_cpp-TypeEquality.o `test -f 'SymTab/TypeEquality.cc' || echo '$(srcdir)/'`SymTab/TypeEquality.cc
+
+SymTab/cfa_cpp-TypeEquality.obj: SymTab/TypeEquality.cc
+@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/cfa_cpp-TypeEquality.obj -MD -MP -MF SymTab/$(DEPDIR)/cfa_cpp-TypeEquality.Tpo -c -o SymTab/cfa_cpp-TypeEquality.obj `if test -f 'SymTab/TypeEquality.cc'; then $(CYGPATH_W) 'SymTab/TypeEquality.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/TypeEquality.cc'; fi`
+@am__fastdepCXX_TRUE@	$(am__mv) SymTab/$(DEPDIR)/cfa_cpp-TypeEquality.Tpo SymTab/$(DEPDIR)/cfa_cpp-TypeEquality.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='SymTab/TypeEquality.cc' object='SymTab/cfa_cpp-TypeEquality.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/cfa_cpp-TypeEquality.obj `if test -f 'SymTab/TypeEquality.cc'; then $(CYGPATH_W) 'SymTab/TypeEquality.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/TypeEquality.cc'; fi`
 
 SynTree/cfa_cpp-Type.o: SynTree/Type.cc
Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision 82dd287be3d478bfc671d7f0679e11c94f8b8500)
+++ src/Parser/DeclarationNode.cc	(revision cff1143e2baa13d1597cb90a47cb8f47aa3cc8db)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Sat May 16 12:34:05 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Jul  3 12:35:02 2015
-// Update Count     : 108
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed Jul 08 16:40:37 2015
+// Update Count     : 121
 //
 
@@ -284,5 +284,9 @@
 	newnode->type->array->dimension = size;
 	newnode->type->array->isStatic = isStatic;
-	newnode->type->array->isVarLen = false;
+	if ( newnode->type->array->dimension == 0 || dynamic_cast<ConstantNode *>( newnode->type->array->dimension ) ) {
+		newnode->type->array->isVarLen = false;
+	} else {
+		newnode->type->array->isVarLen = true;
+	} // if
 	return newnode->addQualifiers( qualifiers );
 }
@@ -464,4 +468,10 @@
 			bitfieldWidth = o->bitfieldWidth;
 		} // if
+
+		// there may be typedefs chained onto the type
+		if ( o->get_link() ) {
+			set_link( o->get_link()->clone() );
+		}
+
 	} // if
 	delete o;
Index: src/Parser/ParseNode.cc
===================================================================
--- src/Parser/ParseNode.cc	(revision 82dd287be3d478bfc671d7f0679e11c94f8b8500)
+++ src/Parser/ParseNode.cc	(revision cff1143e2baa13d1597cb90a47cb8f47aa3cc8db)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Sat May 16 13:26:29 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jun  6 20:17:58 2015
-// Update Count     : 23
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed Jul 08 14:46:45 2015
+// Update Count     : 25
 // 
 
@@ -41,10 +41,7 @@
 
 ParseNode *ParseNode::set_link( ParseNode *next_ ) {
-	ParseNode *follow;
-
 	if ( next_ == 0 ) return this;
 
-	for ( follow = this; follow->next != 0; follow = follow->next );
-	follow->next = next_;
+	get_last()->next = next_;
 
 	return this;
Index: src/SymTab/TypeEquality.cc
===================================================================
--- src/SymTab/TypeEquality.cc	(revision cff1143e2baa13d1597cb90a47cb8f47aa3cc8db)
+++ src/SymTab/TypeEquality.cc	(revision cff1143e2baa13d1597cb90a47cb8f47aa3cc8db)
@@ -0,0 +1,193 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// TypeEquality.cc -- 
+//
+// Author           : Rob Schluntz
+// Created On       : Tue Jul 07 16:28:29 2015
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Jul 09 11:18:46 2015
+// Update Count     : 36
+//
+
+#include <list>
+#include <iterator>
+#include "Validate.h"
+#include "SynTree/Visitor.h"
+#include "SynTree/Type.h"
+#include "SynTree/Statement.h"
+#include "SynTree/TypeSubstitution.h"
+#include "Indexer.h"
+#include "TypeEquality.h"
+
+namespace SymTab {
+	class TypeEquality : public Visitor {
+  public:
+		TypeEquality( Type * other, bool vlaErr ) : result( true ), other( other ), 
+			vlaErr( vlaErr ) {}
+		bool result;
+
+  private:
+		virtual void visit( FunctionType *funcType );
+		virtual void visit( VoidType *voidType );
+		virtual void visit( BasicType *basicType );
+		virtual void visit( PointerType *pointerType );
+		virtual void visit( ArrayType *arrayType );
+		virtual void visit( StructInstType *structInst );
+		virtual void visit( UnionInstType *unionInst );
+		virtual void visit( EnumInstType *enumInst );
+		virtual void visit( TypeInstType *typeInst );
+
+		void handleQualifiers( Type * t );
+
+		Type * other;
+		bool vlaErr;
+	};
+
+	bool typeEquals( Type * t1, Type * t2, bool vlaErr ) {
+		TypeEquality teq( t2, vlaErr );
+		t1->accept( teq );
+		return teq.result;
+	}
+
+	void TypeEquality::handleQualifiers( Type * t ) {
+		result = result && t->get_qualifiers() == other->get_qualifiers();
+	}
+
+	void TypeEquality::visit( VoidType *voidType ) {
+		handleQualifiers( voidType );
+		if ( ! dynamic_cast< VoidType * >( other ) ) {
+			result = false;
+		}
+	}
+
+	void TypeEquality::visit( BasicType *basicType ) {
+		handleQualifiers( basicType );
+		if ( BasicType * bt = dynamic_cast< BasicType * >( other ) ) {
+			result = result && basicType->get_kind() == bt->get_kind(); 
+		} else {
+			result = false;
+		}
+	}
+
+	void TypeEquality::visit( PointerType *pointerType ) {
+		handleQualifiers( pointerType );
+		if ( PointerType * pt = dynamic_cast< PointerType * >( other ) ) {
+			other = pt->get_base();
+			pointerType->get_base()->accept( *this );
+		} else {
+			result = false;
+		}
+	}
+
+	void TypeEquality::visit( ArrayType *arrayType ) {
+		handleQualifiers( arrayType );
+
+		if ( ArrayType * at = dynamic_cast< ArrayType * >( other ) ) {
+			// to be equal, array types must both be VLA or both not VLA
+			// and must both have a dimension expression or not have a dimension
+			result = result	&& arrayType->get_isVarLen() == at->get_isVarLen()
+				&& (arrayType->get_dimension() != 0 && at->get_dimension() != 0
+					|| arrayType->get_dimension() == 0 && at->get_dimension() == 0);
+
+			if ( vlaErr ) {
+				// useful for comparing typedef types - in this case, we 
+				// want types to appear distinct if either is a VLA type
+				if ( arrayType->get_isVarLen() || at->get_isVarLen() ) {
+					result = false;
+				}
+			}
+
+			if ( ! arrayType->get_isVarLen() && ! at->get_isVarLen() &&
+				arrayType->get_dimension() != 0 && at->get_dimension() != 0 ) {
+				ConstantExpr * ce1 = dynamic_cast< ConstantExpr * >( arrayType->get_dimension() );
+				ConstantExpr * ce2 = dynamic_cast< ConstantExpr * >( at->get_dimension() );
+				assert(ce1 && ce2);
+
+				Constant * c1 = ce1->get_constant();
+				Constant * c2 = ce2->get_constant();
+
+				result = result && c1->get_value() == c2->get_value();
+			}
+
+			other = at->get_base();
+			arrayType->get_base()->accept( *this );
+		} else {
+			result = false;
+		}
+	}
+
+	void TypeEquality::visit( FunctionType *funcType ) {
+		handleQualifiers( funcType );
+
+		if ( FunctionType * ft = dynamic_cast< FunctionType * >( other ) ) {
+			// function types must have the same number of return types
+			// and parameters to be equivalent
+			result = result && funcType->get_returnVals().size() == ft->get_returnVals().size()
+				&& funcType->get_parameters().size() == ft->get_parameters().size()
+				&& funcType->get_isVarArgs() == ft->get_isVarArgs();
+
+			std::list< DeclarationWithType * >::iterator it1, it2;
+
+			// return types must be equivalent
+			it1 = funcType->get_returnVals().begin();
+			it2 = ft->get_returnVals().begin();
+			for ( ; it1 != funcType->get_returnVals().end(); ++it1, ++it2 ) {
+				if ( ! result ) return;
+				other = (*it2)->get_type();
+				(*it1)->get_type()->accept( *this );
+			}
+
+			// parameter types must be equivalent
+			it1 = funcType->get_parameters().begin(); 
+			it2 = ft->get_parameters().begin();
+			for ( ; it1 != funcType->get_parameters().end(); ++it1, ++it2 ) {
+				if ( ! result ) return;
+				other = (*it2)->get_type();
+				(*it1)->get_type()->accept( *this );
+			}
+		} else {
+			result = false;
+		}
+	}
+
+	// aggregate types only need to have the same name
+	void TypeEquality::visit( StructInstType *structInst )  {
+		handleQualifiers( structInst );
+		if ( StructInstType * st = dynamic_cast< StructInstType * >( other ) ) {
+			result = result && structInst->get_name() == st->get_name();
+		} else {
+			result = false;
+		}
+	}
+
+	void TypeEquality::visit( UnionInstType *unionInst ) {
+		handleQualifiers( unionInst );
+		if ( UnionInstType * ut = dynamic_cast< UnionInstType * >( other ) ) {
+			result = result && unionInst->get_name() == ut->get_name();
+		} else {
+			result = false;
+		}
+	}
+
+	void TypeEquality::visit( EnumInstType *enumInst ) {
+		handleQualifiers( enumInst );
+		if ( EnumInstType * et = dynamic_cast< EnumInstType * >( other ) ) {
+			result = result && enumInst->get_name() == et->get_name();
+		} else {
+			result = false;
+		}
+	}
+
+	void TypeEquality::visit( TypeInstType *typeInst ) {
+		handleQualifiers( typeInst );
+		if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( other ) ) {
+			result = result && typeInst->get_name() == tt->get_name();
+		} else {
+			result = false;
+		}
+	}
+} // namespace SymTab
Index: src/SymTab/TypeEquality.h
===================================================================
--- src/SymTab/TypeEquality.h	(revision cff1143e2baa13d1597cb90a47cb8f47aa3cc8db)
+++ src/SymTab/TypeEquality.h	(revision cff1143e2baa13d1597cb90a47cb8f47aa3cc8db)
@@ -0,0 +1,21 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// TypeEquality.h -- 
+//
+// Author           : Rob Schluntz
+// Created On       : Tue Jul 07 16:30:07 2015
+// Last Modified By : Rob Schluntz
+// Last Modified On : Wed Jul 08 12:41:15 2015
+// Update Count     : 6
+//
+
+namespace SymTab {
+  // compare types t1 and t2 for equality
+  // if vlaErr is true, then if at least one of the types is a 
+  // variable-length array type, then the result will be false 
+  bool typeEquals( Type * t1, Type * t2, bool vlaErr = false );
+} // namespace SymTab
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 82dd287be3d478bfc671d7f0679e11c94f8b8500)
+++ src/SymTab/Validate.cc	(revision cff1143e2baa13d1597cb90a47cb8f47aa3cc8db)
@@ -10,6 +10,6 @@
 // Created On       : Sun May 17 21:50:04 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Tue Jul 07 10:41:23 2015
-// Update Count     : 136
+// Last Modified On : Wed Jul 08 12:49:36 2015
+// Update Count     : 166
 //
 
@@ -48,10 +48,10 @@
 #include "Indexer.h"
 #include "FixFunction.h"
-#include "ImplementationType.h"
+// #include "ImplementationType.h"
 #include "utility.h"
 #include "UniqueName.h"
 #include "AddVisit.h"
 #include "MakeLibCfa.h"
-
+#include "TypeEquality.h"
 
 #define debugPrint( x ) if ( doDebug ) { std::cout << x; }
@@ -162,4 +162,5 @@
 	class EliminateTypedef : public Mutator {
 	  public:
+	  EliminateTypedef() : scopeLevel( 0 ) {}
 		static void eliminateTypedef( std::list< Declaration * > &translationUnit );
 	  private:
@@ -171,6 +172,8 @@
 		virtual Type *mutate( TypeInstType *aggregateUseType );
 		virtual Expression *mutate( CastExpr *castExpr );
-  
-		std::map< std::string, TypedefDecl * > typedefNames;
+
+		typedef std::map< std::string, std::pair< TypedefDecl *, int > > TypedefMap;
+		TypedefMap typedefNames;
+		int scopeLevel;
 	};
 
@@ -589,4 +592,7 @@
 		assignDecl2->fixUniqueId();
 
+		// these should be built in the same way that the prelude
+		// functions are, so build a list containing the prototypes
+		// and allow MakeLibCfa to autogenerate the bodies.
 		std::list< Declaration * > assigns;
 		assigns.push_back( assignDecl );
@@ -595,5 +601,5 @@
 		LibCfa::makeLibCfa( assigns );
 
-		// need to remove the prototypes, since these can appear nested in a routine
+		// need to remove the prototypes, since this may be nested in a routine
 		for (int start = 0, end = assigns.size()/2; start < end; start++) {
 			delete assigns.front();
@@ -602,6 +608,4 @@
 
 		declsToAdd.insert( declsToAdd.begin(), assigns.begin(), assigns.end() );
-
-		// return assignDecl;
 	}
 
@@ -802,7 +806,9 @@
 
 	Type *EliminateTypedef::mutate( TypeInstType *typeInst ) {
-		std::map< std::string, TypedefDecl * >::const_iterator def = typedefNames.find( typeInst->get_name() );
+		// instances of typedef types will come here. If it is an instance 
+		// of a typdef type, link the instance to its actual type.
+		TypedefMap::const_iterator def = typedefNames.find( typeInst->get_name() );
 		if ( def != typedefNames.end() ) {
-			Type *ret = def->second->get_base()->clone();
+			Type *ret = def->second.first->get_base()->clone();
 			ret->get_qualifiers() += typeInst->get_qualifiers();
 			delete typeInst;
@@ -814,5 +820,17 @@
 	Declaration *EliminateTypedef::mutate( TypedefDecl *tyDecl ) {
 		Declaration *ret = Mutator::mutate( tyDecl );
-		typedefNames[ tyDecl->get_name() ] = tyDecl;
+		if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) {
+			// typedef to the same name from the same scope 
+			// must be from the same type
+
+			Type * t1 = tyDecl->get_base();
+			Type * t2 = typedefNames[ tyDecl->get_name() ].first->get_base();
+			if ( ! typeEquals( t1, t2, true ) ) {
+				throw SemanticError( "cannot redefine typedef: " + tyDecl->get_name() );
+			} 
+		} else {
+			typedefNames[ tyDecl->get_name() ] = std::make_pair( tyDecl, scopeLevel );
+		} // if
+
 		// When a typedef is a forward declaration:
 		//    typedef struct screen SCREEN;
@@ -833,5 +851,5 @@
 
 	TypeDecl *EliminateTypedef::mutate( TypeDecl *typeDecl ) {
-		std::map< std::string, TypedefDecl * >::iterator i = typedefNames.find( typeDecl->get_name() );
+		TypedefMap::iterator i = typedefNames.find( typeDecl->get_name() );
 		if ( i != typedefNames.end() ) {
 			typedefNames.erase( i ) ;
@@ -841,5 +859,5 @@
 
 	DeclarationWithType *EliminateTypedef::mutate( FunctionDecl *funcDecl ) {
-		std::map< std::string, TypedefDecl * > oldNames = typedefNames;
+		TypedefMap oldNames = typedefNames;
 		DeclarationWithType *ret = Mutator::mutate( funcDecl );
 		typedefNames = oldNames;
@@ -848,5 +866,5 @@
 
 	ObjectDecl *EliminateTypedef::mutate( ObjectDecl *objDecl ) {
-		std::map< std::string, TypedefDecl * > oldNames = typedefNames;
+		TypedefMap oldNames = typedefNames;
 		ObjectDecl *ret = Mutator::mutate( objDecl );
 		typedefNames = oldNames;
@@ -855,5 +873,5 @@
 
 	Expression *EliminateTypedef::mutate( CastExpr *castExpr ) {
-		std::map< std::string, TypedefDecl * > oldNames = typedefNames;
+		TypedefMap oldNames = typedefNames;
 		Expression *ret = Mutator::mutate( castExpr );
 		typedefNames = oldNames;
@@ -862,6 +880,8 @@
 
 	CompoundStmt *EliminateTypedef::mutate( CompoundStmt *compoundStmt ) {
-		std::map< std::string, TypedefDecl * > oldNames = typedefNames;
+		TypedefMap oldNames = typedefNames;
+		scopeLevel += 1;
 		CompoundStmt *ret = Mutator::mutate( compoundStmt );
+		scopeLevel -= 1;
 		std::list< Statement * >::iterator i = compoundStmt->get_kids().begin();
 		while ( i != compoundStmt->get_kids().end() ) {
Index: src/SymTab/module.mk
===================================================================
--- src/SymTab/module.mk	(revision 82dd287be3d478bfc671d7f0679e11c94f8b8500)
+++ src/SymTab/module.mk	(revision cff1143e2baa13d1597cb90a47cb8f47aa3cc8db)
@@ -10,7 +10,7 @@
 ## Author           : Richard C. Bilson
 ## Created On       : Mon Jun  1 17:49:17 2015
-## Last Modified By : Peter A. Buhr
-## Last Modified On : Mon Jun  1 17:53:50 2015
-## Update Count     : 1
+## Last Modified By : Rob Schluntz
+## Last Modified On : Tue Jul 07 16:22:23 2015
+## Update Count     : 2
 ###############################################################################
 
@@ -20,4 +20,4 @@
        SymTab/Validate.cc \
        SymTab/FixFunction.cc \
-       SymTab/ImplementationType.cc
-
+       SymTab/ImplementationType.cc \
+       SymTab/TypeEquality.cc
