spirv-fuzz: Fuzzer pass to add composite types (#3171)

Adds a fuzzer pass that randomly adds vector and matrix types not
already present in the module, and randomly adds structs with random
field types and arrays with random base types and sizes. Other passes
will be able to create variables and ids using these types.
diff --git a/source/fuzz/CMakeLists.txt b/source/fuzz/CMakeLists.txt
index ea5e216..c816f87 100644
--- a/source/fuzz/CMakeLists.txt
+++ b/source/fuzz/CMakeLists.txt
@@ -36,6 +36,7 @@
         fuzzer.h
         fuzzer_context.h
         fuzzer_pass.h
+        fuzzer_pass_add_composite_types.h
         fuzzer_pass_add_dead_blocks.h
         fuzzer_pass_add_dead_breaks.h
         fuzzer_pass_add_dead_continues.h
@@ -107,6 +108,7 @@
         fuzzer.cpp
         fuzzer_context.cpp
         fuzzer_pass.cpp
+        fuzzer_pass_add_composite_types.cpp
         fuzzer_pass_add_dead_blocks.cpp
         fuzzer_pass_add_dead_breaks.cpp
         fuzzer_pass_add_dead_continues.cpp
diff --git a/source/fuzz/fuzzer.cpp b/source/fuzz/fuzzer.cpp
index a624c11..27b697c 100644
--- a/source/fuzz/fuzzer.cpp
+++ b/source/fuzz/fuzzer.cpp
@@ -21,6 +21,7 @@
 #include "fuzzer_pass_adjust_memory_operands_masks.h"
 #include "source/fuzz/fact_manager.h"
 #include "source/fuzz/fuzzer_context.h"
+#include "source/fuzz/fuzzer_pass_add_composite_types.h"
 #include "source/fuzz/fuzzer_pass_add_dead_blocks.h"
 #include "source/fuzz/fuzzer_pass_add_dead_breaks.h"
 #include "source/fuzz/fuzzer_pass_add_dead_continues.h"
@@ -178,6 +179,9 @@
   // Apply some semantics-preserving passes.
   std::vector<std::unique_ptr<FuzzerPass>> passes;
   while (passes.empty()) {
+    MaybeAddPass<FuzzerPassAddCompositeTypes>(&passes, ir_context.get(),
+                                              &fact_manager, &fuzzer_context,
+                                              transformation_sequence_out);
     MaybeAddPass<FuzzerPassAddDeadBlocks>(&passes, ir_context.get(),
                                           &fact_manager, &fuzzer_context,
                                           transformation_sequence_out);
diff --git a/source/fuzz/fuzzer_context.cpp b/source/fuzz/fuzzer_context.cpp
index afffcf5..916803a 100644
--- a/source/fuzz/fuzzer_context.cpp
+++ b/source/fuzz/fuzzer_context.cpp
@@ -23,11 +23,16 @@
 // Default <minimum, maximum> pairs of probabilities for applying various
 // transformations. All values are percentages. Keep them in alphabetical order.
 
+const std::pair<uint32_t, uint32_t> kChanceOfAddingAnotherStructField = {20,
+                                                                         90};
+const std::pair<uint32_t, uint32_t> kChanceOfAddingArrayOrStructType = {20, 90};
 const std::pair<uint32_t, uint32_t> kChanceOfAddingDeadBlock = {20, 90};
 const std::pair<uint32_t, uint32_t> kChanceOfAddingDeadBreak = {5, 80};
 const std::pair<uint32_t, uint32_t> kChanceOfAddingDeadContinue = {5, 80};
+const std::pair<uint32_t, uint32_t> kChanceOfAddingMatrixType = {20, 70};
 const std::pair<uint32_t, uint32_t> kChanceOfAddingNoContractionDecoration = {
     5, 70};
+const std::pair<uint32_t, uint32_t> kChanceOfAddingVectorType = {20, 70};
 const std::pair<uint32_t, uint32_t> kChanceOfAdjustingFunctionControl = {20,
                                                                          70};
 const std::pair<uint32_t, uint32_t> kChanceOfAdjustingLoopControl = {20, 90};
@@ -35,6 +40,8 @@
                                                                             90};
 const std::pair<uint32_t, uint32_t> kChanceOfAdjustingSelectionControl = {20,
                                                                           90};
+const std::pair<uint32_t, uint32_t> kChanceOfChoosingStructTypeVsArrayType = {
+    20, 80};
 const std::pair<uint32_t, uint32_t> kChanceOfConstructingComposite = {20, 50};
 const std::pair<uint32_t, uint32_t> kChanceOfCopyingObject = {20, 50};
 const std::pair<uint32_t, uint32_t> kChanceOfDonatingAdditionalModule = {5, 50};
@@ -51,6 +58,7 @@
 const uint32_t kDefaultMaxLoopControlPartialCount = 100;
 const uint32_t kDefaultMaxLoopControlPeelCount = 100;
 const uint32_t kDefaultMaxLoopLimit = 20;
+const uint32_t kDefaultMaxNewArraySizeLimit = 100;
 
 // Default functions for controlling how deep to go during recursive
 // generation/transformation. Keep them in alphabetical order.
@@ -70,14 +78,22 @@
       next_fresh_id_(min_fresh_id),
       go_deeper_in_constant_obfuscation_(
           kDefaultGoDeeperInConstantObfuscation) {
+  chance_of_adding_another_struct_field_ =
+      ChooseBetweenMinAndMax(kChanceOfAddingAnotherStructField);
+  chance_of_adding_array_or_struct_type_ =
+      ChooseBetweenMinAndMax(kChanceOfAddingArrayOrStructType);
   chance_of_adding_dead_block_ =
       ChooseBetweenMinAndMax(kChanceOfAddingDeadBlock);
   chance_of_adding_dead_break_ =
       ChooseBetweenMinAndMax(kChanceOfAddingDeadBreak);
   chance_of_adding_dead_continue_ =
       ChooseBetweenMinAndMax(kChanceOfAddingDeadContinue);
+  chance_of_adding_matrix_type_ =
+      ChooseBetweenMinAndMax(kChanceOfAddingMatrixType);
   chance_of_adding_no_contraction_decoration_ =
       ChooseBetweenMinAndMax(kChanceOfAddingNoContractionDecoration);
+  chance_of_adding_vector_type_ =
+      ChooseBetweenMinAndMax(kChanceOfAddingVectorType);
   chance_of_adjusting_function_control_ =
       ChooseBetweenMinAndMax(kChanceOfAdjustingFunctionControl);
   chance_of_adjusting_loop_control_ =
@@ -86,6 +102,8 @@
       ChooseBetweenMinAndMax(kChanceOfAdjustingMemoryOperandsMask);
   chance_of_adjusting_selection_control_ =
       ChooseBetweenMinAndMax(kChanceOfAdjustingSelectionControl);
+  chance_of_choosing_struct_type_vs_array_type_ =
+      ChooseBetweenMinAndMax(kChanceOfChoosingStructTypeVsArrayType);
   chance_of_constructing_composite_ =
       ChooseBetweenMinAndMax(kChanceOfConstructingComposite);
   chance_of_copying_object_ = ChooseBetweenMinAndMax(kChanceOfCopyingObject);
@@ -106,6 +124,7 @@
   max_loop_control_partial_count_ = kDefaultMaxLoopControlPartialCount;
   max_loop_control_peel_count_ = kDefaultMaxLoopControlPeelCount;
   max_loop_limit_ = kDefaultMaxLoopLimit;
+  max_new_array_size_limit_ = kDefaultMaxNewArraySizeLimit;
 }
 
 FuzzerContext::~FuzzerContext() = default;
diff --git a/source/fuzz/fuzzer_context.h b/source/fuzz/fuzzer_context.h
index cc43370..d4d6d58 100644
--- a/source/fuzz/fuzzer_context.h
+++ b/source/fuzz/fuzzer_context.h
@@ -58,14 +58,26 @@
 
   // Probabilities associated with applying various transformations.
   // Keep them in alphabetical order.
+  uint32_t GetChanceOfAddingAnotherStructField() {
+    return chance_of_adding_another_struct_field_;
+  }
+  uint32_t GetChanceOfAddingArrayOrStructType() {
+    return chance_of_adding_array_or_struct_type_;
+  }
   uint32_t GetChanceOfAddingDeadBlock() { return chance_of_adding_dead_block_; }
   uint32_t GetChanceOfAddingDeadBreak() { return chance_of_adding_dead_break_; }
   uint32_t GetChanceOfAddingDeadContinue() {
     return chance_of_adding_dead_continue_;
   }
+  uint32_t GetChanceOfAddingMatrixType() {
+    return chance_of_adding_matrix_type_;
+  }
   uint32_t GetChanceOfAddingNoContractionDecoration() {
     return chance_of_adding_no_contraction_decoration_;
   }
+  uint32_t GetChanceOfAddingVectorType() {
+    return chance_of_adding_vector_type_;
+  }
   uint32_t GetChanceOfAdjustingFunctionControl() {
     return chance_of_adjusting_function_control_;
   }
@@ -78,6 +90,9 @@
   uint32_t GetChanceOfAdjustingSelectionControl() {
     return chance_of_adjusting_selection_control_;
   }
+  uint32_t GetChanceOfChoosingStructTypeVsArrayType() {
+    return chance_of_choosing_struct_type_vs_array_type_;
+  }
   uint32_t GetChanceOfConstructingComposite() {
     return chance_of_constructing_composite_;
   }
@@ -109,6 +124,10 @@
   uint32_t GetRandomLoopLimit() {
     return random_generator_->RandomUint32(max_loop_limit_);
   }
+  uint32_t GetRandomSizeForNewArray() {
+    // Ensure that the array size is non-zero.
+    return random_generator_->RandomUint32(max_new_array_size_limit_ - 1) + 1;
+  }
 
   // Functions to control how deeply to recurse.
   // Keep them in alphabetical order.
@@ -124,14 +143,19 @@
 
   // Probabilities associated with applying various transformations.
   // Keep them in alphabetical order.
+  uint32_t chance_of_adding_another_struct_field_;
+  uint32_t chance_of_adding_array_or_struct_type_;
   uint32_t chance_of_adding_dead_block_;
   uint32_t chance_of_adding_dead_break_;
   uint32_t chance_of_adding_dead_continue_;
+  uint32_t chance_of_adding_matrix_type_;
   uint32_t chance_of_adding_no_contraction_decoration_;
+  uint32_t chance_of_adding_vector_type_;
   uint32_t chance_of_adjusting_function_control_;
   uint32_t chance_of_adjusting_loop_control_;
   uint32_t chance_of_adjusting_memory_operands_mask_;
   uint32_t chance_of_adjusting_selection_control_;
+  uint32_t chance_of_choosing_struct_type_vs_array_type_;
   uint32_t chance_of_constructing_composite_;
   uint32_t chance_of_copying_object_;
   uint32_t chance_of_donating_additional_module_;
@@ -149,6 +173,7 @@
   uint32_t max_loop_control_partial_count_;
   uint32_t max_loop_control_peel_count_;
   uint32_t max_loop_limit_;
+  uint32_t max_new_array_size_limit_;
 
   // Functions to determine with what probability to go deeper when generating
   // or mutating constructs recursively.
diff --git a/source/fuzz/fuzzer_pass.cpp b/source/fuzz/fuzzer_pass.cpp
index 9d891a5..9964a6c 100644
--- a/source/fuzz/fuzzer_pass.cpp
+++ b/source/fuzz/fuzzer_pass.cpp
@@ -18,8 +18,11 @@
 #include "source/fuzz/transformation_add_constant_scalar.h"
 #include "source/fuzz/transformation_add_global_undef.h"
 #include "source/fuzz/transformation_add_type_boolean.h"
+#include "source/fuzz/transformation_add_type_float.h"
 #include "source/fuzz/transformation_add_type_int.h"
+#include "source/fuzz/transformation_add_type_matrix.h"
 #include "source/fuzz/transformation_add_type_pointer.h"
+#include "source/fuzz/transformation_add_type_vector.h"
 
 namespace spvtools {
 namespace fuzz {
@@ -155,6 +158,56 @@
   return result;
 }
 
+uint32_t FuzzerPass::FindOrCreate32BitFloatType() {
+  opt::analysis::Float float_type(32);
+  auto existing_id = GetIRContext()->get_type_mgr()->GetId(&float_type);
+  if (existing_id) {
+    return existing_id;
+  }
+  auto result = GetFuzzerContext()->GetFreshId();
+  ApplyTransformation(TransformationAddTypeFloat(result, 32));
+  return result;
+}
+
+uint32_t FuzzerPass::FindOrCreateVectorType(uint32_t component_type_id,
+                                            uint32_t component_count) {
+  assert(component_count >= 2 && component_count <= 4 &&
+         "Precondition: component count must be in range [2, 4].");
+  opt::analysis::Type* component_type =
+      GetIRContext()->get_type_mgr()->GetType(component_type_id);
+  assert(component_type && "Precondition: the component type must exist.");
+  opt::analysis::Vector vector_type(component_type, component_count);
+  auto existing_id = GetIRContext()->get_type_mgr()->GetId(&vector_type);
+  if (existing_id) {
+    return existing_id;
+  }
+  auto result = GetFuzzerContext()->GetFreshId();
+  ApplyTransformation(
+      TransformationAddTypeVector(result, component_type_id, component_count));
+  return result;
+}
+
+uint32_t FuzzerPass::FindOrCreateMatrixType(uint32_t column_count,
+                                            uint32_t row_count) {
+  assert(column_count >= 2 && column_count <= 4 &&
+         "Precondition: column count must be in range [2, 4].");
+  assert(row_count >= 2 && row_count <= 4 &&
+         "Precondition: row count must be in range [2, 4].");
+  uint32_t column_type_id =
+      FindOrCreateVectorType(FindOrCreate32BitFloatType(), row_count);
+  opt::analysis::Type* column_type =
+      GetIRContext()->get_type_mgr()->GetType(column_type_id);
+  opt::analysis::Matrix matrix_type(column_type, column_count);
+  auto existing_id = GetIRContext()->get_type_mgr()->GetId(&matrix_type);
+  if (existing_id) {
+    return existing_id;
+  }
+  auto result = GetFuzzerContext()->GetFreshId();
+  ApplyTransformation(
+      TransformationAddTypeMatrix(result, column_type_id, column_count));
+  return result;
+}
+
 uint32_t FuzzerPass::FindOrCreatePointerTo32BitIntegerType(
     bool is_signed, SpvStorageClass storage_class) {
   auto uint32_type_id = FindOrCreate32BitIntegerType(is_signed);
diff --git a/source/fuzz/fuzzer_pass.h b/source/fuzz/fuzzer_pass.h
index 09f831f..e1e8aec 100644
--- a/source/fuzz/fuzzer_pass.h
+++ b/source/fuzz/fuzzer_pass.h
@@ -108,6 +108,23 @@
   // transformation is applied to add it.
   uint32_t FindOrCreate32BitIntegerType(bool is_signed);
 
+  // Returns the id of an OpTypeFloat instruction, with width 32.  If such an
+  // instruction does not exist, a transformation is applied to add it.
+  uint32_t FindOrCreate32BitFloatType();
+
+  // Returns the id of an OpTypeVector instruction, with |component_type_id|
+  // (which must already exist) as its base type, and |component_count|
+  // elements (which must be in the range [2, 4]).  If such an instruction does
+  // not exist, a transformation is applied to add it.
+  uint32_t FindOrCreateVectorType(uint32_t component_type_id,
+                                  uint32_t component_count);
+
+  // Returns the id of an OpTypeMatrix instruction, with |column_count| columns
+  // and |row_count| rows (each of which must be in the range [2, 4]).  If the
+  // float and vector types required to build this matrix type or the matrix
+  // type itself do not exist, transformations are applied to add them.
+  uint32_t FindOrCreateMatrixType(uint32_t column_count, uint32_t row_count);
+
   // Returns the id of an OpTypePointer instruction, with a 32-bit integer base
   // type of signedness specified by |is_signed|.  If the pointer type or
   // required integer base type do not exist, transformations are applied to add
diff --git a/source/fuzz/fuzzer_pass_add_composite_types.cpp b/source/fuzz/fuzzer_pass_add_composite_types.cpp
new file mode 100644
index 0000000..32c720e
--- /dev/null
+++ b/source/fuzz/fuzzer_pass_add_composite_types.cpp
@@ -0,0 +1,138 @@
+// Copyright (c) 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "source/fuzz/fuzzer_pass_add_composite_types.h"
+
+#include "source/fuzz/fuzzer_util.h"
+#include "source/fuzz/transformation_add_type_array.h"
+#include "source/fuzz/transformation_add_type_struct.h"
+
+namespace spvtools {
+namespace fuzz {
+
+FuzzerPassAddCompositeTypes::FuzzerPassAddCompositeTypes(
+    opt::IRContext* ir_context, FactManager* fact_manager,
+    FuzzerContext* fuzzer_context,
+    protobufs::TransformationSequence* transformations)
+    : FuzzerPass(ir_context, fact_manager, fuzzer_context, transformations) {}
+
+FuzzerPassAddCompositeTypes::~FuzzerPassAddCompositeTypes() = default;
+
+void FuzzerPassAddCompositeTypes::Apply() {
+  MaybeAddMissingVectorTypes();
+  MaybeAddMissingMatrixTypes();
+
+  // Randomly interleave between adding struct and array composite types
+  while (GetFuzzerContext()->ChoosePercentage(
+      GetFuzzerContext()->GetChanceOfAddingArrayOrStructType())) {
+    if (GetFuzzerContext()->ChoosePercentage(
+            GetFuzzerContext()->GetChanceOfChoosingStructTypeVsArrayType())) {
+      AddNewStructType();
+    } else {
+      AddNewArrayType();
+    }
+  }
+}
+
+void FuzzerPassAddCompositeTypes::MaybeAddMissingVectorTypes() {
+  // Functions to lazily supply scalar base types on demand if we decide to
+  // create vectors with the relevant base types.
+  std::function<uint32_t()> bool_type_supplier = [this]() -> uint32_t {
+    return FindOrCreateBoolType();
+  };
+  std::function<uint32_t()> float_type_supplier = [this]() -> uint32_t {
+    return FindOrCreate32BitFloatType();
+  };
+  std::function<uint32_t()> int_type_supplier = [this]() -> uint32_t {
+    return FindOrCreate32BitIntegerType(true);
+  };
+  std::function<uint32_t()> uint_type_supplier = [this]() -> uint32_t {
+    return FindOrCreate32BitIntegerType(false);
+  };
+
+  // Consider each of the base types with which we can make vectors.
+  for (auto& base_type_supplier : {bool_type_supplier, float_type_supplier,
+                                   int_type_supplier, uint_type_supplier}) {
+    // Consider each valid vector size.
+    for (uint32_t size = 2; size <= 4; size++) {
+      // Randomly decide whether to create (if it does not already exist) a
+      // vector with this size and base type.
+      if (GetFuzzerContext()->ChoosePercentage(
+              GetFuzzerContext()->GetChanceOfAddingVectorType())) {
+        FindOrCreateVectorType(base_type_supplier(), size);
+      }
+    }
+  }
+}
+
+void FuzzerPassAddCompositeTypes::MaybeAddMissingMatrixTypes() {
+  // Consider every valid matrix dimension.
+  for (uint32_t columns = 2; columns <= 4; columns++) {
+    for (uint32_t rows = 2; rows <= 4; rows++) {
+      // Randomly decide whether to create (if it does not already exist) a
+      // matrix with these dimensions.  As matrices can only have floating-point
+      // base type, we do not need to consider multiple base types as in the
+      // case for vectors.
+      if (GetFuzzerContext()->ChoosePercentage(
+              GetFuzzerContext()->GetChanceOfAddingMatrixType())) {
+        FindOrCreateMatrixType(columns, rows);
+      }
+    }
+  }
+}
+
+void FuzzerPassAddCompositeTypes::AddNewArrayType() {
+  ApplyTransformation(TransformationAddTypeArray(
+      GetFuzzerContext()->GetFreshId(), ChooseScalarOrCompositeType(),
+      FindOrCreate32BitIntegerConstant(
+          GetFuzzerContext()->GetRandomSizeForNewArray(), false)));
+}
+
+void FuzzerPassAddCompositeTypes::AddNewStructType() {
+  std::vector<uint32_t> field_type_ids;
+  do {
+    field_type_ids.push_back(ChooseScalarOrCompositeType());
+  } while (GetFuzzerContext()->ChoosePercentage(
+      GetFuzzerContext()->GetChanceOfAddingAnotherStructField()));
+  ApplyTransformation(TransformationAddTypeStruct(
+      GetFuzzerContext()->GetFreshId(), field_type_ids));
+}
+
+uint32_t FuzzerPassAddCompositeTypes::ChooseScalarOrCompositeType() {
+  // Gather up all the possibly-relevant types.
+  std::vector<uint32_t> candidates;
+  for (auto& inst : GetIRContext()->types_values()) {
+    switch (inst.opcode()) {
+      case SpvOpTypeArray:
+      case SpvOpTypeBool:
+      case SpvOpTypeFloat:
+      case SpvOpTypeInt:
+      case SpvOpTypeMatrix:
+      case SpvOpTypeStruct:
+      case SpvOpTypeVector:
+        candidates.push_back(inst.result_id());
+        break;
+      default:
+        break;
+    }
+  }
+  assert(!candidates.empty() &&
+         "This function should only be called if there is at least one scalar "
+         "or composite type available.");
+  // Return one of these types at random.
+  return candidates[GetFuzzerContext()->RandomIndex(candidates)];
+}
+
+}  // namespace fuzz
+}  // namespace spvtools
diff --git a/source/fuzz/fuzzer_pass_add_composite_types.h b/source/fuzz/fuzzer_pass_add_composite_types.h
new file mode 100644
index 0000000..29d4bb8
--- /dev/null
+++ b/source/fuzz/fuzzer_pass_add_composite_types.h
@@ -0,0 +1,61 @@
+// Copyright (c) 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SOURCE_FUZZ_FUZZER_PASS_ADD_COMPOSITE_TYPES_H_
+#define SOURCE_FUZZ_FUZZER_PASS_ADD_COMPOSITE_TYPES_H_
+
+#include "source/fuzz/fuzzer_pass.h"
+
+namespace spvtools {
+namespace fuzz {
+
+// Fuzzer pass that randomly adds missing vector and matrix types, and new
+// array and struct types, to the module.
+class FuzzerPassAddCompositeTypes : public FuzzerPass {
+ public:
+  FuzzerPassAddCompositeTypes(
+      opt::IRContext* ir_context, FactManager* fact_manager,
+      FuzzerContext* fuzzer_context,
+      protobufs::TransformationSequence* transformations);
+
+  ~FuzzerPassAddCompositeTypes();
+
+  void Apply() override;
+
+ private:
+  // Creates an array of a random size with a random existing base type and adds
+  // it to the module.
+  void AddNewArrayType();
+
+  // Creates a struct with fields of random existing types and adds it to the
+  // module.
+  void AddNewStructType();
+
+  // For each vector type not already present in the module, randomly decides
+  // whether to add it to the module.
+  void MaybeAddMissingVectorTypes();
+
+  // For each matrix type not already present in the module, randomly decides
+  // whether to add it to the module.
+  void MaybeAddMissingMatrixTypes();
+
+  // Returns the id of a scalar or composite type declared in the module,
+  // chosen randomly.
+  uint32_t ChooseScalarOrCompositeType();
+};
+
+}  // namespace fuzz
+}  // namespace spvtools
+
+#endif  // SOURCE_FUZZ_FUZZER_PASS_ADD_COMPOSITE_TYPES_H_
diff --git a/source/fuzz/transformation_add_type_matrix.h b/source/fuzz/transformation_add_type_matrix.h
index ee3caf7..69d6389 100644
--- a/source/fuzz/transformation_add_type_matrix.h
+++ b/source/fuzz/transformation_add_type_matrix.h
@@ -28,8 +28,8 @@
   explicit TransformationAddTypeMatrix(
       const protobufs::TransformationAddTypeMatrix& message);
 
-  TransformationAddTypeMatrix(uint32_t fresh_id, uint32_t base_type_id,
-                              uint32_t size);
+  TransformationAddTypeMatrix(uint32_t fresh_id, uint32_t column_type_id,
+                              uint32_t column_count);
 
   // - |message_.fresh_id| must be a fresh id
   // - |message_.column_type_id| must be the id of a floating-point vector type
diff --git a/source/fuzz/transformation_add_type_vector.h b/source/fuzz/transformation_add_type_vector.h
index 7b50f6a..af840f5 100644
--- a/source/fuzz/transformation_add_type_vector.h
+++ b/source/fuzz/transformation_add_type_vector.h
@@ -28,8 +28,8 @@
   explicit TransformationAddTypeVector(
       const protobufs::TransformationAddTypeVector& message);
 
-  TransformationAddTypeVector(uint32_t fresh_id, uint32_t base_type_id,
-                              uint32_t size);
+  TransformationAddTypeVector(uint32_t fresh_id, uint32_t component_type_id,
+                              uint32_t component_count);
 
   // - |message_.fresh_id| must be a fresh id
   // - |message_.component_type_id| must be the id of a scalar type