Handle elaboration of class properties referenced within sub-scopes.

This commit is contained in:
Stephen Williams 2014-09-06 16:26:08 -07:00
parent 15ccd8f4c9
commit 88e951418b
6 changed files with 63 additions and 15 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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;
}

View File

@ -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,

View File

@ -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);