Implement a module-level symbol table for functions, enforcing uniqueness of
names across the module and auto-renaming conflicts.  Have the parser reject
malformed modules that have redefinitions.

PiperOrigin-RevId: 209227560
diff --git a/lib/Parser/Parser.cpp b/lib/Parser/Parser.cpp
index f263804..ae87ad2 100644
--- a/lib/Parser/Parser.cpp
+++ b/lib/Parser/Parser.cpp
@@ -1945,8 +1945,6 @@
                            "'");
   }
 
-  getModule()->getFunctions().push_back(function);
-
   return finalizeFunction(function, braceLoc);
 }
 
@@ -2122,8 +2120,6 @@
   if (parseStmtBlock(function))
     return ParseFailure;
 
-  getModule()->getFunctions().push_back(function);
-
   return finalizeFunction(function, braceLoc);
 }
 
@@ -2579,6 +2575,7 @@
 ///
 ParseResult ModuleParser::parseExtFunc() {
   consumeToken(Token::kw_extfunc);
+  auto loc = getToken().getLoc();
 
   StringRef name;
   FunctionType *type = nullptr;
@@ -2586,7 +2583,14 @@
     return ParseFailure;
 
   // Okay, the external function definition was parsed correctly.
-  getModule()->getFunctions().push_back(new ExtFunction(name, type));
+  auto *function = new ExtFunction(name, type);
+  getModule()->getFunctions().push_back(function);
+
+  // Verify no name collision / redefinition.
+  if (function->getName().ref() != name)
+    return emitError(loc,
+                     "redefinition of function named '" + name.str() + "'");
+
   return ParseSuccess;
 }
 
@@ -2596,6 +2600,7 @@
 ///
 ParseResult ModuleParser::parseCFGFunc() {
   consumeToken(Token::kw_cfgfunc);
+  auto loc = getToken().getLoc();
 
   StringRef name;
   FunctionType *type = nullptr;
@@ -2603,7 +2608,13 @@
     return ParseFailure;
 
   // Okay, the CFG function signature was parsed correctly, create the function.
-  auto function = new CFGFunction(name, type);
+  auto *function = new CFGFunction(name, type);
+  getModule()->getFunctions().push_back(function);
+
+  // Verify no name collision / redefinition.
+  if (function->getName().ref() != name)
+    return emitError(loc,
+                     "redefinition of function named '" + name.str() + "'");
 
   return CFGFunctionParser(getState(), function).parseFunctionBody();
 }
@@ -2624,7 +2635,13 @@
     return ParseFailure;
 
   // Okay, the ML function signature was parsed correctly, create the function.
-  auto function = MLFunction::create(name, type);
+  auto *function = MLFunction::create(name, type);
+  getModule()->getFunctions().push_back(function);
+
+  // Verify no name collision / redefinition.
+  if (function->getName().ref() != name)
+    return emitError(loc,
+                     "redefinition of function named '" + name.str() + "'");
 
   // Create the parser.
   auto parser = MLFunctionParser(getState(), function);