Use SFINAE to generalize << overloads, give 'constant' a pretty form,
generalize the asmprinters handling of pretty names to allow arbitrary sugar to
be dumped on various constructs.  Give CFG function arguments nice "arg0" names
like MLFunctions get, and give constant integers pretty names like %c37 for a
constant 377

PiperOrigin-RevId: 206953080
diff --git a/lib/IR/StandardOps.cpp b/lib/IR/StandardOps.cpp
index 3d74e58..8f4f1b3 100644
--- a/lib/IR/StandardOps.cpp
+++ b/lib/IR/StandardOps.cpp
@@ -190,6 +190,22 @@
   return nullptr;
 }
 
+void ConstantOp::print(OpAsmPrinter *p) const {
+  *p << "constant " << *getValue() << " : " << *getType();
+}
+
+OpAsmParserResult ConstantOp::parse(OpAsmParser *parser) {
+  Attribute *valueAttr;
+  Type *type;
+  if (parser->parseAttribute(valueAttr) || parser->parseColonType(type))
+    return {};
+
+  auto &builder = parser->getBuilder();
+  return OpAsmParserResult(
+      /*operands=*/{}, type,
+      NamedAttribute(builder.getIdentifier("value"), valueAttr));
+}
+
 /// The constant op requires an attribute, and furthermore requires that it
 /// matches the return type.
 const char *ConstantOp::verify() const {