Add location specifier to MLIR Functions, and:
 - Compress the identifier/kind of a Function into a single word.
 - Eliminate otherFailure from verifier now that we always have a location
 - Eliminate the error string from the verifier now that we always have
   locations.
 - Simplify the parser's handling of fn forward references, using the location
   tracked by the function.

PiperOrigin-RevId: 211985101
diff --git a/lib/Parser/Parser.cpp b/lib/Parser/Parser.cpp
index 154a24c..bc6585c 100644
--- a/lib/Parser/Parser.cpp
+++ b/lib/Parser/Parser.cpp
@@ -68,9 +68,8 @@
   llvm::StringMap<IntegerSet *> integerSetDefinitions;
 
   // This keeps track of all forward references to functions along with the
-  // temporary function used to represent them and the location of the first
-  // reference.
-  llvm::DenseMap<Identifier, std::pair<Function *, SMLoc>> functionForwardRefs;
+  // temporary function used to represent them.
+  llvm::DenseMap<Identifier, Function *> functionForwardRefs;
 
 private:
   ParserState(const ParserState &) = delete;
@@ -605,11 +604,9 @@
   // If not, get or create a forward reference to one.
   if (!function) {
     auto &entry = state.functionForwardRefs[name];
-    if (!entry.first) {
-      entry.first = new ExtFunction(name, type);
-      entry.second = nameLoc;
-    }
-    function = entry.first;
+    if (!entry)
+      entry = new ExtFunction(getEncodedSourceLocation(nameLoc), name, type);
+    function = entry;
   }
 
   if (function->getType() != type)
@@ -2771,7 +2768,7 @@
     return ParseFailure;
 
   // Okay, the external function definition was parsed correctly.
-  auto *function = new ExtFunction(name, type);
+  auto *function = new ExtFunction(getEncodedSourceLocation(loc), name, type);
   getModule()->getFunctions().push_back(function);
 
   // Verify no name collision / redefinition.
@@ -2796,7 +2793,7 @@
     return ParseFailure;
 
   // Okay, the CFG function signature was parsed correctly, create the function.
-  auto *function = new CFGFunction(name, type);
+  auto *function = new CFGFunction(getEncodedSourceLocation(loc), name, type);
   getModule()->getFunctions().push_back(function);
 
   // Verify no name collision / redefinition.
@@ -2823,7 +2820,8 @@
     return ParseFailure;
 
   // Okay, the ML function signature was parsed correctly, create the function.
-  auto *function = MLFunction::create(name, type);
+  auto *function =
+      MLFunction::create(getEncodedSourceLocation(loc), name, type);
   getModule()->getFunctions().push_back(function);
 
   // Verify no name collision / redefinition.
@@ -2907,11 +2905,13 @@
 
     // Resolve the reference.
     auto *resolvedFunction = getModule()->getNamedFunction(name);
-    if (!resolvedFunction)
-      return emitError(forwardRef.second.second,
-                       "reference to undefined function '" + name.str() + "'");
+    if (!resolvedFunction) {
+      forwardRef.second->emitError("reference to undefined function '" +
+                                   name.str() + "'");
+      return ParseFailure;
+    }
 
-    remappingTable[builder.getFunctionAttr(forwardRef.second.first)] =
+    remappingTable[builder.getFunctionAttr(forwardRef.second)] =
         builder.getFunctionAttr(resolvedFunction);
   }
 
@@ -2951,7 +2951,7 @@
   // Now that all references to the forward definition placeholders are
   // resolved, we can deallocate the placeholders.
   for (auto forwardRef : getState().functionForwardRefs)
-    forwardRef.second.first->destroy();
+    forwardRef.second->destroy();
   return ParseSuccess;
 }
 
@@ -3018,19 +3018,8 @@
 
   // Make sure the parse module has no other structural problems detected by the
   // verifier.
-  //
-  // TODO(clattner): The verifier should always emit diagnostics when we have
-  // more location information available.  We shouldn't need this hook.
-  std::string errorResult;
-  module->verify(&errorResult);
-
-  // We don't have location information for general verifier errors, so emit the
-  // error with an unknown location.
-  if (!errorResult.empty()) {
-    context->emitDiagnostic(UnknownLoc::get(context), errorResult,
-                            MLIRContext::DiagnosticKind::Error);
+  if (module->verify())
     return nullptr;
-  }
 
   return module.release();
 }