diff --git a/elab_scope.cc b/elab_scope.cc index 87593c192..04cff8861 100644 --- a/elab_scope.cc +++ b/elab_scope.cc @@ -434,6 +434,7 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass) class_scope->set_line(pclass); class_scope->set_class_def(use_class); use_class->set_class_scope(class_scope); + use_class->set_definition_scope(scope); // Collect the properties, elaborate them, and add them to the // elaborated class definition. diff --git a/net_scope.cc b/net_scope.cc index f7b4b925a..e20173ab9 100644 --- a/net_scope.cc +++ b/net_scope.cc @@ -654,6 +654,13 @@ netclass_t*NetScope::find_class(perm_string name) if (type_==MODULE) return 0; + if (up_==0 && type_==CLASS) { + assert(class_def_); + + NetScope*def_parent = class_def_->definition_scope(); + return def_parent->find_class(name); + } + // If there is no further to look, ... if (up_ == 0) return 0; diff --git a/netclass.cc b/netclass.cc index f302585d1..9c2d56c29 100644 --- a/netclass.cc +++ b/netclass.cc @@ -24,7 +24,7 @@ using namespace std; netclass_t::netclass_t(perm_string name, netclass_t*sup) -: name_(name), super_(sup), class_scope_(0) +: name_(name), super_(sup), class_scope_(0), definition_scope_(0) { } @@ -56,6 +56,12 @@ void netclass_t::set_class_scope(NetScope*class_scope) class_scope_ = class_scope; } +void netclass_t::set_definition_scope(NetScope*definition_scope) +{ + assert(definition_scope_ == 0); + definition_scope_ = definition_scope; +} + ivl_variable_type_t netclass_t::base_type() const { return IVL_VT_CLASS; diff --git a/netclass.h b/netclass.h index da7fb3e96..8679fa4f9 100644 --- a/netclass.h +++ b/netclass.h @@ -43,9 +43,19 @@ class netclass_t : public ivl_type_s { bool set_property(perm_string pname, property_qualifier_t qual, ivl_type_s*ptype); // Set the scope for the class. The scope has no parents and - // is used for the elaboration of methods (tasks/functions). + // is used for the elaboration of methods + // (tasks/functions). In other words, this is the class itself. void set_class_scope(NetScope*cscope); + // Set the scope for the class definition. This is the scope + // where the class definition was encountered, and may be used + // to locate symbols that the class definition may inherit + // from its context. This can be nil, or a package or module + // where a class is defined. + void set_definition_scope(NetScope*dscope); + + NetScope*definition_scope(void); + // As an ivl_type_s object, the netclass is always an // ivl_VT_CLASS object. ivl_variable_type_t base_type() const; @@ -115,6 +125,14 @@ class netclass_t : public ivl_type_s { // This holds task/function definitions for methods. NetScope*class_scope_; + + // This holds the context for the class type definition. + NetScope*definition_scope_; }; +inline NetScope*netclass_t::definition_scope(void) +{ + return definition_scope_; +} + #endif /* IVL_netclass_H */