@@ -444,12 +444,56 @@ inline tag_typet &to_tag_type(typet &type)
444444 return static_cast <tag_typet &>(type);
445445}
446446
447+ // / A struct or union tag type. This is only to be used to create type-safe /
448+ // / APIs, no instances of this one can be created directly, use \ref
449+ // / struct_tag_typet or \ref union_tag_typet when creating objects.
450+ class struct_or_union_tag_typet : public tag_typet
451+ {
452+ protected:
453+ struct_or_union_tag_typet (const irep_idt &id, const irep_idt &identifier)
454+ : tag_typet(id, identifier)
455+ {
456+ PRECONDITION (id == ID_struct_tag || id == ID_union_tag);
457+ }
458+ };
459+
460+ // / Check whether a reference to a typet is a \ref struct_or_union_tag_typet.
461+ // / \param type: Source type.
462+ // / \return True if \p type is a \ref struct_or_union_tag_typet.
463+ template <>
464+ inline bool can_cast_type<struct_or_union_tag_typet>(const typet &type)
465+ {
466+ return type.id () == ID_struct_tag || type.id () == ID_union_tag;
467+ }
468+
469+ // / \brief Cast a typet to a \ref struct_or_union_tag_typet
470+ // /
471+ // / This is an unchecked conversion. \a type must be known to be \ref
472+ // / struct_or_union_tag_typet. Will fail with a precondition violation if type
473+ // / doesn't match.
474+ // /
475+ // / \param type: Source type.
476+ // / \return Object of type \ref struct_or_union_tag_typet
477+ inline const struct_or_union_tag_typet &
478+ to_struct_or_union_tag_type (const typet &type)
479+ {
480+ PRECONDITION (can_cast_type<struct_or_union_tag_typet>(type));
481+ return static_cast <const struct_or_union_tag_typet &>(type);
482+ }
483+
484+ // / \copydoc to_struct_or_union_tag_type(const typet &)
485+ inline struct_or_union_tag_typet &to_struct_or_union_tag_type (typet &type)
486+ {
487+ PRECONDITION (can_cast_type<struct_or_union_tag_typet>(type));
488+ return static_cast <struct_or_union_tag_typet &>(type);
489+ }
490+
447491// / A struct tag type, i.e., \ref struct_typet with an identifier
448- class struct_tag_typet : public tag_typet
492+ class struct_tag_typet : public struct_or_union_tag_typet
449493{
450494public:
451- explicit struct_tag_typet (const irep_idt &identifier):
452- tag_typet (ID_struct_tag, identifier)
495+ explicit struct_tag_typet (const irep_idt &identifier)
496+ : struct_or_union_tag_typet (ID_struct_tag, identifier)
453497 {
454498 }
455499};
0 commit comments