Use Format for args instead of DatumType. (#661)

This CL converts the arg holder to store a Format instead of a
DatumType.
diff --git a/src/amberscript/parser.cc b/src/amberscript/parser.cc
index 83cd0a7..3a65af7 100644
--- a/src/amberscript/parser.cc
+++ b/src/amberscript/parser.cc
@@ -840,11 +840,13 @@
     token = tokenizer_->NextToken();
     if (!token->IsString())
       return Result("expected argument identifier");
+
     arg_name = token->AsString();
   } else if (token->AsString() == "ARG_NUMBER") {
     token = tokenizer_->NextToken();
     if (!token->IsInteger())
       return Result("expected argument number");
+
     arg_no = token->AsUint32();
   } else {
     return Result("expected ARG_NAME or ARG_NUMBER");
@@ -876,7 +878,7 @@
   Pipeline::ArgSetInfo info;
   info.name = arg_name;
   info.ordinal = arg_no;
-  info.type = arg_type;
+  info.fmt = arg_type.AsFormat();
   info.value = value;
   pipeline->SetArg(std::move(info));
   return ValidateEndOfStatement("SET command");
diff --git a/src/pipeline.cc b/src/pipeline.cc
index ddfc089..53e72e4 100644
--- a/src/pipeline.cc
+++ b/src/pipeline.cc
@@ -53,7 +53,15 @@
   clone->index_buffer_ = index_buffer_;
   clone->fb_width_ = fb_width_;
   clone->fb_height_ = fb_height_;
-  clone->set_arg_values_ = set_arg_values_;
+
+  for (const auto& args : set_arg_values_) {
+    clone->set_arg_values_.push_back({});
+    clone->set_arg_values_.back().name = args.name;
+    clone->set_arg_values_.back().ordinal = args.ordinal;
+    clone->set_arg_values_.back().fmt = MakeUnique<Format>(*args.fmt);
+    clone->set_arg_values_.back().value = args.value;
+  }
+
   if (!opencl_pod_buffers_.empty()) {
     // Generate specific buffers for the clone.
     clone->GenerateOpenCLPodBuffers();
@@ -560,7 +568,7 @@
       buffer->SetSizeInElements(offset + arg_size);
     }
     // Check the data size.
-    if (arg_size != arg_info.type.SizeInBytes()) {
+    if (arg_size != arg_info.fmt->SizeInBytes()) {
       std::string message = "SET command uses incorrect data size: kernel " +
                             shader_info.GetEntryPoint();
       if (uses_name) {
diff --git a/src/pipeline.h b/src/pipeline.h
index 8f9be50..5cb63d4 100644
--- a/src/pipeline.h
+++ b/src/pipeline.h
@@ -245,7 +245,7 @@
   struct ArgSetInfo {
     std::string name;
     uint32_t ordinal = 0;
-    DatumType type;
+    std::unique_ptr<Format> fmt;
     Value value;
   };
 
diff --git a/src/pipeline_test.cc b/src/pipeline_test.cc
index c6e15d7..8bba23e 100644
--- a/src/pipeline_test.cc
+++ b/src/pipeline_test.cc
@@ -523,29 +523,31 @@
   // Set commands.
   Value int_value;
   int_value.SetIntValue(1);
-  DatumType int_type;
-  int_type.SetType(DataType::kInt32);
-  DatumType char_type;
-  char_type.SetType(DataType::kInt8);
+
+  auto int_fmt = MakeUnique<Format>();
+  int_fmt->AddComponent(FormatComponentType::kR, FormatMode::kSInt, 32);
+
+  auto char_fmt = MakeUnique<Format>();
+  char_fmt->AddComponent(FormatComponentType::kR, FormatMode::kSInt, 8);
 
   Pipeline::ArgSetInfo arg_info1;
   arg_info1.name = "arg_a";
   arg_info1.ordinal = 99;
-  arg_info1.type = int_type;
+  arg_info1.fmt = MakeUnique<Format>(*int_fmt);
   arg_info1.value = int_value;
   p.SetArg(std::move(arg_info1));
 
   Pipeline::ArgSetInfo arg_info2;
   arg_info2.name = "arg_b";
   arg_info2.ordinal = 99;
-  arg_info2.type = char_type;
+  arg_info2.fmt = MakeUnique<Format>(*char_fmt);
   arg_info2.value = int_value;
   p.SetArg(std::move(arg_info2));
 
   Pipeline::ArgSetInfo arg_info3;
   arg_info3.name = "arg_c";
   arg_info3.ordinal = 99;
-  arg_info3.type = int_type;
+  arg_info3.fmt = MakeUnique<Format>(*int_fmt);
   arg_info3.value = int_value;
   p.SetArg(std::move(arg_info3));
 
@@ -587,13 +589,14 @@
   // Set commands.
   Value int_value;
   int_value.SetIntValue(1);
-  DatumType int_type;
-  int_type.SetType(DataType::kInt32);
+
+  auto int_fmt = MakeUnique<Format>();
+  int_fmt->AddComponent(FormatComponentType::kR, FormatMode::kSInt, 32);
 
   Pipeline::ArgSetInfo arg_info1;
   arg_info1.name = "arg_z";
   arg_info1.ordinal = 99;
-  arg_info1.type = int_type;
+  arg_info1.fmt = std::move(int_fmt);
   arg_info1.value = int_value;
   p.SetArg(std::move(arg_info1));
 
@@ -628,13 +631,14 @@
   // Set commands.
   Value int_value;
   int_value.SetIntValue(1);
-  DatumType short_type;
-  short_type.SetType(DataType::kInt16);
+
+  auto short_fmt = MakeUnique<Format>();
+  short_fmt->AddComponent(FormatComponentType::kR, FormatMode::kSInt, 16);
 
   Pipeline::ArgSetInfo arg_info1;
   arg_info1.name = "";
   arg_info1.ordinal = 0;
-  arg_info1.type = short_type;
+  arg_info1.fmt = std::move(short_fmt);
   arg_info1.value = int_value;
   p.SetArg(std::move(arg_info1));
 
@@ -687,29 +691,31 @@
   // Set commands.
   Value int_value;
   int_value.SetIntValue(1);
-  DatumType int_type;
-  int_type.SetType(DataType::kInt32);
-  DatumType char_type;
-  char_type.SetType(DataType::kInt8);
+
+  auto int_fmt = MakeUnique<Format>();
+  int_fmt->AddComponent(FormatComponentType::kR, FormatMode::kSInt, 32);
+
+  auto char_fmt = MakeUnique<Format>();
+  char_fmt->AddComponent(FormatComponentType::kR, FormatMode::kSInt, 8);
 
   Pipeline::ArgSetInfo arg_info1;
   arg_info1.name = "arg_a";
   arg_info1.ordinal = 99;
-  arg_info1.type = int_type;
+  arg_info1.fmt = MakeUnique<Format>(*int_fmt);
   arg_info1.value = int_value;
   p.SetArg(std::move(arg_info1));
 
   Pipeline::ArgSetInfo arg_info2;
   arg_info2.name = "arg_b";
   arg_info2.ordinal = 99;
-  arg_info2.type = char_type;
+  arg_info2.fmt = MakeUnique<Format>(*char_fmt);
   arg_info2.value = int_value;
   p.SetArg(std::move(arg_info2));
 
   Pipeline::ArgSetInfo arg_info3;
   arg_info3.name = "arg_c";
   arg_info3.ordinal = 99;
-  arg_info3.type = int_type;
+  arg_info3.fmt = MakeUnique<Format>(*int_fmt);
   arg_info3.value = int_value;
   p.SetArg(std::move(arg_info3));