Push location information more tightly into the IR, providing space for every
operation and statement to have a location, and make it so a location is
required to be specified whenever you make one (though a null location is still
allowed).  This is to encourage compiler authors to propagate loc info
properly, allowing our failability story to work well.

This is still a WIP - it isn't clear if we want to continue abusing Attribute
for location information, or whether we should introduce a new class heirarchy
to do so.  This is good step along the way, and unblocks some of the tf/xla
work that builds upon it.

PiperOrigin-RevId: 210001406
diff --git a/lib/IR/Operation.cpp b/lib/IR/Operation.cpp
index aed6fcc..71167bd 100644
--- a/lib/IR/Operation.cpp
+++ b/lib/IR/Operation.cpp
@@ -24,7 +24,7 @@
 #include "mlir/IR/Statements.h"
 using namespace mlir;
 
-Operation::Operation(Identifier name, bool isInstruction,
+Operation::Operation(bool isInstruction, Identifier name,
                      ArrayRef<NamedAttribute> attrs, MLIRContext *context)
     : nameAndIsInstruction(name, isInstruction) {
   this->attrs = AttributeListStorage::get(attrs, context);
@@ -44,6 +44,14 @@
   return cast<OperationStmt>(this)->getContext();
 }
 
+/// The source location the operation was defined or derived from.  Note that
+/// it is possible for this pointer to be null.
+Attribute *Operation::getLoc() const {
+  if (auto *inst = dyn_cast<OperationInst>(this))
+    return inst->getLoc();
+  return cast<OperationStmt>(this)->getLoc();
+}
+
 /// Return the function this operation is defined in.
 Function *Operation::getOperationFunction() {
   if (auto *inst = dyn_cast<OperationInst>(this))
@@ -139,14 +147,14 @@
 /// Emit a note about this operation, reporting up to any diagnostic
 /// handlers that may be listening.
 void Operation::emitNote(const Twine &message) const {
-  getContext()->emitDiagnostic(getAttr(":location"), message,
+  getContext()->emitDiagnostic(getLoc(), message,
                                MLIRContext::DiagnosticKind::Note);
 }
 
 /// Emit a warning about this operation, reporting up to any diagnostic
 /// handlers that may be listening.
 void Operation::emitWarning(const Twine &message) const {
-  getContext()->emitDiagnostic(getAttr(":location"), message,
+  getContext()->emitDiagnostic(getLoc(), message,
                                MLIRContext::DiagnosticKind::Warning);
 }
 
@@ -155,6 +163,6 @@
 /// the containing application, only use when the IR is in an inconsistent
 /// state.
 void Operation::emitError(const Twine &message) const {
-  getContext()->emitDiagnostic(getAttr(":location"), message,
+  getContext()->emitDiagnostic(getLoc(), message,
                                MLIRContext::DiagnosticKind::Error);
 }