Implement ML function arguments. Add representation for argument list in ML Function using TrailingObjects template. Implement argument iterators, parsing and printing.

Unrelated minor change - remove OperationStmt::dropReferences(). Since MLFunction does not have cyclic operand references (it's an AST) destruction can be safely done w/o a special pass to drop references.

PiperOrigin-RevId: 207583024
diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp
index 96c6dfc..4719b35 100644
--- a/lib/IR/Function.cpp
+++ b/lib/IR/Function.cpp
@@ -36,7 +36,7 @@
     delete cast<ExtFunction>(this);
     break;
   case Kind::MLFunc:
-    delete cast<MLFunction>(this);
+    cast<MLFunction>(this)->destroy();
     break;
   case Kind::CFGFunc:
     delete cast<CFGFunction>(this);
@@ -118,13 +118,37 @@
 // MLFunction implementation.
 //===----------------------------------------------------------------------===//
 
+/// Create a new MLFunction with the specific fields.
+MLFunction *MLFunction::create(StringRef name, FunctionType *type) {
+  const auto &argTypes = type->getInputs();
+  auto byteSize = totalSizeToAlloc<MLFuncArgument>(argTypes.size());
+  void *rawMem = malloc(byteSize);
+
+  // Initialize the MLFunction part of the function object.
+  auto function = ::new (rawMem) MLFunction(name, type);
+
+  // Initialize the arguments.
+  auto arguments = function->getArgumentsInternal();
+  for (unsigned i = 0, e = argTypes.size(); i != e; ++i)
+    new (&arguments[i]) MLFuncArgument(argTypes[i], function);
+  return function;
+}
+
 MLFunction::MLFunction(StringRef name, FunctionType *type)
     : Function(name, type, Kind::MLFunc), StmtBlock(StmtBlockKind::MLFunc) {}
 
 MLFunction::~MLFunction() {
-  struct DropReferencesPass : public StmtWalker<DropReferencesPass> {
-    void visitOperationStmt(OperationStmt *stmt) { stmt->dropAllReferences(); }
-  };
-  DropReferencesPass pass;
-  pass.walk(const_cast<MLFunction *>(this));
+  // Explicitly erase statements instead of relying of 'StmtBlock' destructor
+  // since child statements need to be destroyed before function arguments
+  // are destroyed.
+  clear();
+
+  // Explicitly run the destructors for the function arguments.
+  for (auto &arg : getArgumentsInternal())
+    arg.~MLFuncArgument();
+}
+
+void MLFunction::destroy() {
+  this->~MLFunction();
+  free(this);
 }