| 3163 | } |
| 3164 | |
| 3165 | CheckedError Parser::ParseRoot(const char *source, const char **include_paths, |
| 3166 | const char *source_filename) { |
| 3167 | ECHECK(DoParse(source, include_paths, source_filename, nullptr)); |
| 3168 | |
| 3169 | // Check that all types were defined. |
| 3170 | for (auto it = structs_.vec.begin(); it != structs_.vec.end();) { |
| 3171 | auto &struct_def = **it; |
| 3172 | if (struct_def.predecl) { |
| 3173 | if (opts.proto_mode) { |
| 3174 | // Protos allow enums to be used before declaration, so check if that |
| 3175 | // is the case here. |
| 3176 | EnumDef *enum_def = nullptr; |
| 3177 | for (size_t components = |
| 3178 | struct_def.defined_namespace->components.size() + 1; |
| 3179 | components && !enum_def; components--) { |
| 3180 | auto qualified_name = |
| 3181 | struct_def.defined_namespace->GetFullyQualifiedName( |
| 3182 | struct_def.name, components - 1); |
| 3183 | enum_def = LookupEnum(qualified_name); |
| 3184 | } |
| 3185 | if (enum_def) { |
| 3186 | // This is pretty slow, but a simple solution for now. |
| 3187 | auto initial_count = struct_def.refcount; |
| 3188 | for (auto struct_it = structs_.vec.begin(); |
| 3189 | struct_it != structs_.vec.end(); ++struct_it) { |
| 3190 | auto &sd = **struct_it; |
| 3191 | for (auto field_it = sd.fields.vec.begin(); |
| 3192 | field_it != sd.fields.vec.end(); ++field_it) { |
| 3193 | auto &field = **field_it; |
| 3194 | if (field.value.type.struct_def == &struct_def) { |
| 3195 | field.value.type.struct_def = nullptr; |
| 3196 | field.value.type.enum_def = enum_def; |
| 3197 | auto &bt = IsVector(field.value.type) |
| 3198 | ? field.value.type.element |
| 3199 | : field.value.type.base_type; |
| 3200 | FLATBUFFERS_ASSERT(bt == BASE_TYPE_STRUCT); |
| 3201 | bt = enum_def->underlying_type.base_type; |
| 3202 | struct_def.refcount--; |
| 3203 | enum_def->refcount++; |
| 3204 | } |
| 3205 | } |
| 3206 | } |
| 3207 | if (struct_def.refcount) |
| 3208 | return Error("internal: " + NumToString(struct_def.refcount) + "/" + |
| 3209 | NumToString(initial_count) + |
| 3210 | " use(s) of pre-declaration enum not accounted for: " + |
| 3211 | enum_def->name); |
| 3212 | structs_.dict.erase(structs_.dict.find(struct_def.name)); |
| 3213 | it = structs_.vec.erase(it); |
| 3214 | delete &struct_def; |
| 3215 | continue; // Skip error. |
| 3216 | } |
| 3217 | } |
| 3218 | auto err = "type referenced but not defined (check namespace): " + |
| 3219 | struct_def.name; |
| 3220 | if (struct_def.original_location) |
| 3221 | err += ", originally at: " + *struct_def.original_location; |
| 3222 | return Error(err); |
nothing calls this directly
no test coverage detected