Allows structs to be stored directly as member variables.

Introduce a "native_inline" attribute that can be applied on fields that are structs.
This results in NativeTable code generation that sets the struct "inline" rather than
storing it in a pointer.

From cl/140527470.

Change-Id: I208724f552b8b921b20923e0bf82f42cb3582416
parent d3429187
...@@ -234,6 +234,8 @@ struct FieldDef : public Definition { ...@@ -234,6 +234,8 @@ struct FieldDef : public Definition {
// written in new data nor accessed in new code. // written in new data nor accessed in new code.
bool required; // Field must always be present. bool required; // Field must always be present.
bool key; // Field functions as a key for creating sorted vectors. bool key; // Field functions as a key for creating sorted vectors.
bool native_inline; // Field will be defined inline (instead of as a pointer)
// for native tables if field is a struct.
size_t padding; // Bytes to always pad after this field. size_t padding; // Bytes to always pad after this field.
}; };
...@@ -454,6 +456,7 @@ class Parser : public ParserState { ...@@ -454,6 +456,7 @@ class Parser : public ParserState {
known_attributes_["idempotent"] = true; known_attributes_["idempotent"] = true;
known_attributes_["cpp_type"] = true; known_attributes_["cpp_type"] = true;
known_attributes_["cpp_ptr_type"] = true; known_attributes_["cpp_ptr_type"] = true;
known_attributes_["native_inline"] = true;
} }
~Parser() { ~Parser() {
......
...@@ -332,7 +332,7 @@ class CppGenerator : public BaseGenerator { ...@@ -332,7 +332,7 @@ class CppGenerator : public BaseGenerator {
">"; ">";
case BASE_TYPE_STRUCT: case BASE_TYPE_STRUCT:
if (IsStruct(type)) { if (IsStruct(type)) {
if (invector) { if (invector || field.native_inline) {
return WrapInNameSpace(*type.struct_def); return WrapInNameSpace(*type.struct_def);
} else { } else {
return GenTypeNativePtr(WrapInNameSpace(*type.struct_def), &field, return GenTypeNativePtr(WrapInNameSpace(*type.struct_def), &field,
...@@ -1016,7 +1016,7 @@ class CppGenerator : public BaseGenerator { ...@@ -1016,7 +1016,7 @@ class CppGenerator : public BaseGenerator {
return val + "->str()"; return val + "->str()";
case BASE_TYPE_STRUCT: case BASE_TYPE_STRUCT:
if (IsStruct(type)) { if (IsStruct(type)) {
if (invector) { if (invector || afield.native_inline) {
return "*" + val; return "*" + val;
} else { } else {
return GenTypeNativePtr(WrapInNameSpace(*type.struct_def), return GenTypeNativePtr(WrapInNameSpace(*type.struct_def),
...@@ -1059,7 +1059,11 @@ class CppGenerator : public BaseGenerator { ...@@ -1059,7 +1059,11 @@ class CppGenerator : public BaseGenerator {
code += "{ for (flatbuffers::uoffset_t _i = 0;"; code += "{ for (flatbuffers::uoffset_t _i = 0;";
code += " _i < _e->size(); _i++) { "; code += " _i < _e->size(); _i++) { ";
code += dest + ".push_back("; code += dest + ".push_back(";
std::string indexing = "_e->Get(_i)"; std::string indexing;
if (field.value.type.enum_def) {
indexing += "(" + field.value.type.enum_def->name + ")";
}
indexing += "_e->Get(_i)";
if (field.value.type.element == BASE_TYPE_BOOL) if (field.value.type.element == BASE_TYPE_BOOL)
indexing += "!=0"; indexing += "!=0";
code += GenUnpackVal(field.value.type.VectorType(), code += GenUnpackVal(field.value.type.VectorType(),
...@@ -1151,15 +1155,27 @@ class CppGenerator : public BaseGenerator { ...@@ -1151,15 +1155,27 @@ class CppGenerator : public BaseGenerator {
code += "_fbb.CreateVectorOfStructs(" + accessor + ")"; code += "_fbb.CreateVectorOfStructs(" + accessor + ")";
} else { } else {
code += "_fbb.CreateVector<flatbuffers::Offset<"; code += "_fbb.CreateVector<flatbuffers::Offset<";
code += vector_type.struct_def->name + ">>(" + accessor; code += WrapInNameSpace(*vector_type.struct_def) + ">>(" +
accessor;
code += ".size(), [&](size_t i) { return Create"; code += ".size(), [&](size_t i) { return Create";
code += vector_type.struct_def->name + "(_fbb, " + accessor; code += vector_type.struct_def->name + "(_fbb, " + accessor;
code += "[i]" + GenPtrGet(field) + ", rehasher); })"; code += "[i]" + GenPtrGet(field) + ", rehasher); })";
} }
break; break;
default: case BASE_TYPE_BOOL:
code += "_fbb.CreateVector(" + accessor + ")"; code += "_fbb.CreateVector(" + accessor + ")";
break; break;
default: {
std::string args = accessor;
if (field.value.type.enum_def) {
const std::string basetype = GenTypeBasic(
field.value.type.enum_def->underlying_type, false);
args = "(const " + basetype + "*)" + accessor +
".data(), " + accessor + ".size()";
}
code += "_fbb.CreateVector(" + args + ")";
break;
}
} }
code += postfix; code += postfix;
break; break;
...@@ -1169,7 +1185,11 @@ class CppGenerator : public BaseGenerator { ...@@ -1169,7 +1185,11 @@ class CppGenerator : public BaseGenerator {
break; break;
case BASE_TYPE_STRUCT: case BASE_TYPE_STRUCT:
if (IsStruct(field.value.type)) { if (IsStruct(field.value.type)) {
if (field.native_inline) {
code += "&" + accessor;
} else {
code += ptrprefix + accessor + GenPtrGet(field) + postfix; code += ptrprefix + accessor + GenPtrGet(field) + postfix;
}
} else { } else {
code += ptrprefix + "Create"; code += ptrprefix + "Create";
code += field.value.type.struct_def->name; code += field.value.type.struct_def->name;
......
...@@ -680,6 +680,11 @@ CheckedError Parser::ParseField(StructDef &struct_def) { ...@@ -680,6 +680,11 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
return Error("'key' field must be string or scalar type"); return Error("'key' field must be string or scalar type");
} }
} }
field->native_inline = field->attributes.Lookup("native_inline") != nullptr;
if (field->native_inline && !IsStruct(field->value.type))
return Error("native_inline can only be defined on structs'");
auto nested = field->attributes.Lookup("nested_flatbuffer"); auto nested = field->attributes.Lookup("nested_flatbuffer");
if (nested) { if (nested) {
if (nested->type.base_type != BASE_TYPE_STRING) if (nested->type.base_type != BASE_TYPE_STRING)
...@@ -1758,9 +1763,6 @@ CheckedError Parser::SkipAnyJsonValue() { ...@@ -1758,9 +1763,6 @@ CheckedError Parser::SkipAnyJsonValue() {
case kTokenFloatConstant: case kTokenFloatConstant:
EXPECT(kTokenFloatConstant); EXPECT(kTokenFloatConstant);
break; break;
case kTokenNull:
EXPECT(kTokenNull);
break;
default: default:
return Error(std::string("Unexpected token:") + std::string(1, static_cast<char>(token_))); return Error(std::string("Unexpected token:") + std::string(1, static_cast<char>(token_)));
} }
......
No preview for this file type
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment