Repair handling of attributes attached to variables.

(cherry picked from commit 5d05d97eb0)
This commit is contained in:
Stephen Williams 2012-05-09 10:56:52 -07:00
parent c3f25c3c6c
commit 303710fa32
4 changed files with 63 additions and 43 deletions

22
parse.y
View File

@ -66,6 +66,11 @@ static stack<PBlock*> current_block_stack;
* simulation issues. */ * simulation issues. */
static unsigned args_after_notifier; static unsigned args_after_notifier;
/* The rules sometimes push attributes into a global context where
sub-rules may grab them. This makes parser rules a little easier to
write in some cases. */
static list<named_pexpr_t>*attributes_in_context = 0;
/* Later version of bison (including 1.35) will not compile in stack /* Later version of bison (including 1.35) will not compile in stack
extension if the output is compiled with C++ and either the YYSTYPE extension if the output is compiled with C++ and either the YYSTYPE
or YYLTYPE are provided by the source code. However, I can get the or YYLTYPE are provided by the source code. However, I can get the
@ -1806,22 +1811,22 @@ block_item_decl
is implicit in the "integer" of the declaration. */ is implicit in the "integer" of the declaration. */
: K_integer signed_unsigned_opt register_variable_list ';' : K_integer signed_unsigned_opt register_variable_list ';'
{ pform_set_reg_integer($3); { pform_set_reg_integer($3, attributes_in_context);
} }
| K_time register_variable_list ';' | K_time register_variable_list ';'
{ pform_set_reg_time($2); { pform_set_reg_time($2, attributes_in_context);
} }
/* variable declarations. Note that data_type can be 0 if we are /* variable declarations. Note that data_type can be 0 if we are
recovering from an error. */ recovering from an error. */
| data_type register_variable_list ';' | data_type register_variable_list ';'
{ if ($1) pform_set_data_type(@1, $1, $2); { if ($1) pform_set_data_type(@1, $1, $2, attributes_in_context);
} }
| K_reg data_type register_variable_list ';' | K_reg data_type register_variable_list ';'
{ if ($2) pform_set_data_type(@2, $2, $3); { if ($2) pform_set_data_type(@2, $2, $3, attributes_in_context);
} }
| K_event list_of_identifiers ';' | K_event list_of_identifiers ';'
@ -4100,12 +4105,15 @@ module_item
will see the discipline name as an identifier. We match it to the will see the discipline name as an identifier. We match it to the
discipline or type name semantically. */ discipline or type name semantically. */
| DISCIPLINE_IDENTIFIER list_of_identifiers ';' | DISCIPLINE_IDENTIFIER list_of_identifiers ';'
{ pform_attach_discipline(@1, $1, $2); } { pform_attach_discipline(@1, $1, $2); }
/* block_item_decl rule is shared with task blocks and named /* block_item_decl rule is shared with task blocks and named
begin/end. */ begin/end. Careful to pass attributes to the block_item_decl. */
| block_item_decl | attribute_list_opt { attributes_in_context = $1; } block_item_decl
{ delete attributes_in_context;
attributes_in_context = 0;
}
/* */ /* */

View File

@ -1521,7 +1521,8 @@ static void pform_set_net_range(perm_string name,
const list<pform_range_t>*range, const list<pform_range_t>*range,
bool signed_flag, bool signed_flag,
ivl_variable_type_t dt, ivl_variable_type_t dt,
PWSRType rt) PWSRType rt,
std::list<named_pexpr_t>*attr)
{ {
PWire*cur = pform_get_wire_in_scope(name); PWire*cur = pform_get_wire_in_scope(name);
if (cur == 0) { if (cur == 0) {
@ -1541,17 +1542,20 @@ static void pform_set_net_range(perm_string name,
if (dt != IVL_VT_NO_TYPE) if (dt != IVL_VT_NO_TYPE)
cur->set_data_type(dt); cur->set_data_type(dt);
pform_bind_attributes(cur->attributes, attr, true);
} }
void pform_set_net_range(list<perm_string>*names, void pform_set_net_range(list<perm_string>*names,
list<pform_range_t>*range, list<pform_range_t>*range,
bool signed_flag, bool signed_flag,
ivl_variable_type_t dt) ivl_variable_type_t dt,
std::list<named_pexpr_t>*attr)
{ {
for (list<perm_string>::iterator cur = names->begin() for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; ++ cur ) { ; cur != names->end() ; ++ cur ) {
perm_string txt = *cur; perm_string txt = *cur;
pform_set_net_range(txt, range, signed_flag, dt, SR_NET); pform_set_net_range(txt, range, signed_flag, dt, SR_NET, attr);
} }
delete names; delete names;
@ -2036,7 +2040,7 @@ void pform_makewire(const vlltype&li,
pform_makewire(li, txt, type, pt, dt, attr); pform_makewire(li, txt, type, pt, dt, attr);
/* This has already been done for real variables. */ /* This has already been done for real variables. */
if (dt != IVL_VT_REAL) { if (dt != IVL_VT_REAL) {
pform_set_net_range(txt, range, signed_flag, dt, rt); pform_set_net_range(txt, range, signed_flag, dt, rt, 0);
} }
} }
@ -2066,7 +2070,7 @@ void pform_makewire(const vlltype&li,
/* This has already been done for real variables. */ /* This has already been done for real variables. */
if (dt != IVL_VT_REAL) { if (dt != IVL_VT_REAL) {
pform_set_net_range(first->name, range, signed_flag, dt, pform_set_net_range(first->name, range, signed_flag, dt,
SR_NET); SR_NET, 0);
} }
PWire*cur = pform_get_wire_in_scope(first->name); PWire*cur = pform_get_wire_in_scope(first->name);
@ -2534,14 +2538,14 @@ void pform_set_port_type(const struct vlltype&li,
perm_string txt = *cur; perm_string txt = *cur;
pform_set_port_type(txt, pt, li.text, li.first_line); pform_set_port_type(txt, pt, li.text, li.first_line);
pform_set_net_range(txt, range, signed_flag, IVL_VT_NO_TYPE, pform_set_net_range(txt, range, signed_flag, IVL_VT_NO_TYPE,
SR_PORT); SR_PORT, 0);
} }
delete names; delete names;
delete range; delete range;
} }
static void pform_set_reg_integer(perm_string name) static void pform_set_reg_integer(perm_string name, list<named_pexpr_t>*attr)
{ {
PWire*cur = pform_get_make_wire_in_scope(name, NetNet::INTEGER, NetNet::NOT_A_PORT, IVL_VT_LOGIC); PWire*cur = pform_get_make_wire_in_scope(name, NetNet::INTEGER, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
assert(cur); assert(cur);
@ -2553,19 +2557,21 @@ static void pform_set_reg_integer(perm_string name)
rlist.push_back(rng); rlist.push_back(rng);
cur->set_range(rlist, SR_NET); cur->set_range(rlist, SR_NET);
cur->set_signed(true); cur->set_signed(true);
pform_bind_attributes(cur->attributes, attr, true);
} }
void pform_set_reg_integer(list<perm_string>*names) void pform_set_reg_integer(list<perm_string>*names, list<named_pexpr_t>*attr)
{ {
for (list<perm_string>::iterator cur = names->begin() for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; ++ cur ) { ; cur != names->end() ; ++ cur ) {
perm_string txt = *cur; perm_string txt = *cur;
pform_set_reg_integer(txt); pform_set_reg_integer(txt, attr);
} }
delete names; delete names;
} }
static void pform_set_reg_time(perm_string name) static void pform_set_reg_time(perm_string name, list<named_pexpr_t>*attr)
{ {
PWire*cur = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_LOGIC); PWire*cur = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_LOGIC);
assert(cur); assert(cur);
@ -2576,19 +2582,21 @@ static void pform_set_reg_time(perm_string name)
list<pform_range_t>rlist; list<pform_range_t>rlist;
rlist.push_back(rng); rlist.push_back(rng);
cur->set_range(rlist, SR_NET); cur->set_range(rlist, SR_NET);
pform_bind_attributes(cur->attributes, attr, true);
} }
void pform_set_reg_time(list<perm_string>*names) void pform_set_reg_time(list<perm_string>*names, list<named_pexpr_t>*attr)
{ {
for (list<perm_string>::iterator cur = names->begin() for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; ++ cur ) { ; cur != names->end() ; ++ cur ) {
perm_string txt = *cur; perm_string txt = *cur;
pform_set_reg_time(txt); pform_set_reg_time(txt, attr);
} }
delete names; delete names;
} }
static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_string name) static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_string name, list<named_pexpr_t>*attr)
{ {
PWire*cur = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_BOOL); PWire*cur = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_BOOL);
assert(cur); assert(cur);
@ -2601,14 +2609,15 @@ static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_strin
list<pform_range_t>rlist; list<pform_range_t>rlist;
rlist.push_back(rng); rlist.push_back(rng);
cur->set_range(rlist, SR_NET); cur->set_range(rlist, SR_NET);
pform_bind_attributes(cur->attributes, attr, true);
} }
void pform_set_integer_2atom(uint64_t width, bool signed_flag, list<perm_string>*names) static void pform_set_integer_2atom(uint64_t width, bool signed_flag, list<perm_string>*names, list<named_pexpr_t>*attr)
{ {
for (list<perm_string>::iterator cur = names->begin() for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; ++ cur ) { ; cur != names->end() ; ++ cur ) {
perm_string txt = *cur; perm_string txt = *cur;
pform_set_integer_2atom(width, signed_flag, txt); pform_set_integer_2atom(width, signed_flag, txt, attr);
} }
delete names; delete names;
} }
@ -2617,32 +2626,32 @@ void pform_set_integer_2atom(uint64_t width, bool signed_flag, list<perm_string>
* This function detects the derived class for the given type and * This function detects the derived class for the given type and
* dispatches the type to the proper subtype function. * dispatches the type to the proper subtype function.
*/ */
void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list<perm_string>*names) void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list<perm_string>*names, list<named_pexpr_t>*attr)
{ {
if (atom2_type_t*atom2_type = dynamic_cast<atom2_type_t*> (data_type)) { if (atom2_type_t*atom2_type = dynamic_cast<atom2_type_t*> (data_type)) {
pform_set_integer_2atom(atom2_type->type_code, atom2_type->signed_flag, names); pform_set_integer_2atom(atom2_type->type_code, atom2_type->signed_flag, names, attr);
return; return;
} }
if (struct_type_t*struct_type = dynamic_cast<struct_type_t*> (data_type)) { if (struct_type_t*struct_type = dynamic_cast<struct_type_t*> (data_type)) {
pform_set_struct_type(struct_type, names); pform_set_struct_type(struct_type, names, attr);
return; return;
} }
if (enum_type_t*enum_type = dynamic_cast<enum_type_t*> (data_type)) { if (enum_type_t*enum_type = dynamic_cast<enum_type_t*> (data_type)) {
pform_set_enum(li, enum_type, names); pform_set_enum(li, enum_type, names, attr);
return; return;
} }
if (vector_type_t*vec_type = dynamic_cast<vector_type_t*> (data_type)) { if (vector_type_t*vec_type = dynamic_cast<vector_type_t*> (data_type)) {
pform_set_net_range(names, vec_type->pdims.get(), pform_set_net_range(names, vec_type->pdims.get(),
vec_type->signed_flag, vec_type->signed_flag,
vec_type->base_type); vec_type->base_type, attr);
return; return;
} }
if (/*real_type_t*real_type =*/ dynamic_cast<real_type_t*> (data_type)) { if (/*real_type_t*real_type =*/ dynamic_cast<real_type_t*> (data_type)) {
pform_set_net_range(names, 0, true, IVL_VT_REAL); pform_set_net_range(names, 0, true, IVL_VT_REAL, attr);
return; return;
} }
@ -2655,7 +2664,7 @@ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list<pe
} }
static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type,
perm_string name) perm_string name, std::list<named_pexpr_t>*attr)
{ {
(void) li; // The line information is not currently needed. (void) li; // The line information is not currently needed.
PWire*cur = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, enum_type->base_type); PWire*cur = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, enum_type->base_type);
@ -2667,9 +2676,10 @@ static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type,
assert(enum_type->range->size() == 1); assert(enum_type->range->size() == 1);
cur->set_range(*enum_type->range, SR_NET); cur->set_range(*enum_type->range, SR_NET);
cur->set_enumeration(enum_type); cur->set_enumeration(enum_type);
pform_bind_attributes(cur->attributes, attr, true);
} }
void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list<perm_string>*names) void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list<perm_string>*names, std::list<named_pexpr_t>*attr)
{ {
// By definition, the base type can only be IVL_VT_LOGIC or // By definition, the base type can only be IVL_VT_LOGIC or
// IVL_VT_BOOL. // IVL_VT_BOOL.
@ -2689,7 +2699,7 @@ void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list<perm_st
for (list<perm_string>::iterator cur = names->begin() for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; ++ cur) { ; cur != names->end() ; ++ cur) {
perm_string txt = *cur; perm_string txt = *cur;
pform_set_enum(li, enum_type, txt); pform_set_enum(li, enum_type, txt, attr);
} }
delete names; delete names;

15
pform.h
View File

@ -292,18 +292,19 @@ extern void pform_set_port_type(const struct vlltype&li,
extern void pform_set_net_range(list<perm_string>*names, extern void pform_set_net_range(list<perm_string>*names,
list<pform_range_t>*, list<pform_range_t>*,
bool signed_flag, bool signed_flag,
ivl_variable_type_t); ivl_variable_type_t,
std::list<named_pexpr_t>*attr);
extern void pform_set_reg_idx(perm_string name, PExpr*l, PExpr*r); extern void pform_set_reg_idx(perm_string name, PExpr*l, PExpr*r);
extern void pform_set_reg_integer(list<perm_string>*names); extern void pform_set_reg_integer(list<perm_string>*names, list<named_pexpr_t>*attr);
extern void pform_set_reg_time(list<perm_string>*names); extern void pform_set_reg_time(list<perm_string>*names, list<named_pexpr_t>*attr);
extern void pform_set_integer_2atom(uint64_t width, bool signed_flag, list<perm_string>*names); //XXXXextern void pform_set_integer_2atom(uint64_t width, bool signed_flag, list<perm_string>*names);
extern void pform_set_data_type(const struct vlltype&li, data_type_t*, list<perm_string>*names); extern void pform_set_data_type(const struct vlltype&li, data_type_t*, list<perm_string>*names, list<named_pexpr_t>*attr);
extern void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list<perm_string>*names); extern void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list<perm_string>*names, std::list<named_pexpr_t>*attr);
extern void pform_set_struct_type(struct_type_t*struct_type, list<perm_string>*names); extern void pform_set_struct_type(struct_type_t*struct_type, std::list<perm_string>*names, std::list<named_pexpr_t>*attr);
/* pform_set_attrib and pform_set_type_attrib exist to support the /* pform_set_attrib and pform_set_type_attrib exist to support the
$attribute syntax, which can only set string values to $attribute syntax, which can only set string values to

View File

@ -48,18 +48,19 @@ static ivl_variable_type_t figure_struct_base_type(struct_type_t*struct_type)
* out the base type of the packed variable. Elaboration, later on, * out the base type of the packed variable. Elaboration, later on,
* well figure out the rest. * well figure out the rest.
*/ */
static void pform_set_packed_struct(struct_type_t*struct_type, perm_string name) static void pform_set_packed_struct(struct_type_t*struct_type, perm_string name, list<named_pexpr_t>*attr)
{ {
ivl_variable_type_t base_type = figure_struct_base_type(struct_type); ivl_variable_type_t base_type = figure_struct_base_type(struct_type);
PWire*net = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, base_type); PWire*net = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, base_type);
net->set_struct_type(struct_type); net->set_struct_type(struct_type);
pform_bind_attributes(net->attributes, attr, true);
} }
static void pform_set_struct_type(struct_type_t*struct_type, perm_string name) static void pform_set_struct_type(struct_type_t*struct_type, perm_string name, list<named_pexpr_t>*attr)
{ {
if (struct_type->packed_flag) { if (struct_type->packed_flag) {
pform_set_packed_struct(struct_type, name); pform_set_packed_struct(struct_type, name, attr);
return; return;
} }
@ -67,11 +68,11 @@ static void pform_set_struct_type(struct_type_t*struct_type, perm_string name)
ivl_assert(*struct_type, 0); ivl_assert(*struct_type, 0);
} }
void pform_set_struct_type(struct_type_t*struct_type, list<perm_string>*names) void pform_set_struct_type(struct_type_t*struct_type, list<perm_string>*names, list<named_pexpr_t>*attr)
{ {
for (list<perm_string>::iterator cur = names->begin() for (list<perm_string>::iterator cur = names->begin()
; cur != names->end() ; ++ cur) { ; cur != names->end() ; ++ cur) {
pform_set_struct_type(struct_type, *cur); pform_set_struct_type(struct_type, *cur, attr);
} }
} }