Do not allow to create objects of virtual classes

It is not allowed to create objects of virtual classes. Currently the
virtual keyword is accepted by the parser, but otherwise ignored.

Keep track of whether a class is virtual and generate an error when the
class new operator is used for a virtual type.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2022-09-19 20:23:02 +02:00
parent 2a15489e9d
commit e0ec2ed386
7 changed files with 22 additions and 3 deletions

View File

@ -6652,6 +6652,14 @@ NetExpr* PENewClass::elaborate_expr(Design*des, NetScope*scope,
return 0;
}
if (ctype->is_virtual()) {
cerr << get_fileline() << ": error: "
<< "Can not create object of virtual class `"
<< ctype->get_name() << "`." << endl;
des->errors++;
return 0;
}
NetExpr*obj = new NetENew(ntype);
obj->set_line(*this);

View File

@ -493,6 +493,7 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
class_scope->set_class_def(use_class);
use_class->set_class_scope(class_scope);
use_class->set_definition_scope(scope);
use_class->set_virtual(use_type->virtual_class);
set_scope_timescale(des, class_scope, pclass);
class_scope->add_typedefs(&pclass->typedefs);

View File

@ -116,6 +116,9 @@ class netclass_t : public ivl_type_s {
const NetExpr* get_parameter(Design *des, perm_string name,
ivl_type_t &par_type) const;
void set_virtual(bool virtual_class) { virtual_class_ = virtual_class; }
bool is_virtual() const { return virtual_class_; }
private:
perm_string name_;
// If this is derived from another base class, point to it
@ -137,6 +140,8 @@ class netclass_t : public ivl_type_s {
// This holds the context for the class type definition.
NetScope*definition_scope_;
bool virtual_class_;
};
inline NetScope*netclass_t::definition_scope(void)

View File

@ -797,7 +797,7 @@ class_declaration /* IEEE1800-2005: A.1.2 */
class_type_t *class_type= new class_type_t(name);
FILE_NAME(class_type, @4);
pform_set_typedef(@4, name, class_type, nullptr);
pform_start_class_declaration(@2, class_type, $5.type, $5.exprs, $3);
pform_start_class_declaration(@2, class_type, $5.type, $5.exprs, $3, $1);
}
class_items_opt K_endclass
{ // Process a class.

View File

@ -173,7 +173,8 @@ extern void pform_start_class_declaration(const struct vlltype&loc,
class_type_t*type,
data_type_t*base_type,
std::list<PExpr*>*base_exprs,
LexicalScope::lifetime_t lifetime);
LexicalScope::lifetime_t lifetime,
bool virtual_class);
extern void pform_class_property(const struct vlltype&loc,
property_qualifier_t pq,
data_type_t*data_type,

View File

@ -43,7 +43,8 @@ void pform_start_class_declaration(const struct vlltype&loc,
class_type_t*type,
data_type_t*base_type,
list<PExpr*>*base_exprs,
LexicalScope::lifetime_t lifetime)
LexicalScope::lifetime_t lifetime,
bool virtual_class)
{
PClass*class_scope = pform_push_class_scope(loc, type->name, lifetime);
class_scope->type = type;
@ -52,6 +53,7 @@ void pform_start_class_declaration(const struct vlltype&loc,
assert(type->base_type == 0);
type->base_type.reset(base_type);
type->virtual_class = virtual_class;
assert(type->base_args.empty());
if (base_exprs) {

View File

@ -379,6 +379,8 @@ struct class_type_t : public data_type_t {
std::unique_ptr<data_type_t> base_type;
std::list<PExpr*>base_args;
bool virtual_class;
// This is a map of the properties. Map the name to the type.
struct prop_info_t : public LineInfo {
inline prop_info_t() : qual(property_qualifier_t::make_none()) { }