Repository: carbon-language/carbon-lang
File: toolchain/check/handle_class.cpp (C++)

Code before:
  }

  bool defining_vtable_ptr = class_info.is_dynamic;
  if (class_info.base_id.is_valid()) {
    auto base_info = context.insts().GetAs<SemIR::BaseDecl>(class_info.base_id);
    if (auto* base_class_info = TryGetAsClass(context, base_info.base_type_id);
        base_class_info && base_class_info->is_dynamic) {
      defining_vtable_ptr = false;
    }
  }

  llvm::SmallVector<SemIR::InstId> object_rep_fields;
  auto fields = context.inst_blocks().Get(fields_id);
  if (defining_vtable_ptr) {
    if (!fields.empty()) {
      auto field =
          context.insts().GetAs<SemIR::StructTypeField>(fields.front());
      object_rep_fields.push_back(
          context.AddInstInNoBlock<SemIR::StructTypeField>(
              Parse::NodeId::Invalid,
              {.name_id = SemIR::NameId::Vptr,
               .field_type_id = context.GetPointerType(field.field_type_id)}));
    }
  }

  object_rep_fields.append(fields.begin(), fields.end());

  return context.AddInst<SemIR::CompleteTypeWitness>(
      node_id,
      {.type_id = context.GetBuiltinType(SemIR::BuiltinInstKind::WitnessType),
       .object_repr_id = context.GetStructType(
           defining_vtable_ptr ? context.inst_blocks().Add(object_rep_fields)
                               : fields_id)});
}

auto HandleParseNode(Context& context, Parse::ClassDefinitionId node_id)
    -> bool {
  auto fields_id = context.args_type_info_stack().Pop();
  auto class_id =
      context.node_stack().Pop<Parse::NodeKind::ClassDefinitionStart>();

  // The class type is now fully defined. Compute its object representation.
  auto complete_type_witness_id =
      CheckCompleteClassType(context, node_id, class_id, fields_id);
  auto& class_info = context.classes().Get(class_id);
  class_info.complete_type_witness_id = complete_type_witness_id;

  context.inst_block_stack().Pop();

  FinishGenericDefinition(context, class_info.generic_id);


Review comment (suggestion):
Perhaps...
```suggestion
    object_rep_fields.append(fields.begin(), fields.end());
  }
```
given that you don't use `object_rep_fields` in the `!defining_vtable_ptr` case.

Code after:

  bool defining_vtable_ptr = class_info.is_dynamic;
  if (class_info.base_id.is_valid()) {
    auto base_info = context.insts().GetAs<SemIR::BaseDecl>(class_info.base_id);
    // TODO: If the base class is template dependent, we will need to decide
    // whether to add a vptr as part of instantiation.
    if (auto* base_class_info = TryGetAsClass(context, base_info.base_type_id);
        base_class_info && base_class_info->is_dynamic) {
      defining_vtable_ptr = false;
    }
  }

  if (defining_vtable_ptr) {
    context.args_type_info_stack().AddFrontInstId(
        context.AddInstInNoBlock<SemIR::StructTypeField>(
            Parse::NodeId::Invalid,
            {.name_id = SemIR::NameId::Vptr,
             .field_type_id = context.GetPointerType(
                 context.GetBuiltinType(SemIR::BuiltinInstKind::VtableType))}));
  }

  auto fields_id = context.args_type_info_stack().Pop();

  return context.AddInst<SemIR::CompleteTypeWitness>(
      node_id,
      {.type_id = context.GetBuiltinType(SemIR::BuiltinInstKind::WitnessType),
       .object_repr_id = context.GetStructType(fields_id)});
}

auto HandleParseNode(Context& context, Parse::ClassDefinitionId node_id)
    -> bool {
  auto class_id =
      context.node_stack().Pop<Parse::NodeKind::ClassDefinitionStart>();

  // The class type is now fully defined. Compute its object representation.
  auto complete_type_witness_id =
      CheckCompleteClassType(context, node_id, class_id);
  auto& class_info = context.classes().Get(class_id);
  class_info.complete_type_witness_id = complete_type_witness_id;

  context.inst_block_stack().Pop();

  FinishGenericDefinition(context, class_info.generic_id);

  // The decl_name_stack and scopes are popped by `ProcessNodeIds`.
  return true;
}

}  // namespace Carbon::Check