Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision 52c2a72881ce34e949bfca571ffcb391d884f339)
+++ src/Makefile.in	(revision bed4c63e6705d5b6c020d4f687b6de771de36626)
@@ -153,5 +153,4 @@
 	ResolvExpr/driver_cfa_cpp-Occurs.$(OBJEXT) \
 	ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT) \
-	SymTab/driver_cfa_cpp-IdTable.$(OBJEXT) \
 	SymTab/driver_cfa_cpp-Indexer.$(OBJEXT) \
 	SymTab/driver_cfa_cpp-Mangler.$(OBJEXT) \
@@ -360,12 +359,11 @@
 	ResolvExpr/RenameVars.cc ResolvExpr/FindOpenVars.cc \
 	ResolvExpr/PolyCost.cc ResolvExpr/Occurs.cc \
-	ResolvExpr/TypeEnvironment.cc SymTab/IdTable.cc \
-	SymTab/Indexer.cc SymTab/Mangler.cc SymTab/Validate.cc \
-	SymTab/FixFunction.cc SymTab/ImplementationType.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 \
+	ResolvExpr/TypeEnvironment.cc SymTab/Indexer.cc \
+	SymTab/Mangler.cc SymTab/Validate.cc SymTab/FixFunction.cc \
+	SymTab/ImplementationType.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/VarArgsType.cc SynTree/Constant.cc \
 	SynTree/Expression.cc SynTree/TupleExpr.cc \
@@ -660,6 +658,4 @@
 	@$(MKDIR_P) SymTab/$(DEPDIR)
 	@: > SymTab/$(DEPDIR)/$(am__dirstamp)
-SymTab/driver_cfa_cpp-IdTable.$(OBJEXT): SymTab/$(am__dirstamp) \
-	SymTab/$(DEPDIR)/$(am__dirstamp)
 SymTab/driver_cfa_cpp-Indexer.$(OBJEXT): SymTab/$(am__dirstamp) \
 	SymTab/$(DEPDIR)/$(am__dirstamp)
@@ -827,5 +823,4 @@
 	-rm -f ResolvExpr/driver_cfa_cpp-Unify.$(OBJEXT)
 	-rm -f SymTab/driver_cfa_cpp-FixFunction.$(OBJEXT)
-	-rm -f SymTab/driver_cfa_cpp-IdTable.$(OBJEXT)
 	-rm -f SymTab/driver_cfa_cpp-ImplementationType.$(OBJEXT)
 	-rm -f SymTab/driver_cfa_cpp-Indexer.$(OBJEXT)
@@ -933,5 +928,4 @@
 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Po@am__quote@
@@ -1792,18 +1786,4 @@
 @am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-TypeEnvironment.obj `if test -f 'ResolvExpr/TypeEnvironment.cc'; then $(CYGPATH_W) 'ResolvExpr/TypeEnvironment.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/TypeEnvironment.cc'; fi`
 
-SymTab/driver_cfa_cpp-IdTable.o: SymTab/IdTable.cc
-@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-IdTable.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Tpo -c -o SymTab/driver_cfa_cpp-IdTable.o `test -f 'SymTab/IdTable.cc' || echo '$(srcdir)/'`SymTab/IdTable.cc
-@am__fastdepCXX_TRUE@	$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='SymTab/IdTable.cc' object='SymTab/driver_cfa_cpp-IdTable.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) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-IdTable.o `test -f 'SymTab/IdTable.cc' || echo '$(srcdir)/'`SymTab/IdTable.cc
-
-SymTab/driver_cfa_cpp-IdTable.obj: SymTab/IdTable.cc
-@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-IdTable.obj -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Tpo -c -o SymTab/driver_cfa_cpp-IdTable.obj `if test -f 'SymTab/IdTable.cc'; then $(CYGPATH_W) 'SymTab/IdTable.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/IdTable.cc'; fi`
-@am__fastdepCXX_TRUE@	$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='SymTab/IdTable.cc' object='SymTab/driver_cfa_cpp-IdTable.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) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-IdTable.obj `if test -f 'SymTab/IdTable.cc'; then $(CYGPATH_W) 'SymTab/IdTable.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/IdTable.cc'; fi`
-
 SymTab/driver_cfa_cpp-Indexer.o: SymTab/Indexer.cc
 @am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Indexer.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Tpo -c -o SymTab/driver_cfa_cpp-Indexer.o `test -f 'SymTab/Indexer.cc' || echo '$(srcdir)/'`SymTab/Indexer.cc
Index: src/SymTab/IdTable.cc
===================================================================
--- src/SymTab/IdTable.cc	(revision 52c2a72881ce34e949bfca571ffcb391d884f339)
+++ 	(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 52c2a72881ce34e949bfca571ffcb391d884f339)
+++ 	(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/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision 52c2a72881ce34e949bfca571ffcb391d884f339)
+++ src/SymTab/Indexer.cc	(revision bed4c63e6705d5b6c020d4f687b6de771de36626)
@@ -21,5 +21,9 @@
 #include <utility>
 
-#include "IdTable.h"
+#include "Mangler.h"
+
+#include "Common/utility.h"
+
+#include "ResolvExpr/typeops.h"
 
 #include "SynTree/Declaration.h"
@@ -28,6 +32,4 @@
 #include "SynTree/Initializer.h"
 #include "SynTree/Statement.h"
-
-#include "Common/utility.h"
 
 #define debugPrint(x) if ( doDebug ) { std::cout << x; }
@@ -41,4 +43,6 @@
 	}
 
+	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;
@@ -47,4 +51,12 @@
 	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 ) {
@@ -420,17 +432,19 @@
 	}
 
-
-	void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &list ) const {
+	
+
+	void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const {
 		if ( ! tables ) return;
+
+		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 ) {
+				out.push_back( decl->second );
+			}
+		}
 		
-		tables->idTable.lookupId( id, list );
-		tables->base.lookupId( id, list );
-	}
-
-	DeclarationWithType* Indexer::lookupId( const std::string &id) const {
-		if ( ! tables ) return 0;
-		
-		DeclarationWithType *ret = tables->idTable.lookupId(id);
-		return ret ? ret : tables->base.lookupId(id);
+		// get declarations from base indexers
+		tables->base.lookupId( id, out );
 	}
 
@@ -470,4 +484,32 @@
 	}
 
+	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::hasCDeclWithName( const std::string &id ) 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 ) {
+				if ( decl->second->get_linkage() == LinkageSpec::C ) return true;
+			}
+		}
+
+		return tables->base.hasCDeclWithName( id );
+	}
+	
 	NamedTypeDecl *Indexer::lookupTypeAtScope( const std::string &id, unsigned long scope ) const {
 		if ( ! tables ) return 0;
@@ -510,8 +552,64 @@
 	}
 
+	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();
-		tables->idTable.addDecl( decl );
-		++tables->size;
+
+		const std::string &name = decl->get_name();
+		std::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
+
+		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 && hasCDeclWithName( name ) ) {
+				throw SemanticError( "invalid overload of C function ", decl );
+			}
+			
+			tables->idTable[ name ][ mangleName ] = decl;
+			++tables->size;
+		}
 	}
 
@@ -650,5 +748,5 @@
 			if ( doDebug ) {
 				cout << "--- Leaving scope " << tables->scope << " containing" << std::endl;
-				tables->idTable.dump( cout );
+				dump( tables->idTable, cout );
 				dump( tables->typeTable, cout );
 				dump( tables->structTable, cout );
@@ -669,5 +767,5 @@
 
 	    cerr << "===idTable===" << std::endl;
-	    if ( tables ) tables->idTable.dump( os );
+	    if ( tables ) dump( tables->idTable, os );
 	    cerr << "===typeTable===" << std::endl;
 	    if ( tables ) dump( tables->typeTable, os );
Index: src/SymTab/Indexer.h
===================================================================
--- src/SymTab/Indexer.h	(revision 52c2a72881ce34e949bfca571ffcb391d884f339)
+++ src/SymTab/Indexer.h	(revision bed4c63e6705d5b6c020d4f687b6de771de36626)
@@ -80,14 +80,23 @@
 		void leaveScope();
 
+		/// Gets all declarations with the given ID
 		void lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const;
-		DeclarationWithType* lookupId( const std::string &id ) 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;
+		/// 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:
+		/// 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
+		bool hasCDeclWithName( const std::string &id ) 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;
Index: src/SymTab/module.mk
===================================================================
--- src/SymTab/module.mk	(revision 52c2a72881ce34e949bfca571ffcb391d884f339)
+++ src/SymTab/module.mk	(revision bed4c63e6705d5b6c020d4f687b6de771de36626)
@@ -15,6 +15,5 @@
 ###############################################################################
 
-SRC += SymTab/IdTable.cc \
-       SymTab/Indexer.cc \
+SRC += SymTab/Indexer.cc \
        SymTab/Mangler.cc \
        SymTab/Validate.cc \
