@@ -566,28 +566,74 @@ void addStandardTypeHandlers(std::string& code) {
566
566
)" ;
567
567
}
568
568
569
- // TODO support thrift isset
570
- void getClassTypeHandler (const Class& c, std::string& code) {
569
+ } // namespace
570
+
571
+ void CodeGen::getClassTypeHandler (const Class& c, std::string& code) {
571
572
std::string funcName = " getSizeType" ;
573
+ std::string extras;
574
+
575
+ const Member* thriftIssetMember = nullptr ;
576
+ if (const auto it = thriftIssetMembers_.find (&c);
577
+ it != thriftIssetMembers_.end ()) {
578
+ thriftIssetMember = it->second ;
579
+
580
+ extras += " \n using thrift_data = apache::thrift::TStructDataStorage<" +
581
+ c.fqName () + " >;" ;
582
+
583
+ extras += (boost::format (R"(
584
+ static int getThriftIsset(const %1%& t, size_t i) {
585
+ if (&thrift_data::isset_indexes == nullptr) return -1;
586
+
587
+ auto idx = thrift_data::isset_indexes[i];
588
+ if (idx == -1) return -1;
589
+
590
+ return t.%2%.get(idx);
591
+ }
592
+ )" ) % c.name () %
593
+ thriftIssetMember->name )
594
+ .str ();
595
+ }
596
+
597
+ size_t lastNonPaddingElement = -1 ;
598
+ for (size_t i = 0 ; i < c.members .size (); i++) {
599
+ const auto & el = c.members [i];
600
+ if (!el.name .starts_with (type_graph::AddPadding::MemberPrefix)) {
601
+ lastNonPaddingElement = i;
602
+ }
603
+ }
572
604
573
605
std::string typeStaticType;
574
606
{
575
607
size_t pairs = 0 ;
576
608
577
- for (size_t i = 0 ; i < c. members . size () ; i++) {
609
+ for (size_t i = 0 ; i < lastNonPaddingElement + 1 ; i++) {
578
610
const auto & member = c.members [i];
611
+ if (member.name .starts_with (type_graph::AddPadding::MemberPrefix)) {
612
+ continue ;
613
+ }
579
614
580
- if (i != c. members . size () - 1 ) {
615
+ if (i != lastNonPaddingElement ) {
581
616
typeStaticType += " types::st::Pair<DB, " ;
582
617
pairs++;
583
618
}
584
619
620
+ if (thriftIssetMember != nullptr && thriftIssetMember != &member) {
621
+ // Return an additional VarInt before every field except for __isset
622
+ // itself.
623
+ pairs++;
624
+ if (i == lastNonPaddingElement) {
625
+ typeStaticType += " types::st::Pair<DB, types::st::VarInt<DB>, " ;
626
+ } else {
627
+ typeStaticType += " types::st::VarInt<DB>, types::st::Pair<DB, " ;
628
+ }
629
+ }
630
+
585
631
typeStaticType +=
586
632
(boost::format (" typename TypeHandler<DB, decltype(%1%::%2%)>::type" ) %
587
633
c.name () % member.name )
588
634
.str ();
589
635
590
- if (i != c. members . size () - 1 ) {
636
+ if (i != lastNonPaddingElement ) {
591
637
typeStaticType += " , " ;
592
638
}
593
639
}
@@ -603,10 +649,17 @@ void getClassTypeHandler(const Class& c, std::string& code) {
603
649
if (!c.members .empty ()) {
604
650
traverser = " auto ret = returnArg" ;
605
651
}
606
- for (size_t i = 0 ; i < c. members . size () ; i++) {
652
+ for (size_t i = 0 ; i < lastNonPaddingElement + 1 ; i++) {
607
653
const auto & member = c.members [i];
654
+ if (member.name .starts_with (type_graph::AddPadding::MemberPrefix)) {
655
+ continue ;
656
+ }
608
657
609
- if (i != c.members .size () - 1 ) {
658
+ if (thriftIssetMember != nullptr && thriftIssetMember != &member) {
659
+ traverser += " \n .write(getThriftIsset(t, " + std::to_string (i) + " ))" ;
660
+ }
661
+
662
+ if (i != lastNonPaddingElement) {
610
663
traverser += " \n .delegate([&t](auto ret) {" ;
611
664
traverser += " \n return OIInternal::getSizeType<DB>(t." +
612
665
member.name + " , ret);" ;
@@ -625,20 +678,22 @@ void getClassTypeHandler(const Class& c, std::string& code) {
625
678
626
679
code += (boost::format (R"(
627
680
template <typename DB>
628
- class TypeHandler<DB, %1%> {
681
+ class TypeHandler<DB, %1%> {%2%
629
682
public:
630
- using type = %2 %;
631
- static types::st::Unit<DB> %3 %(
683
+ using type = %3 %;
684
+ static types::st::Unit<DB> %4 %(
632
685
const %1%& t,
633
686
typename TypeHandler<DB, %1%>::type returnArg) {
634
- %4 %
687
+ %5 %
635
688
}
636
689
};
637
690
)" ) % c.name () %
638
- typeStaticType % funcName % traverser)
691
+ extras % typeStaticType % funcName % traverser)
639
692
.str ();
640
693
}
641
694
695
+ namespace {
696
+
642
697
void getContainerTypeHandler (std::unordered_set<const ContainerInfo*>& used,
643
698
const Container& c,
644
699
std::string& code) {
@@ -658,19 +713,17 @@ void getContainerTypeHandler(std::unordered_set<const ContainerInfo*>& used,
658
713
code += fmt.str ();
659
714
}
660
715
661
- void addTypeHandlers (
662
- std::unordered_set<const ContainerInfo*>& definedContainers,
663
- const TypeGraph& typeGraph,
664
- std::string& code) {
716
+ } // namespace
717
+
718
+ void CodeGen::addTypeHandlers (const TypeGraph& typeGraph, std::string& code) {
665
719
for (const Type& t : typeGraph.finalTypes ) {
666
720
if (const auto * c = dynamic_cast <const Class*>(&t)) {
667
721
getClassTypeHandler (*c, code);
668
722
} else if (const auto * con = dynamic_cast <const Container*>(&t)) {
669
- getContainerTypeHandler (definedContainers , *con, code);
723
+ getContainerTypeHandler (definedContainers_ , *con, code);
670
724
}
671
725
}
672
726
}
673
- } // namespace
674
727
675
728
bool CodeGen::codegenFromDrgn (struct drgn_type * drgnType, std::string& code) {
676
729
try {
@@ -787,7 +840,7 @@ void CodeGen::generate(
787
840
788
841
if (config_.features [Feature::TypedDataSegment]) {
789
842
addStandardTypeHandlers (code);
790
- addTypeHandlers (definedContainers_, typeGraph, code);
843
+ addTypeHandlers (typeGraph, code);
791
844
} else {
792
845
addStandardGetSizeFuncDecls (code);
793
846
addGetSizeFuncDecls (typeGraph, code);
0 commit comments