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

Code before:
      return adapted_class_info.complete_type_witness_id;
    }
  }

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

// Checks that the specified finished class definition is valid and builds and
// returns a corresponding complete type witness instruction.
static auto CheckCompleteClassType(Context& context, Parse::NodeId node_id,
                                   SemIR::ClassId class_id,
                                   SemIR::InstBlockId fields_id)
    -> SemIR::InstId {
  auto& class_info = context.classes().Get(class_id);
  if (class_info.adapt_id.is_valid()) {
    return CheckCompleteAdapterClassType(context, node_id, class_id, fields_id);
  }

  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)

Review comment (suggestion):
```suggestion
    // 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);
```

Code after:
    }
  }

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

// Checks that the specified finished class definition is valid and builds and
// returns a corresponding complete type witness instruction.
static auto CheckCompleteClassType(Context& context, Parse::NodeId node_id,
                                   SemIR::ClassId class_id) -> SemIR::InstId {
  auto& class_info = context.classes().Get(class_id);
  if (class_info.adapt_id.is_valid()) {
    auto fields_id = context.args_type_info_stack().Pop();

    return CheckCompleteAdapterClassType(context, node_id, class_id, fields_id);
  }

  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 =