Integrate upstream cpp emitter changes (#6977)

Takes over upstream changes
* iml130/mlir-emitc@d2ea898
* iml130/mlir-emitc@a55966e
* iml130/mlir-emitc@45c5dc2
* iml130/mlir-emitc@9a97180
* iml130/mlir-emitc@2aef52c
* iml130/mlir-emitc@b401a08

and updates the Cpp emitter usage.
diff --git a/iree/compiler/Dialect/VM/Target/C/CModuleTarget.cpp b/iree/compiler/Dialect/VM/Target/C/CModuleTarget.cpp
index 4bb731a..dc48c0a 100644
--- a/iree/compiler/Dialect/VM/Target/C/CModuleTarget.cpp
+++ b/iree/compiler/Dialect/VM/Target/C/CModuleTarget.cpp
@@ -381,8 +381,8 @@
     Operation *op = funcOp.getOperation();
     if (op->hasAttr("emitc.static")) output << "static ";
 
-    if (failed(emitter.emitTypes(*funcOp.getOperation(),
-                                 funcOp.getType().getResults())))
+    if (failed(
+            emitter.emitTypes(funcOp.getLoc(), funcOp.getType().getResults())))
       return failure();
     output << " " << funcOp.getName();
 
@@ -391,7 +391,7 @@
     bool error = false;
     llvm::interleaveComma(
         funcOp.getArguments(), output, [&](BlockArgument arg) {
-          if (failed(emitter.emitType(*funcOp.getOperation(), arg.getType())))
+          if (failed(emitter.emitType(funcOp.getLoc(), arg.getType())))
             error = true;
         });
     if (error) return failure();
diff --git a/third_party/mlir-emitc/include/emitc/Target/Cpp/CppEmitter.h b/third_party/mlir-emitc/include/emitc/Target/Cpp/CppEmitter.h
index 579b5e3..eb8c22f 100644
--- a/third_party/mlir-emitc/include/emitc/Target/Cpp/CppEmitter.h
+++ b/third_party/mlir-emitc/include/emitc/Target/Cpp/CppEmitter.h
@@ -63,23 +63,23 @@
   explicit CppEmitter(raw_ostream &os, bool declareVariablesAtTop);
 
   /// Emits attribute or returns failure.
-  LogicalResult emitAttribute(Operation &op, Attribute attr);
+  LogicalResult emitAttribute(Location loc, Attribute attr);
 
   /// Emits operation 'op' with/without training semicolon or returns failure.
   LogicalResult emitOperation(Operation &op, bool trailingSemicolon);
 
   /// Emits type 'type' or returns failure.
-  LogicalResult emitType(Operation &op, Type type);
+  LogicalResult emitType(Location loc, Type type);
 
   /// Emits array of types as a std::tuple of the emitted types.
   /// - emits void for an empty array;
   /// - emits the type of the only element for arrays of size one;
   /// - emits a std::tuple otherwise;
-  LogicalResult emitTypes(Operation &op, ArrayRef<Type> types);
+  LogicalResult emitTypes(Location loc, ArrayRef<Type> types);
 
   /// Emits array of types as a std::tuple of the emitted types independently of
   /// the array size.
-  LogicalResult emitTupleType(Operation &op, ArrayRef<Type> types);
+  LogicalResult emitTupleType(Location loc, ArrayRef<Type> types);
 
   /// Emits an assignment for a variable which has been declared previously.
   LogicalResult emitVariableAssignment(OpResult result);
@@ -113,8 +113,8 @@
   /// Return the existing or a new label of a Block.
   StringRef getOrCreateName(Block &block);
 
-  /// Whether to map an mlir integer to a signed integer in C++.
-  bool shouldMapToSigned(IntegerType::SignednessSemantics val);
+  /// Whether to map an mlir integer to a unsigned integer in C++.
+  bool shouldMapToUnsigned(IntegerType::SignednessSemantics val);
 
   /// RAII helper function to manage entering/exiting C++ scopes.
   struct Scope {
diff --git a/third_party/mlir-emitc/lib/Target/Cpp/TranslateToCpp.cpp b/third_party/mlir-emitc/lib/Target/Cpp/TranslateToCpp.cpp
index d79814c..0596d35 100644
--- a/third_party/mlir-emitc/lib/Target/Cpp/TranslateToCpp.cpp
+++ b/third_party/mlir-emitc/lib/Target/Cpp/TranslateToCpp.cpp
@@ -43,7 +43,7 @@
 
     if (failed(emitter.emitVariableAssignment(result)))
       return failure();
-    return emitter.emitAttribute(*operation, value);
+    return emitter.emitAttribute(operation->getLoc(), value);
   }
 
   // Emit a variable declaration for an emitc.constant op without value.
@@ -57,7 +57,7 @@
   // Emit a variable declaration.
   if (failed(emitter.emitAssignPrefix(*operation)))
     return failure();
-  return emitter.emitAttribute(*operation, value);
+  return emitter.emitAttribute(operation->getLoc(), value);
 }
 
 static LogicalResult printOperation(CppEmitter &emitter,
@@ -90,7 +90,7 @@
 
   os << "goto ";
   if (!(emitter.hasBlockLabel(successor)))
-    return branchOp.emitOpError() << "Unable to find label for successor block";
+    return branchOp.emitOpError("unable to find label for successor block");
   os << emitter.getOrCreateName(successor);
   return success();
 }
@@ -115,8 +115,7 @@
 
   os << "goto ";
   if (!(emitter.hasBlockLabel(trueSuccessor))) {
-    return condBranchOp.emitOpError()
-           << "Unable to find label for successor block";
+    return condBranchOp.emitOpError("unable to find label for successor block");
   }
   os << emitter.getOrCreateName(trueSuccessor) << ";\n";
   os << "} else {\n";
@@ -132,7 +131,7 @@
   os << "goto ";
   if (!(emitter.hasBlockLabel(falseSuccessor))) {
     return condBranchOp.emitOpError()
-           << "Unable to find label for successor block";
+           << "unable to find label for successor block";
   }
   os << emitter.getOrCreateName(falseSuccessor) << ";\n";
   os << "}";
@@ -165,15 +164,15 @@
       if (t.getType().isIndex()) {
         int64_t idx = t.getInt();
         if ((idx < 0) || (idx >= op.getNumOperands()))
-          return op.emitOpError() << "invalid operand index";
+          return op.emitOpError("invalid operand index");
         if (!emitter.hasValueInScope(op.getOperand(idx)))
-          return op.emitOpError()
-                 << "operand " << idx << "'s value not defined in scope";
+          return op.emitOpError("operand ")
+                 << idx << "'s value not defined in scope";
         os << emitter.getOrCreateName(op.getOperand(idx));
         return success();
       }
     }
-    if (failed(emitter.emitAttribute(op, attr)))
+    if (failed(emitter.emitAttribute(op.getLoc(), attr)))
       return failure();
 
     return success();
@@ -240,8 +239,7 @@
   }
 
   for (auto pair : llvm::zip(iterArgs, operands)) {
-    if (failed(emitter.emitType(*forOp.getOperation(),
-                                std::get<0>(pair).getType())))
+    if (failed(emitter.emitType(forOp.getLoc(), std::get<0>(pair).getType())))
       return failure();
     os << " " << emitter.getOrCreateName(std::get<0>(pair)) << " = ";
     os << emitter.getOrCreateName(std::get<1>(pair)) << ";";
@@ -249,8 +247,8 @@
   }
 
   os << "for (";
-  if (failed(emitter.emitType(*forOp.getOperation(),
-                              forOp.getInductionVar().getType())))
+  if (failed(
+          emitter.emitType(forOp.getLoc(), forOp.getInductionVar().getType())))
     return failure();
   os << " ";
   os << emitter.getOrCreateName(forOp.getInductionVar());
@@ -364,7 +362,7 @@
             os << emitter.getOrCreateName(result) << " = ";
 
             if (!emitter.hasValueInScope(operand))
-              return yieldOp.emitError() << "operand value not in scope";
+              return yieldOp.emitError("operand value not in scope");
             os << emitter.getOrCreateName(operand);
             return success();
           },
@@ -406,13 +404,13 @@
   // We need to declare variables at top if the function has multiple blocks.
   if (!emitter.shouldDeclareVariablesAtTop() &&
       functionOp.getBlocks().size() > 1) {
-    return functionOp.emitOpError()
-           << "with multiple blocks needs variables declared at top";
+    return functionOp.emitOpError(
+        "with multiple blocks needs variables declared at top");
   }
 
   CppEmitter::Scope scope(emitter);
   raw_indented_ostream &os = emitter.ostream();
-  if (failed(emitter.emitTypes(*functionOp.getOperation(),
+  if (failed(emitter.emitTypes(functionOp.getLoc(),
                                functionOp.getType().getResults())))
     return failure();
   os << " " << functionOp.getName();
@@ -421,8 +419,7 @@
   if (failed(interleaveCommaWithError(
           functionOp.getArguments(), os,
           [&](BlockArgument arg) -> LogicalResult {
-            if (failed(emitter.emitType(*functionOp.getOperation(),
-                                        arg.getType())))
+            if (failed(emitter.emitType(functionOp.getLoc(), arg.getType())))
               return failure();
             os << " " << emitter.getOrCreateName(arg);
             return success();
@@ -439,7 +436,7 @@
             if (failed(emitter.emitVariableDeclaration(
                     result, /*trailingSemicolon=*/true))) {
               return WalkResult(
-                  op->emitError("Unable to declare result variable for op"));
+                  op->emitError("unable to declare result variable for op"));
             }
           }
           return WalkResult::advance();
@@ -461,7 +458,8 @@
       if (emitter.hasValueInScope(arg))
         return functionOp.emitOpError(" block argument #")
                << arg.getArgNumber() << " is out of scope";
-      if (failed(emitter.emitType(*block.getParentOp(), arg.getType()))) {
+      if (failed(
+              emitter.emitType(block.getParentOp()->getLoc(), arg.getType()))) {
         return failure();
       }
       os << " " << emitter.getOrCreateName(arg) << ";\n";
@@ -475,7 +473,10 @@
         return failure();
     }
     for (Operation &op : block.getOperations()) {
-      // Don't print additional semicolons after these operations.
+      // When generating code for an scf.if or std.cond_br op no semicolon needs
+      // to be printed after the closing brace.
+      // When generating code for an scf.for op, printing a trailing semicolon
+      // is handled within the printOperation function.
       bool trailingSemicolon = !isa<scf::IfOp, scf::ForOp, CondBranchOp>(op);
 
       if (failed(emitter.emitOperation(
@@ -507,14 +508,14 @@
   return *blockMapper.begin(&block);
 }
 
-bool CppEmitter::shouldMapToSigned(IntegerType::SignednessSemantics val) {
+bool CppEmitter::shouldMapToUnsigned(IntegerType::SignednessSemantics val) {
   switch (val) {
   case IntegerType::Signless:
-    return true;
-  case IntegerType::Signed:
-    return true;
-  case IntegerType::Unsigned:
     return false;
+  case IntegerType::Signed:
+    return false;
+  case IntegerType::Unsigned:
+    return true;
   }
 }
 
@@ -524,7 +525,7 @@
   return blockMapper.count(&block);
 }
 
-LogicalResult CppEmitter::emitAttribute(Operation &op, Attribute attr) {
+LogicalResult CppEmitter::emitAttribute(Location loc, Attribute attr) {
   auto printInt = [&](APInt val, bool isSigned) {
     if (val.getBitWidth() == 1) {
       if (val.getBoolValue())
@@ -576,7 +577,7 @@
   // Print integer attributes.
   if (auto iAttr = attr.dyn_cast<IntegerAttr>()) {
     if (auto iType = iAttr.getType().dyn_cast<IntegerType>()) {
-      printInt(iAttr.getValue(), shouldMapToSigned(iType.getSignedness()));
+      printInt(iAttr.getValue(), shouldMapToUnsigned(iType.getSignedness()));
       return success();
     }
     if (auto iType = iAttr.getType().dyn_cast<IndexType>()) {
@@ -591,7 +592,7 @@
                          .dyn_cast<IntegerType>()) {
       os << '{';
       interleaveComma(dense, os, [&](APInt val) {
-        printInt(val, shouldMapToSigned(iType.getSignedness()));
+        printInt(val, shouldMapToUnsigned(iType.getSignedness()));
       });
       os << '}';
       return success();
@@ -616,16 +617,16 @@
   // Print symbolic reference attributes.
   if (auto sAttr = attr.dyn_cast<SymbolRefAttr>()) {
     if (sAttr.getNestedReferences().size() > 1)
-      return op.emitError(" attribute has more than 1 nested reference");
-    os << sAttr.getRootReference();
+      return emitError(loc, "attribute has more than 1 nested reference");
+    os << sAttr.getRootReference().getValue();
     return success();
   }
 
   // Print type attributes.
   if (auto type = attr.dyn_cast<TypeAttr>())
-    return emitType(op, type.getValue());
+    return emitType(loc, type.getValue());
 
-  return op.emitError("cannot emit attribute of type ") << attr.getType();
+  return emitError(loc, "cannot emit attribute of type ") << attr.getType();
 }
 
 LogicalResult CppEmitter::emitOperands(Operation &op) {
@@ -657,7 +658,7 @@
     if (llvm::is_contained(exclude, attr.first.strref()))
       return success();
     os << "/* " << attr.first << " */";
-    if (failed(emitAttribute(op, attr.second)))
+    if (failed(emitAttribute(op.getLoc(), attr.second)))
       return failure();
     return success();
   };
@@ -667,7 +668,7 @@
 LogicalResult CppEmitter::emitVariableAssignment(OpResult result) {
   if (!hasValueInScope(result)) {
     return result.getDefiningOp()->emitOpError(
-        "result variable for the operation has not been declared.");
+        "result variable for the operation has not been declared");
   }
   os << getOrCreateName(result) << " = ";
   return success();
@@ -677,9 +678,9 @@
                                                   bool trailingSemicolon) {
   if (hasValueInScope(result)) {
     return result.getDefiningOp()->emitError(
-        "result variable for the operation already declared.");
+        "result variable for the operation already declared");
   }
-  if (failed(emitType(*result.getOwner(), result.getType())))
+  if (failed(emitType(result.getOwner()->getLoc(), result.getType())))
     return failure();
   os << " " << getOrCreateName(result);
   if (trailingSemicolon)
@@ -720,7 +721,7 @@
 
 LogicalResult CppEmitter::emitLabel(Block &block) {
   if (!hasBlockLabel(block))
-    return block.getParentOp()->emitError("Label for block not found.");
+    return block.getParentOp()->emitError("label for block not found");
   os << getOrCreateName(block) << ":\n";
   return success();
 }
@@ -740,7 +741,7 @@
                 ModuleOp, ReturnOp>(
               [&](auto op) { return printOperation(*this, op); })
           .Default([&](Operation *) {
-            return op.emitOpError() << "unable to find printer for op";
+            return op.emitOpError("unable to find printer for op");
           });
 
   if (failed(status))
@@ -749,7 +750,7 @@
   return success();
 }
 
-LogicalResult CppEmitter::emitType(Operation &op, Type type) {
+LogicalResult CppEmitter::emitType(Location loc, Type type) {
   if (auto iType = type.dyn_cast<IntegerType>()) {
     switch (iType.getWidth()) {
     case 1:
@@ -758,12 +759,12 @@
     case 16:
     case 32:
     case 64:
-      if (shouldMapToSigned(iType.getSignedness()))
-        return (os << "int" << iType.getWidth() << "_t"), success();
-      else
+      if (shouldMapToUnsigned(iType.getSignedness()))
         return (os << "uint" << iType.getWidth() << "_t"), success();
+      else
+        return (os << "int" << iType.getWidth() << "_t"), success();
     default:
-      return op.emitError("cannot emit integer type ") << type;
+      return emitError(loc, "cannot emit integer type ") << type;
     }
   }
   if (auto fType = type.dyn_cast<FloatType>()) {
@@ -773,18 +774,18 @@
     case 64:
       return (os << "double"), success();
     default:
-      return op.emitError("cannot emit float type ") << type;
+      return emitError(loc, "cannot emit float type ") << type;
     }
   }
   if (auto iType = type.dyn_cast<IndexType>())
     return (os << "size_t"), success();
   if (auto tType = type.dyn_cast<TensorType>()) {
     if (!tType.hasRank())
-      return op.emitError("cannot emit unranked tensor type");
+      return emitError(loc, "cannot emit unranked tensor type");
     if (!tType.hasStaticShape())
-      return op.emitError("cannot emit tensor type with non static shape");
+      return emitError(loc, "cannot emit tensor type with non static shape");
     os << "Tensor<";
-    if (failed(emitType(op, tType.getElementType())))
+    if (failed(emitType(loc, tType.getElementType())))
       return failure();
     auto shape = tType.getShape();
     for (auto dimSize : shape) {
@@ -795,30 +796,30 @@
     return success();
   }
   if (auto tType = type.dyn_cast<TupleType>())
-    return emitTupleType(op, tType.getTypes());
+    return emitTupleType(loc, tType.getTypes());
   if (auto oType = type.dyn_cast<emitc::OpaqueType>()) {
     os << oType.getValue();
     return success();
   }
-  return op.emitError("cannot emit type ") << type;
+  return emitError(loc, "cannot emit type ") << type;
 }
 
-LogicalResult CppEmitter::emitTypes(Operation &op, ArrayRef<Type> types) {
+LogicalResult CppEmitter::emitTypes(Location loc, ArrayRef<Type> types) {
   switch (types.size()) {
   case 0:
     os << "void";
     return success();
   case 1:
-    return emitType(op, types.front());
+    return emitType(loc, types.front());
   default:
-    return emitTupleType(op, types);
+    return emitTupleType(loc, types);
   }
 }
 
-LogicalResult CppEmitter::emitTupleType(Operation &op, ArrayRef<Type> types) {
+LogicalResult CppEmitter::emitTupleType(Location loc, ArrayRef<Type> types) {
   os << "std::tuple<";
   if (failed(interleaveCommaWithError(
-          types, os, [&](Type type) { return emitType(op, type); })))
+          types, os, [&](Type type) { return emitType(loc, type); })))
     return failure();
   os << ">";
   return success();