Elaborate class properties during signal phase instead of scope phase

Elaborating uses a multi stage approach. Currently non-static class
properties are elaborated during the scope elaboration phase. This can
cause problems if the type of a property is declared in a different scope.
In that case it is possible that the scope in which the type is defined has
not been elaborated yet and the type is not available. E.g.

```
package P;
  typedef int T;
endpackage

class C;
  P::T x;
endclass
```

Another area where this is problematic is when a class has a property of a
another class that has a forward declaration. In this case the type of the
forward declared class, which is created when the scope is elaborated, is
not available when the scope of the class that is using it is elaborated.
E.g.

```
typedef class B;

class A;
  B b;
endclass

class B;
endclass
```

To avoid this elaborate the properties during the signal elaboration phase.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2022-09-21 10:04:45 +02:00
parent 3509cc86f8
commit b4b591adba
2 changed files with 16 additions and 24 deletions

View File

@ -513,29 +513,6 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
}
elaborate_scope_enumerations(des, class_scope, pclass->enum_sets);
// Collect the properties, elaborate them, and add them to the
// elaborated class definition.
for (map<perm_string, class_type_t::prop_info_t>::iterator cur = use_type->properties.begin()
; cur != use_type->properties.end() ; ++ cur) {
ivl_type_t tmp = cur->second.type->elaborate_type(des, class_scope);
ivl_assert(*pclass, tmp);
if (debug_scopes) {
cerr << pclass->get_fileline() << ": elaborate_scope_class: "
<< " Property " << cur->first
<< " type=" << *tmp << endl;
}
if (dynamic_cast<const netqueue_t *> (tmp)) {
cerr << cur->second.get_fileline() << ": sorry: "
<< "Queues inside classes are not yet supported." << endl;
des->errors++;
}
use_class->set_property(cur->first, cur->second.qual, tmp);
}
for (map<perm_string,PTask*>::iterator cur = pclass->tasks.begin()
; cur != pclass->tasks.end() ; ++cur) {

View File

@ -374,9 +374,25 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
void netclass_t::elaborate_sig(Design*des, PClass*pclass)
{
// Collect the properties, elaborate them, and add them to the
// elaborated class definition.
for (map<perm_string,struct class_type_t::prop_info_t>::iterator cur = pclass->type->properties.begin()
; cur != pclass->type->properties.end() ; ++ cur) {
ivl_type_t use_type = cur->second.type->elaborate_type(des, class_scope_);
if (debug_scopes) {
cerr << pclass->get_fileline() << ": elaborate_scope_class: "
<< " Property " << cur->first
<< " type=" << *use_type << endl;
}
if (dynamic_cast<const netqueue_t *> (use_type)) {
cerr << cur->second.get_fileline() << ": sorry: "
<< "Queues inside classes are not yet supported." << endl;
des->errors++;
}
set_property(cur->first, cur->second.qual, use_type);
if (! cur->second.qual.test_static())
continue;
@ -388,7 +404,6 @@ void netclass_t::elaborate_sig(Design*des, PClass*pclass)
}
list<netrange_t> nil_list;
ivl_type_t use_type = cur->second.type->elaborate_type(des, class_scope_);
/* NetNet*sig = */ new NetNet(class_scope_, cur->first, NetNet::REG,
nil_list, use_type);
}