Finish support for function attributes, and improve lots of things:
 - Have the parser rewrite forward references to their resolved values at the
   end of parsing.
 - Implement verifier support for detecting malformed function attrs.
 - Add efficient query for (in general, recursive) attributes to tell if they
   contain a function.

As part of this, improve other general infrastructure:
 - Implement support for verifying OperationStmt's in ml functions, refactoring
   and generalizing support for operations in the verifier.
 - Refactor location handling code in mlir-opt to have the non-error expecting
   form of mlir-opt invocations to report error locations precisely.
 - Fix parser to detect verifier failures and report them through errorReporter
   instead of printing the error and crashing.

This regresses the location info for verifier errors in the parser that were
previously ascribed to the function.  This will get resolved in future patches
by adding support for function attributes, which we can use to manage location
information.

PiperOrigin-RevId: 209600980
diff --git a/tools/mlir-opt/mlir-opt.cpp b/tools/mlir-opt/mlir-opt.cpp
index 29fc9c4..2c6b76b 100644
--- a/tools/mlir-opt/mlir-opt.cpp
+++ b/tools/mlir-opt/mlir-opt.cpp
@@ -169,11 +169,11 @@
   for (auto &subbuffer : sourceBuffers) {
     SourceMgr sourceMgr;
     // Tell sourceMgr about this buffer, which is what the parser will pick up.
-    auto bufferId = sourceMgr.AddNewSourceBuffer(
-        MemoryBuffer::getMemBufferCopy(subbuffer), SMLoc());
+    sourceMgr.AddNewSourceBuffer(MemoryBuffer::getMemBufferCopy(subbuffer),
+                                 SMLoc());
 
     // Extract the expected errors.
-    llvm::Regex expected("expected-error(@[+-][0-9]+)? *{{(.*)}}");
+    llvm::Regex expected("expected-error *(@[+-][0-9]+)? *{{(.*)}}");
     SmallVector<ExpectedError, 2> expectedErrors;
     SmallVector<StringRef, 100> lines;
     subbuffer.split(lines, '\n');
@@ -221,30 +221,6 @@
     // Parse the input file.
     MLIRContext context;
     initializeMLIRContext(&context);
-
-    // TODO: refactor into initializeMLIRContext so the normal parser pass
-    // gets to use this.
-    context.registerDiagnosticHandler([&](Attribute *location,
-                                          StringRef message,
-                                          MLIRContext::DiagnosticKind kind) {
-      auto offset = cast<IntegerAttr>(location)->getValue();
-      auto ptr = sourceMgr.getMemoryBuffer(bufferId)->getBufferStart() + offset;
-      SourceMgr::DiagKind diagKind;
-      switch (kind) {
-      case MLIRContext::DiagnosticKind::Error:
-        diagKind = SourceMgr::DK_Error;
-        break;
-      case MLIRContext::DiagnosticKind::Warning:
-        diagKind = SourceMgr::DK_Warning;
-        break;
-      case MLIRContext::DiagnosticKind::Note:
-        diagKind = SourceMgr::DK_Note;
-        break;
-      }
-      checker(
-          sourceMgr.GetMessage(SMLoc::getFromPointer(ptr), diagKind, message));
-    });
-
     std::unique_ptr<Module> module(
         parseSourceFile(sourceMgr, &context, checker));