Handle elaboration of class properties referenced within sub-scopes.
This commit is contained in:
parent
15ccd8f4c9
commit
88e951418b
13
elab_expr.cc
13
elab_expr.cc
|
|
@ -3146,6 +3146,10 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
|||
ivl_assert(*this, use_scope);
|
||||
}
|
||||
|
||||
if (NetExpr* tmp = elaborate_expr_class_member_(des, scope, 0, flags)) {
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* NetScope*found_in = */ symbol_search(this, des, use_scope, path_,
|
||||
net, par, eve,
|
||||
ex1, ex2);
|
||||
|
|
@ -3289,7 +3293,7 @@ NetExpr* PEIdent::elaborate_expr_class_member_(Design*des, NetScope*scope,
|
|||
if (path_.size() != 1)
|
||||
return 0;
|
||||
|
||||
const netclass_t*class_type = scope->parent()->class_def();
|
||||
const netclass_t*class_type = find_class_containing_scope(*this, scope);
|
||||
if (class_type == 0)
|
||||
return 0;
|
||||
|
||||
|
|
@ -3298,10 +3302,13 @@ NetExpr* PEIdent::elaborate_expr_class_member_(Design*des, NetScope*scope,
|
|||
if (pidx < 0)
|
||||
return 0;
|
||||
|
||||
NetNet*this_net = scope->find_signal(perm_string::literal("@"));
|
||||
NetScope*scope_method = find_method_containing_scope(*this, scope);
|
||||
ivl_assert(*this, scope_method);
|
||||
|
||||
NetNet*this_net = scope_method->find_signal(perm_string::literal("@"));
|
||||
if (this_net == 0) {
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Unable to find 'this' port of " << scope_path(scope)
|
||||
<< "Unable to find 'this' port of " << scope_path(scope_method)
|
||||
<< "." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -392,7 +392,7 @@ NetAssign_* PEIdent::elaborate_lval_method_class_member_(Design*des,
|
|||
if (path_.size() != 1)
|
||||
return 0;
|
||||
|
||||
const netclass_t*class_type = scope->parent()->class_def();
|
||||
const netclass_t*class_type = find_class_containing_scope(*this, scope);
|
||||
if (class_type == 0)
|
||||
return 0;
|
||||
|
||||
|
|
@ -403,10 +403,13 @@ NetAssign_* PEIdent::elaborate_lval_method_class_member_(Design*des,
|
|||
if (pidx < 0)
|
||||
return 0;
|
||||
|
||||
NetNet*this_net = scope->find_signal(perm_string::literal("@"));
|
||||
NetScope*scope_method = find_method_containing_scope(*this, scope);
|
||||
ivl_assert(*this, scope_method);
|
||||
|
||||
NetNet*this_net = scope_method->find_signal(perm_string::literal("@"));
|
||||
if (this_net == 0) {
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Unable to find 'this' port of " << scope_path(scope)
|
||||
<< "Unable to find 'this' port of " << scope_path(scope_method)
|
||||
<< "." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
11
elaborate.cc
11
elaborate.cc
|
|
@ -4607,17 +4607,10 @@ NetForce* PForce::elaborate(Design*des, NetScope*scope) const
|
|||
|
||||
static void find_property_in_class(const LineInfo&loc, const NetScope*scope, perm_string name, const netclass_t*&found_in, int&property)
|
||||
{
|
||||
// Search up for the containing class.
|
||||
while (scope && scope->type() != NetScope::CLASS)
|
||||
scope = scope->parent();
|
||||
|
||||
found_in = 0;
|
||||
found_in = find_class_containing_scope(loc, scope);
|
||||
property = -1;
|
||||
|
||||
if (scope==0) return;
|
||||
|
||||
found_in = scope->class_def();
|
||||
ivl_assert(loc, found_in);
|
||||
if (found_in==0) return;
|
||||
|
||||
property = found_in->property_idx_from_name(name);
|
||||
if (property < 0) {
|
||||
|
|
|
|||
33
netmisc.cc
33
netmisc.cc
|
|
@ -1496,3 +1496,36 @@ NetPartSelect* detect_partselect_lval(Link&pin)
|
|||
|
||||
return found_ps;
|
||||
}
|
||||
|
||||
const netclass_t* find_class_containing_scope(const LineInfo&loc, const NetScope*scope)
|
||||
{
|
||||
while (scope && scope->type() != NetScope::CLASS)
|
||||
scope = scope->parent();
|
||||
|
||||
if (scope == 0)
|
||||
return 0;
|
||||
|
||||
const netclass_t*found_in = scope->class_def();
|
||||
ivl_assert(loc, found_in);
|
||||
return found_in;
|
||||
}
|
||||
/*
|
||||
* Find the scope that contains this scope, that is the method for a
|
||||
* class scope. Look for the scope whose PARENT is the scope for a
|
||||
* class. This is going to be a method.
|
||||
*/
|
||||
NetScope* find_method_containing_scope(const LineInfo&, NetScope*scope)
|
||||
{
|
||||
NetScope*up = scope->parent();
|
||||
|
||||
while (up && up->type() != NetScope::CLASS) {
|
||||
scope = up;
|
||||
up = up->parent();
|
||||
}
|
||||
|
||||
if (up == 0) return 0;
|
||||
|
||||
// Should I check if this scope is a TASK or FUNC?
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -309,6 +309,13 @@ extern hname_t eval_path_component(Design*des, NetScope*scope,
|
|||
const name_component_t&comp,
|
||||
bool&error_flag);
|
||||
|
||||
/*
|
||||
* If this scope is contained within a class scope (i.e. a method of a
|
||||
* class) then return the class definition that contains it.
|
||||
*/
|
||||
extern const netclass_t*find_class_containing_scope(const LineInfo&loc,const NetScope*scope);
|
||||
extern NetScope* find_method_containing_scope(const LineInfo&log, NetScope*scope);
|
||||
|
||||
/*
|
||||
* Return true if the data type is a type that is normally available
|
||||
* in vector for. IVL_VT_BOOL and IVL_VT_LOGIC are vectorable,
|
||||
|
|
|
|||
|
|
@ -651,6 +651,11 @@ void dll_target::expr_ufunc(const NetEUFunc*net)
|
|||
FILE_NAME(expr, net);
|
||||
|
||||
expr->u_.ufunc_.def = lookup_scope_(net->func());
|
||||
if (expr->u_.ufunc_.def == 0) {
|
||||
cerr << net->get_fileline() << ": internal error: "
|
||||
<< "dll_target::expr_ufunc: "
|
||||
<< "Unable to match scope " << scope_path(net->func()) << endl;
|
||||
}
|
||||
ivl_assert(*net, expr->u_.ufunc_.def);
|
||||
ivl_assert(*net, expr->u_.ufunc_.def->type_ == IVL_SCT_FUNCTION);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue