Index: src/SymTab/AggregateTable.h
===================================================================
--- src/SymTab/AggregateTable.h	(revision 4cc428651c83d14e03e03eefcb10aece78034e35)
+++ 	(revision )
@@ -1,53 +1,0 @@
-//
-// 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.
-//
-// AggregateTable.h -- 
-//
-// Author           : Richard C. Bilson
-// Created On       : Sun May 17 16:17:26 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sun May 17 16:19:29 2015
-// Update Count     : 4
-//
-
-#ifndef AGGREGATETABLE_H
-#define AGGREGATETABLE_H
-
-#include <map>
-#include <stack>
-#include <string>
-#include <functional>
-
-#include "StackTable.h"
-#include "SynTree/Declaration.h"
-
-namespace SymTab {
-	template< class AggregateDeclClass >
-	class AggregateTableConflictFunction : public std::binary_function< AggregateDeclClass *, AggregateDeclClass *, AggregateDeclClass *> {
-	  public:
-		AggregateDeclClass *operator()( AggregateDeclClass *existing, AggregateDeclClass *added ) {
-			if ( existing->get_members().empty() ) {
-				return added;
-			} else if ( ! added->get_members().empty() ) {
-				throw SemanticError( "redeclaration of ", added );
-			} // if
-			return existing;
-		}
-	};
-
-	typedef StackTable< StructDecl, AggregateTableConflictFunction< StructDecl > > StructTable;
-	typedef StackTable< EnumDecl, AggregateTableConflictFunction< EnumDecl > > EnumTable;
-	typedef StackTable< UnionDecl, AggregateTableConflictFunction< UnionDecl > > UnionTable;
-	typedef StackTable< ContextDecl, AggregateTableConflictFunction< ContextDecl > > ContextTable;
-} // namespace SymTab
-
-#endif // AGGREGATETABLE_H
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: src/SymTab/Autogen.cc
===================================================================
--- src/SymTab/Autogen.cc	(revision 4cc428651c83d14e03e03eefcb10aece78034e35)
+++ src/SymTab/Autogen.cc	(revision eab39cd564d14ce04f69d69d6601d9e1588e282f)
@@ -10,5 +10,5 @@
 // Created On       : Thu Mar 03 15:45:56 2016
 // Last Modified By : Rob Schluntz
-// Last Modified On : Thu Mar 03 15:45:56 2016
+// Last Modified On : Mon Apr 04 17:19:28 2016
 // Update Count     : 1
 //
@@ -34,5 +34,5 @@
 		virtual void visit( UnionDecl *structDecl );
 		virtual void visit( TypeDecl *typeDecl );
-		virtual void visit( ContextDecl *ctxDecl );
+		virtual void visit( TraitDecl *ctxDecl );
 		virtual void visit( FunctionDecl *functionDecl );
 
@@ -468,6 +468,6 @@
 	}
 
-	void AutogenerateRoutines::visit( ContextDecl *) {
-		// ensure that we don't add assignment ops for types defined as part of the context
+	void AutogenerateRoutines::visit( TraitDecl *) {
+		// ensure that we don't add assignment ops for types defined as part of the trait
 	}
 
Index: src/SymTab/FixFunction.cc
===================================================================
--- src/SymTab/FixFunction.cc	(revision 4cc428651c83d14e03e03eefcb10aece78034e35)
+++ src/SymTab/FixFunction.cc	(revision eab39cd564d14ce04f69d69d6601d9e1588e282f)
@@ -10,6 +10,6 @@
 // Created On       : Sun May 17 16:19:49 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sun May 17 16:22:54 2015
-// Update Count     : 2
+// Last Modified On : Wed Mar  2 17:31:10 2016
+// Update Count     : 3
 //
 
@@ -61,5 +61,5 @@
 	}
 
-	Type * FixFunction::mutate(ContextInstType *aggregateUseType) {
+	Type * FixFunction::mutate(TraitInstType *aggregateUseType) {
 		return aggregateUseType;
 	}
Index: src/SymTab/FixFunction.h
===================================================================
--- src/SymTab/FixFunction.h	(revision 4cc428651c83d14e03e03eefcb10aece78034e35)
+++ src/SymTab/FixFunction.h	(revision eab39cd564d14ce04f69d69d6601d9e1588e282f)
@@ -10,6 +10,6 @@
 // Created On       : Sun May 17 17:02:08 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sun May 17 17:03:43 2015
-// Update Count     : 2
+// Last Modified On : Wed Mar  2 17:34:06 2016
+// Update Count     : 3
 //
 
@@ -38,5 +38,5 @@
 		virtual Type* mutate(UnionInstType *aggregateUseType);
 		virtual Type* mutate(EnumInstType *aggregateUseType);
-		virtual Type* mutate(ContextInstType *aggregateUseType);
+		virtual Type* mutate(TraitInstType *aggregateUseType);
 		virtual Type* mutate(TypeInstType *aggregateUseType);
 		virtual Type* mutate(TupleType *tupleType);
Index: src/SymTab/IdTable.cc
===================================================================
--- src/SymTab/IdTable.cc	(revision 4cc428651c83d14e03e03eefcb10aece78034e35)
+++ 	(revision )
@@ -1,189 +1,0 @@
-//
-// 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.
-//
-// IdTable.cc -- 
-//
-// Author           : Richard C. Bilson
-// Created On       : Sun May 17 17:04:02 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Jan  8 22:59:23 2016
-// Update Count     : 74
-//
-
-#include <cassert>
-
-#include "SynTree/Declaration.h"
-#include "ResolvExpr/typeops.h"
-#include "Indexer.h"
-#include "Mangler.h"
-#include "IdTable.h"
-#include "Common/SemanticError.h"
-
-using std::string;
-
-namespace SymTab {
-	IdTable::IdTable() : scopeLevel( 0 ) {
-	}
-
-	void IdTable::enterScope() {
-		scopeLevel++;
-	}
-
-	void IdTable::leaveScope() {
-		for ( OuterTableType::iterator outer = table.begin(); outer != table.end(); ++outer ) {
-			for ( InnerTableType::iterator inner = outer->second.begin(); inner != outer->second.end(); ++inner ) {
-				std::stack< DeclEntry >& entry = inner->second;
-				// xxx - should be while?
-				if ( ! entry.empty() && entry.top().second == scopeLevel ) {
-					entry.pop();
-				} // if
-			} // for
-		} // for
-
-		scopeLevel--;
-		assert( scopeLevel >= 0 );
-	}
-
-	void IdTable::addDecl( DeclarationWithType *decl ) {
-		const string &name = decl->get_name();
-		string manglename;
-		if ( decl->get_linkage() == LinkageSpec::C ) {
-			manglename = name;
-		} else if ( LinkageSpec::isOverridable( decl->get_linkage() ) ) {
-			// mangle the name without including the appropriate suffix, so overridable routines are placed into the
-			// same "bucket" as their user defined versions.
-			manglename = Mangler::mangle( decl, false );
-		} else {
-			manglename = Mangler::mangle( decl );
-		} // if
-
-		InnerTableType &declTable = table[ name ];
-		InnerTableType::iterator it = declTable.find( manglename );
-
-		if ( it == declTable.end() ) {
-			// first time this name mangling has been defined
-			declTable[ manglename ].push( DeclEntry( decl, scopeLevel ) );
-		} else {
-			std::stack< DeclEntry >& entry = it->second;
-			if ( ! entry.empty() && entry.top().second == scopeLevel ) {
-				// if we're giving the same name mangling to things of different types then there is something wrong
-				Declaration *old = entry.top().first;
-				assert( (dynamic_cast<ObjectDecl*>( decl ) && dynamic_cast<ObjectDecl*>( old ) )
-				  || (dynamic_cast<FunctionDecl*>( decl ) && dynamic_cast<FunctionDecl*>( old ) ) );
-
-				if ( LinkageSpec::isOverridable( old->get_linkage() ) ) {
-					// new definition shadows the autogenerated one, even at the same scope
-					declTable[ manglename ].push( DeclEntry( decl, scopeLevel ) );
-				} else if ( decl->get_linkage() != LinkageSpec::C || ResolvExpr::typesCompatible( decl->get_type(), entry.top().first->get_type(), Indexer() ) ) {
-					// typesCompatible doesn't really do the right thing here. When checking compatibility of function types,
-					// we should ignore outermost pointer qualifiers, except _Atomic?
-					FunctionDecl *newentry = dynamic_cast< FunctionDecl* >( decl );
-					FunctionDecl *oldentry = dynamic_cast< FunctionDecl* >( old );
-					if ( newentry && oldentry ) {
-						if ( newentry->get_statements() && oldentry->get_statements() ) {
-							throw SemanticError( "duplicate function definition for 1 ", decl );
-						} // if
-					} else {
-						// two objects with the same mangled name defined in the same scope.
-						// both objects must be marked extern or both must be intrinsic for this to be okay
-						// xxx - perhaps it's actually if either is intrinsic then this is okay?
-						//       might also need to be same storage class?
-						ObjectDecl *newobj = dynamic_cast< ObjectDecl* >( decl );
-						ObjectDecl *oldobj = dynamic_cast< ObjectDecl* >( old );
-						if (newobj->get_storageClass() != DeclarationNode::Extern && oldobj->get_storageClass() != DeclarationNode::Extern ) {
-							throw SemanticError( "duplicate definition for 3 ", decl );
-						} // if
-					} // if
-				} else {
-					throw SemanticError( "duplicate definition for ", decl );
-				} // if
-			} else {
-				// new scope level - shadow existing definition
-				declTable[ manglename ].push( DeclEntry( decl, scopeLevel ) );
-			} // if
-		} // if
-		// this ensures that no two declarations with the same unmangled name both have C linkage
-		for ( InnerTableType::iterator i = declTable.begin(); i != declTable.end(); ++i ) {
-			if ( ! i->second.empty() && i->second.top().first->get_linkage() == LinkageSpec::C && declTable.size() > 1 ) {
-				InnerTableType::iterator j = i;
-				for ( j++; j != declTable.end(); ++j ) {
-					if ( ! j->second.empty() && j->second.top().first->get_linkage() == LinkageSpec::C ) {
-						throw SemanticError( "invalid overload of C function " );
-					} // if
-				} // for
-			} // if
-		} // for
-	}
-
-	void IdTable::lookupId( const std::string &id, std::list< DeclarationWithType* >& decls ) const {
-		OuterTableType::const_iterator outer = table.find( id );
-		if ( outer == table.end() ) return;
-		const InnerTableType &declTable = outer->second;
-		for ( InnerTableType::const_iterator it = declTable.begin(); it != declTable.end(); ++it ) {
-			const std::stack< DeclEntry >& entry = it->second;
-			if ( ! entry.empty() ) {
-				decls.push_back( entry.top().first );
-			} // if
-		} // for
-	}
-
-	DeclarationWithType * IdTable::lookupId( const std::string &id) const {
-		DeclarationWithType* result = 0;
-		int depth = -1;
-
-		OuterTableType::const_iterator outer = table.find( id );
-		if ( outer == table.end() ) return 0;
-		const InnerTableType &declTable = outer->second;
-		for ( InnerTableType::const_iterator it = declTable.begin(); it != declTable.end(); ++it ) {
-			const std::stack< DeclEntry >& entry = it->second;
-			if ( ! entry.empty() && entry.top().second > depth ) {
-				result = entry.top().first;
-				depth = entry.top().second;
-			} // if
-		} // for
-		return result;
-	}
-
-	void IdTable::dump( std::ostream &os ) const {
-		for ( OuterTableType::const_iterator outer = table.begin(); outer != table.end(); ++outer ) {
-			for ( InnerTableType::const_iterator inner = outer->second.begin(); inner != outer->second.end(); ++inner ) {
-#if 0
-				const std::stack< DeclEntry >& entry = inner->second;
-				if ( ! entry.empty() ) { // && entry.top().second == scopeLevel ) {
-					os << outer->first << " (" << inner->first << ") (" << entry.top().second << ")" << std::endl;
-				} else {
-					os << outer->first << " (" << inner->first << ") ( entry-empty)" << std::endl;
-				} // if
-#endif
-#if 0
-				std::stack<DeclEntry> stack = inner->second;
-				os << "dumping a stack" << std::endl;
-				while ( ! stack.empty()) {
-					DeclEntry d = stack.top();
-					os << outer->first << " (" << inner->first << ") (" << d.second << ") " << std::endl;
-					stack.pop();
-				} // while
-#endif
-			} // for
-		} // for
-#if 0
-		for ( OuterTableType::const_iterator outer = table.begin(); outer != table.end(); ++outer ) {
-			for ( InnerTableType::const_iterator inner = outer->second.begin(); inner != outer->second.end(); ++inner ) {
-				const std::stack< DeclEntry >& entry = inner->second;
-				if ( ! entry.empty() && entry.top().second == scopeLevel ) {
-					os << outer->first << " (" << inner->first << ") (" << scopeLevel << ")" << std::endl;
-				} // if
-			} // for
-		} // for
-#endif
-	}
-} // namespace SymTab
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: src/SymTab/IdTable.h
===================================================================
--- src/SymTab/IdTable.h	(revision 4cc428651c83d14e03e03eefcb10aece78034e35)
+++ 	(revision )
@@ -1,54 +1,0 @@
-//
-// 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.
-//
-// IdTable.h -- 
-//
-// Author           : Richard C. Bilson
-// Created On       : Sun May 17 21:30:02 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 16:49:33 2015
-// Update Count     : 4
-//
-
-#ifndef IDTABLE_H
-#define IDTABLE_H
-
-#include <iostream>
-#include <map>
-#include <string>
-#include <stack>
-
-#include "SynTree/SynTree.h"
-
-namespace SymTab {
-	class IdTable {
-	  public:
-		IdTable();
-  
-		void enterScope();
-		void leaveScope();
-		void addDecl( DeclarationWithType *decl );
-		void lookupId( const std::string &id, std::list< DeclarationWithType* >& decls ) const;
-		DeclarationWithType* lookupId( const std::string &id) const;
-  
-		void dump( std::ostream &os ) const;			// debugging
-	  private:
-		typedef std::pair< DeclarationWithType*, int > DeclEntry;
-		typedef std::map< std::string, std::stack< DeclEntry > > InnerTableType;
-		typedef std::map< std::string, InnerTableType > OuterTableType;
-
-		OuterTableType table;
-		int scopeLevel;
-	};
-} // namespace SymTab
-
-#endif // IDTABLE_H
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: src/SymTab/ImplementationType.cc
===================================================================
--- src/SymTab/ImplementationType.cc	(revision 4cc428651c83d14e03e03eefcb10aece78034e35)
+++ src/SymTab/ImplementationType.cc	(revision eab39cd564d14ce04f69d69d6601d9e1588e282f)
@@ -10,6 +10,6 @@
 // Created On       : Sun May 17 21:32:01 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sun May 17 21:34:40 2015
-// Update Count     : 2
+// Last Modified On : Wed Mar  2 17:31:20 2016
+// Update Count     : 3
 //
 
@@ -37,5 +37,5 @@
 		virtual void visit(UnionInstType *aggregateUseType);
 		virtual void visit(EnumInstType *aggregateUseType);
-		virtual void visit(ContextInstType *aggregateUseType);
+		virtual void visit(TraitInstType *aggregateUseType);
 		virtual void visit(TypeInstType *aggregateUseType);
 		virtual void visit(TupleType *tupleType);
@@ -96,5 +96,5 @@
 	}
 
-	void ImplementationType::visit(ContextInstType *aggregateUseType) {
+	void ImplementationType::visit(TraitInstType *aggregateUseType) {
 	}
 
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision 4cc428651c83d14e03e03eefcb10aece78034e35)
+++ src/SymTab/Indexer.cc	(revision eab39cd564d14ce04f69d69d6601d9e1588e282f)
@@ -9,8 +9,22 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 21:37:33 2015
-// Last Modified By : Rob Schluntz
-// Last Modified On : Wed Aug 05 13:52:42 2015
-// Update Count     : 10
-//
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Mar  2 17:31:29 2016
+// Update Count     : 11
+//
+
+#include "Indexer.h"
+
+#include <string>
+#include <typeinfo>
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
+
+#include "Mangler.h"
+
+#include "Common/utility.h"
+
+#include "ResolvExpr/typeops.h"
 
 #include "SynTree/Declaration.h"
@@ -19,7 +33,4 @@
 #include "SynTree/Initializer.h"
 #include "SynTree/Statement.h"
-#include "Indexer.h"
-#include <typeinfo>
-#include "Common/utility.h"
 
 #define debugPrint(x) if ( doDebug ) { std::cout << x; }
@@ -33,7 +44,104 @@
 	}
 
-	Indexer::Indexer( bool useDebug ) : doDebug( useDebug ) {}
-
-	Indexer::~Indexer() {}
+	typedef std::unordered_map< std::string, DeclarationWithType* > MangleTable;
+	typedef std::unordered_map< std::string, MangleTable > IdTable;
+	typedef std::unordered_map< std::string, NamedTypeDecl* > TypeTable;
+	typedef std::unordered_map< std::string, StructDecl* > StructTable;
+	typedef std::unordered_map< std::string, EnumDecl* > EnumTable;
+	typedef std::unordered_map< std::string, UnionDecl* > UnionTable;
+	typedef std::unordered_map< std::string, TraitDecl* > TraitTable;
+
+	void dump( const IdTable &table, std::ostream &os ) {
+		for ( IdTable::const_iterator id = table.begin(); id != table.end(); ++id ) {
+			for ( MangleTable::const_iterator mangle = id->second.begin(); mangle != id->second.end(); ++mangle ) {
+				os << mangle->second << std::endl;
+			}
+		}
+	}
+	
+	template< typename Decl >
+	void dump( const std::unordered_map< std::string, Decl* > &table, std::ostream &os ) {
+		for ( typename std::unordered_map< std::string, Decl* >::const_iterator it = table.begin(); it != table.end(); ++it ) {
+			os << it->second << std::endl;
+		} // for
+	}
+	
+	struct Indexer::Impl {
+		Impl( unsigned long _scope ) : refCount(1), scope( _scope ), size( 0 ), base(),
+				idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {}
+		Impl( unsigned long _scope, Indexer &&_base ) : refCount(1), scope( _scope ), size( 0 ), base( _base ),
+				idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {}
+		unsigned long refCount;   ///< Number of references to these tables
+		unsigned long scope;      ///< Scope these tables are associated with
+		unsigned long size;       ///< Number of elements stored in this table
+		const Indexer base;       ///< Base indexer this extends
+		
+		IdTable idTable;          ///< Identifier namespace
+		TypeTable typeTable;      ///< Type namespace
+		StructTable structTable;  ///< Struct namespace
+		EnumTable enumTable;      ///< Enum namespace
+		UnionTable unionTable;    ///< Union namespace
+		TraitTable traitTable;    ///< Trait namespace
+	};
+
+	Indexer::Impl *Indexer::newRef( Indexer::Impl *toClone ) {
+		if ( ! toClone ) return 0;
+
+		// shorten the search chain by skipping empty links
+		Indexer::Impl *ret = toClone->size == 0 ? toClone->base.tables : toClone;
+		if ( ret ) { ++ret->refCount; }
+
+		return ret;
+	}
+
+	void Indexer::deleteRef( Indexer::Impl *toFree ) {
+		if ( ! toFree ) return;
+
+		if ( --toFree->refCount == 0 ) delete toFree;
+	}
+
+	void Indexer::makeWritable() {
+		if ( ! tables ) {
+			// create indexer if not yet set
+			tables = new Indexer::Impl( scope );
+		} else if ( tables->refCount > 1 || tables->scope != scope ) {
+			// make this indexer the base of a fresh indexer at the current scope
+			tables = new Indexer::Impl( scope, std::move( *this ) );
+		}
+	}
+
+	Indexer::Indexer( bool _doDebug ) : tables( 0 ), scope( 0 ), doDebug( _doDebug ) {}
+
+	Indexer::Indexer( const Indexer &that ) : tables( newRef( that.tables ) ), scope( that.scope ), doDebug( that.doDebug ) {}
+
+	Indexer::Indexer( Indexer &&that ) : tables( that.tables ), scope( that.scope ), doDebug( that.doDebug ) {
+		that.tables = 0;
+	}
+
+	Indexer::~Indexer() {
+		deleteRef( tables );
+	}
+
+	Indexer& Indexer::operator= ( const Indexer &that ) {
+		deleteRef( tables );
+
+		tables = newRef( that.tables );
+		scope = that.scope;
+		doDebug = that.doDebug;
+
+		return *this;
+	}
+
+	Indexer& Indexer::operator= ( Indexer &&that ) {
+		deleteRef( tables );
+
+		tables = that.tables;
+		scope = that.scope;
+		doDebug = that.doDebug;
+
+		that.tables = 0;
+
+		return *this;
+	}
 
 	void Indexer::visit( ObjectDecl *objectDecl ) {
@@ -45,5 +153,5 @@
 		if ( objectDecl->get_name() != "" ) {
 			debugPrint( "Adding object " << objectDecl->get_name() << std::endl );
-			idTable.addDecl( objectDecl );
+			addId( objectDecl );
 		} // if
 	}
@@ -52,5 +160,5 @@
 		if ( functionDecl->get_name() == "" ) return;
 		debugPrint( "Adding function " << functionDecl->get_name() << std::endl );
-		idTable.addDecl( functionDecl );
+		addId( functionDecl );
 		enterScope();
 		maybeAccept( functionDecl->get_functionType(), *this );
@@ -90,5 +198,5 @@
 		leaveScope();
 		debugPrint( "Adding type " << typeDecl->get_name() << std::endl );
-		typeTable.add( typeDecl );
+		addType( typeDecl );
 		acceptAll( typeDecl->get_assertions(), *this );
 	}
@@ -100,5 +208,5 @@
 		leaveScope();
 		debugPrint( "Adding typedef " << typeDecl->get_name() << std::endl );
-		typeTable.add( typeDecl );
+		addType( typeDecl );
 	}
 
@@ -108,5 +216,5 @@
 		cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
 		debugPrint( "Adding fwd decl for struct " << fwdDecl.get_name() << std::endl );
-		structTable.add( &fwdDecl );
+		addStruct( &fwdDecl );
   
 		enterScope();
@@ -117,5 +225,5 @@
 		debugPrint( "Adding struct " << aggregateDecl->get_name() << std::endl );
 		// this addition replaces the forward declaration
-		structTable.add( aggregateDecl );
+		addStruct( aggregateDecl );
 	}
 
@@ -125,5 +233,5 @@
 		cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
 		debugPrint( "Adding fwd decl for union " << fwdDecl.get_name() << std::endl );
-		unionTable.add( &fwdDecl );
+		addUnion( &fwdDecl );
   
 		enterScope();
@@ -133,15 +241,15 @@
   
 		debugPrint( "Adding union " << aggregateDecl->get_name() << std::endl );
-		unionTable.add( aggregateDecl );
+		addUnion( aggregateDecl );
 	}
 
 	void Indexer::visit( EnumDecl *aggregateDecl ) {
 		debugPrint( "Adding enum " << aggregateDecl->get_name() << std::endl );
-		enumTable.add( aggregateDecl );
+		addEnum( aggregateDecl );
 		// unlike structs, contexts, and unions, enums inject their members into the global scope
 		acceptAll( aggregateDecl->get_members(), *this );
 	}
 
-	void Indexer::visit( ContextDecl *aggregateDecl ) {
+	void Indexer::visit( TraitDecl *aggregateDecl ) {
 		enterScope();
 		acceptAll( aggregateDecl->get_parameters(), *this );
@@ -150,5 +258,5 @@
   
 		debugPrint( "Adding context " << aggregateDecl->get_name() << std::endl );
-		contextTable.add( aggregateDecl );
+		addTrait( aggregateDecl );
 	}
 
@@ -293,5 +401,5 @@
 
 
-	void Indexer::visit( ContextInstType *contextInst ) {
+	void Indexer::visit( TraitInstType *contextInst ) {
 		acceptAll( contextInst->get_parameters(), *this );
 		acceptAll( contextInst->get_members(), *this );
@@ -299,7 +407,7 @@
 
 	void Indexer::visit( StructInstType *structInst ) {
-		if ( ! structTable.lookup( structInst->get_name() ) ) {
+		if ( ! lookupStruct( structInst->get_name() ) ) {
 			debugPrint( "Adding struct " << structInst->get_name() << " from implicit forward declaration" << std::endl );
-			structTable.add( structInst->get_name() );
+			addStruct( structInst->get_name() );
 		}
 		enterScope();
@@ -309,7 +417,7 @@
 
 	void Indexer::visit( UnionInstType *unionInst ) {
-		if ( ! unionTable.lookup( unionInst->get_name() ) ) {
+		if ( ! lookupUnion( unionInst->get_name() ) ) {
 			debugPrint( "Adding union " << unionInst->get_name() << " from implicit forward declaration" << std::endl );
-			unionTable.add( unionInst->get_name() );
+			addUnion( unionInst->get_name() );
 		}
 		enterScope();
@@ -325,90 +433,361 @@
 	}
 
-
-	void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &list ) const {
-		idTable.lookupId( id, list );
-	}
-
-	DeclarationWithType* Indexer::lookupId( const std::string &id) const {
-		return idTable.lookupId(id);
+	
+
+	void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const {
+		std::unordered_set< std::string > foundMangleNames;
+		
+		Indexer::Impl *searchTables = tables;
+		while ( searchTables ) {
+
+			IdTable::const_iterator decls = searchTables->idTable.find( id );
+			if ( decls != searchTables->idTable.end() ) {
+				const MangleTable &mangleTable = decls->second;
+				for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
+					// mark the mangled name as found, skipping this insertion if a declaration for that name has already been found
+					if ( foundMangleNames.insert( decl->first ).second == false ) continue;
+					
+					out.push_back( decl->second );
+				}
+			}
+			
+			// get declarations from base indexers
+			searchTables = searchTables->base.tables;
+		}
 	}
 
 	NamedTypeDecl *Indexer::lookupType( const std::string &id ) const {
-		return typeTable.lookup( id );
+		if ( ! tables ) return 0;
+
+		TypeTable::const_iterator ret = tables->typeTable.find( id );
+		return ret != tables->typeTable.end() ? ret->second : tables->base.lookupType( id );
 	}
 
 	StructDecl *Indexer::lookupStruct( const std::string &id ) const {
-		return structTable.lookup( id );
+		if ( ! tables ) return 0;
+
+		StructTable::const_iterator ret = tables->structTable.find( id );
+		return ret != tables->structTable.end() ? ret->second : tables->base.lookupStruct( id );
 	}
 
 	EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
-		return enumTable.lookup( id );
+		if ( ! tables ) return 0;
+
+		EnumTable::const_iterator ret = tables->enumTable.find( id );
+		return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnum( id );
 	}
 
 	UnionDecl *Indexer::lookupUnion( const std::string &id ) const {
-		return unionTable.lookup( id );
-	}
-
-	ContextDecl  * Indexer::lookupContext( const std::string &id ) const {
-		return contextTable.lookup( id );
+		if ( ! tables ) return 0;
+
+		UnionTable::const_iterator ret = tables->unionTable.find( id );
+		return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnion( id );
+	}
+
+	TraitDecl *Indexer::lookupTrait( const std::string &id ) const {
+		if ( ! tables ) return 0;
+
+		TraitTable::const_iterator ret = tables->traitTable.find( id );
+		return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTrait( id );
+	}
+
+	DeclarationWithType *Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const {
+		if ( ! tables ) return 0;
+		if ( tables->scope < scope ) return 0;
+
+		IdTable::const_iterator decls = tables->idTable.find( id );
+		if ( decls != tables->idTable.end() ) {
+			const MangleTable &mangleTable = decls->second;
+			MangleTable::const_iterator decl = mangleTable.find( mangleName );
+			if ( decl != mangleTable.end() ) return decl->second;
+		}
+
+		return tables->base.lookupIdAtScope( id, mangleName, scope );
+	}
+
+	bool Indexer::hasIncompatibleCDecl( const std::string &id, const std::string &mangleName ) const {
+		if ( ! tables ) return false;
+
+		IdTable::const_iterator decls = tables->idTable.find( id );
+		if ( decls != tables->idTable.end() ) {
+			const MangleTable &mangleTable = decls->second;
+			for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
+				// check for C decls with the same name, skipping 
+				// those with a compatible type (by mangleName)
+				if ( decl->second->get_linkage() == LinkageSpec::C && decl->first != mangleName ) return true;
+			}
+		}
+
+		return tables->base.hasIncompatibleCDecl( id, mangleName );
+	}
+	
+	NamedTypeDecl *Indexer::lookupTypeAtScope( const std::string &id, unsigned long scope ) const {
+		if ( ! tables ) return 0;
+		if ( tables->scope < scope ) return 0;
+
+		TypeTable::const_iterator ret = tables->typeTable.find( id );
+		return ret != tables->typeTable.end() ? ret->second : tables->base.lookupTypeAtScope( id, scope );
+	}
+	
+	StructDecl *Indexer::lookupStructAtScope( const std::string &id, unsigned long scope ) const {
+		if ( ! tables ) return 0;
+		if ( tables->scope < scope ) return 0;
+
+		StructTable::const_iterator ret = tables->structTable.find( id );
+		return ret != tables->structTable.end() ? ret->second : tables->base.lookupStructAtScope( id, scope );
+	}
+	
+	EnumDecl *Indexer::lookupEnumAtScope( const std::string &id, unsigned long scope ) const {
+		if ( ! tables ) return 0;
+		if ( tables->scope < scope ) return 0;
+
+		EnumTable::const_iterator ret = tables->enumTable.find( id );
+		return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnumAtScope( id, scope );
+	}
+	
+	UnionDecl *Indexer::lookupUnionAtScope( const std::string &id, unsigned long scope ) const {
+		if ( ! tables ) return 0;
+		if ( tables->scope < scope ) return 0;
+
+		UnionTable::const_iterator ret = tables->unionTable.find( id );
+		return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnionAtScope( id, scope );
+	}
+	
+	TraitDecl *Indexer::lookupTraitAtScope( const std::string &id, unsigned long scope ) const {
+		if ( ! tables ) return 0;
+		if ( tables->scope < scope ) return 0;
+
+		TraitTable::const_iterator ret = tables->traitTable.find( id );
+		return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTraitAtScope( id, scope );
+	}
+
+	bool addedIdConflicts( DeclarationWithType *existing, DeclarationWithType *added ) {
+		// if we're giving the same name mangling to things of different types then there is something wrong
+		assert( (dynamic_cast<ObjectDecl*>( added ) && dynamic_cast<ObjectDecl*>( existing ) )
+			|| (dynamic_cast<FunctionDecl*>( added ) && dynamic_cast<FunctionDecl*>( existing ) ) );
+
+		if ( LinkageSpec::isOverridable( existing->get_linkage() ) ) {
+			// new definition shadows the autogenerated one, even at the same scope
+			return false;
+		} else if ( added->get_linkage() != LinkageSpec::C || ResolvExpr::typesCompatible( added->get_type(), existing->get_type(), Indexer() ) ) {
+			// typesCompatible doesn't really do the right thing here. When checking compatibility of function types,
+			// we should ignore outermost pointer qualifiers, except _Atomic?
+			FunctionDecl *newentry = dynamic_cast< FunctionDecl* >( added );
+			FunctionDecl *oldentry = dynamic_cast< FunctionDecl* >( existing );
+			if ( newentry && oldentry ) {
+				if ( newentry->get_statements() && oldentry->get_statements() ) {
+					throw SemanticError( "duplicate function definition for ", added );
+				} // if
+			} else {
+				// two objects with the same mangled name defined in the same scope.
+				// both objects must be marked extern or both must be intrinsic for this to be okay
+				// xxx - perhaps it's actually if either is intrinsic then this is okay?
+				//       might also need to be same storage class?
+				ObjectDecl *newobj = dynamic_cast< ObjectDecl* >( added );
+				ObjectDecl *oldobj = dynamic_cast< ObjectDecl* >( existing );
+				if ( newobj->get_storageClass() != DeclarationNode::Extern && oldobj->get_storageClass() != DeclarationNode::Extern ) {
+					throw SemanticError( "duplicate object definition for ", added );
+				} // if
+			} // if
+		} else {
+			throw SemanticError( "duplicate definition for ", added );
+		} // if
+
+		return true;
+	}
+	
+	void Indexer::addId( DeclarationWithType *decl ) {
+		makeWritable();
+
+		const std::string &name = decl->get_name();
+		std::string mangleName;
+		if ( LinkageSpec::isOverridable( decl->get_linkage() ) ) {
+			// mangle the name without including the appropriate suffix, so overridable routines are placed into the
+			// same "bucket" as their user defined versions.
+			mangleName = Mangler::mangle( decl, false );
+		} else {
+			mangleName = Mangler::mangle( decl );
+		} // if
+
+		DeclarationWithType *existing = lookupIdAtScope( name, mangleName, scope );
+		if ( ! existing || ! addedIdConflicts( existing, decl ) ) {
+			// this ensures that no two declarations with the same unmangled name both have C linkage
+			if ( decl->get_linkage() == LinkageSpec::C && hasIncompatibleCDecl( name, mangleName ) ) {
+				throw SemanticError( "invalid overload of C function ", decl );
+			} // NOTE this is broken in Richard's original code in such a way that it never triggers (it 
+			  // doesn't check decls that have the same manglename, and all C-linkage decls are defined to 
+			  // have their name as their manglename, hence the error can never trigger).
+			  // The code here is closer to correct, but name mangling would have to be completely 
+			  // isomorphic to C type-compatibility, which it may not be.
+			
+			tables->idTable[ name ][ mangleName ] = decl;
+			++tables->size;
+		}
+	}
+
+	bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) {
+		if ( existing->get_base() == 0 ) {
+			return false;
+		} else if ( added->get_base() == 0 ) {
+			return true;
+		} else {
+			throw SemanticError( "redeclaration of ", added );
+		}
+	}
+	
+	void Indexer::addType( NamedTypeDecl *decl ) {
+		makeWritable();
+
+		const std::string &id = decl->get_name();
+		TypeTable::iterator existing = tables->typeTable.find( id );
+		if ( existing == tables->typeTable.end() ) {
+			NamedTypeDecl *parent = tables->base.lookupTypeAtScope( id, scope );
+			if ( ! parent || ! addedTypeConflicts( parent, decl ) ) {
+				tables->typeTable.insert( existing, std::make_pair( id, decl ) );
+				++tables->size;
+			}
+		} else {
+			if ( ! addedTypeConflicts( existing->second, decl ) ) {
+				existing->second = decl;
+			}
+		}
+	}
+
+	bool addedDeclConflicts( AggregateDecl *existing, AggregateDecl *added ) {
+		if ( existing->get_members().empty() ) {
+			return false;
+		} else if ( ! added->get_members().empty() ) {
+			throw SemanticError( "redeclaration of ", added );
+		} // if
+		return true;
+	}
+
+	void Indexer::addStruct( const std::string &id ) {
+		addStruct( new StructDecl( id ) );
+	}
+	
+	void Indexer::addStruct( StructDecl *decl ) {
+		makeWritable();
+
+		const std::string &id = decl->get_name();
+		StructTable::iterator existing = tables->structTable.find( id );
+		if ( existing == tables->structTable.end() ) {
+			StructDecl *parent = tables->base.lookupStructAtScope( id, scope );
+			if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
+				tables->structTable.insert( existing, std::make_pair( id, decl ) );
+				++tables->size;
+			}
+		} else {
+			if ( ! addedDeclConflicts( existing->second, decl ) ) {
+				existing->second = decl;
+			}
+		}
+	}
+	
+	void Indexer::addEnum( EnumDecl *decl ) {
+		makeWritable();
+
+		const std::string &id = decl->get_name();
+		EnumTable::iterator existing = tables->enumTable.find( id );
+		if ( existing == tables->enumTable.end() ) {
+			EnumDecl *parent = tables->base.lookupEnumAtScope( id, scope );
+			if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
+				tables->enumTable.insert( existing, std::make_pair( id, decl ) );
+				++tables->size;
+			}
+		} else {
+			if ( ! addedDeclConflicts( existing->second, decl ) ) {
+				existing->second = decl;
+			}
+		}
+	}
+
+	void Indexer::addUnion( const std::string &id ) {
+		addUnion( new UnionDecl( id ) );
+	}
+	
+	void Indexer::addUnion( UnionDecl *decl ) {
+		makeWritable();
+
+		const std::string &id = decl->get_name();
+		UnionTable::iterator existing = tables->unionTable.find( id );
+		if ( existing == tables->unionTable.end() ) {
+			UnionDecl *parent = tables->base.lookupUnionAtScope( id, scope );
+			if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
+				tables->unionTable.insert( existing, std::make_pair( id, decl ) );
+				++tables->size;
+			}
+		} else {
+			if ( ! addedDeclConflicts( existing->second, decl ) ) {
+				existing->second = decl;
+			}
+		}
+	}
+	
+	void Indexer::addTrait( TraitDecl *decl ) {
+		makeWritable();
+
+		const std::string &id = decl->get_name();
+		TraitTable::iterator existing = tables->traitTable.find( id );
+		if ( existing == tables->traitTable.end() ) {
+			TraitDecl *parent = tables->base.lookupTraitAtScope( id, scope );
+			if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
+				tables->traitTable.insert( existing, std::make_pair( id, decl ) );
+				++tables->size;
+			}
+		} else {
+			if ( ! addedDeclConflicts( existing->second, decl ) ) {
+				existing->second = decl;
+			}
+		}
 	}
 
 	void Indexer::enterScope() {
+		++scope;
+		
 		if ( doDebug ) {
-			std::cout << "--- Entering scope" << std::endl;
-		}
-		idTable.enterScope();
-		typeTable.enterScope();
-		structTable.enterScope();
-		enumTable.enterScope();
-		unionTable.enterScope();
-		contextTable.enterScope();
+			std::cout << "--- Entering scope " << scope << std::endl;
+		}
 	}
 
 	void Indexer::leaveScope() {
 		using std::cout;
-		using std::endl;
-  
-		if ( doDebug ) {
-			cout << "--- Leaving scope containing" << endl;
-			idTable.dump( cout );
-			typeTable.dump( cout );
-			structTable.dump( cout );
-			enumTable.dump( cout );
-			unionTable.dump( cout );
-			contextTable.dump( cout );
-		}
-		idTable.leaveScope();
-		typeTable.leaveScope();
-		structTable.leaveScope();
-		enumTable.leaveScope();
-		unionTable.leaveScope();
-		contextTable.leaveScope();
+
+		assert( scope > 0 && "cannot leave initial scope" );
+		--scope;
+
+		while ( tables && tables->scope > scope ) {
+			if ( doDebug ) {
+				cout << "--- Leaving scope " << tables->scope << " containing" << std::endl;
+				dump( tables->idTable, cout );
+				dump( tables->typeTable, cout );
+				dump( tables->structTable, cout );
+				dump( tables->enumTable, cout );
+				dump( tables->unionTable, cout );
+				dump( tables->traitTable, cout );
+			}
+
+			// swap tables for base table until we find one at an appropriate scope
+			Indexer::Impl *base = newRef( tables->base.tables );
+			deleteRef( tables );
+			tables = base;
+		}
 	}
 
 	void Indexer::print( std::ostream &os, int indent ) const {
 	    using std::cerr;
-	    using std::endl;
-
-	    cerr << "===idTable===" << endl;
-	    idTable.dump( os );
-	    cerr << "===typeTable===" << endl;
-	    typeTable.dump( os );
-	    cerr << "===structTable===" << endl;
-	    structTable.dump( os );
-	    cerr << "===enumTable===" << endl;
-	    enumTable.dump( os );
-	    cerr << "===unionTable===" << endl;
-	    unionTable.dump( os );
-	    cerr << "===contextTable===" << endl;
-	    contextTable.dump( os );
-#if 0
-		idTable.dump( os );
-		typeTable.dump( os );
-		structTable.dump( os );
-		enumTable.dump( os );
-		unionTable.dump( os );
-		contextTable.dump( os );
-#endif
+
+	    cerr << "===idTable===" << std::endl;
+	    if ( tables ) dump( tables->idTable, os );
+	    cerr << "===typeTable===" << std::endl;
+	    if ( tables ) dump( tables->typeTable, os );
+	    cerr << "===structTable===" << std::endl;
+	    if ( tables ) dump( tables->structTable, os );
+	    cerr << "===enumTable===" << std::endl;
+	    if ( tables ) dump( tables->enumTable, os );
+	    cerr << "===unionTable===" << std::endl;
+	    if ( tables ) dump( tables->unionTable, os );
+	    cerr << "===contextTable===" << std::endl;
+	    if ( tables ) dump( tables->traitTable, os );
 	}
 } // namespace SymTab
Index: src/SymTab/Indexer.h
===================================================================
--- src/SymTab/Indexer.h	(revision 4cc428651c83d14e03e03eefcb10aece78034e35)
+++ src/SymTab/Indexer.h	(revision eab39cd564d14ce04f69d69d6601d9e1588e282f)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 21:38:55 2015
-// Last Modified By : Rob Schluntz
-// Last Modified On : Thu Sep 17 16:05:38 2015
-// Update Count     : 5
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Mar  2 17:34:14 2016
+// Update Count     : 6
 //
 
@@ -21,7 +21,4 @@
 
 #include "SynTree/Visitor.h"
-#include "IdTable.h"
-#include "AggregateTable.h"
-#include "TypeTable.h"
 
 namespace SymTab {
@@ -29,5 +26,10 @@
 	  public:
 		Indexer( bool useDebug = false );
+
+		Indexer( const Indexer &that );
+		Indexer( Indexer &&that );
 		virtual ~Indexer();
+		Indexer& operator= ( const Indexer &that );
+		Indexer& operator= ( Indexer &&that );
 
 		//using Visitor::visit;
@@ -39,5 +41,5 @@
 		virtual void visit( UnionDecl *aggregateDecl );
 		virtual void visit( EnumDecl *aggregateDecl );
-		virtual void visit( ContextDecl *aggregateDecl );
+		virtual void visit( TraitDecl *aggregateDecl );
 
 		virtual void visit( CompoundStmt *compoundStmt );
@@ -67,5 +69,5 @@
 		virtual void visit( UntypedValofExpr *valofExpr );
 
-		virtual void visit( ContextInstType *contextInst );
+		virtual void visit( TraitInstType *contextInst );
 		virtual void visit( StructInstType *contextInst );
 		virtual void visit( UnionInstType *contextInst );
@@ -78,22 +80,51 @@
 		void leaveScope();
 
-		void lookupId( const std::string &id, std::list< DeclarationWithType* >& ) const;
-		DeclarationWithType* lookupId( const std::string &id) const;
+		/// Gets all declarations with the given ID
+		void lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const;
+		/// Gets the top-most type declaration with the given ID
 		NamedTypeDecl *lookupType( const std::string &id ) const;
+		/// Gets the top-most struct declaration with the given ID
 		StructDecl *lookupStruct( const std::string &id ) const;
+		/// Gets the top-most enum declaration with the given ID
 		EnumDecl *lookupEnum( const std::string &id ) const;
+		/// Gets the top-most union declaration with the given ID
 		UnionDecl *lookupUnion( const std::string &id ) const;
-		ContextDecl *lookupContext( const std::string &id ) const;
+		/// Gets the top-most trait declaration with the given ID
+		TraitDecl *lookupTrait( const std::string &id ) const;
   
 		void print( std::ostream &os, int indent = 0 ) const;
 	  private:
-		IdTable idTable;
-		TypeTable typeTable;
-		StructTable structTable;
-		EnumTable enumTable;
-		UnionTable unionTable;
-		ContextTable contextTable;
-  
-		bool doDebug;					// display debugging trace
+		/// looks up a specific mangled ID at the given scope
+		DeclarationWithType *lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
+		/// returns true if there exists a declaration with C linkage and the given name with a different mangled name
+		bool hasIncompatibleCDecl( const std::string &id, const std::string &mangleName ) const;
+		// equivalents to lookup functions that only look at tables at scope `scope` (which should be >= tables->scope)
+		NamedTypeDecl *lookupTypeAtScope( const std::string &id, unsigned long scope ) const;
+		StructDecl *lookupStructAtScope( const std::string &id, unsigned long scope ) const;
+		EnumDecl *lookupEnumAtScope( const std::string &id, unsigned long scope ) const;
+		UnionDecl *lookupUnionAtScope( const std::string &id, unsigned long scope ) const;
+		TraitDecl *lookupTraitAtScope( const std::string &id, unsigned long scope ) const;
+		
+		void addId( DeclarationWithType *decl );
+		void addType( NamedTypeDecl *decl );
+		void addStruct( const std::string &id );
+		void addStruct( StructDecl *decl );
+		void addEnum( EnumDecl *decl );
+		void addUnion( const std::string &id );
+		void addUnion( UnionDecl *decl );
+		void addTrait( TraitDecl *decl );
+		
+		struct Impl;
+		Impl *tables;         ///< Copy-on-write instance of table data structure
+		unsigned long scope;  ///< Scope index of this pointer
+		bool doDebug;         ///< Display debugging trace?
+
+		/// Takes a new ref to a table (returns null if null)
+		static Impl *newRef( Impl *toClone );
+		/// Clears a ref to a table (does nothing if null)
+		static void deleteRef( Impl *toFree );
+
+		/// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope)
+		void makeWritable();
 	};
 } // namespace SymTab
Index: src/SymTab/Mangler.cc
===================================================================
--- src/SymTab/Mangler.cc	(revision 4cc428651c83d14e03e03eefcb10aece78034e35)
+++ src/SymTab/Mangler.cc	(revision eab39cd564d14ce04f69d69d6601d9e1588e282f)
@@ -227,4 +227,5 @@
 
 	void Mangler::visit( VarArgsType *varArgsType ) {
+		printQualifiers( varArgsType );
 		mangleName << "VARGS";
 	}
Index: src/SymTab/StackTable.cc
===================================================================
--- src/SymTab/StackTable.cc	(revision 4cc428651c83d14e03e03eefcb10aece78034e35)
+++ 	(revision )
@@ -1,84 +1,0 @@
-//
-// 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.
-//
-// StackTable.cc -- 
-//
-// Author           : Richard C. Bilson
-// Created On       : Sun May 17 21:45:15 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 16:51:53 2015
-// Update Count     : 3
-//
-
-#include <cassert>
-
-#include "StackTable.h"
-
-namespace SymTab {
-	template< typename Element, typename ConflictFunction >
-	StackTable< Element, ConflictFunction >::StackTable() : scopeLevel( 0 ) {
-	}
-
-	template< typename Element, typename ConflictFunction >
-	void StackTable< Element, ConflictFunction >::enterScope() {
-		scopeLevel++;
-	}
-
-	template< typename Element, typename ConflictFunction >
-	void StackTable< Element, ConflictFunction >::leaveScope() {
-		for ( typename TableType::iterator it = table.begin(); it != table.end(); ++it ) {
-			std::stack< Entry >& entry = it->second;
-			if ( ! entry.empty() && entry.top().second == scopeLevel ) {
-				entry.pop();
-			} // if
-		} // for
-		scopeLevel--;
-		assert( scopeLevel >= 0 );
-	}
-
-	template< typename Element, typename ConflictFunction >
-	void StackTable< Element, ConflictFunction >::add( Element *type ) {
-		std::stack< Entry >& entry = table[ type->get_name() ];
-		if ( ! entry.empty() && entry.top().second == scopeLevel ) {
-			entry.top().first = conflictFunction( entry.top().first, type );
-		} else {
-			entry.push( Entry( type, scopeLevel ) );
-		} // if
-	}
-
-	template< typename Element, typename ConflictFunction >
-	void StackTable< Element, ConflictFunction >::add( std::string fwdDeclName ) {
-		add( new Element( fwdDeclName ) );
-	}
-
-	template< typename Element, typename ConflictFunction >
-	Element *StackTable< Element, ConflictFunction >::lookup( std::string id ) const {
-		typename TableType::const_iterator it = table.find( id );
-		if ( it == table.end() ) {
-			return 0;
-		} else if ( ! it->second.empty() ) {
-			return it->second.top().first;
-		} else {
-			return 0;
-		} // if
-	}
-
-	template< typename Element, typename ConflictFunction >
-	void StackTable< Element, ConflictFunction >::dump( std::ostream &os ) const {
-		for ( typename TableType::const_iterator it = table.begin(); it != table.end(); ++it ) {
-			const std::stack< Entry >& entry = it->second;
-			if ( ! entry.empty() && entry.top().second == scopeLevel ) {
-				os << it->first << std::endl;
-			} // if
-		} // for
-	}
-} // namespace SymTab
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: src/SymTab/StackTable.h
===================================================================
--- src/SymTab/StackTable.h	(revision 4cc428651c83d14e03e03eefcb10aece78034e35)
+++ 	(revision )
@@ -1,55 +1,0 @@
-//
-// 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.
-//
-// StackTable.h -- 
-//
-// Author           : Richard C. Bilson
-// Created On       : Sun May 17 21:47:10 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 16:50:36 2015
-// Update Count     : 4
-//
-
-#ifndef STACKTABLE_H
-#define STACKTABLE_H
-
-#include <map>
-#include <stack>
-#include <string>
-#include <functional>
-
-namespace SymTab {
-	template< typename Element, typename ConflictFunction >
-	class StackTable {
-	  public:
-		StackTable();
-
-		void enterScope();
-		void leaveScope();
-		void add( Element *type );
-		void add( std::string fwdDeclName );
-		Element *lookup( std::string id ) const;
-
-		void dump( std::ostream &os ) const;			// debugging
-	  private:
-		typedef std::pair< Element*, int > Entry;
-		typedef std::map< std::string, std::stack< Entry > > TableType;
-  
-		ConflictFunction conflictFunction;
-		TableType table;
-		int scopeLevel;
-	};
-} // SymTab
-
-#include "StackTable.cc"
-
-#endif // STACKTABLE_H
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: src/SymTab/TypeEquality.cc
===================================================================
--- src/SymTab/TypeEquality.cc	(revision 4cc428651c83d14e03e03eefcb10aece78034e35)
+++ src/SymTab/TypeEquality.cc	(revision eab39cd564d14ce04f69d69d6601d9e1588e282f)
@@ -194,5 +194,5 @@
 
 	void TypeEquality::visit( VarArgsType *varArgsType ) {
-		// don't handle qualifiers; var args pack shouldn't have any
+		handleQualifiers( varArgsType );
 		if ( ! dynamic_cast< VarArgsType * >( other ) ) {
 			result = false;
Index: src/SymTab/TypeTable.h
===================================================================
--- src/SymTab/TypeTable.h	(revision 4cc428651c83d14e03e03eefcb10aece78034e35)
+++ 	(revision )
@@ -1,53 +1,0 @@
-//
-// 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.
-//
-// TypeTable.h -- 
-//
-// Author           : Richard C. Bilson
-// Created On       : Sun May 17 21:48:32 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 16:50:25 2015
-// Update Count     : 3
-//
-
-#ifndef TYPETABLE_H
-#define TYPETABLE_H
-
-#include <cassert>
-#include <map>
-#include <stack>
-#include <string>
-#include <functional>
-
-#include "StackTable.h"
-#include "SynTree/Declaration.h"
-
-namespace SymTab {
-	class TypeTableConflictFunction : public std::binary_function< NamedTypeDecl *, NamedTypeDecl *, NamedTypeDecl * > {
-	  public:
-		NamedTypeDecl *operator()( NamedTypeDecl *existing, NamedTypeDecl *added ) {
-			if ( existing->get_base() == 0 ) {
-				return added;
-			} else if ( added->get_base() == 0 ) {
-				return existing;
-			} else {
-				throw SemanticError( "redeclaration of ", added );
-			} // if
-			assert( false );
-			return 0;
-		}
-	};
-
-	typedef StackTable< NamedTypeDecl, TypeTableConflictFunction > TypeTable;
-} // namespace SymTab
-
-#endif // TYPETABLE_H
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 4cc428651c83d14e03e03eefcb10aece78034e35)
+++ src/SymTab/Validate.cc	(revision eab39cd564d14ce04f69d69d6601d9e1588e282f)
@@ -10,5 +10,5 @@
 // Created On       : Sun May 17 21:50:04 2015
 // Last Modified By : Rob Schluntz
-// Last Modified On : Mon Feb 22 12:26:37 2016
+// Last Modified On : Mon Apr 04 17:13:29 2016
 // Update Count     : 297
 //
@@ -102,5 +102,5 @@
 		virtual void visit( StructInstType *structInst );
 		virtual void visit( UnionInstType *unionInst );
-		virtual void visit( ContextInstType *contextInst );
+		virtual void visit( TraitInstType *contextInst );
 		virtual void visit( StructDecl *structDecl );
 		virtual void visit( UnionDecl *unionDecl );
@@ -158,5 +158,5 @@
 		virtual Declaration *mutate( UnionDecl * unionDecl );
 		virtual Declaration *mutate( EnumDecl * enumDecl );
-		virtual Declaration *mutate( ContextDecl * contextDecl );
+		virtual Declaration *mutate( TraitDecl * contextDecl );
 
 		template<typename AggDecl>
@@ -370,7 +370,7 @@
 	}
 
-	void Pass2::visit( ContextInstType *contextInst ) {
+	void Pass2::visit( TraitInstType *contextInst ) {
 		Parent::visit( contextInst );
-		ContextDecl *ctx = indexer->lookupContext( contextInst->get_name() );
+		TraitDecl *ctx = indexer->lookupTrait( contextInst->get_name() );
 		if ( ! ctx ) {
 			throw SemanticError( "use of undeclared context " + contextInst->get_name() );
@@ -378,5 +378,5 @@
 		for ( std::list< TypeDecl * >::const_iterator i = ctx->get_parameters().begin(); i != ctx->get_parameters().end(); ++i ) {
 			for ( std::list< DeclarationWithType * >::const_iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
-				if ( ContextInstType *otherCtx = dynamic_cast< ContextInstType * >(*assert ) ) {
+				if ( TraitInstType *otherCtx = dynamic_cast< TraitInstType * >(*assert ) ) {
 					cloneAll( otherCtx->get_members(), contextInst->get_members() );
 				} else {
@@ -442,5 +442,5 @@
 			while ( ! toBeDone.empty() ) {
 				for ( std::list< DeclarationWithType * >::iterator assertion = toBeDone.begin(); assertion != toBeDone.end(); ++assertion ) {
-					if ( ContextInstType *ctx = dynamic_cast< ContextInstType * >( (*assertion )->get_type() ) ) {
+					if ( TraitInstType *ctx = dynamic_cast< TraitInstType * >( (*assertion )->get_type() ) ) {
 						for ( std::list< Declaration * >::const_iterator i = ctx->get_members().begin(); i != ctx->get_members().end(); ++i ) {
 							DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *i );
@@ -652,5 +652,5 @@
 	}
 
-		Declaration *EliminateTypedef::mutate( ContextDecl * contextDecl ) {
+		Declaration *EliminateTypedef::mutate( TraitDecl * contextDecl ) {
 		Mutator::mutate( contextDecl );
 		return handleAggregate( contextDecl );
Index: src/SymTab/module.mk
===================================================================
--- src/SymTab/module.mk	(revision 4cc428651c83d14e03e03eefcb10aece78034e35)
+++ src/SymTab/module.mk	(revision eab39cd564d14ce04f69d69d6601d9e1588e282f)
@@ -15,6 +15,5 @@
 ###############################################################################
 
-SRC += SymTab/IdTable.cc \
-       SymTab/Indexer.cc \
+SRC += SymTab/Indexer.cc \
        SymTab/Mangler.cc \
        SymTab/Validate.cc \
