From 5d05d97eb0c9a6852a4901be2ef6aae3a8129d03 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Wed, 9 May 2012 10:56:52 -0700 Subject: [PATCH] Repair handling of attributes attached to variables. --- parse.y | 22 +++++++++++------ pform.cc | 58 ++++++++++++++++++++++++++------------------ pform.h | 15 ++++++------ pform_struct_type.cc | 11 +++++---- 4 files changed, 63 insertions(+), 43 deletions(-) diff --git a/parse.y b/parse.y index c6a5017a5..5d67e237b 100644 --- a/parse.y +++ b/parse.y @@ -66,6 +66,11 @@ static stack current_block_stack; * simulation issues. */ 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*attributes_in_context = 0; + /* Later version of bison (including 1.35) will not compile in stack 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 @@ -1806,22 +1811,22 @@ block_item_decl is implicit in the "integer" of the declaration. */ : 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 ';' - { 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 recovering from an error. */ | 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 ';' - { 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 ';' @@ -4100,12 +4105,15 @@ module_item will see the discipline name as an identifier. We match it to the discipline or type name semantically. */ | 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 - 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; + } /* */ diff --git a/pform.cc b/pform.cc index 7fb93e9c2..ac8cb2a9b 100644 --- a/pform.cc +++ b/pform.cc @@ -1521,7 +1521,8 @@ static void pform_set_net_range(perm_string name, const list*range, bool signed_flag, ivl_variable_type_t dt, - PWSRType rt) + PWSRType rt, + std::list*attr) { PWire*cur = pform_get_wire_in_scope(name); if (cur == 0) { @@ -1541,17 +1542,20 @@ static void pform_set_net_range(perm_string name, if (dt != IVL_VT_NO_TYPE) cur->set_data_type(dt); + + pform_bind_attributes(cur->attributes, attr, true); } void pform_set_net_range(list*names, list*range, bool signed_flag, - ivl_variable_type_t dt) + ivl_variable_type_t dt, + std::list*attr) { for (list::iterator cur = names->begin() ; cur != names->end() ; ++ 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; @@ -2036,7 +2040,7 @@ void pform_makewire(const vlltype&li, pform_makewire(li, txt, type, pt, dt, attr); /* This has already been done for real variables. */ 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. */ if (dt != IVL_VT_REAL) { pform_set_net_range(first->name, range, signed_flag, dt, - SR_NET); + SR_NET, 0); } 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; pform_set_port_type(txt, pt, li.text, li.first_line); pform_set_net_range(txt, range, signed_flag, IVL_VT_NO_TYPE, - SR_PORT); + SR_PORT, 0); } delete names; delete range; } -static void pform_set_reg_integer(perm_string name) +static void pform_set_reg_integer(perm_string name, list*attr) { PWire*cur = pform_get_make_wire_in_scope(name, NetNet::INTEGER, NetNet::NOT_A_PORT, IVL_VT_LOGIC); assert(cur); @@ -2553,19 +2557,21 @@ static void pform_set_reg_integer(perm_string name) rlist.push_back(rng); cur->set_range(rlist, SR_NET); cur->set_signed(true); + + pform_bind_attributes(cur->attributes, attr, true); } -void pform_set_reg_integer(list*names) +void pform_set_reg_integer(list*names, list*attr) { for (list::iterator cur = names->begin() ; cur != names->end() ; ++ cur ) { perm_string txt = *cur; - pform_set_reg_integer(txt); + pform_set_reg_integer(txt, attr); } delete names; } -static void pform_set_reg_time(perm_string name) +static void pform_set_reg_time(perm_string name, list*attr) { PWire*cur = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_LOGIC); assert(cur); @@ -2576,19 +2582,21 @@ static void pform_set_reg_time(perm_string name) listrlist; rlist.push_back(rng); cur->set_range(rlist, SR_NET); + + pform_bind_attributes(cur->attributes, attr, true); } -void pform_set_reg_time(list*names) +void pform_set_reg_time(list*names, list*attr) { for (list::iterator cur = names->begin() ; cur != names->end() ; ++ cur ) { perm_string txt = *cur; - pform_set_reg_time(txt); + pform_set_reg_time(txt, attr); } 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*attr) { PWire*cur = pform_get_make_wire_in_scope(name, NetNet::REG, NetNet::NOT_A_PORT, IVL_VT_BOOL); assert(cur); @@ -2601,14 +2609,15 @@ static void pform_set_integer_2atom(uint64_t width, bool signed_flag, perm_strin listrlist; rlist.push_back(rng); 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*names) +static void pform_set_integer_2atom(uint64_t width, bool signed_flag, list*names, list*attr) { for (list::iterator cur = names->begin() ; cur != names->end() ; ++ cur ) { perm_string txt = *cur; - pform_set_integer_2atom(width, signed_flag, txt); + pform_set_integer_2atom(width, signed_flag, txt, attr); } delete names; } @@ -2617,32 +2626,32 @@ void pform_set_integer_2atom(uint64_t width, bool signed_flag, list * This function detects the derived class for the given type and * dispatches the type to the proper subtype function. */ -void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list*names) +void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list*names, list*attr) { if (atom2_type_t*atom2_type = dynamic_cast (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; } if (struct_type_t*struct_type = dynamic_cast (data_type)) { - pform_set_struct_type(struct_type, names); + pform_set_struct_type(struct_type, names, attr); return; } if (enum_type_t*enum_type = dynamic_cast (data_type)) { - pform_set_enum(li, enum_type, names); + pform_set_enum(li, enum_type, names, attr); return; } if (vector_type_t*vec_type = dynamic_cast (data_type)) { pform_set_net_range(names, vec_type->pdims.get(), vec_type->signed_flag, - vec_type->base_type); + vec_type->base_type, attr); return; } if (/*real_type_t*real_type =*/ dynamic_cast (data_type)) { - pform_set_net_range(names, 0, true, IVL_VT_REAL); + pform_set_net_range(names, 0, true, IVL_VT_REAL, attr); return; } @@ -2655,7 +2664,7 @@ void pform_set_data_type(const struct vlltype&li, data_type_t*data_type, list*attr) { (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); @@ -2667,9 +2676,10 @@ static void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, assert(enum_type->range->size() == 1); cur->set_range(*enum_type->range, SR_NET); 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*names) +void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list*names, std::list*attr) { // By definition, the base type can only be IVL_VT_LOGIC or // IVL_VT_BOOL. @@ -2689,7 +2699,7 @@ void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list::iterator cur = names->begin() ; cur != names->end() ; ++ cur) { perm_string txt = *cur; - pform_set_enum(li, enum_type, txt); + pform_set_enum(li, enum_type, txt, attr); } delete names; diff --git a/pform.h b/pform.h index be4d744d8..c907c6b95 100644 --- a/pform.h +++ b/pform.h @@ -292,18 +292,19 @@ extern void pform_set_port_type(const struct vlltype&li, extern void pform_set_net_range(list*names, list*, bool signed_flag, - ivl_variable_type_t); + ivl_variable_type_t, + std::list*attr); extern void pform_set_reg_idx(perm_string name, PExpr*l, PExpr*r); -extern void pform_set_reg_integer(list*names); -extern void pform_set_reg_time(list*names); +extern void pform_set_reg_integer(list*names, list*attr); +extern void pform_set_reg_time(list*names, list*attr); -extern void pform_set_integer_2atom(uint64_t width, bool signed_flag, list*names); +//XXXXextern void pform_set_integer_2atom(uint64_t width, bool signed_flag, list*names); -extern void pform_set_data_type(const struct vlltype&li, data_type_t*, list*names); +extern void pform_set_data_type(const struct vlltype&li, data_type_t*, list*names, list*attr); -extern void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list*names); +extern void pform_set_enum(const struct vlltype&li, enum_type_t*enum_type, list*names, std::list*attr); -extern void pform_set_struct_type(struct_type_t*struct_type, list*names); +extern void pform_set_struct_type(struct_type_t*struct_type, std::list*names, std::list*attr); /* pform_set_attrib and pform_set_type_attrib exist to support the $attribute syntax, which can only set string values to diff --git a/pform_struct_type.cc b/pform_struct_type.cc index 1fe44bbe8..16ef1debd 100644 --- a/pform_struct_type.cc +++ b/pform_struct_type.cc @@ -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, * 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*attr) { 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); 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*attr) { if (struct_type->packed_flag) { - pform_set_packed_struct(struct_type, name); + pform_set_packed_struct(struct_type, name, attr); return; } @@ -67,11 +68,11 @@ static void pform_set_struct_type(struct_type_t*struct_type, perm_string name) ivl_assert(*struct_type, 0); } -void pform_set_struct_type(struct_type_t*struct_type, list*names) +void pform_set_struct_type(struct_type_t*struct_type, list*names, list*attr) { for (list::iterator cur = names->begin() ; cur != names->end() ; ++ cur) { - pform_set_struct_type(struct_type, *cur); + pform_set_struct_type(struct_type, *cur, attr); } }