| 2513 | } |
| 2514 | |
| 2515 | CheckedError Parser::ParseDecl() { |
| 2516 | std::vector<std::string> dc = doc_comment_; |
| 2517 | bool fixed = IsIdent("struct"); |
| 2518 | if (!fixed && !IsIdent("table")) return Error("declaration expected"); |
| 2519 | NEXT(); |
| 2520 | std::string name = attribute_; |
| 2521 | EXPECT(kTokenIdentifier); |
| 2522 | StructDef *struct_def; |
| 2523 | ECHECK(StartStruct(name, &struct_def)); |
| 2524 | struct_def->doc_comment = dc; |
| 2525 | struct_def->fixed = fixed; |
| 2526 | ECHECK(ParseMetaData(&struct_def->attributes)); |
| 2527 | struct_def->sortbysize = |
| 2528 | struct_def->attributes.Lookup("original_order") == nullptr && !fixed; |
| 2529 | EXPECT('{'); |
| 2530 | while (token_ != '}') ECHECK(ParseField(*struct_def)); |
| 2531 | if (fixed) { |
| 2532 | const auto force_align = struct_def->attributes.Lookup("force_align"); |
| 2533 | if (force_align) { |
| 2534 | size_t align; |
| 2535 | ECHECK(ParseAlignAttribute(force_align->constant, struct_def->minalign, |
| 2536 | &align)); |
| 2537 | struct_def->minalign = align; |
| 2538 | } |
| 2539 | if (!struct_def->bytesize) return Error("size 0 structs not allowed"); |
| 2540 | } |
| 2541 | struct_def->PadLastField(struct_def->minalign); |
| 2542 | // Check if this is a table that has manual id assignments |
| 2543 | auto &fields = struct_def->fields.vec; |
| 2544 | if (!fixed && fields.size()) { |
| 2545 | size_t num_id_fields = 0; |
| 2546 | for (auto it = fields.begin(); it != fields.end(); ++it) { |
| 2547 | if ((*it)->attributes.Lookup("id")) num_id_fields++; |
| 2548 | } |
| 2549 | // If any fields have ids.. |
| 2550 | if (num_id_fields || opts.require_explicit_ids) { |
| 2551 | // Then all fields must have them. |
| 2552 | if (num_id_fields != fields.size()) { |
| 2553 | if (opts.require_explicit_ids) { |
| 2554 | return Error( |
| 2555 | "all fields must have an 'id' attribute when " |
| 2556 | "--require-explicit-ids is used"); |
| 2557 | } else { |
| 2558 | return Error( |
| 2559 | "either all fields or no fields must have an 'id' attribute"); |
| 2560 | } |
| 2561 | } |
| 2562 | // Simply sort by id, then the fields are the same as if no ids had |
| 2563 | // been specified. |
| 2564 | std::sort(fields.begin(), fields.end(), compareFieldDefs); |
| 2565 | // Verify we have a contiguous set, and reassign vtable offsets. |
| 2566 | FLATBUFFERS_ASSERT(fields.size() <= |
| 2567 | flatbuffers::numeric_limits<voffset_t>::max()); |
| 2568 | for (voffset_t i = 0; i < static_cast<voffset_t>(fields.size()); i++) { |
| 2569 | auto &field = *fields[i]; |
| 2570 | const auto &id_str = field.attributes.Lookup("id")->constant; |
| 2571 | // Metadata values have a dynamic type, they can be `float`, 'int', or |
| 2572 | // 'string`. |
nothing calls this directly
no test coverage detected