diff --git a/parse.y b/parse.y index 4850a0611..20e3b14d2 100644 --- a/parse.y +++ b/parse.y @@ -309,9 +309,8 @@ static void current_task_set_statement(const YYLTYPE&loc, std::vectorset_statement(tmp); @@ -330,9 +329,7 @@ static void current_task_set_statement(const YYLTYPE&loc, std::vectorset_statement(tmp); @@ -368,9 +364,7 @@ static void current_function_set_statement(const YYLTYPE&loc, std::vectorsize() > 1 && !gn_system_verilog()) { - yyerror(@7, "error: Task body with multiple statements requires SystemVerilog."); + if ($7 && $7->size() > 1) { + pform_requires_sv(@7, "Task body with multiple statements"); } delete $7; } @@ -2452,10 +2445,8 @@ tf_port_item /* IEEE1800-2005: A.2.7 */ tmp = pform_make_task_ports(@3, use_port_type, $2, ilist); } if ($4 != 0) { - if (gn_system_verilog()) { + if (pform_requires_sv(@4, "Task/function port with unpacked dimensions")) { pform_set_reg_idx(name, $4); - } else { - yyerror(@4, "error: Task/function port with unpacked dimensions requires SystemVerilog."); } } @@ -2479,10 +2470,7 @@ tf_port_item /* IEEE1800-2005: A.2.7 */ tf_port_item_expr_opt : '=' expression - { if (! gn_system_verilog()) { - yyerror(@1, "error: Task/function default arguments require " - "SystemVerilog."); - } + { pform_requires_sv(@$, "Task/function default argument"); $$ = $2; } | { $$ = 0; } @@ -2582,9 +2570,7 @@ variable_dimension /* IEEE1800-2005: A.2.5 */ | '[' ']' { std::list *tmp = new std::list; pform_range_t index (0,0); - if (!gn_system_verilog()) { - yyerror("error: Dynamic array declaration require SystemVerilog."); - } + pform_requires_sv(@$, "Dynamic array declaration"); tmp->push_back(index); $$ = tmp; } @@ -2592,9 +2578,7 @@ variable_dimension /* IEEE1800-2005: A.2.5 */ { // SystemVerilog queue list *tmp = new std::list; pform_range_t index (new PENull,0); - if (!gn_system_verilog()) { - yyerror("error: Queue declaration require SystemVerilog."); - } + pform_requires_sv(@$, "Queue declaration"); tmp->push_back(index); $$ = tmp; } @@ -2602,9 +2586,7 @@ variable_dimension /* IEEE1800-2005: A.2.5 */ { // SystemVerilog queue with a max size list *tmp = new std::list; pform_range_t index (new PENull,$4); - if (!gn_system_verilog()) { - yyerror("error: Queue declarations require SystemVerilog."); - } + pform_requires_sv(@$, "Queue declaration"); tmp->push_back(index); $$ = tmp; } @@ -2612,10 +2594,8 @@ variable_dimension /* IEEE1800-2005: A.2.5 */ variable_lifetime : lifetime - { if (!gn_system_verilog()) { - yyerror(@1, "error: overriding the default variable lifetime " - "requires SystemVerilog."); - } else if ($1 != pform_peek_scope()->default_lifetime) { + { if (pform_requires_sv(@1, "Overriding default variable lifetime") && + $1 != pform_peek_scope()->default_lifetime) { yyerror(@1, "sorry: overriding the default variable lifetime " "is not yet supported."); } @@ -3913,9 +3893,7 @@ expr_primary FILE_NAME(tmp, @1); delete[]$1; $$ = tmp; - if (!gn_system_verilog()) { - yyerror(@1, "error: Empty function argument list requires SystemVerilog."); - } + pform_requires_sv(@1, "Empty function argument list"); } | implicit_class_handle @@ -4158,24 +4136,22 @@ expr_primary | expr_primary '\'' '(' expression ')' { PExpr*base = $4; - if (gn_system_verilog()) { + if (pform_requires_sv(@1, "Size cast")) { PECastSize*tmp = new PECastSize($1, base); FILE_NAME(tmp, @1); $$ = tmp; } else { - yyerror(@1, "error: Size cast requires SystemVerilog."); $$ = base; } } | simple_type_or_string '\'' '(' expression ')' { PExpr*base = $4; - if (gn_system_verilog()) { + if (pform_requires_sv(@1, "Type cast")) { PECastType*tmp = new PECastType($1, base); FILE_NAME(tmp, @1); $$ = tmp; } else { - yyerror(@1, "error: Type cast requires SystemVerilog."); $$ = base; } } @@ -4409,12 +4385,9 @@ hierarchy_identifier $$ = tmp; } | hierarchy_identifier '[' '$' ']' - { pform_name_t * tmp = $1; + { pform_requires_sv(@3, "Last element expression ($)"); + pform_name_t * tmp = $1; name_component_t&tail = tmp->back(); - if (! gn_system_verilog()) { - yyerror(@3, "error: Last element expression ($) " - "requires SystemVerilog. Try enabling SystemVerilog."); - } index_component_t itmp; itmp.sel = index_component_t::SEL_BIT_LAST; itmp.msb = 0; @@ -4585,9 +4558,7 @@ port_declaration $$ = ptmp; } | attribute_list_opt K_input net_type_opt data_type_or_implicit IDENTIFIER '=' expression - { if (!gn_system_verilog()) { - yyerror("error: Default port values require SystemVerilog."); - } + { pform_requires_sv(@6, "Default port value"); Module::port_t*ptmp; perm_string name = lex_strings.make($5); data_type_t*use_type = $4; @@ -4935,11 +4906,8 @@ module_parameter_port_list_opt module_parameter : parameter param_type parameter_assign | localparam param_type parameter_assign - { if (!gn_system_verilog()) { - yyerror(@1, "error: Local parameters in module parameter " - "port lists requires SystemVerilog."); - } - } + { pform_requires_sv(@1, "Local parameter in module parameter port list"); + } ; module_parameter_port_list @@ -5379,10 +5347,7 @@ module_item | K_function error K_endfunction label_opt { yyerror(@1, "error: I give up on this function definition."); if ($4) { - if (!gn_system_verilog()) { - yyerror(@4, "error: Function end names require " - "SystemVerilog."); - } + pform_requires_sv(@4, "Function end label"); delete[]$4; } yyerrok; @@ -6514,10 +6479,7 @@ statement_item /* This is roughly statement_item in the LRM */ block_item_decls_opt { if (!$2) { if ($4) { - if (! gn_system_verilog()) { - yyerror("error: Variable declaration in unnamed block " - "requires SystemVerilog."); - } + pform_requires_sv(@4, "Variable declaration in unnamed block"); } else { /* If there are no declarations in the scope then just delete it. */ pform_pop_scope(); @@ -6560,10 +6522,7 @@ statement_item /* This is roughly statement_item in the LRM */ { if (!$2) { if ($4) { - if (! gn_system_verilog()) { - yyerror("error: Variable declaration in unnamed block " - "requires SystemVerilog."); - } + pform_requires_sv(@4, "Variable declaration in unnamed block"); } else { /* If there are no declarations in the scope then just delete it. */ pform_pop_scope(); @@ -6847,9 +6806,7 @@ statement_item /* This is roughly statement_item in the LRM */ | hierarchy_identifier K_with '{' constraint_block_item_list_opt '}' ';' { /* ....randomize with { } */ if ($1 && peek_tail_name(*$1) == "randomize") { - if (!gn_system_verilog()) - yyerror(@2, "error: Randomize with constraint requires SystemVerilog."); - else + if (pform_requires_sv(@2, "Randomize with constraint")) yyerror(@2, "sorry: Randomize with constraint not supported."); } else { yyerror(@2, "error: Constraint block can only be applied to randomize method."); diff --git a/parse_misc.h b/parse_misc.h index c7a6faa2e..c20cc0e4e 100644 --- a/parse_misc.h +++ b/parse_misc.h @@ -57,6 +57,7 @@ extern YYLTYPE yylloc; */ extern int VLlex(); extern void VLerror(const char*msg); +extern void VLerror(const YYLTYPE&loc, va_list ap); extern void VLerror(const YYLTYPE&loc, const char*msg, ...) __attribute__((format(printf,2,3))); #define yywarn VLwarn extern void VLwarn(const char*msg); diff --git a/pform.cc b/pform.cc index 4de09e481..4ab111ea0 100644 --- a/pform.cc +++ b/pform.cc @@ -1334,10 +1334,9 @@ void pform_startmodule(const struct vlltype&loc, const char*name, error_count += 1; } - if (lifetime != LexicalScope::INHERITED && !gn_system_verilog()) { - cerr << loc << ": error: Default subroutine lifetimes " - "require SystemVerilog." << endl; - error_count += 1; + + if (lifetime != LexicalScope::INHERITED) { + pform_requires_sv(loc, "Default subroutine lifetime"); } if (gn_system_verilog() && ! pform_cur_module.empty()) { @@ -3138,11 +3137,7 @@ PAssign* pform_compressed_assign_from_inc_dec(const struct vlltype&loc, PExpr*ex PExpr* pform_genvar_inc_dec(const struct vlltype&loc, const char*name, bool inc_flag) { - if (!gn_system_verilog()) { - cerr << loc << ": error: Increment/decrement operators " - "require SystemVerilog." << endl; - error_count += 1; - } + pform_requires_sv(loc, "Increment/decrement operator"); PExpr*lval = new PEIdent(lex_strings.make(name)); PExpr*rval = new PENumber(new verinum(1)); @@ -3760,6 +3755,15 @@ void pform_add_modport_port(const struct vlltype&loc, pform_cur_modport->simple_ports[name] = make_pair(port_type, expr); } +bool pform_requires_sv(const struct vlltype&loc, const char *feature) +{ + if (gn_system_verilog()) + return true; + + VLerror(loc, "error: %s requires SystemVerilog.", feature); + + return false; +} FILE*vl_input = 0; extern void reset_lexor(); diff --git a/pform.h b/pform.h index cfefa09b3..b1b5e7a1d 100644 --- a/pform.h +++ b/pform.h @@ -612,4 +612,6 @@ extern bool allow_timeprec_decl; void pform_put_enum_type_in_scope(enum_type_t*enum_set); +bool pform_requires_sv(const struct vlltype&loc, const char *feature); + #endif /* IVL_pform_H */