@@ -873,4 +873,120 @@ to_annotated_pointer_constant_expr(exprt &expr)
873
873
return ret;
874
874
}
875
875
876
+ // / The offset (in bytes) of a pointer relative to the object
877
+ class pointer_offset_exprt : public unary_exprt
878
+ {
879
+ public:
880
+ explicit pointer_offset_exprt (exprt pointer, typet type)
881
+ : unary_exprt(ID_pointer_offset, std::move(pointer), std::move(type))
882
+ {
883
+ }
884
+
885
+ exprt &pointer ()
886
+ {
887
+ return op0 ();
888
+ }
889
+
890
+ const exprt &pointer () const
891
+ {
892
+ return op0 ();
893
+ }
894
+ };
895
+
896
+ template <>
897
+ inline bool can_cast_expr<pointer_offset_exprt>(const exprt &base)
898
+ {
899
+ return base.id () == ID_pointer_offset;
900
+ }
901
+
902
+ inline void validate_expr (const pointer_offset_exprt &value)
903
+ {
904
+ validate_operands (value, 1 , " pointer_offset must have one operand" );
905
+ DATA_INVARIANT (
906
+ value.pointer ().type ().id () == ID_pointer,
907
+ " pointer_offset must have pointer-typed operand" );
908
+ }
909
+
910
+ // / \brief Cast an exprt to a \ref pointer_offset_exprt
911
+ // /
912
+ // / \a expr must be known to be \ref pointer_offset_exprt.
913
+ // /
914
+ // / \param expr: Source expression
915
+ // / \return Object of type \ref pointer_offset_exprt
916
+ inline const pointer_offset_exprt &to_pointer_offset_expr (const exprt &expr)
917
+ {
918
+ PRECONDITION (expr.id () == ID_pointer_offset);
919
+ const pointer_offset_exprt &ret =
920
+ static_cast <const pointer_offset_exprt &>(expr);
921
+ validate_expr (ret);
922
+ return ret;
923
+ }
924
+
925
+ // / \copydoc to_pointer_offset_expr(const exprt &)
926
+ inline pointer_offset_exprt &to_pointer_offset_expr (exprt &expr)
927
+ {
928
+ PRECONDITION (expr.id () == ID_pointer_offset);
929
+ pointer_offset_exprt &ret = static_cast <pointer_offset_exprt &>(expr);
930
+ validate_expr (ret);
931
+ return ret;
932
+ }
933
+
934
+ // / A numerical identifier for the object a pointer points to
935
+ class pointer_object_exprt : public unary_exprt
936
+ {
937
+ public:
938
+ explicit pointer_object_exprt (exprt pointer, typet type)
939
+ : unary_exprt(ID_pointer_object, std::move(pointer), std::move(type))
940
+ {
941
+ }
942
+
943
+ exprt &pointer ()
944
+ {
945
+ return op0 ();
946
+ }
947
+
948
+ const exprt &pointer () const
949
+ {
950
+ return op0 ();
951
+ }
952
+ };
953
+
954
+ template <>
955
+ inline bool can_cast_expr<pointer_object_exprt>(const exprt &base)
956
+ {
957
+ return base.id () == ID_pointer_object;
958
+ }
959
+
960
+ inline void validate_expr (const pointer_object_exprt &value)
961
+ {
962
+ validate_operands (value, 1 , " pointer_object must have one operand" );
963
+ DATA_INVARIANT (
964
+ value.pointer ().type ().id () == ID_pointer,
965
+ " pointer_object must have pointer-typed operand" );
966
+ }
967
+
968
+ // / \brief Cast an exprt to a \ref pointer_object_exprt
969
+ // /
970
+ // / \a expr must be known to be \ref pointer_object_exprt.
971
+ // /
972
+ // / \param expr: Source expression
973
+ // / \return Object of type \ref pointer_object_exprt
974
+ inline const pointer_object_exprt &to_pointer_object_expr (const exprt &expr)
975
+ {
976
+ PRECONDITION (expr.id () == ID_pointer_object);
977
+ const pointer_object_exprt &ret =
978
+ static_cast <const pointer_object_exprt &>(expr);
979
+ validate_expr (ret);
980
+ return ret;
981
+ }
982
+
983
+ // / \copydoc to_pointer_object_expr(const exprt &)
984
+ inline pointer_object_exprt &to_pointer_object_expr (exprt &expr)
985
+ {
986
+ PRECONDITION (expr.id () == ID_pointer_object);
987
+ pointer_object_exprt &ret = static_cast <pointer_object_exprt &>(expr);
988
+ validate_expr (ret);
989
+ return ret;
990
+ }
991
+
876
992
#endif // CPROVER_UTIL_POINTER_EXPR_H
0 commit comments