Merge pull request #861 from larsclausen/scoped-symbol-search
Add common implementation for scoped symbol search
This commit is contained in:
commit
b6644186a6
28
PExpr.cc
28
PExpr.cc
|
|
@ -221,12 +221,12 @@ PEBShift::~PEBShift()
|
|||
}
|
||||
|
||||
PECallFunction::PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms)
|
||||
: package_(0), path_(n), parms_(parms), is_overridden_(false)
|
||||
: path_(n), parms_(parms), is_overridden_(false)
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(PPackage*pkg, const pform_name_t&n, const vector<PExpr *> &parms)
|
||||
: package_(pkg), path_(n), parms_(parms), is_overridden_(false)
|
||||
: path_(pkg, n), parms_(parms), is_overridden_(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -239,7 +239,7 @@ static pform_name_t pn_from_ps(perm_string n)
|
|||
}
|
||||
|
||||
PECallFunction::PECallFunction(PPackage*pkg, const pform_name_t &n, const list<PExpr *> &parms)
|
||||
: package_(pkg), path_(n), parms_(parms.size()), is_overridden_(false)
|
||||
: path_(pkg, n), parms_(parms.size()), is_overridden_(false)
|
||||
{
|
||||
int tmp_idx = 0;
|
||||
assert(parms_.size() == parms.size());
|
||||
|
|
@ -249,18 +249,18 @@ PECallFunction::PECallFunction(PPackage*pkg, const pform_name_t&n, const list<PE
|
|||
}
|
||||
|
||||
PECallFunction::PECallFunction(perm_string n, const vector<PExpr*>&parms)
|
||||
: package_(0), path_(pn_from_ps(n)), parms_(parms), is_overridden_(false)
|
||||
: path_(pn_from_ps(n)), parms_(parms), is_overridden_(false)
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(perm_string n)
|
||||
: package_(0), path_(pn_from_ps(n)), is_overridden_(false)
|
||||
: path_(pn_from_ps(n)), is_overridden_(false)
|
||||
{
|
||||
}
|
||||
|
||||
// NOTE: Anachronism. Try to work all use of svector out.
|
||||
PECallFunction::PECallFunction(const pform_name_t&n, const list<PExpr *> &parms)
|
||||
: package_(0), path_(n), parms_(parms.size()), is_overridden_(false)
|
||||
: path_(n), parms_(parms.size()), is_overridden_(false)
|
||||
{
|
||||
int tmp_idx = 0;
|
||||
assert(parms_.size() == parms.size());
|
||||
|
|
@ -270,7 +270,7 @@ PECallFunction::PECallFunction(const pform_name_t&n, const list<PExpr *> &parms)
|
|||
}
|
||||
|
||||
PECallFunction::PECallFunction(perm_string n, const list<PExpr*>&parms)
|
||||
: package_(0), path_(pn_from_ps(n)), parms_(parms.size()), is_overridden_(false)
|
||||
: path_(pn_from_ps(n)), parms_(parms.size()), is_overridden_(false)
|
||||
{
|
||||
int tmp_idx = 0;
|
||||
assert(parms_.size() == parms.size());
|
||||
|
|
@ -387,18 +387,18 @@ const verireal& PEFNumber::value() const
|
|||
}
|
||||
|
||||
PEIdent::PEIdent(const pform_name_t&that)
|
||||
: package_(0), path_(that), no_implicit_sig_(false)
|
||||
: path_(that), no_implicit_sig_(false)
|
||||
{
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(perm_string s, bool no_implicit_sig)
|
||||
: package_(0), no_implicit_sig_(no_implicit_sig)
|
||||
: no_implicit_sig_(no_implicit_sig)
|
||||
{
|
||||
path_.push_back(name_component_t(s));
|
||||
path_.name.push_back(name_component_t(s));
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(PPackage*pkg, const pform_name_t&that)
|
||||
: package_(pkg), path_(that), no_implicit_sig_(true)
|
||||
: path_(pkg, that), no_implicit_sig_(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -427,8 +427,10 @@ void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
|||
- this is not an implicit named port connection */
|
||||
if (no_implicit_sig_)
|
||||
return;
|
||||
if ((path_.size() == 1) && (path_.front().index.size() == 0)) {
|
||||
perm_string name = path_.front().name;
|
||||
if (path_.package)
|
||||
return;
|
||||
if (path_.name.size() == 1 && path_.name.front().index.empty()) {
|
||||
perm_string name = path_.name.front().name;
|
||||
LexicalScope*ss = scope;
|
||||
while (ss) {
|
||||
if (ss->wires.find(name) != ss->wires.end())
|
||||
|
|
|
|||
10
PExpr.h
10
PExpr.h
|
|
@ -366,13 +366,10 @@ class PEIdent : public PExpr {
|
|||
virtual bool is_collapsible_net(Design*des, NetScope*scope,
|
||||
NetNet::PortType port_type) const;
|
||||
|
||||
const PPackage* package() const { return package_; }
|
||||
|
||||
const pform_name_t& path() const { return path_; }
|
||||
const pform_scoped_name_t& path() const { return path_; }
|
||||
|
||||
private:
|
||||
PPackage*package_;
|
||||
pform_name_t path_;
|
||||
pform_scoped_name_t path_;
|
||||
bool no_implicit_sig_;
|
||||
|
||||
private:
|
||||
|
|
@ -912,8 +909,7 @@ class PECallFunction : public PExpr {
|
|||
width_mode_t&mode);
|
||||
|
||||
private:
|
||||
PPackage*package_;
|
||||
pform_name_t path_;
|
||||
pform_scoped_name_t path_;
|
||||
std::vector<PExpr *> parms_;
|
||||
|
||||
// For system functions.
|
||||
|
|
|
|||
|
|
@ -419,7 +419,7 @@ PReturn::~PReturn()
|
|||
}
|
||||
|
||||
PTrigger::PTrigger(PPackage*pkg, const pform_name_t&ev)
|
||||
: package_(pkg), event_(ev)
|
||||
: event_(pkg, ev)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -600,8 +600,7 @@ class PTrigger : public Statement {
|
|||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
PPackage*package_;
|
||||
pform_name_t event_;
|
||||
pform_scoped_name_t event_;
|
||||
};
|
||||
|
||||
class PNBTrigger : public Statement {
|
||||
|
|
|
|||
67
elab_expr.cc
67
elab_expr.cc
|
|
@ -54,11 +54,10 @@ bool type_is_vectorable(ivl_variable_type_t type)
|
|||
}
|
||||
}
|
||||
|
||||
static ivl_nature_t find_access_function(const pform_name_t&path)
|
||||
static ivl_nature_t find_access_function(const pform_scoped_name_t &path)
|
||||
{
|
||||
if (path.size() != 1)
|
||||
return 0;
|
||||
else
|
||||
if (path.package || path.name.size() != 1)
|
||||
return nullptr;
|
||||
return access_function_nature[peek_tail_name(path)];
|
||||
}
|
||||
|
||||
|
|
@ -1531,15 +1530,9 @@ unsigned PECallFunction::test_width(Design*des, NetScope*scope,
|
|||
if (peek_tail_name(path_)[0] == '$')
|
||||
return test_width_sfunc_(des, scope, mode);
|
||||
|
||||
NetScope *use_scope = scope;
|
||||
if (package_) {
|
||||
use_scope = des->find_package(package_->pscope_name());
|
||||
ivl_assert(*this, use_scope);
|
||||
}
|
||||
|
||||
// Search for the symbol. This should turn up a scope.
|
||||
symbol_search_results search_results;
|
||||
bool search_flag = symbol_search(this, des, use_scope, path_, &search_results);
|
||||
bool search_flag = symbol_search(this, des, scope, path_, &search_results);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PECallFunction::test_width: "
|
||||
|
|
@ -1905,7 +1898,7 @@ NetExpr* PECallFunction::elaborate_access_func_(Design*des, NetScope*scope,
|
|||
PEIdent*arg_ident = dynamic_cast<PEIdent*> (arg1);
|
||||
ivl_assert(*this, arg_ident);
|
||||
|
||||
const pform_name_t&path = arg_ident->path();
|
||||
const pform_name_t&path = arg_ident->path().name;
|
||||
ivl_assert(*this, path.size()==1);
|
||||
perm_string name = peek_tail_name(path);
|
||||
|
||||
|
|
@ -1953,7 +1946,7 @@ NetExpr* PECallFunction::elaborate_access_func_(Design*des, NetScope*scope,
|
|||
static NetExpr* check_for_enum_methods(const LineInfo*li,
|
||||
Design*des, NetScope*scope,
|
||||
const netenum_t*netenum,
|
||||
const pform_name_t&use_path,
|
||||
const pform_scoped_name_t&use_path,
|
||||
perm_string method_name,
|
||||
NetExpr*expr,
|
||||
PExpr*parg, unsigned args)
|
||||
|
|
@ -2634,10 +2627,6 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
|
|||
<< "path_: " << path_ << endl;
|
||||
cerr << get_fileline() << ": PECallFunction::elaborate_expr: "
|
||||
<< "expr_wid: " << expr_wid << endl;
|
||||
if (package_)
|
||||
cerr << get_fileline() << ": PECallFunction::elaborate_expr: "
|
||||
<< "package_: " << package_->pscope_name()
|
||||
<< " at " << package_->get_fileline() << endl;
|
||||
}
|
||||
|
||||
if (peek_tail_name(path_)[0] == '$')
|
||||
|
|
@ -2655,15 +2644,9 @@ NetExpr* PECallFunction::elaborate_expr_(Design*des, NetScope*scope,
|
|||
{
|
||||
flags &= ~SYS_TASK_ARG; // don't propagate the SYS_TASK_ARG flag
|
||||
|
||||
NetScope *use_scope = scope;
|
||||
if (package_) {
|
||||
use_scope = des->find_package(package_->pscope_name());
|
||||
ivl_assert(*this, use_scope);
|
||||
}
|
||||
|
||||
// Search for the symbol. This should turn up a scope.
|
||||
symbol_search_results search_results;
|
||||
bool search_flag = symbol_search(this, des, use_scope, path_, &search_results);
|
||||
bool search_flag = symbol_search(this, des, scope, path_, &search_results);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PECallFunction::elaborate_expr: "
|
||||
|
|
@ -4004,7 +3987,7 @@ unsigned PEIdent::test_width_method_(const symbol_search_results &sr)
|
|||
if (path_.size() < 2)
|
||||
return 0;
|
||||
|
||||
pform_name_t use_path = path_;
|
||||
pform_name_t use_path = path_.name;
|
||||
perm_string member_name = peek_tail_name(path_);
|
||||
use_path.pop_back();
|
||||
|
||||
|
|
@ -4093,14 +4076,8 @@ unsigned PEIdent::test_width_parameter_(const NetExpr *par, width_mode_t&mode)
|
|||
|
||||
unsigned PEIdent::test_width(Design*des, NetScope*scope, width_mode_t&mode)
|
||||
{
|
||||
NetScope*use_scope = scope;
|
||||
if (package_) {
|
||||
use_scope = des->find_package(package_->pscope_name());
|
||||
ivl_assert(*this, use_scope);
|
||||
}
|
||||
|
||||
symbol_search_results sr;
|
||||
symbol_search(this, des, use_scope, path_, &sr);
|
||||
symbol_search(this, des, scope, path_, &sr);
|
||||
|
||||
if (unsigned tmp = test_width_method_(sr)) {
|
||||
return tmp;
|
||||
|
|
@ -4329,18 +4306,12 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
{
|
||||
bool need_const = NEED_CONST & flags;
|
||||
|
||||
NetScope*use_scope = scope;
|
||||
if (package_) {
|
||||
use_scope = des->find_package(package_->pscope_name());
|
||||
ivl_assert(*this, use_scope);
|
||||
}
|
||||
|
||||
symbol_search_results sr;
|
||||
symbol_search(this, des, use_scope, path_, &sr);
|
||||
symbol_search(this, des, scope, path_, &sr);
|
||||
|
||||
if (!sr.net) {
|
||||
cerr << get_fileline() << ": error: Unable to bind variable `"
|
||||
<< path_ << "' in `" << scope_path(use_scope) << "'" << endl;
|
||||
<< path_ << "' in `" << scope_path(scope) << "'" << endl;
|
||||
des->errors++;
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -4516,21 +4487,13 @@ NetExpr* PEIdent::elaborate_expr_(Design*des, NetScope*scope,
|
|||
scope->is_const_func(false);
|
||||
}
|
||||
|
||||
// If this identifier is pulled from a package, then switch
|
||||
// the scope we are using.
|
||||
NetScope*use_scope = scope;
|
||||
if (package_) {
|
||||
use_scope = des->find_package(package_->pscope_name());
|
||||
ivl_assert(*this, use_scope);
|
||||
}
|
||||
|
||||
// Find the net/parameter/event object that this name refers
|
||||
// to. The path_ may be a scoped path, and may include method
|
||||
// or member name parts. For example, main.a.b.c may refer to
|
||||
// a net called "b" in the scope "main.a" and with a member
|
||||
// named "c". symbol_search() handles this for us.
|
||||
symbol_search_results sr;
|
||||
symbol_search(this, des, use_scope, path_, &sr);
|
||||
symbol_search(this, des, scope, path_, &sr);
|
||||
|
||||
// If the identifier name is a parameter name, then return
|
||||
// the parameter value.
|
||||
|
|
@ -4888,7 +4851,7 @@ NetExpr* PEIdent::elaborate_expr_(Design*des, NetScope*scope,
|
|||
}
|
||||
}
|
||||
|
||||
list<hname_t> spath = eval_scope_path(des, scope, path_);
|
||||
list<hname_t> spath = eval_scope_path(des, scope, path_.name);
|
||||
|
||||
ivl_assert(*this, spath.size() == path_.size());
|
||||
|
||||
|
|
@ -6285,8 +6248,8 @@ NetExpr* PEIdent::elaborate_expr_net(Design*des, NetScope*scope,
|
|||
node->set_line(*this);
|
||||
|
||||
index_component_t::ctype_t use_sel = index_component_t::SEL_NONE;
|
||||
if (! path_.back().index.empty())
|
||||
use_sel = path_.back().index.back().sel;
|
||||
if (! path_.name.back().index.empty())
|
||||
use_sel = path_.name.back().index.back().sel;
|
||||
|
||||
if (net->get_scalar() && use_sel != index_component_t::SEL_NONE) {
|
||||
cerr << get_fileline() << ": error: can not select part of ";
|
||||
|
|
|
|||
23
elab_lval.cc
23
elab_lval.cc
|
|
@ -165,17 +165,8 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
|||
<< "Elaborate l-value ident expression: " << *this << endl;
|
||||
}
|
||||
|
||||
/* Normally find the name in the passed scope. But if this is
|
||||
imported from a package, then located the variable from the
|
||||
package scope. */
|
||||
NetScope*use_scope = scope;
|
||||
if (package_) {
|
||||
use_scope = des->find_package(package_->pscope_name());
|
||||
ivl_assert(*this, use_scope);
|
||||
}
|
||||
|
||||
symbol_search_results sr;
|
||||
symbol_search(this, des, use_scope, path_, &sr);
|
||||
symbol_search(this, des, scope, path_, &sr);
|
||||
|
||||
NetNet *reg = sr.net;
|
||||
pform_name_t &member_path = sr.path_tail;
|
||||
|
|
@ -183,16 +174,16 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
|||
/* The l-value must be a variable. If not, then give up and
|
||||
print a useful error message. */
|
||||
if (reg == 0) {
|
||||
if (use_scope->type()==NetScope::FUNC
|
||||
&& use_scope->func_def()->is_void()
|
||||
&& use_scope->basename()==peek_tail_name(path_)) {
|
||||
if (scope->type()==NetScope::FUNC
|
||||
&& scope->func_def()->is_void()
|
||||
&& scope->basename()==peek_tail_name(path_)) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Cannot assign to " << path_
|
||||
<< " because function " << scope_path(use_scope)
|
||||
<< " because function " << scope_path(scope)
|
||||
<< " is void." << endl;
|
||||
} else {
|
||||
cerr << get_fileline() << ": error: Could not find variable ``"
|
||||
<< path_ << "'' in ``" << scope_path(use_scope) <<
|
||||
<< path_ << "'' in ``" << scope_path(scope) <<
|
||||
"''" << endl;
|
||||
}
|
||||
des->errors += 1;
|
||||
|
|
@ -1153,7 +1144,7 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
|
|||
// indices we may need to apply. This is to handle the case
|
||||
// that the base is an array of structs, and not just a
|
||||
// struct.
|
||||
pform_name_t::const_reverse_iterator name_idx = path_.rbegin();
|
||||
pform_name_t::const_reverse_iterator name_idx = path_.name.rbegin();
|
||||
for (size_t idx = 1 ; idx < member_path.size() ; idx += 1)
|
||||
++ name_idx;
|
||||
if (name_idx->name != peek_head_name(member_path)) {
|
||||
|
|
|
|||
16
elab_net.cc
16
elab_net.cc
|
|
@ -515,7 +515,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
const NetExpr*par = 0;
|
||||
NetEvent* eve = 0;
|
||||
|
||||
symbol_search(this, des, scope, path_, sig, par, eve);
|
||||
symbol_search(this, des, scope, path_.name, sig, par, eve);
|
||||
|
||||
if (eve != 0) {
|
||||
cerr << get_fileline() << ": error: named events (" << path_
|
||||
|
|
@ -525,7 +525,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
|||
return 0;
|
||||
}
|
||||
|
||||
pform_name_t base_path = path_;
|
||||
pform_name_t base_path = path_.name;
|
||||
pform_name_t member_path;
|
||||
while (sig == 0 && !base_path.empty()) {
|
||||
symbol_search(this, des, scope, base_path, sig, par, eve);
|
||||
|
|
@ -984,7 +984,7 @@ NetNet* PEIdent::elaborate_bi_net(Design*des, NetScope*scope) const
|
|||
NetNet* PEIdent::elaborate_subport(Design*des, NetScope*scope) const
|
||||
{
|
||||
ivl_assert(*this, scope->type() == NetScope::MODULE);
|
||||
NetNet*sig = des->find_signal(scope, path_);
|
||||
NetNet*sig = des->find_signal(scope, path_.name);
|
||||
if (sig == 0) {
|
||||
cerr << get_fileline() << ": error: no wire/reg " << path_
|
||||
<< " in module " << scope_path(scope) << "." << endl;
|
||||
|
|
@ -1118,14 +1118,8 @@ NetNet* PEIdent::elaborate_subport(Design*des, NetScope*scope) const
|
|||
|
||||
NetNet*PEIdent::elaborate_unpacked_net(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetScope *use_scope = scope;
|
||||
if (package_) {
|
||||
use_scope = des->find_package(package_->pscope_name());
|
||||
ivl_assert(*this, use_scope);
|
||||
}
|
||||
|
||||
symbol_search_results sr;
|
||||
symbol_search(this, des, use_scope, path_, &sr);
|
||||
symbol_search(this, des, scope, path_, &sr);
|
||||
if (!sr.net) {
|
||||
cerr << get_fileline() << ": error: Net " << path_
|
||||
<< " is not defined in this context." << endl;
|
||||
|
|
@ -1153,7 +1147,7 @@ bool PEIdent::is_collapsible_net(Design*des, NetScope*scope,
|
|||
const NetExpr*par = 0;
|
||||
NetEvent* eve = 0;
|
||||
|
||||
symbol_search(this, des, scope, path_, sig, par, eve);
|
||||
symbol_search(this, des, scope, path_.name, sig, par, eve);
|
||||
|
||||
if (eve != 0)
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
|||
// wires within the scope.
|
||||
map<perm_string,PWire*>::const_iterator wt;
|
||||
for (unsigned cc = 0 ; cc < pp->expr.size() ; cc += 1) {
|
||||
pform_name_t port_path (pp->expr[cc]->path());
|
||||
pform_name_t port_path (pp->expr[cc]->path().name);
|
||||
// A concatenated wire of a port really should not
|
||||
// have any hierarchy.
|
||||
if (port_path.size() != 1) {
|
||||
|
|
|
|||
45
elaborate.cc
45
elaborate.cc
|
|
@ -1410,7 +1410,7 @@ void PGModule::elaborate_mod_(Design*des, Module*rmod, NetScope*scope) const
|
|||
vector<PEIdent*> mport = rmod->get_port(idx);
|
||||
if (mport.empty()) continue;
|
||||
|
||||
perm_string pname = peek_tail_name(mport[0]->path());
|
||||
perm_string pname = peek_tail_name(mport[0]->path().name);
|
||||
|
||||
NetNet*tmp = instance[0]->find_signal(pname);
|
||||
|
||||
|
|
@ -4856,22 +4856,11 @@ cerr << endl;
|
|||
skip the rest of the expression handling. */
|
||||
|
||||
if (PEIdent*id = dynamic_cast<PEIdent*>(expr_[idx]->expr())) {
|
||||
NetNet* sig = 0;
|
||||
const NetExpr*par = 0;
|
||||
NetEvent* eve = 0;
|
||||
symbol_search_results sr;
|
||||
symbol_search(this, des, scope, id->path(), &sr);
|
||||
|
||||
NetScope*use_scope = scope;
|
||||
if (id->package()) {
|
||||
use_scope = des->find_package(id->package()->pscope_name());
|
||||
ivl_assert(*this, use_scope);
|
||||
}
|
||||
|
||||
NetScope*found_in = symbol_search(this, des, use_scope,
|
||||
id->path(),
|
||||
sig, par, eve);
|
||||
|
||||
if (found_in && eve) {
|
||||
wa->add_event(eve);
|
||||
if (sr.scope && sr.eve) {
|
||||
wa->add_event(sr.eve);
|
||||
/* You can not look for the posedge or negedge of
|
||||
* an event. */
|
||||
if (expr_[idx]->type() != PEEvent::ANYEDGE) {
|
||||
|
|
@ -4888,7 +4877,7 @@ cerr << endl;
|
|||
assert(0);
|
||||
}
|
||||
cerr << " can not be used with a named event ("
|
||||
<< eve->name() << ")." << endl;
|
||||
<< sr.eve->name() << ")." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
continue;
|
||||
|
|
@ -5577,7 +5566,7 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
|
|||
// If there is an initialization assignment, make the expression,
|
||||
// and later the initial assignment to the condition variable. The
|
||||
// statement in the for loop is very specifically an assignment.
|
||||
sig = des->find_signal(scope, id1->path());
|
||||
sig = des->find_signal(scope, id1->path().name);
|
||||
if (sig == 0) {
|
||||
cerr << id1->get_fileline() << ": register ``" << id1->path()
|
||||
<< "'' unknown in " << scope_path(scope) << "." << endl;
|
||||
|
|
@ -5957,34 +5946,22 @@ NetProc* PTrigger::elaborate(Design*des, NetScope*scope) const
|
|||
{
|
||||
assert(scope);
|
||||
|
||||
NetScope*use_scope = scope;
|
||||
if (package_) {
|
||||
use_scope = des->find_package(package_->pscope_name());
|
||||
ivl_assert(*this, use_scope);
|
||||
}
|
||||
|
||||
NetNet* sig = 0;
|
||||
const NetExpr*par = 0;
|
||||
NetEvent* eve = 0;
|
||||
|
||||
NetScope*found_in = symbol_search(this, des, use_scope, event_,
|
||||
sig, par, eve);
|
||||
|
||||
if (found_in == 0) {
|
||||
symbol_search_results sr;
|
||||
if (!symbol_search(this, des, scope, event_, &sr)) {
|
||||
cerr << get_fileline() << ": error: event <" << event_ << ">"
|
||||
<< " not found." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (eve == 0) {
|
||||
if (!sr.eve) {
|
||||
cerr << get_fileline() << ": error: <" << event_ << ">"
|
||||
<< " is not a named event." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEvTrig*trig = new NetEvTrig(eve);
|
||||
NetEvTrig*trig = new NetEvTrig(sr.eve);
|
||||
trig->set_line(*this);
|
||||
return trig;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
// Check that package scoped identifiers lookup does not cross the package
|
||||
// boundary.
|
||||
|
||||
int x;
|
||||
|
||||
package P;
|
||||
endpackage
|
||||
|
||||
module test;
|
||||
initial begin
|
||||
int y;
|
||||
y = P::x; // This should fail. x is visible from within the package,
|
||||
// but can't be accessed through a package scoped identifier.
|
||||
$display("FAILED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
// Check that package scoped identifiers lookup does not cross the package
|
||||
// boundary.
|
||||
|
||||
package P;
|
||||
endpackage
|
||||
|
||||
module test;
|
||||
int x;
|
||||
initial begin
|
||||
int y;
|
||||
y = P::test.x; // This should fail. test.x is visible from within the
|
||||
// package, but it can not be accessed through a package
|
||||
// scoped identifier.
|
||||
$display("FAILED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -711,6 +711,8 @@ sv_ps_function7 normal,-g2009 ivltests
|
|||
sv_ps_function_fail1 CE,-g2009 ivltests
|
||||
sv_ps_function_fail2 CE,-g2009 ivltests
|
||||
sv_ps_function_fail3 CE,-g2009 ivltests
|
||||
sv_ps_hier_fail1 CE,-g2009 ivltests
|
||||
sv_ps_hier_fail2 CE,-g2009 ivltests
|
||||
sv_ps_member_sel1 normal,-g2009 ivltests
|
||||
sv_ps_member_sel2 normal,-g2009 ivltests
|
||||
sv_ps_member_sel3 normal,-g2009 ivltests
|
||||
|
|
|
|||
|
|
@ -107,7 +107,11 @@ static inline bool test_function_return_value(const symbol_search_results&search
|
|||
|
||||
extern bool symbol_search(const LineInfo*li, Design*des, NetScope*scope,
|
||||
pform_name_t path, struct symbol_search_results*res,
|
||||
NetScope*start_scope = 0);
|
||||
NetScope*start_scope = nullptr, bool prefix_scope = false);
|
||||
|
||||
extern bool symbol_search(const LineInfo *li, Design *des, NetScope *scope,
|
||||
const pform_scoped_name_t &path,
|
||||
struct symbol_search_results*res);
|
||||
|
||||
/*
|
||||
* Search for a symbol using the "start" scope as the starting
|
||||
|
|
|
|||
|
|
@ -123,6 +123,16 @@ ostream& operator<< (ostream&o, const pform_name_t&that)
|
|||
return o;
|
||||
}
|
||||
|
||||
ostream& operator<< (ostream &o, const pform_scoped_name_t &that)
|
||||
{
|
||||
if (that.package) {
|
||||
o << that.package->pscope_name() << "::";
|
||||
}
|
||||
|
||||
o << that.name;
|
||||
return o;
|
||||
}
|
||||
|
||||
std::ostream& operator << (std::ostream&out, ivl_process_type_t pt)
|
||||
{
|
||||
switch (pt) {
|
||||
|
|
@ -405,8 +415,6 @@ void PEConcat::dump(ostream&out) const
|
|||
|
||||
void PECallFunction::dump(ostream &out) const
|
||||
{
|
||||
if (package_) out << package_->pscope_name() << "::";
|
||||
|
||||
out << path_ << "(";
|
||||
|
||||
if (! parms_.empty()) {
|
||||
|
|
@ -509,8 +517,6 @@ void PENumber::dump(ostream&out) const
|
|||
|
||||
void PEIdent::dump(ostream&out) const
|
||||
{
|
||||
if (package_)
|
||||
out << package_->pscope_name() << "::";
|
||||
out << path_;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ class NetScope;
|
|||
class Definitions;
|
||||
class PExpr;
|
||||
class PScope;
|
||||
class PPackage;
|
||||
class PWire;
|
||||
class Statement;
|
||||
class netclass_t;
|
||||
|
|
@ -441,6 +442,18 @@ ivl_type_t elaborate_array_type(Design *des, NetScope *scope,
|
|||
*/
|
||||
typedef std::list<name_component_t> pform_name_t;
|
||||
|
||||
struct pform_scoped_name_t {
|
||||
pform_scoped_name_t() = default;
|
||||
pform_scoped_name_t(PPackage *p, const pform_name_t &n) : package(p),
|
||||
name(n) {}
|
||||
pform_scoped_name_t(const pform_name_t &n) : name(n) {}
|
||||
|
||||
const name_component_t& back() const { return name.back(); }
|
||||
size_t size() const { return name.size(); }
|
||||
|
||||
PPackage *package = nullptr;
|
||||
pform_name_t name;
|
||||
};
|
||||
|
||||
inline perm_string peek_head_name(const pform_name_t&that)
|
||||
{
|
||||
|
|
@ -452,6 +465,16 @@ inline perm_string peek_tail_name(const pform_name_t&that)
|
|||
return that.back().name;
|
||||
}
|
||||
|
||||
inline perm_string peek_head_name(const pform_scoped_name_t &that)
|
||||
{
|
||||
return peek_head_name(that.name);
|
||||
}
|
||||
|
||||
inline perm_string peek_tail_name(const pform_scoped_name_t &that)
|
||||
{
|
||||
return peek_tail_name(that.name);
|
||||
}
|
||||
|
||||
/*
|
||||
* In pform names, the "super" and "this" keywords are converted to
|
||||
* These tokens so that they don't interfere with the namespace and
|
||||
|
|
@ -466,6 +489,7 @@ static inline std::ostream& operator<< (std::ostream&out, const data_type_t&that
|
|||
}
|
||||
|
||||
extern std::ostream& operator<< (std::ostream&out, const pform_name_t&);
|
||||
extern std::ostream& operator<< (std::ostream&out, const pform_scoped_name_t&);
|
||||
extern std::ostream& operator<< (std::ostream&out, const name_component_t&that);
|
||||
extern std::ostream& operator<< (std::ostream&out, const index_component_t&that);
|
||||
extern std::ostream& operator<< (std::ostream&out, enum typedef_t::basic_type bt);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
# include "netparray.h"
|
||||
# include "netmisc.h"
|
||||
# include "compiler.h"
|
||||
# include "PPackage.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
using namespace std;
|
||||
|
|
@ -38,10 +39,9 @@ using namespace std;
|
|||
|
||||
bool symbol_search(const LineInfo*li, Design*des, NetScope*scope,
|
||||
pform_name_t path, struct symbol_search_results*res,
|
||||
NetScope*start_scope)
|
||||
NetScope*start_scope, bool prefix_scope)
|
||||
{
|
||||
assert(scope);
|
||||
bool prefix_scope = false;
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << li->get_fileline() << ": symbol_search: "
|
||||
|
|
@ -68,7 +68,8 @@ bool symbol_search(const LineInfo*li, Design*des, NetScope*scope,
|
|||
// recursively. Ideally, the result is a scope that we search
|
||||
// for the tail key, but there are other special cases as well.
|
||||
if (! path.empty()) {
|
||||
bool flag = symbol_search(li, des, scope, path, res, start_scope);
|
||||
bool flag = symbol_search(li, des, scope, path, res, start_scope,
|
||||
prefix_scope);
|
||||
if (! flag)
|
||||
return false;
|
||||
|
||||
|
|
@ -308,6 +309,24 @@ bool symbol_search(const LineInfo*li, Design*des, NetScope*scope,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool symbol_search(const LineInfo *li, Design *des, NetScope *scope,
|
||||
const pform_scoped_name_t &path,
|
||||
struct symbol_search_results *res)
|
||||
{
|
||||
NetScope *search_scope = scope;
|
||||
bool prefix_scope = false;
|
||||
|
||||
if (path.package) {
|
||||
search_scope = des->find_package(path.package->pscope_name());
|
||||
if (!search_scope)
|
||||
return false;
|
||||
prefix_scope = true;
|
||||
}
|
||||
|
||||
return symbol_search(li, des, search_scope, path.name, res, search_scope,
|
||||
prefix_scope);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compatibility version. Remove me!
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue