Index: src/AST/SymbolTable.cpp
===================================================================
--- src/AST/SymbolTable.cpp	(revision 24d6572fc571b2a894d56a9335edd57899c448c0)
+++ src/AST/SymbolTable.cpp	(revision caf06aa71fb525bbcc4811ec5a00225c9c9c6583)
@@ -91,9 +91,17 @@
 }
 
-SymbolTable::SymbolTable()
+SymbolTable::SymbolTable( ErrorDetection errorMode )
 : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(),
-  prevScope(), scope( 0 ), repScope( 0 ) { ++*stats().count; }
+  prevScope(), scope( 0 ), repScope( 0 ), errorMode(errorMode) { ++*stats().count; }
 
 SymbolTable::~SymbolTable() { stats().size->push( idTable ? idTable->size() : 0 ); }
+
+void SymbolTable::OnFindError( CodeLocation location, std::string error ) const {
+	assertf( errorMode != AssertClean, "Name collision/redefinition, found during a compilation phase where none should be possible.  Detail: %s", error.c_str() );
+	if (errorMode == ValidateOnAdd) {
+		SemanticError(location, error);
+	}
+	assertf( errorMode == IgnoreErrors, "Unrecognized symbol-table error mode %d", errorMode );
+}
 
 void SymbolTable::enterScope() {
@@ -274,31 +282,29 @@
 }
 
-namespace {
-	/// true if redeclaration conflict between two types
-	bool addedTypeConflicts( const NamedTypeDecl * existing, const NamedTypeDecl * added ) {
-		if ( existing->base == nullptr ) {
-			return false;
-		} else if ( added->base == nullptr ) {
-			return true;
-		} else {
-			// typedef redeclarations are errors only if types are different
-			if ( ! ResolvExpr::typesCompatible( existing->base, added->base ) ) {
-				SemanticError( added->location, "redeclaration of " + added->name );
-			}
-		}
-		// does not need to be added to the table if both existing and added have a base that are
-		// the same
+bool SymbolTable::addedTypeConflicts(
+		const NamedTypeDecl * existing, const NamedTypeDecl * added ) const {
+	if ( existing->base == nullptr ) {
+		return false;
+	} else if ( added->base == nullptr ) {
 		return true;
-	}
-
-	/// true if redeclaration conflict between two aggregate declarations
-	bool addedDeclConflicts( const AggregateDecl * existing, const AggregateDecl * added ) {
-		if ( ! existing->body ) {
-			return false;
-		} else if ( added->body ) {
-			SemanticError( added, "redeclaration of " );
-		}
-		return true;
-	}
+	} else {
+		// typedef redeclarations are errors only if types are different
+		if ( ! ResolvExpr::typesCompatible( existing->base, added->base ) ) {
+			OnFindError( added->location, "redeclaration of " + added->name );
+		}
+	}
+	// does not need to be added to the table if both existing and added have a base that are
+	// the same
+	return true;
+}
+
+bool SymbolTable::addedDeclConflicts( 
+		const AggregateDecl * existing, const AggregateDecl * added ) const {
+	if ( ! existing->body ) {
+		return false;
+	} else if ( added->body ) {
+		OnFindError( added, "redeclaration of " );
+	}
+	return true;
 }
 
@@ -653,10 +659,10 @@
 		if ( deleter && ! existing.deleter ) {
 			if ( handleConflicts.mode == OnConflict::Error ) {
-				SemanticError( added, "deletion of defined identifier " );
+				OnFindError( added, "deletion of defined identifier " );
 			}
 			return true;
 		} else if ( ! deleter && existing.deleter ) {
 			if ( handleConflicts.mode == OnConflict::Error ) {
-				SemanticError( added, "definition of deleted identifier " );
+				OnFindError( added, "definition of deleted identifier " );
 			}
 			return true;
@@ -666,5 +672,5 @@
 		if ( isDefinition( added ) && isDefinition( existing.id ) ) {
 			if ( handleConflicts.mode == OnConflict::Error ) {
-				SemanticError( added,
+				OnFindError( added,
 					isFunction( added ) ?
 						"duplicate function definition for " :
@@ -675,5 +681,5 @@
 	} else {
 		if ( handleConflicts.mode == OnConflict::Error ) {
-			SemanticError( added, "duplicate definition for " );
+			OnFindError( added, "duplicate definition for " );
 		}
 		return true;
@@ -727,5 +733,5 @@
 		// Check that a Cforall declaration doesn't override any C declaration
 		if ( hasCompatibleCDecl( name, mangleName ) ) {
-			SemanticError( decl, "Cforall declaration hides C function " );
+			OnFindError( decl, "Cforall declaration hides C function " );
 		}
 	} else {
@@ -733,5 +739,5 @@
 		// type-compatibility, which it may not be.
 		if ( hasIncompatibleCDecl( name, mangleName ) ) {
-			SemanticError( decl, "conflicting overload of C function " );
+			OnFindError( decl, "conflicting overload of C function " );
 		}
 	}
