summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2018-10-05 15:09:31 -0700
committerGabe Black <gabeblack@google.com>2018-10-16 00:55:52 +0000
commitf4a671e1eb534b9cf3e33af581adc364c577c57b (patch)
tree68dcf38aea81e4d79e90f808cfd7804301048cec
parent224e28c32bb937f5ad37a31138a5fa4cae247871 (diff)
downloadgem5-f4a671e1eb534b9cf3e33af581adc364c577c57b.tar.xz
systemc: Report an error if an sc_event_finder is used on an unbound port.
Rather than assuming the port is bound, check and report an error. Change-Id: I4af89d104bc6de9932ff044740446833732d01d9 Reviewed-on: https://gem5-review.googlesource.com/c/13300 Reviewed-by: Gabe Black <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
-rw-r--r--src/systemc/ext/core/sc_event.hh90
1 files changed, 50 insertions, 40 deletions
diff --git a/src/systemc/ext/core/sc_event.hh b/src/systemc/ext/core/sc_event.hh
index f70951d6a..90c1911ca 100644
--- a/src/systemc/ext/core/sc_event.hh
+++ b/src/systemc/ext/core/sc_event.hh
@@ -32,8 +32,10 @@
#include <cassert>
#include <set>
+#include <sstream>
#include <vector>
+#include "../utils/sc_report_handler.hh"
#include "sc_port.hh"
#include "sc_time.hh"
@@ -56,46 +58,6 @@ class sc_interface;
class sc_object;
class sc_port_base;
-class sc_event_finder
-{
- protected:
- virtual ~sc_event_finder() {}
-
- public:
- // Should be "implementation defined" but used in the tests.
- virtual const sc_event &find_event(sc_interface *if_p=NULL) const = 0;
- virtual const sc_port_base *port() const = 0;
-};
-
-template <class IF>
-class sc_event_finder_t : public sc_event_finder
-{
- public:
- sc_event_finder_t(const sc_port_base &p,
- const sc_event & (IF::*_method)() const) :
- _method(_method)
- {
- _port = dynamic_cast<const sc_port_b<IF> *>(&p);
- assert(_port);
- }
-
- virtual ~sc_event_finder_t() {}
-
- const sc_port_base *port() const { return _port; }
-
- const sc_event &
- find_event(sc_interface *if_p=NULL) const override
- {
- const IF *iface = if_p ? dynamic_cast<const IF *>(if_p) :
- dynamic_cast<const IF *>(_port->get_interface());
- return (const_cast<IF *>(iface)->*_method)();
- }
-
- private:
- const sc_port_b<IF> *_port;
- const sc_event &(IF::*_method)() const;
-};
-
class sc_event_and_list
{
public:
@@ -243,6 +205,54 @@ class sc_event
::sc_gem5::Event *_gem5_event;
};
+class sc_event_finder
+{
+ protected:
+ virtual ~sc_event_finder() {}
+
+ public:
+ // Should be "implementation defined" but used in the tests.
+ virtual const sc_event &find_event(sc_interface *if_p=NULL) const = 0;
+ virtual const sc_port_base *port() const = 0;
+};
+
+template <class IF>
+class sc_event_finder_t : public sc_event_finder
+{
+ public:
+ sc_event_finder_t(const sc_port_base &p,
+ const sc_event & (IF::*_method)() const) :
+ _method(_method)
+ {
+ _port = dynamic_cast<const sc_port_b<IF> *>(&p);
+ assert(_port);
+ }
+
+ virtual ~sc_event_finder_t() {}
+
+ const sc_port_base *port() const { return _port; }
+
+ const sc_event &
+ find_event(sc_interface *if_p=NULL) const override
+ {
+ static const sc_event none;
+ const IF *iface = if_p ? dynamic_cast<const IF *>(if_p) :
+ dynamic_cast<const IF *>(_port->get_interface());
+ if (!iface) {
+ std::ostringstream ss;
+ ss << "port is not bound: port '" << _port->name() << "' (" <<
+ _port->kind() << ")";
+ SC_REPORT_ERROR("(E118) find event failed", ss.str().c_str());
+ return none;
+ }
+ return (const_cast<IF *>(iface)->*_method)();
+ }
+
+ private:
+ const sc_port_b<IF> *_port;
+ const sc_event &(IF::*_method)() const;
+};
+
const std::vector<sc_event *> &sc_get_top_level_events();
sc_event *sc_find_event(const char *);