Fix field-level native_type for vector pack and CreateTable args

Complete field-level native_type/native_type_pack_name support in C++
codegen by fixing two remaining locations that only checked struct-level
attributes: vector-of-structs packing and CreateTable argument passing.
Add tests with a struct lacking struct-level native_type to verify
field-level attributes work end-to-end.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-09 15:47:07 +02:00
parent 4edfa03ffc
commit 9e9f5bbfcf
6 changed files with 197 additions and 15 deletions

View File

@@ -3812,14 +3812,25 @@ class CppGenerator : public BaseGenerator {
if (IsStruct(vector_type)) {
const auto& struct_attrs =
field.value.type.struct_def->attributes;
const auto native_type = struct_attrs.Lookup("native_type");
// Field-level native_type takes priority over struct-level
// native_type
auto field_native_type = field.attributes.Lookup("native_type");
const auto native_type = field_native_type
? field_native_type
: struct_attrs.Lookup("native_type");
if (native_type) {
code += "_fbb.CreateVectorOfNativeStructs<";
code += WrapInNameSpace(*vector_type.struct_def) + ", " +
native_type->constant + ">";
code += "(" + value;
// Field-level native_type_pack_name takes priority over
// struct-level
auto field_pack_name =
field.attributes.Lookup("native_type_pack_name");
const auto pack_name =
struct_attrs.Lookup("native_type_pack_name");
field_pack_name
? field_pack_name
: struct_attrs.Lookup("native_type_pack_name");
if (pack_name) {
code += ", ::flatbuffers::Pack" + pack_name->constant;
}
@@ -4114,9 +4125,15 @@ class CppGenerator : public BaseGenerator {
bool check_ptr = false;
if (field->value.type.base_type == BASE_TYPE_STRUCT) {
if (IsStruct(field->value.type)) {
// Field-level native_type takes priority over struct-level
// native_type
auto field_native_type =
field->attributes.Lookup("native_type");
auto native_type =
field->value.type.struct_def->attributes.Lookup(
"native_type");
field_native_type
? field_native_type
: field->value.type.struct_def->attributes.Lookup(
"native_type");
auto native_inline = field->attributes.Lookup("native_inline");
if (native_type) {
pass_by_address = true;