@@ -632,3 +632,66 @@ exprt build_sizeof_expr(
632
632
633
633
return result;
634
634
}
635
+
636
+ bool get_subexpression_at_offset (
637
+ exprt& result,
638
+ mp_integer offset,
639
+ const typet& target_type,
640
+ const namespacet& ns)
641
+ {
642
+ if (offset==0 && result.type ()==target_type)
643
+ return true ;
644
+
645
+ const typet& source_type=result.type ();
646
+
647
+ if (source_type.id ()==ID_struct)
648
+ {
649
+ const auto & st=to_struct_type (source_type);
650
+ const struct_typet::componentst &components=st.components ();
651
+ member_offset_iterator offsets (st,ns);
652
+ while (offsets->first <components.size () && offsets->second !=-1 && offsets->second <=offset)
653
+ {
654
+ auto nextit=offsets;
655
+ ++nextit;
656
+ if ((offsets->first +1 )==components.size () || offset<nextit->second )
657
+ {
658
+ // This field might be, or might contain, the answer.
659
+ result=member_exprt (result,
660
+ components[offsets->first ].get_name (),
661
+ components[offsets->first ].type ());
662
+ return get_subexpression_at_offset (result, offset - offsets->second , target_type, ns);
663
+ }
664
+ ++offsets;
665
+ }
666
+ return false ;
667
+ }
668
+ else if (source_type.id ()==ID_array)
669
+ {
670
+ // A cell of the array might be, or contain, the subexpression we're looking for.
671
+ const auto & at=to_array_type (source_type);
672
+ mp_integer elem_size=pointer_offset_size (at.subtype (),ns);
673
+ if (elem_size==-1 )
674
+ return false ;
675
+ mp_integer cellidx=offset / elem_size;
676
+ if (cellidx < 0 || !cellidx.is_long ())
677
+ return false ;
678
+ offset=offset % elem_size;
679
+ result=index_exprt (result,from_integer (cellidx,unsignedbv_typet (64 )));
680
+ return get_subexpression_at_offset (result,offset,target_type,ns);
681
+ }
682
+ else
683
+ return false ;
684
+
685
+ }
686
+
687
+ bool get_subexpression_at_offset (
688
+ exprt& result,
689
+ const exprt& offset,
690
+ const typet& target_type,
691
+ const namespacet& ns)
692
+ {
693
+ mp_integer offset_const;
694
+ if (to_integer (offset,offset_const))
695
+ return false ;
696
+ return get_subexpression_at_offset (result,offset_const,target_type,ns);
697
+ }
0 commit comments