Merge pull request #1366 from larsclausen/sv2023-type-param-restrictions

Add support for restricted type parameters
This commit is contained in:
Cary R. 2026-05-16 17:44:12 -07:00 committed by GitHub
commit 8229ce1b49
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
43 changed files with 664 additions and 61 deletions

View File

@ -1,7 +1,7 @@
#ifndef IVL_PScope_H
#define IVL_PScope_H
/*
* Copyright (c) 2008-2025 Stephen Williams (steve@icarus.com)
* Copyright (c) 2008-2026 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -121,6 +121,8 @@ class LexicalScope {
bool overridable;
// Whether the parameter is a type parameter
bool type_flag = false;
// Type restriction for a type parameter
type_restrict_t type_restrict;
// The lexical position of the declaration
unsigned lexical_pos = 0;

View File

@ -452,27 +452,7 @@ ivl_type_t typedef_t::elaborate_type(Design *des, NetScope *scope)
if (!elab_type)
return netvector_t::integer_type();
bool type_ok = true;
switch (basic_type) {
case ENUM:
type_ok = dynamic_cast<const netenum_t *>(elab_type);
break;
case STRUCT: {
const netstruct_t *struct_type = dynamic_cast<const netstruct_t *>(elab_type);
type_ok = struct_type && !struct_type->union_flag();
break;
}
case UNION: {
const netstruct_t *struct_type = dynamic_cast<const netstruct_t *>(elab_type);
type_ok = struct_type && struct_type->union_flag();
break;
}
case CLASS:
type_ok = dynamic_cast<const netclass_t *>(elab_type);
break;
default:
break;
}
bool type_ok = basic_type.matches(elab_type);
if (!type_ok) {
cerr << data_type->get_fileline() << " error: "

View File

@ -0,0 +1,35 @@
// Check that restricted class type parameter defaults are supported.
class C0;
bit [7:0] value;
endclass
module M #(
parameter type class T = C0
);
T x;
endmodule
module test;
`define check(val, exp) \
if (val !== exp) begin \
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \
failed = 1'b1; \
end
bit failed = 1'b0;
M i_m();
initial begin
i_m.x = new;
`check($bits(i_m.x.value), 8)
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -0,0 +1,41 @@
// Check that restricted class type parameter overrides are supported.
class C0;
bit [7:0] value;
endclass
class C1;
bit [15:0] value;
endclass
module M #(
parameter type class T = C0
);
T x;
endmodule
module test;
`define check(val, exp) \
if (val !== exp) begin \
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \
failed = 1'b1; \
end
bit failed = 1'b0;
M #(
.T(C1)
) i_m();
initial begin
i_m.x = new;
`check($bits(i_m.x.value), 16)
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -0,0 +1,11 @@
// Check that a class restricted type parameter rejects non-class defaults.
module test #(
parameter type class T = int
);
initial begin
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,21 @@
// Check that a class restricted type parameter rejects non-class overrides.
class class_t;
endclass
module M #(
parameter type class T = class_t
);
endmodule
module test;
M #(
.T(int)
) i_m();
initial begin
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,33 @@
// Check that restricted enum type parameter defaults are supported.
typedef enum bit [2:0] {
A0, B0
} T0;
module M #(
parameter type enum T = T0
);
T x;
endmodule
module test;
`define check(val, exp) \
if (val !== exp) begin \
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \
failed = 1'b1; \
end
bit failed = 1'b0;
M i_m();
initial begin
`check($bits(i_m.x), $bits(T0))
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -0,0 +1,39 @@
// Check that restricted enum type parameter overrides are supported.
typedef enum bit [2:0] {
A0, B0
} T0;
typedef enum bit [3:0] {
A1, B1
} T1;
module M #(
parameter type enum T = T0
);
T x;
endmodule
module test;
`define check(val, exp) \
if (val !== exp) begin \
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \
failed = 1'b1; \
end
bit failed = 1'b0;
M #(
.T(T1)
) i_m();
initial begin
`check($bits(i_m.x), $bits(T1))
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -0,0 +1,11 @@
// Check that an enum restricted type parameter rejects non-enum defaults.
module test #(
parameter type enum T = int
);
initial begin
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,22 @@
// Check that an enum restricted type parameter rejects non-enum overrides.
typedef enum bit {
ENUM_VALUE
} enum_t;
module M #(
parameter type enum T = enum_t
);
endmodule
module test;
M #(
.T(int)
) i_m();
initial begin
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,33 @@
// Check that restricted struct type parameter defaults are supported.
typedef struct packed {
logic [3:0] x;
} T0;
module M #(
parameter type struct T = T0
);
T x;
endmodule
module test;
`define check(val, exp) \
if (val !== exp) begin \
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \
failed = 1'b1; \
end
bit failed = 1'b0;
M i_m();
initial begin
`check($bits(i_m.x), $bits(T0))
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -0,0 +1,39 @@
// Check that restricted struct type parameter overrides are supported.
typedef struct packed {
logic [3:0] x;
} T0;
typedef struct packed {
logic [7:0] x;
} T1;
module M #(
parameter type struct T = T0
);
T x;
endmodule
module test;
`define check(val, exp) \
if (val !== exp) begin \
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \
failed = 1'b1; \
end
bit failed = 1'b0;
M #(
.T(T1)
) i_m();
initial begin
`check($bits(i_m.x), $bits(T1))
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -0,0 +1,16 @@
// Check that a struct restricted type parameter rejects non-struct defaults.
typedef union packed {
logic [3:0] value;
logic [3:0] other;
} union_t;
module test #(
parameter type struct T = union_t
);
initial begin
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,27 @@
// Check that a struct restricted type parameter rejects non-struct overrides.
typedef struct packed {
logic [3:0] value;
} struct_t;
typedef union packed {
logic [3:0] value;
logic [3:0] other;
} union_t;
module M #(
parameter type struct T = struct_t
);
endmodule
module test;
M #(
.T(union_t)
) i_m();
initial begin
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,34 @@
// Check that restricted union type parameter defaults are supported.
typedef union packed {
logic [3:0] x;
logic [3:0] y;
} T0;
module M #(
parameter type union T = T0
);
T x;
endmodule
module test;
`define check(val, exp) \
if (val !== exp) begin \
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \
failed = 1'b1; \
end
bit failed = 1'b0;
M i_m();
initial begin
`check($bits(i_m.x), $bits(T0))
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -0,0 +1,41 @@
// Check that restricted union type parameter overrides are supported.
typedef union packed {
logic [3:0] x;
logic [3:0] y;
} T0;
typedef union packed {
logic [7:0] x;
logic [7:0] y;
} T1;
module M #(
parameter type union T = T0
);
T x;
endmodule
module test;
`define check(val, exp) \
if (val !== exp) begin \
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \
failed = 1'b1; \
end
bit failed = 1'b0;
M #(
.T(T1)
) i_m();
initial begin
`check($bits(i_m.x), $bits(T1))
if (!failed) begin
$display("PASSED");
end
end
endmodule

View File

@ -0,0 +1,15 @@
// Check that a union restricted type parameter rejects non-union defaults.
typedef struct packed {
logic [3:0] value;
} struct_t;
module test #(
parameter type union T = struct_t
);
initial begin
$display("FAILED");
end
endmodule

View File

@ -0,0 +1,27 @@
// Check that a union restricted type parameter rejects non-union overrides.
typedef struct packed {
logic [3:0] value;
} struct_t;
typedef union packed {
logic [3:0] value;
logic [3:0] other;
} union_t;
module M #(
parameter type union T = union_t
);
endmodule
module test;
M #(
.T(struct_t)
) i_m();
initial begin
$display("FAILED");
end
endmodule

View File

@ -342,6 +342,22 @@ sv_queue_assign_op vvp_tests/sv_queue_assign_op.json
sv_soft_packed_union vvp_tests/sv_soft_packed_union.json
sv_soft_packed_union_fail1 vvp_tests/sv_soft_packed_union_fail1.json
sv_super_member_fail vvp_tests/sv_super_member_fail.json
sv_type_param_restrict_class1 vvp_tests/sv_type_param_restrict_class1.json
sv_type_param_restrict_class2 vvp_tests/sv_type_param_restrict_class2.json
sv_type_param_restrict_class_fail1 vvp_tests/sv_type_param_restrict_class_fail1.json
sv_type_param_restrict_class_fail2 vvp_tests/sv_type_param_restrict_class_fail2.json
sv_type_param_restrict_enum1 vvp_tests/sv_type_param_restrict_enum1.json
sv_type_param_restrict_enum2 vvp_tests/sv_type_param_restrict_enum2.json
sv_type_param_restrict_enum_fail1 vvp_tests/sv_type_param_restrict_enum_fail1.json
sv_type_param_restrict_enum_fail2 vvp_tests/sv_type_param_restrict_enum_fail2.json
sv_type_param_restrict_struct1 vvp_tests/sv_type_param_restrict_struct1.json
sv_type_param_restrict_struct2 vvp_tests/sv_type_param_restrict_struct2.json
sv_type_param_restrict_struct_fail1 vvp_tests/sv_type_param_restrict_struct_fail1.json
sv_type_param_restrict_struct_fail2 vvp_tests/sv_type_param_restrict_struct_fail2.json
sv_type_param_restrict_union1 vvp_tests/sv_type_param_restrict_union1.json
sv_type_param_restrict_union2 vvp_tests/sv_type_param_restrict_union2.json
sv_type_param_restrict_union_fail1 vvp_tests/sv_type_param_restrict_union_fail1.json
sv_type_param_restrict_union_fail2 vvp_tests/sv_type_param_restrict_union_fail2.json
sv_wildcard_import8 vvp_tests/sv_wildcard_import8.json
sdf_header vvp_tests/sdf_header.json
task_return1 vvp_tests/task_return1.json

View File

@ -0,0 +1,9 @@
{
"type" : "normal",
"source" : "sv_type_param_restrict_class1.v",
"iverilog-args" : [ "-g2023" ],
"vlog95" : {
"__comment" : "Classes are not supported",
"type" : "CE"
}
}

View File

@ -0,0 +1,9 @@
{
"type" : "normal",
"source" : "sv_type_param_restrict_class2.v",
"iverilog-args" : [ "-g2023" ],
"vlog95" : {
"__comment" : "Classes are not supported",
"type" : "CE"
}
}

View File

@ -0,0 +1,5 @@
{
"type" : "CE",
"source" : "sv_type_param_restrict_class_fail1.v",
"iverilog-args" : [ "-g2023" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "CE",
"source" : "sv_type_param_restrict_class_fail2.v",
"iverilog-args" : [ "-g2023" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "sv_type_param_restrict_enum1.v",
"iverilog-args" : [ "-g2023" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "sv_type_param_restrict_enum2.v",
"iverilog-args" : [ "-g2023" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "CE",
"source" : "sv_type_param_restrict_enum_fail1.v",
"iverilog-args" : [ "-g2023" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "CE",
"source" : "sv_type_param_restrict_enum_fail2.v",
"iverilog-args" : [ "-g2023" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "sv_type_param_restrict_struct1.v",
"iverilog-args" : [ "-g2023" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "sv_type_param_restrict_struct2.v",
"iverilog-args" : [ "-g2023" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "CE",
"source" : "sv_type_param_restrict_struct_fail1.v",
"iverilog-args" : [ "-g2023" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "CE",
"source" : "sv_type_param_restrict_struct_fail2.v",
"iverilog-args" : [ "-g2023" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "sv_type_param_restrict_union1.v",
"iverilog-args" : [ "-g2023" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "sv_type_param_restrict_union2.v",
"iverilog-args" : [ "-g2023" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "CE",
"source" : "sv_type_param_restrict_union_fail1.v",
"iverilog-args" : [ "-g2023" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "CE",
"source" : "sv_type_param_restrict_union_fail2.v",
"iverilog-args" : [ "-g2023" ]
}

View File

@ -838,6 +838,16 @@ void NetScope::evaluate_type_parameter_(Design *des, param_ref_t cur)
data_type_t *ptype = type_expr->get_type();
NetScope *type_scope = cur->second.val_scope;
cur->second.ivl_type = ptype->elaborate_type(des, type_scope);
if (!cur->second.ivl_type)
return;
if (!cur->second.type_restrict.matches(cur->second.ivl_type)) {
cerr << type_expr->get_fileline() << ": error: "
<< "Type parameter `" << cur->first << "` expects a `"
<< cur->second.type_restrict << "` type, got `"
<< *cur->second.ivl_type << "`." << endl;
des->errors++;
}
}
void NetScope::evaluate_parameter_(Design*des, param_ref_t cur)

View File

@ -281,6 +281,7 @@ void NetScope::set_parameter(perm_string key, bool is_annotatable,
ref.local_flag = param.local_flag;
ref.overridable = param.overridable;
ref.type_flag = param.type_flag;
ref.type_restrict = param.type_restrict;
ref.lexical_pos = param.lexical_pos;
ivl_assert(param, !ref.range);
ref.range = range_list;

View File

@ -1279,6 +1279,8 @@ class NetScope : public Definitions, public Attrib {
bool overridable = false;
// Is it a type parameter
bool type_flag = false;
// Type restriction for a type parameter
type_restrict_t type_restrict;
// The lexical position of the declaration
unsigned lexical_pos = 0;
// range constraints

43
parse.y
View File

@ -45,6 +45,7 @@ extern void lex_end_table();
static data_type_t* param_data_type = 0;
static bool param_is_local = false;
static bool param_is_type = false;
static type_restrict_t param_type_restrict;
static bool in_gen_region = false;
static std::list<pform_range_t>* specparam_active_range = 0;
@ -598,7 +599,7 @@ Module::port_t *module_declare_interface_port(const YYLTYPE&loc, char *type,
LexicalScope::lifetime_t lifetime;
enum typedef_t::basic_type typedef_basic_type;
enum type_restrict_t::type_t type_restrict;
};
%token <text> IDENTIFIER INTERFACE_IDENTIFIER SYSTEM_IDENTIFIER STRING TIME_LITERAL
@ -858,7 +859,7 @@ Module::port_t *module_declare_interface_port(const YYLTYPE&loc, char *type,
%type <letter> compressed_operator
%type <typedef_basic_type> typedef_basic_type
%type <type_restrict> forward_type forward_type_without_enum
%token K_TAND
%nonassoc K_PLUS_EQ K_MINUS_EQ K_MUL_EQ K_DIV_EQ K_MOD_EQ K_AND_EQ K_OR_EQ
@ -2882,11 +2883,16 @@ block_item_decls_opt
* `typedef enum <TYPE_IDENTIFIER>` can either be the start of a enum forward
* declaration or a enum type declaration with a type identifier as its base
* type. And this abmiguity can not be resolved if we reduce the K_enum to
* typedef_basic_type. */
typedef_basic_type
: K_struct { $$ = typedef_t::STRUCT; }
| K_union { $$ = typedef_t::UNION; }
| K_class { $$ = typedef_t::CLASS; }
* forward_type_without_enum. */
forward_type_without_enum
: K_struct { $$ = type_restrict_t::STRUCT; }
| K_union { $$ = type_restrict_t::UNION; }
| K_class { $$ = type_restrict_t::CLASS; }
;
forward_type
: K_enum { $$ = type_restrict_t::ENUM; }
| forward_type_without_enum
;
/* Type declarations are parsed here. The rule actions call pform
@ -2902,17 +2908,17 @@ type_declaration
| K_typedef identifier_name ';'
{ perm_string name = lex_strings.make($2);
pform_forward_typedef(@2, name, typedef_t::ANY);
pform_forward_typedef(@2, name, type_restrict_t::ANY);
delete[]$2;
}
| K_typedef typedef_basic_type identifier_name ';'
| K_typedef forward_type_without_enum identifier_name ';'
{ perm_string name = lex_strings.make($3);
pform_forward_typedef(@3, name, $2);
delete[]$3;
}
| K_typedef K_enum identifier_name ';'
{ perm_string name = lex_strings.make($3);
pform_forward_typedef(@3, name, typedef_t::ENUM);
pform_forward_typedef(@3, name, type_restrict_t::ENUM);
delete[]$3;
}
| K_typedef error ';'
@ -4924,7 +4930,16 @@ module_parameter_port_list_opt
;
type_param
: K_type { param_is_type = true; }
: K_type
{ param_is_type = true;
param_type_restrict = {};
}
| K_type forward_type
{ if (generation_flag < GN_VER2023)
yyerror(@1, "error: Restricted type parameters require SystemVerilog 2023 or later.");
param_is_type = true;
param_type_restrict = $2;
}
;
module_parameter
@ -4940,6 +4955,7 @@ module_parameter_port_list
{ param_data_type = $1;
param_is_local = false;
param_is_type = false;
param_type_restrict = {};
}
parameter_assign
{ pform_requires_sv(@3, "Omitting initial `parameter` in parameter port "
@ -4955,6 +4971,7 @@ module_parameter_port_list
"data type in parameter port list");
param_data_type = $3;
param_is_type = false;
param_type_restrict = {};
}
}
parameter_assign
@ -5598,6 +5615,7 @@ param_type
: data_type_or_implicit
{ param_is_type = false;
param_data_type = $1;
param_type_restrict = {};
}
| type_param
@ -5632,7 +5650,8 @@ parameter_assign_list
parameter_assign
: IDENTIFIER dimensions_opt initializer_opt parameter_value_ranges_opt
{ pform_set_parameter(@1, lex_strings.make($1), param_is_local,
param_is_type, param_data_type, $2, $3, $4);
param_is_type, param_type_restrict,
param_data_type, $2, $3, $4);
delete[]$1;
}
;

View File

@ -841,7 +841,7 @@ static typedef_t *pform_get_typedef(const struct vlltype&loc, perm_string name)
}
void pform_forward_typedef(const struct vlltype&loc, perm_string name,
enum typedef_t::basic_type basic_type)
type_restrict_t basic_type)
{
typedef_t *td = pform_get_typedef(loc, name);
@ -2948,6 +2948,7 @@ static void pform_set_type_parameter(const struct vlltype&loc, perm_string name,
void pform_set_parameter(const struct vlltype&loc,
perm_string name, bool is_local, bool is_type,
type_restrict_t type_restrict,
data_type_t*data_type, const list<pform_range_t>*udims,
PExpr*expr, LexicalScope::range_t*value_range)
{
@ -3020,6 +3021,7 @@ void pform_set_parameter(const struct vlltype&loc,
parm->local_flag = is_local;
parm->overridable = overridable;
parm->type_flag = is_type;
parm->type_restrict = type_restrict;
parm->lexical_pos = loc.lexical_pos;
scope->parameters[name] = parm;

View File

@ -323,7 +323,7 @@ extern void pform_set_typedef(const struct vlltype&loc, perm_string name,
data_type_t*data_type,
std::list<pform_range_t>*unp_ranges = nullptr);
extern void pform_forward_typedef(const struct vlltype&loc, perm_string name,
enum typedef_t::basic_type basic_type);
type_restrict_t basic_type);
extern void pform_set_type_referenced(const struct vlltype&loc, const char*name);
@ -412,6 +412,7 @@ extern LexicalScope::range_t* pform_parameter_value_range(bool exclude_flag,
extern void pform_set_parameter(const struct vlltype&loc,
perm_string name,
bool is_local, bool is_type,
type_restrict_t type_restrict,
data_type_t*data_type, const std::list<pform_range_t>*udims,
PExpr*expr, LexicalScope::range_t*value_range);
extern void pform_set_specparam(const struct vlltype&loc,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007-2019 Stephen Williams (steve@icarus.com)
* Copyright (c) 2007-2026 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -19,6 +19,8 @@
# include "pform_types.h"
# include "netclass.h"
# include "netenum.h"
data_type_t::~data_type_t()
{
@ -55,34 +57,59 @@ bool typedef_t::set_data_type(data_type_t *t)
return true;
}
bool typedef_t::set_basic_type(enum basic_type bt)
bool typedef_t::set_basic_type(type_restrict_t type)
{
if (bt == ANY)
return basic_type.merge(type);
}
bool type_restrict_t::merge(type_restrict_t other)
{
if (other.type == ANY)
return true;
if (basic_type != ANY && bt != basic_type)
if (this->type != ANY && other.type != this->type)
return false;
basic_type = bt;
this->type = other.type;
return true;
}
std::ostream& operator<< (std::ostream&out, enum typedef_t::basic_type bt)
bool type_restrict_t::matches(ivl_type_t ivl_type) const
{
switch (bt) {
case typedef_t::ANY:
switch (this->type) {
case ENUM:
return dynamic_cast<const netenum_t *>(ivl_type);
case STRUCT: {
const netstruct_t *struct_type = dynamic_cast<const netstruct_t *>(ivl_type);
return struct_type && !struct_type->union_flag();
}
case UNION: {
const netstruct_t *struct_type = dynamic_cast<const netstruct_t *>(ivl_type);
return struct_type && struct_type->union_flag();
}
case CLASS:
return dynamic_cast<const netclass_t *>(ivl_type);
default:
return true;
}
}
std::ostream& operator<< (std::ostream&out, const type_restrict_t& type)
{
switch (type.type) {
case type_restrict_t::ANY:
out << "any";
break;
case typedef_t::ENUM:
case type_restrict_t::ENUM:
out << "enum";
break;
case typedef_t::STRUCT:
case type_restrict_t::STRUCT:
out << "struct";
break;
case typedef_t::UNION:
case type_restrict_t::UNION:
out << "union";
break;
case typedef_t::CLASS:
case type_restrict_t::CLASS:
out << "class";
break;
}

View File

@ -49,6 +49,24 @@ class netclass_t;
class netenum_t;
typedef named<PExpr*> named_pexpr_t;
struct type_restrict_t {
enum type_t {
ANY,
ENUM,
STRUCT,
UNION,
CLASS
};
type_restrict_t() = default;
type_restrict_t(type_t kind) : type(kind) { }
bool merge(type_restrict_t other);
bool matches(ivl_type_t type) const;
enum type_t type = ANY;
};
/*
* The pform_ident_t holds the identifier name and its lexical position
* (the lexical_pos supplied by the scanner).
@ -180,26 +198,18 @@ class data_type_t : public PNamedItem {
};
struct typedef_t : public PNamedItem {
explicit typedef_t(perm_string n) : basic_type(ANY), name(n) { };
explicit typedef_t(perm_string n) : name(n) { };
ivl_type_t elaborate_type(Design*des, NetScope*scope);
enum basic_type {
ANY,
ENUM,
STRUCT,
UNION,
CLASS
};
bool set_data_type(data_type_t *t);
const data_type_t *get_data_type() const { return data_type.get(); }
bool set_basic_type(basic_type bt);
enum basic_type get_basic_type() const { return basic_type; }
bool set_basic_type(type_restrict_t type);
type_restrict_t get_basic_type() const { return basic_type; }
protected:
enum basic_type basic_type;
type_restrict_t basic_type;
std::unique_ptr<data_type_t> data_type;
public:
perm_string name;
@ -498,6 +508,6 @@ extern std::ostream& operator<< (std::ostream&out, const pform_name_t&);
extern std::ostream& operator<< (std::ostream&out, const pform_scoped_name_t&);
extern std::ostream& operator<< (std::ostream&out, const name_component_t&that);
extern std::ostream& operator<< (std::ostream&out, const index_component_t&that);
extern std::ostream& operator<< (std::ostream&out, enum typedef_t::basic_type bt);
extern std::ostream& operator<< (std::ostream&out, const type_restrict_t& type);
#endif /* IVL_pform_types_H */