@@ -873,4 +873,120 @@ to_annotated_pointer_constant_expr(exprt &expr)
873873 return ret;
874874}
875875
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+
876992#endif // CPROVER_UTIL_POINTER_EXPR_H
0 commit comments