_Nullable cpp interface (#4451)
* add _Nullable Support for C++ interface * add _Nullable Support for C++ interface
This commit is contained in:
parent
9c3920d0ab
commit
30e7d16104
|
@ -372,6 +372,7 @@ struct IDLOptions {
|
|||
bool generate_object_based_api;
|
||||
std::string cpp_object_api_pointer_type;
|
||||
std::string cpp_object_api_string_type;
|
||||
bool clang_nullable;
|
||||
std::string object_prefix;
|
||||
std::string object_suffix;
|
||||
bool union_value_namespacing;
|
||||
|
@ -426,6 +427,7 @@ struct IDLOptions {
|
|||
generate_name_strings(false),
|
||||
generate_object_based_api(false),
|
||||
cpp_object_api_pointer_type("std::unique_ptr"),
|
||||
clang_nullable(false),
|
||||
object_suffix("T"),
|
||||
union_value_namespacing(true),
|
||||
allow_non_utf8(false),
|
||||
|
|
|
@ -89,6 +89,7 @@ std::string FlatCompiler::GetUsageString(const char* program_name) const {
|
|||
" --cpp-ptr-type T Set object API pointer type (default std::unique_ptr)\n"
|
||||
" --cpp-str-type T Set object API string type (default std::string)\n"
|
||||
" T::c_str() and T::length() must be supported\n"
|
||||
" --clang-nullable Add Clang _Nullable for C++ pointers.\n"
|
||||
" --object-prefix Customise class prefix for C++ object-based API.\n"
|
||||
" --object-suffix Customise class suffix for C++ object-based API.\n"
|
||||
" Default value is \"T\"\n"
|
||||
|
@ -205,6 +206,8 @@ int FlatCompiler::Compile(int argc, const char** argv) {
|
|||
} else if (arg == "--cpp-str-type") {
|
||||
if (++argi >= argc) Error("missing type following" + arg, true);
|
||||
opts.cpp_object_api_string_type = argv[argi];
|
||||
} else if (arg == "--clang-nullable") {
|
||||
opts.clang_nullable = true;
|
||||
} else if (arg == "--object-prefix") {
|
||||
if (++argi >= argc) Error("missing prefix following" + arg, true);
|
||||
opts.object_prefix = argv[argi];
|
||||
|
|
|
@ -127,6 +127,10 @@ class CppGenerator : public BaseGenerator {
|
|||
code_ += "#define " + include_guard;
|
||||
code_ += "";
|
||||
|
||||
if (parser_.opts.clang_nullable) {
|
||||
code_ += "#pragma clang system_header\n\n";
|
||||
}
|
||||
|
||||
code_ += "#include \"flatbuffers/flatbuffers.h\"";
|
||||
if (parser_.uses_flexbuffers_) {
|
||||
code_ += "#include \"flatbuffers/flexbuffers.h\"";
|
||||
|
@ -244,10 +248,11 @@ class CppGenerator : public BaseGenerator {
|
|||
|
||||
code_.SetValue("STRUCT_NAME", name);
|
||||
code_.SetValue("CPP_NAME", cpp_name);
|
||||
code_.SetValue("NULLABLE_EXT", NullableExtension());
|
||||
|
||||
// The root datatype accessor:
|
||||
code_ += "inline \\";
|
||||
code_ += "const {{CPP_NAME}} *Get{{STRUCT_NAME}}(const void *buf) {";
|
||||
code_ += "const {{CPP_NAME}} *{{NULLABLE_EXT}}Get{{STRUCT_NAME}}(const void *buf) {";
|
||||
code_ += " return flatbuffers::GetRoot<{{CPP_NAME}}>(buf);";
|
||||
code_ += "}";
|
||||
code_ += "";
|
||||
|
@ -427,6 +432,10 @@ class CppGenerator : public BaseGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
std::string NullableExtension() {
|
||||
return parser_.opts.clang_nullable ? " _Nullable " : "";
|
||||
}
|
||||
|
||||
static std::string NativeName(const std::string &name, const StructDef *sd, const IDLOptions & opts) {
|
||||
return sd && !sd->fixed ? opts.object_prefix + name + opts.object_suffix : name;
|
||||
}
|
||||
|
@ -1469,10 +1478,12 @@ class CppGenerator : public BaseGenerator {
|
|||
}
|
||||
call += ")";
|
||||
|
||||
std::string afterptr = " *" + NullableExtension();
|
||||
GenComment(field.doc_comment, " ");
|
||||
code_.SetValue("FIELD_TYPE",
|
||||
GenTypeGet(field.value.type, " ", "const ", " *", true));
|
||||
GenTypeGet(field.value.type, " ", "const ", afterptr.c_str(), true));
|
||||
code_.SetValue("FIELD_VALUE", GenUnderlyingCast(field, true, call));
|
||||
code_.SetValue("NULLABLE_EXT", NullableExtension());
|
||||
|
||||
code_ += " {{FIELD_TYPE}}{{FIELD_NAME}}() const {";
|
||||
code_ += " return {{FIELD_VALUE}};";
|
||||
|
@ -1482,7 +1493,7 @@ class CppGenerator : public BaseGenerator {
|
|||
auto u = field.value.type.enum_def;
|
||||
|
||||
code_ += " template<typename T> "
|
||||
"const T *{{FIELD_NAME}}_as() const;";
|
||||
"const T *{{NULLABLE_EXT}}{{FIELD_NAME}}_as() const;";
|
||||
|
||||
for (auto u_it = u->vals.vec.begin();
|
||||
u_it != u->vals.vec.end(); ++u_it) {
|
||||
|
@ -1499,9 +1510,10 @@ class CppGenerator : public BaseGenerator {
|
|||
code_.SetValue("U_FIELD_TYPE", "const " + full_struct_name + " *");
|
||||
code_.SetValue("U_FIELD_NAME",
|
||||
Name(field) + "_as_" + Name(ev));
|
||||
code_.SetValue("U_NULLABLE", NullableExtension());
|
||||
|
||||
// `const Type *union_name_asType() const` accessor.
|
||||
code_ += " {{U_FIELD_TYPE}}{{U_FIELD_NAME}}() const {";
|
||||
code_ += " {{U_FIELD_TYPE}}{{U_NULLABLE}}{{U_FIELD_NAME}}() const {";
|
||||
code_ += " return {{U_GET_TYPE}}() == {{U_ELEMENT_TYPE}} ? "
|
||||
"static_cast<{{U_FIELD_TYPE}}>({{FIELD_NAME}}()) "
|
||||
": nullptr;";
|
||||
|
@ -1524,7 +1536,8 @@ class CppGenerator : public BaseGenerator {
|
|||
code_ += " return {{SET_FN}}({{OFFSET_NAME}}, {{FIELD_VALUE}}, {{DEFAULT_VALUE}});";
|
||||
code_ += " }";
|
||||
} else {
|
||||
auto type = GenTypeGet(field.value.type, " ", "", " *", true);
|
||||
auto postptr = " *" + NullableExtension();
|
||||
auto type = GenTypeGet(field.value.type, " ", "", postptr.c_str(), true);
|
||||
auto underlying = accessor + type + ">(" + offset_str + ")";
|
||||
code_.SetValue("FIELD_TYPE", type);
|
||||
code_.SetValue("FIELD_VALUE",
|
||||
|
|
Loading…
Reference in New Issue