Add support for implict this in class methods
This commit is contained in:
parent
d16a9dcfc6
commit
d85096c56a
3
PExpr.h
3
PExpr.h
|
|
@ -936,7 +936,8 @@ class PECallFunction : public PExpr {
|
|||
NetExpr*elaborate_expr_pkg_(Design*des, NetScope*scope,
|
||||
unsigned expr_wid, unsigned flags)const;
|
||||
NetExpr*elaborate_expr_method_(Design*des, NetScope*scope,
|
||||
unsigned expr_wid) const;
|
||||
unsigned expr_wid,
|
||||
bool add_this_flag = false) const;
|
||||
#if 0
|
||||
NetExpr*elaborate_expr_string_method_(Design*des, NetScope*scope) const;
|
||||
NetExpr*elaborate_expr_enum_method_(Design*des, NetScope*scope,
|
||||
|
|
|
|||
|
|
@ -224,7 +224,8 @@ class PCallTask : public Statement {
|
|||
NetProc* elaborate_sys(Design*des, NetScope*scope) const;
|
||||
NetProc* elaborate_usr(Design*des, NetScope*scope) const;
|
||||
|
||||
NetProc*elaborate_method_(Design*des, NetScope*scope) const;
|
||||
NetProc*elaborate_method_(Design*des, NetScope*scope,
|
||||
bool add_this_flag = false) const;
|
||||
NetProc*elaborate_function_(Design*des, NetScope*scope) const;
|
||||
|
||||
NetProc*elaborate_build_call_(Design*des, NetScope*scope,
|
||||
|
|
|
|||
28
elab_expr.cc
28
elab_expr.cc
|
|
@ -2064,11 +2064,24 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope,
|
|||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
ivl_assert(*this, def);
|
||||
|
||||
ivl_assert(*this, def);
|
||||
NetScope*dscope = def->scope();
|
||||
ivl_assert(*this, dscope);
|
||||
|
||||
/* In SystemVerilog a method calling another method in the
|
||||
* current class needs to be elaborated as a method with an
|
||||
* implicit this added. */
|
||||
if (gn_system_verilog() && (path_.size() == 1)) {
|
||||
const NetScope *c_scope = scope->get_class_scope();
|
||||
if (c_scope && (c_scope == dscope->get_class_scope())) {
|
||||
NetExpr*tmp = elaborate_expr_method_(des, scope, expr_wid,
|
||||
true);
|
||||
assert(tmp);
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
bool need_const = NEED_CONST & flags;
|
||||
|
||||
// It is possible to get here before the called function has been
|
||||
|
|
@ -2262,17 +2275,22 @@ unsigned PECallFunction::elaborate_arguments_(Design*des, NetScope*scope,
|
|||
}
|
||||
|
||||
NetExpr* PECallFunction::elaborate_expr_method_(Design*des, NetScope*scope,
|
||||
unsigned expr_wid) const
|
||||
unsigned expr_wid,
|
||||
bool add_this_flag) const
|
||||
{
|
||||
pform_name_t use_path = path_;
|
||||
perm_string method_name = peek_tail_name(use_path);
|
||||
use_path.pop_back();
|
||||
|
||||
/* Add the implicit this reference when requested. */
|
||||
if (add_this_flag) {
|
||||
assert(use_path.empty());
|
||||
use_path.push_front(name_component_t(perm_string::literal("@")));
|
||||
}
|
||||
|
||||
// If there is no object to the left of the method name, then
|
||||
// give up on the idea of looking for an object method.
|
||||
if (use_path.empty()) {
|
||||
return 0;
|
||||
}
|
||||
if (use_path.empty()) return 0;
|
||||
|
||||
NetNet *net = 0;
|
||||
const NetExpr *par;
|
||||
|
|
|
|||
20
elaborate.cc
20
elaborate.cc
|
|
@ -3439,6 +3439,17 @@ NetProc* PCallTask::elaborate_usr(Design*des, NetScope*scope) const
|
|||
}
|
||||
assert(def);
|
||||
|
||||
/* In SystemVerilog a method calling another method in the
|
||||
* current class needs to be elaborated as a method with an
|
||||
* implicit this added. */
|
||||
if (gn_system_verilog() && (path_.size() == 1)) {
|
||||
const NetScope *c_scope = scope->get_class_scope();
|
||||
if (c_scope && (c_scope == task->get_class_scope())) {
|
||||
NetProc *tmp = elaborate_method_(des, scope, true);
|
||||
assert(tmp);
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned parm_count = def->port_count();
|
||||
|
||||
|
|
@ -3490,7 +3501,8 @@ NetProc* PCallTask::elaborate_sys_task_method_(Design*des, NetScope*scope,
|
|||
return sys;
|
||||
}
|
||||
|
||||
NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope) const
|
||||
NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
|
||||
bool add_this_flag) const
|
||||
{
|
||||
pform_name_t use_path = path_;
|
||||
perm_string method_name = peek_tail_name(use_path);
|
||||
|
|
@ -3501,6 +3513,12 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope) const
|
|||
NetEvent *eve;
|
||||
const NetExpr *ex1, *ex2;
|
||||
|
||||
/* Add the implicit this reference when requested. */
|
||||
if (add_this_flag) {
|
||||
assert(use_path.empty());
|
||||
use_path.push_front(name_component_t(perm_string::literal("@")));
|
||||
}
|
||||
|
||||
// There is no signal to search for so this cannot be a method.
|
||||
if (use_path.empty()) return 0;
|
||||
|
||||
|
|
|
|||
26
net_scope.cc
26
net_scope.cc
|
|
@ -691,6 +691,32 @@ const NetScope* NetScope::child(const hname_t&name) const
|
|||
return cur->second;
|
||||
}
|
||||
|
||||
/* Helper function to see if the given scope is defined in a class and if
|
||||
* so return the class scope. */
|
||||
const NetScope* NetScope::get_class_scope() const
|
||||
{
|
||||
const NetScope*scope = this;
|
||||
while (scope) {
|
||||
switch(scope->type()) {
|
||||
case NetScope::CLASS:
|
||||
return scope;
|
||||
case NetScope::TASK:
|
||||
case NetScope::FUNC:
|
||||
case NetScope::BEGIN_END:
|
||||
case NetScope::FORK_JOIN:
|
||||
break;
|
||||
case NetScope::MODULE:
|
||||
case NetScope::GENBLOCK:
|
||||
case NetScope::PACKAGE:
|
||||
return 0;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
scope = scope->parent();
|
||||
}
|
||||
return scope;
|
||||
}
|
||||
|
||||
const NetScope* NetScope::child_byname(perm_string name) const
|
||||
{
|
||||
hname_t hname (name);
|
||||
|
|
|
|||
|
|
@ -995,6 +995,9 @@ class NetScope : public Definitions, public Attrib {
|
|||
const NetScope* parent() const { return up_; }
|
||||
const NetScope* child(const hname_t&name) const;
|
||||
|
||||
/* A helper function to find the enclosing class scope. */
|
||||
const NetScope* get_class_scope() const;
|
||||
|
||||
// Look for a child scope by name. This ignores the number
|
||||
// part of the child scope name, so there may be multiple
|
||||
// matches. Only return one. This function is only really
|
||||
|
|
|
|||
Loading…
Reference in New Issue