From 21857a732b2d95ce4131cb038b1e9d92df70e058 Mon Sep 17 00:00:00 2001 From: Thomas Spriggs Date: Fri, 10 Aug 2018 12:12:16 +0100 Subject: [PATCH] Add support for getting components by name to `struct_exprt` This commit uses a template to implement both the const and non-const overloads of `struct_exprt::component`. This reduces the overhead of maintaining 2 identical versions and means that both overloads must be implemented in the same way. --- src/util/std_expr.cpp | 30 ++++++++++++++++++++++++++++++ src/util/std_expr.h | 3 +++ 2 files changed, 33 insertions(+) diff --git a/src/util/std_expr.cpp b/src/util/std_expr.cpp index 431ca387530..88608f650b7 100644 --- a/src/util/std_expr.cpp +++ b/src/util/std_expr.cpp @@ -8,6 +8,8 @@ Author: Daniel Kroening, kroening@kroening.com #include "std_expr.h" +#include + #include #include "arith_tools.h" @@ -167,3 +169,31 @@ address_of_exprt::address_of_exprt(const exprt &_op): unary_exprt(ID_address_of, _op, pointer_type(_op.type())) { } + +// Implementation of struct_exprt::component for const / non const overloads. +template +auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) + -> decltype(struct_expr.op0()) +{ + static_assert( + std::is_base_of::value, "T must be a struct_exprt."); + const auto index = + to_struct_type(ns.follow(struct_expr.type())).component_number(name); + DATA_INVARIANT( + index < struct_expr.operands().size(), + "component matching index should exist"); + return struct_expr.operands()[index]; +} + +/// \return The expression for a named component of this struct. +exprt &struct_exprt::component(const irep_idt &name, const namespacet &ns) +{ + return ::component(*this, name, ns); +} + +/// \return The expression for a named component of this struct. +const exprt & +struct_exprt::component(const irep_idt &name, const namespacet &ns) const +{ + return ::component(*this, name, ns); +} diff --git a/src/util/std_expr.h b/src/util/std_expr.h index e979f45ee69..97861252881 100644 --- a/src/util/std_expr.h +++ b/src/util/std_expr.h @@ -1823,6 +1823,9 @@ class struct_exprt:public exprt exprt(ID_struct, _type) { } + + exprt &component(const irep_idt &name, const namespacet &ns); + const exprt &component(const irep_idt &name, const namespacet &ns) const; }; /*! \brief Cast a generic exprt to a \ref struct_exprt