From 8ba168308255d5db72d9437975f7d7470ae90786 Mon Sep 17 00:00:00 2001 From: Derek Bailey Date: Sun, 5 Feb 2023 14:29:09 -0600 Subject: [PATCH] use switch statements for BASE_TYPE_ lookups (#7813) --- include/flatbuffers/idl.h | 25 +++++++++++++++++---- src/idl_gen_cpp.cpp | 47 ++++++++++++++++++++++----------------- src/idl_gen_fbs.cpp | 2 +- src/idl_parser.cpp | 29 +++++------------------- tests/fuzz_test.cpp | 2 +- 5 files changed, 56 insertions(+), 49 deletions(-) diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 7c96e38e032..9ad6edcdd6d 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -146,12 +146,29 @@ inline bool IsUnsigned(BaseType t) { (t == BASE_TYPE_ULONG); } -// clang-format on +inline size_t SizeOf(const BaseType t) { + switch (t) { + #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ + case BASE_TYPE_##ENUM: return sizeof(CTYPE); + FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) + #undef FLATBUFFERS_TD + default: FLATBUFFERS_ASSERT(0); + } + return 0; +} -extern const char *const kTypeNames[]; -extern const char kTypeSizes[]; +inline const char* TypeName(const BaseType t) { + switch (t) { + #define FLATBUFFERS_TD(ENUM, IDLTYPE, ...) \ + case BASE_TYPE_##ENUM: return IDLTYPE; + FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) + #undef FLATBUFFERS_TD + default: FLATBUFFERS_ASSERT(0); + } + return nullptr; +} -inline size_t SizeOf(BaseType t) { return kTypeSizes[t]; } +// clang-format on struct StructDef; struct EnumDef; diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index 90cc25fff01..1033a8954ce 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -721,19 +721,20 @@ class CppGenerator : public BaseGenerator { // Return a C++ type from the table in idl.h std::string GenTypeBasic(const Type &type, bool user_facing_type) const { - // clang-format off - static const char *const ctypename[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - #CTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - }; - // clang-format on if (user_facing_type) { if (type.enum_def) return WrapInNameSpace(*type.enum_def); if (type.base_type == BASE_TYPE_BOOL) return "bool"; } - return ctypename[type.base_type]; + switch (type.base_type) { + // clang-format off + #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ + case BASE_TYPE_##ENUM: return #CTYPE; + FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) + #undef FLATBUFFERS_TD + //clang-format on + default: FLATBUFFERS_ASSERT(0); + } + return ""; } // Return a C++ pointer type, specialized to the actual struct/table types, @@ -2262,11 +2263,14 @@ class CppGenerator : public BaseGenerator { const bool is_array = IsArray(curr_field->value.type); const bool is_struct = IsStruct(curr_field->value.type); - // If encouter a key field, call KeyCompareWithValue to compare this field. + // If encouter a key field, call KeyCompareWithValue to compare this + // field. if (curr_field->key) { - code_ += - space + "const auto {{RHS}} = {{RHS_PREFIX}}.{{CURR_FIELD_NAME}}();"; - code_ += space + "const auto {{CURR_FIELD_NAME}}_compare_result = {{LHS_PREFIX}}.KeyCompareWithValue({{RHS}});"; + code_ += space + + "const auto {{RHS}} = {{RHS_PREFIX}}.{{CURR_FIELD_NAME}}();"; + code_ += space + + "const auto {{CURR_FIELD_NAME}}_compare_result = " + "{{LHS_PREFIX}}.KeyCompareWithValue({{RHS}});"; code_ += space + "if ({{CURR_FIELD_NAME}}_compare_result != 0)"; code_ += space + " return {{CURR_FIELD_NAME}}_compare_result;"; @@ -2298,7 +2302,9 @@ class CppGenerator : public BaseGenerator { } else if (IsStruct(elem_type)) { if (curr_field->key) { - code_ += space + "const auto {{CURR_FIELD_NAME}}_compare_result = {{LHS_PREFIX}}.KeyCompareWithValue({{RHS}});"; + code_ += space + + "const auto {{CURR_FIELD_NAME}}_compare_result = " + "{{LHS_PREFIX}}.KeyCompareWithValue({{RHS}});"; code_ += space + "if ({{CURR_FIELD_NAME}}_compare_result != 0)"; code_ += space + " return {{CURR_FIELD_NAME}}_compare_result;"; continue; @@ -2331,7 +2337,7 @@ class CppGenerator : public BaseGenerator { code_ += " return *{{FIELD_NAME}}() < *o->{{FIELD_NAME}}();"; } else if (is_array || is_struct) { code_ += " return KeyCompareWithValue(o->{{FIELD_NAME}}()) < 0;"; - }else { + } else { code_ += " return {{FIELD_NAME}}() < o->{{FIELD_NAME}}();"; } code_ += " }"; @@ -2343,8 +2349,8 @@ class CppGenerator : public BaseGenerator { } else if (is_array) { const auto &elem_type = field.value.type.VectorType(); std::string input_type = "::flatbuffers::Array<" + - GenTypeGet(elem_type, "", "", "", false) + - ", " + NumToString(elem_type.fixed_length) + ">"; + GenTypeGet(elem_type, "", "", "", false) + ", " + + NumToString(elem_type.fixed_length) + ">"; code_.SetValue("INPUT_TYPE", input_type); code_ += " int KeyCompareWithValue(const {{INPUT_TYPE}} *_{{FIELD_NAME}}" @@ -2367,7 +2373,8 @@ class CppGenerator : public BaseGenerator { " const auto &lhs_{{FIELD_NAME}} = " "*(curr_{{FIELD_NAME}}->Get(i));"; code_ += - " const auto &rhs_{{FIELD_NAME}} = *(_{{FIELD_NAME}}->Get(i));"; + " const auto &rhs_{{FIELD_NAME}} = " + "*(_{{FIELD_NAME}}->Get(i));"; GenComparatorForStruct(*elem_type.struct_def, 6, "lhs_" + code_.GetValue("FIELD_NAME"), "rhs_" + code_.GetValue("FIELD_NAME")); @@ -3980,8 +3987,8 @@ class CppCodeGenerator : public CodeGenerator { // Generate code from the provided `buffer` of given `length`. The buffer is a // serialized reflection.fbs. Status GenerateCode(const uint8_t *buffer, int64_t length) override { - (void) buffer; - (void) length; + (void)buffer; + (void)length; return Status::NOT_IMPLEMENTED; } diff --git a/src/idl_gen_fbs.cpp b/src/idl_gen_fbs.cpp index 7fcfd17b39b..d8db7d4ffba 100644 --- a/src/idl_gen_fbs.cpp +++ b/src/idl_gen_fbs.cpp @@ -37,7 +37,7 @@ static std::string GenType(const Type &type, bool underlying = false) { return type.enum_def->defined_namespace->GetFullyQualifiedName( type.enum_def->name); } else { - return kTypeNames[type.base_type]; + return TypeName(type.base_type); } } } diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index ca658b9fd10..0adc9286871 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -356,23 +356,6 @@ template static void AssignIndices(const std::vector &defvec) { } // namespace -// clang-format off -const char *const kTypeNames[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, ...) \ - IDLTYPE, - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD - nullptr -}; - -const char kTypeSizes[] = { - #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ - sizeof(CTYPE), - FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) - #undef FLATBUFFERS_TD -}; -// clang-format on - void Parser::Message(const std::string &msg) { if (!error_.empty()) error_ += "\n"; // log all warnings and errors error_ += file_being_parsed_.length() ? AbsolutePath(file_being_parsed_) : ""; @@ -1947,8 +1930,8 @@ CheckedError Parser::ParseFunction(const std::string *name, Value &e) { const auto functionname = attribute_; if (!IsFloat(e.type.base_type)) { return Error(functionname + ": type of argument mismatch, expecting: " + - kTypeNames[BASE_TYPE_DOUBLE] + - ", found: " + kTypeNames[e.type.base_type] + + TypeName(BASE_TYPE_DOUBLE) + + ", found: " + TypeName(e.type.base_type) + ", name: " + (name ? *name : "") + ", value: " + e.constant); } NEXT(); @@ -1994,8 +1977,8 @@ CheckedError Parser::TryTypedValue(const std::string *name, int dtoken, e.type.base_type = req; } else { return Error(std::string("type mismatch: expecting: ") + - kTypeNames[e.type.base_type] + - ", found: " + kTypeNames[req] + + TypeName(e.type.base_type) + + ", found: " + TypeName(req) + ", name: " + (name ? *name : "") + ", value: " + e.constant); } } @@ -2056,7 +2039,7 @@ CheckedError Parser::ParseSingleValue(const std::string *name, Value &e, return Error( std::string("type mismatch or invalid value, an initializer of " "non-string field must be trivial ASCII string: type: ") + - kTypeNames[in_type] + ", name: " + (name ? *name : "") + + TypeName(in_type) + ", name: " + (name ? *name : "") + ", value: " + attribute_); } @@ -2128,7 +2111,7 @@ CheckedError Parser::ParseSingleValue(const std::string *name, Value &e, if (!match) { std::string msg; msg += "Cannot assign token starting with '" + TokenToStringId(token_) + - "' to value of <" + std::string(kTypeNames[in_type]) + "> type."; + "' to value of <" + std::string(TypeName(in_type)) + "> type."; return Error(msg); } const auto match_type = e.type.base_type; // may differ from in_type diff --git a/tests/fuzz_test.cpp b/tests/fuzz_test.cpp index 060742466cd..b0ba3cd308a 100644 --- a/tests/fuzz_test.cpp +++ b/tests/fuzz_test.cpp @@ -234,7 +234,7 @@ void FuzzTest2() { break; default: // All the scalar types. - schema += flatbuffers::kTypeNames[base_type]; + schema += flatbuffers::TypeName(base_type); if (!deprecated) { // We want each instance to use its own random value.