diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index 6b7521e85..9c7fe7df1 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -45,9 +45,6 @@ V3ParseImp* V3ParseImp::s_parsep = NULL; int V3ParseSym::s_anonNum = 0; -extern void yyerror(const char*); -extern void yyerrorf(const char* format, ...); - //###################################################################### // Parser constructor @@ -126,16 +123,16 @@ void V3ParseImp::timescaleMod(FileLine* fl, AstNodeModule* modp, bool unitSet, d void V3ParseImp::verilatorCmtLintSave() { m_lintState.push_back(*parsep()->fileline()); } -void V3ParseImp::verilatorCmtLintRestore() { +void V3ParseImp::verilatorCmtLintRestore(FileLine* fl) { if (m_lintState.empty()) { - yyerrorf("/*verilator lint_restore*/ without matching save."); + fl->v3error("/*verilator lint_restore*/ without matching save"); return; } - parsep()->fileline()->warnStateFrom(m_lintState.back()); + fl->warnStateFrom(m_lintState.back()); m_lintState.pop_back(); } -void V3ParseImp::verilatorCmtLint(const char* textp, bool warnOff) { +void V3ParseImp::verilatorCmtLint(FileLine* fl, const char* textp, bool warnOff) { const char* sp = textp; while (*sp && !isspace(*sp)) sp++; while (*sp && isspace(*sp)) sp++; @@ -146,12 +143,13 @@ void V3ParseImp::verilatorCmtLint(const char* textp, bool warnOff) { if ((pos = msg.find('*')) != string::npos) msg.erase(pos); if (!(parsep()->fileline()->warnOff(msg, warnOff))) { if (!parsep()->optFuture(msg)) { - yyerrorf("Unknown verilator lint message code: %s, in %s", msg.c_str(), textp); + fl->v3error("Unknown verilator lint message code: '" << msg << "', in '" << textp + << "'"); } } } -void V3ParseImp::verilatorCmtBad(const char* textp) { +void V3ParseImp::verilatorCmtBad(FileLine* fl, const char* textp) { string cmtparse = textp; if (cmtparse.substr(0, strlen("/*verilator")) == "/*verilator") { cmtparse.replace(0, strlen("/*verilator"), ""); @@ -159,7 +157,7 @@ void V3ParseImp::verilatorCmtBad(const char* textp) { while (isspace(cmtparse[0])) cmtparse.replace(0, 1, ""); string cmtname; for (int i = 0; isalnum(cmtparse[i]); i++) { cmtname += cmtparse[i]; } - if (!parsep()->optFuture(cmtname)) yyerrorf("Unknown verilator comment: %s", textp); + if (!parsep()->optFuture(cmtname)) fl->v3error("Unknown verilator comment: '" << textp << "'"); } void V3ParseImp::errorPreprocDirective(const char* textp) { diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index 40eeb53b9..cef05f600 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -148,10 +148,10 @@ public: void ppline(const char* textp); void linenoInc() { fileline()->linenoInc(); } - void verilatorCmtLint(const char* textp, bool warnOff); + void verilatorCmtLint(FileLine* fl, const char* textp, bool warnOff); void verilatorCmtLintSave(); - void verilatorCmtLintRestore(); - void verilatorCmtBad(const char* textp); + void verilatorCmtLintRestore(FileLine* fl); + void verilatorCmtBad(FileLine* fl, const char* textp); void errorPreprocDirective(const char* textp); void tag(const char* text); void tagNodep(AstNode* nodep) { m_tagNodep = nodep; } diff --git a/src/verilog.l b/src/verilog.l index eeac94409..8baf30c9a 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -53,8 +53,9 @@ extern void yyerrorf(const char* format, ...); #define ERROR_RSVD_WORD(language) \ do { \ - FL_FWD; \ - yyerrorf("Unsupported: " language " reserved word not implemented: '%s'", yytext); \ + FL; \ + yylval.fl->v3error("Unsupported: " << language << " reserved word not implemented: '" \ + << yytext << "'"); \ FL_BRK; \ } while (0) @@ -92,11 +93,11 @@ void yyerrorf(const char* format, ...) { //====================================================================== -static double lexParseDouble(const char* textp, size_t length) { +static double lexParseDouble(FileLine* fl, const char* textp, size_t length) { string text = std::string(textp, length); bool success = false; double d = VString::parseDouble(text, &success); - if (!success) yyerrorf("Syntax error parsing real: %s", text.c_str()); + if (!success) fl->v3error("Syntax error parsing real: '" << textp << "'"); return d; } @@ -323,7 +324,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "endmodule" { FL; return yENDMODULE; } "endprimitive" { FL; return yENDPRIMITIVE; } "endspecify" { FL; return yENDSPECIFY; } - "endtable" { FL_FWD; yyerrorf("Syntax error: ENDTABLE outside of TABLE"); FL_BRK; } + "endtable" { FL; yylval.fl->v3error("Syntax error: ENDTABLE outside of TABLE"); FL_BRK; } "endtask" { FL; return yENDTASK; } "event" { FL; return yEVENT; } "for" { FL; return yFOR; } @@ -428,7 +429,8 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "design" { ERROR_RSVD_WORD("Verilog 2001-config"); } "endconfig" { ERROR_RSVD_WORD("Verilog 2001-config"); } "incdir" { ERROR_RSVD_WORD("Verilog 2001-config"); } - "include" { FL_FWD; yyerrorf("Unsupported: Verilog 2001-config reserved word not implemented; suggest you want `include instead: %s", yytext); FL_BRK; } + "include" { FL; yylval.fl->v3error("Unsupported: Verilog 2001-config reserved word not implemented; suggest you want `include instead: '" << yytext << "'"); + FL_BRK; } "instance" { ERROR_RSVD_WORD("Verilog 2001-config"); } "liblist" { ERROR_RSVD_WORD("Verilog 2001-config"); } "library" { ERROR_RSVD_WORD("Verilog 2001-config"); } @@ -724,10 +726,10 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "/*verilator full_case*/" { FL; return yVL_FULL_CASE; } "/*verilator inline_module*/" { FL; return yVL_INLINE_MODULE; } "/*verilator isolate_assignments*/" { FL; return yVL_ISOLATE_ASSIGNMENTS; } - "/*verilator lint_off"[^*]*"*/" { FL_FWD; PARSEP->verilatorCmtLint(yytext, true); FL_BRK; } - "/*verilator lint_on"[^*]*"*/" { FL_FWD; PARSEP->verilatorCmtLint(yytext, false); FL_BRK; } - "/*verilator lint_restore*/" { FL_FWD; PARSEP->verilatorCmtLintRestore(); FL_BRK; } - "/*verilator lint_save*/" { FL_FWD; PARSEP->verilatorCmtLintSave(); FL_BRK; } + "/*verilator lint_off"[^*]*"*/" { FL; PARSEP->verilatorCmtLint(yylval.fl, yytext, true); FL_BRK; } + "/*verilator lint_on"[^*]*"*/" { FL; PARSEP->verilatorCmtLint(yylval.fl, yytext, false); FL_BRK; } + "/*verilator lint_restore*/" { FL; PARSEP->verilatorCmtLintRestore(PARSEP->fileline()); FL_BRK; } + "/*verilator lint_save*/" { FL; PARSEP->verilatorCmtLintSave(); FL_BRK; } "/*verilator no_clocker*/" { FL; return yVL_NO_CLOCKER; } "/*verilator no_inline_module*/" { FL; return yVL_NO_INLINE_MODULE; } "/*verilator no_inline_task*/" { FL; return yVL_NO_INLINE_TASK; } @@ -747,7 +749,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "/*verilator tracing_on*/" { FL_FWD; PARSEP->fileline()->tracingOn(true); FL_BRK; } "/**/" { FL_FWD; FL_BRK; } - "/*"[^*]+"*/" { FL_FWD; PARSEP->verilatorCmtBad(yytext); FL_BRK; } + "/*"[^*]+"*/" { FL; PARSEP->verilatorCmtBad(yylval.fl, yytext); FL_BRK; } } /************************************************************************/ @@ -817,7 +819,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "-:" { FL; return yP_MINUSCOLON; } ".*" { FL; return yP_DOTSTAR; } ":+" { FL; yyless(1); - PARSEP->fileline()->v3warn(COLONPLUS, "Perhaps instead of ':+' the intent was '+:'?"); + yylval.fl->v3warn(COLONPLUS, "Perhaps instead of ':+' the intent was '+:'?"); return ':'; } } @@ -896,11 +898,11 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} return yaINTNUM; } [0-9][_0-9]*(\.[_0-9]+)([eE][-+]?[_0-9]+)? { - FL; yylval.cdouble = lexParseDouble(yytext, yyleng); + FL; yylval.cdouble = lexParseDouble(yylval.fl, yytext, yyleng); return yaFLOATNUM; } [0-9][_0-9]*(\.[_0-9]+)?([eE][-+]?[_0-9]+) { - FL; yylval.cdouble = lexParseDouble(yytext, yyleng); + FL; yylval.cdouble = lexParseDouble(yylval.fl, yytext, yyleng); return yaFLOATNUM; } [0-9][_0-9]*(\.[_0-9]+)?(fs|ps|ns|us|ms|s) { @@ -915,9 +917,10 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} /************************************************************************/ /* STRINGS */ -<> { FL_FWD; yyerrorf("EOF in unterminated string"); +<> { FL; yylval.fl->v3error("EOF in unterminated string"); yyleng = 0; yy_pop_state(); FL_BRK; yyterminate(); } -{crnl} { FL_FWD; yyerrorf("Unterminated string"); FL_BRK; } +{crnl} { FL; yylval.fl->v3error("Unterminated string"); + FL_BRK; } \\{crnl} { yymore(); } \\. { yymore(); } \" { yy_pop_state(); @@ -932,7 +935,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "*)" { FL_FWD; yy_pop_state(); FL_BRK; } {word} { yymore(); } . { yymore(); } -<> { FL_FWD; yyerrorf("EOF in (*"); +<> { FL; yylval.fl->v3error("EOF in (*"); yyleng = 0; yy_pop_state(); FL_BRK; yyterminate(); } /************************************************************************/ @@ -950,7 +953,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "endtable" { yy_pop_state(); FL; return yENDTABLE; }
"`line"{ws}+[^\n\r]*{crnl} { FL_FWD; PARSEP->ppline(yytext); FL_BRK; }
. { yymore(); } -
<> { FL_FWD; yyerrorf("EOF in TABLE"); +
<> { FL; yylval.fl->v3error("EOF in TABLE"); yyleng = 0; yy_pop_state(); FL_BRK; yyterminate(); } /************************************************************************/ @@ -965,8 +968,10 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "`default_decay_time"{ws}+[^\n\r]* { FL_FWD; FL_BRK; } // Verilog spec - delays only "`default_nettype"{ws}+"wire" { FL_FWD; PARSEP->fileline()->warnOn(V3ErrorCode::I_DEF_NETTYPE_WIRE, true); FL_BRK; } "`default_nettype"{ws}+"none" { FL_FWD; PARSEP->fileline()->warnOn(V3ErrorCode::I_DEF_NETTYPE_WIRE, false); FL_BRK; } - "`default_nettype"{ws}+[a-zA-Z0-9]* { FL_FWD; yyerrorf("Unsupported: `default_nettype of other than none or wire: %s", yytext); FL_BRK; } - "`default_trireg_strength"{ws}+[^\n\r]* { FL_FWD; yyerrorf("Unsupported: Verilog optional directive not implemented: %s", yytext); FL_BRK; } + "`default_nettype"{ws}+[a-zA-Z0-9]* { FL; yylval.fl->v3error("Unsupported: `default_nettype of other than none or wire: '" << yytext << "'"); + FL_BRK; } + "`default_trireg_strength"{ws}+[^\n\r]* { FL; yylval.fl->v3error("Unsupported: Verilog optional directive not implemented: '" << yytext << "'"); + FL_BRK; } "`delay_mode_distributed" { FL_FWD; FL_BRK; } // Verilog spec - delays only "`delay_mode_path" { FL_FWD; FL_BRK; } // Verilog spec - delays only "`delay_mode_unit" { FL_FWD; FL_BRK; } // Verilog spec - delays only @@ -992,12 +997,12 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "`resetall" { FL; PARSEP->fileline()->warnOn(V3ErrorCode::I_DEF_NETTYPE_WIRE, true); return yaT_RESETALL; } // Rest handled by preproc "`suppress_faults" { FL_FWD; FL_BRK; } // Verilog-XL compatibility - "`timescale"{ws}+[^\n\r]* { FL_FWD; PARSEP->timescalePreproc(PARSEP->fileline(), - yytext + strlen("`timescale")); + "`timescale"{ws}+[^\n\r]* { FL; PARSEP->timescalePreproc(yylval.fl, + yytext + strlen("`timescale")); FL_BRK; } "`unconnected_drive"{ws}+"pull0" { FL_FWD; PARSEP->unconnectedDrive(VOptionBool::OPT_FALSE); FL_BRK; } "`unconnected_drive"{ws}+"pull1" { FL_FWD; PARSEP->unconnectedDrive(VOptionBool::OPT_TRUE); FL_BRK; } - "`unconnected_drive" { FL_FWD; yyerrorf("Bad `unconnected_drive syntax"); FL_BRK; } + "`unconnected_drive" { FL; yylval.fl->v3error("Bad `unconnected_drive syntax"); FL_BRK; } "`uselib"{ws}+[^\n\r]* { FL_FWD; FL_BRK; } // Verilog-XL compatibility /* See also setLanguage below */ @@ -1011,8 +1016,8 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "`begin_keywords"[ \t]*\"1800-2012\" { FL_FWD; yy_push_state(S12); PARSEP->pushBeginKeywords(YY_START); FL_BRK; } "`begin_keywords"[ \t]*\"1800-2017\" { FL_FWD; yy_push_state(S17); PARSEP->pushBeginKeywords(YY_START); FL_BRK; } "`begin_keywords"[ \t]*\"1800[+]VAMS\" { FL_FWD; yy_push_state(SAX); PARSEP->pushBeginKeywords(YY_START); FL_BRK; } /*Latest SV*/ - "`end_keywords" { FL_FWD; yy_pop_state(); - if (!PARSEP->popBeginKeywords()) yyerrorf("`end_keywords when not inside `begin_keywords block"); + "`end_keywords" { FL; yy_pop_state(); + if (!PARSEP->popBeginKeywords()) yylval.fl->v3error("`end_keywords when not inside `begin_keywords block"); FL_BRK; } /* Verilator */ @@ -1026,9 +1031,9 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "`verilog" { FL_FWD; BEGIN PARSEP->lastVerilogState(); FL_BRK; } /* Errors */ - "<<<<<<<"[^\n\r]* { FL_FWD; yyerrorf("version control conflict marker in file"); FL_BRK; } - "======="[^\n\r]* { FL_FWD; yyerrorf("version control conflict marker in file"); FL_BRK; } - ">>>>>>>"[^\n\r]* { FL_FWD; yyerrorf("version control conflict marker in file"); FL_BRK; } + "<<<<<<<"[^\n\r]* { FL; yylval.fl->v3error("version control conflict marker in file"); FL_BRK; } + "======="[^\n\r]* { FL; yylval.fl->v3error("version control conflict marker in file"); FL_BRK; } + ">>>>>>>"[^\n\r]* { FL; yylval.fl->v3error("version control conflict marker in file"); FL_BRK; } /* If add to this list also add to V3LanguageWords.h */ } @@ -1057,7 +1062,9 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} } /* Catch all - absolutely last */ -<*>.|\n { FL_FWD; yyerrorf("Missing verilog.l rule: Default rule invoked in state %d: %s", YY_START, yytext); FL_BRK; } +<*>.|\n { FL; yylval.fl->v3error("Missing verilog.l rule: Default rule invoked in state " + << YY_START << " '" << yytext << "'"); + FL_BRK; } %% // Avoid code here as cl format misindents // For implementation functions see V3ParseImp.cpp diff --git a/test_regress/t/t_lint_restore_prag_bad.out b/test_regress/t/t_lint_restore_prag_bad.out index 00ac14fc0..9221464af 100644 --- a/test_regress/t/t_lint_restore_prag_bad.out +++ b/test_regress/t/t_lint_restore_prag_bad.out @@ -1,4 +1,4 @@ -%Error: t/t_lint_restore_prag_bad.v:10:4: /*verilator lint_restore*/ without matching save. +%Error: t/t_lint_restore_prag_bad.v:10:4: /*verilator lint_restore*/ without matching save 10 | /*verilator lint_restore*/ | ^~~~~~~~~~~~~~~~~~~~~~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_pp_underline_bad.out b/test_regress/t/t_pp_underline_bad.out index b68627482..d2bd08689 100644 --- a/test_regress/t/t_pp_underline_bad.out +++ b/test_regress/t/t_pp_underline_bad.out @@ -1,7 +1,7 @@ %Error: t/t_pp_underline_bad.v:8:4: Extra underscore in meta-comment; use /*verilator {...}*/ not /*verilator_{...}*/ 8 | // verilator_no_inline_module | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -%Error: t/t_pp_underline_bad.v:8:4: Unknown verilator comment: /*verilator _no_inline_module*/ +%Error: t/t_pp_underline_bad.v:8:4: Unknown verilator comment: '/*verilator _no_inline_module*/' 8 | /*verilator _no_inline_module*/ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ %Error: Exiting due to