From 384185016807b7cb092e437122c6d76da7785a8c Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 6 Jul 2010 20:29:12 -0400 Subject: [PATCH] Preproc: fix pass-through of `line enter-exit codes. Internals: Merge Verilog-Perl preproc changes through d450722. --- src/V3Error.cpp | 14 +++++++++++++- src/V3Error.h | 3 ++- src/V3PreLex.h | 12 +++++++++--- src/V3PreLex.l | 23 +++++++++++------------ src/V3PreProc.cpp | 11 +++-------- src/verilog.l | 3 ++- test_regress/t/t_preproc.out | 34 ++++++++++++++++++++++++++-------- test_regress/t/t_preproc.pl | 2 +- test_regress/t/t_preproc.v | 18 +++++++++++++++--- 9 files changed, 82 insertions(+), 38 deletions(-) diff --git a/src/V3Error.cpp b/src/V3Error.cpp index 12cca0764..bbf313a60 100644 --- a/src/V3Error.cpp +++ b/src/V3Error.cpp @@ -79,7 +79,13 @@ FileLine::FileLine(FileLine::EmptySecret) { } } -void FileLine::lineDirective(const char* textp) { +string FileLine::lineDirectiveStrg(int enterExit) const { + char numbuf[20]; sprintf(numbuf, "%d", lineno()); + char levelbuf[20]; sprintf(levelbuf, "%d", enterExit); + return ((string)"`line "+numbuf+" \""+filename()+"\" "+levelbuf+"\n"); +} + +void FileLine::lineDirective(const char* textp, int& enterExitRef) { // Handle `line directive // Skip `line while (*textp && isspace(*textp)) textp++; @@ -102,6 +108,12 @@ void FileLine::lineDirective(const char* textp) { strfn = strfn.substr(0, textp-fn); this->filename(strfn); } + + // Grab level + while (*textp && (isspace(*textp) || *textp=='"')) textp++; + if (isdigit(*textp)) enterExitRef = atoi(textp); + else enterExitRef = 0; + //printf ("PPLINE %d '%s'\n", s_lineno, s_filename.c_str()); } diff --git a/src/V3Error.h b/src/V3Error.h index 4ce40636c..8599ebbb7 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -236,7 +236,7 @@ protected: friend class V3PreLex; void lineno(int num) { m_lineno = num; } void filename(const string& name) { m_filename = name; } - void lineDirective(const char* textp); + void lineDirective(const char* textp, int& enterExitRef); void incLineno() { m_lineno++; } FileLine* copyOrSameFileLine(); public: @@ -254,6 +254,7 @@ public: const string filename () const { return m_filename; } const string filebasename () const; const string profileFuncname() const; + string lineDirectiveStrg(int enter_exit_level) const; void warnOn(V3ErrorCode code, bool flag) { m_warnOn.set(code,flag); } // Turn on/off warning messages on this line. void warnOff(V3ErrorCode code, bool flag) { warnOn(code,!flag); } bool warnOff(const string& code, bool flag); // Returns 1 if ok diff --git a/src/V3PreLex.h b/src/V3PreLex.h index be60293ee..9656666ec 100644 --- a/src/V3PreLex.h +++ b/src/V3PreLex.h @@ -111,6 +111,7 @@ void yy_delete_buffer( YY_BUFFER_STATE b ); //====================================================================== #define KEEPCMT_SUB 2 +#define KEEPCMT_EXP 3 //====================================================================== // Class entry for each per-lexer state @@ -121,7 +122,7 @@ class V3PreLex { // Parse state stack m_bufferStack; // Stack of inserted text above current point - deque m_buffers; ///< Buffer of characters to process + deque m_buffers; // Buffer of characters to process // State to lexer static V3PreLex* s_currentLexp; // Current lexing point @@ -135,6 +136,7 @@ class V3PreLex { bool m_pslMoreNeeded;// Next // comment is really psl bool m_defCmtSlash; // /*...*/ comment in define had \ ending string m_defValue; // Definition value being built. + int m_enterExit; // For VL_LINE, the enter/exit level // CONSTRUCTORS V3PreLex() { @@ -143,6 +145,7 @@ class V3PreLex { m_formalLevel = 0; m_parenLevel = 0; m_defCmtSlash = false; + m_enterExit = 0; m_pslParenLevel = 0; m_pslMoreNeeded = false; initFirstBuffer(); @@ -153,9 +156,11 @@ class V3PreLex { void initFirstBuffer(); // Called by V3PreLex.l from lexer + FileLine* curFilelinep() { return m_curFilelinep; } + void curFilelinep(FileLine* fl) { m_curFilelinep = fl; } void appendDefValue(const char* text, size_t len); - void lineDirective(const char* text); - void incLineno() { m_curFilelinep->incLineno(); } + void lineDirective(const char* textp); + void incLineno() { curFilelinep()->incLineno(); } // Called by V3PreProc.cpp to inform lexer void pushStateDefArg(int level); void pushStateDefForm(); @@ -167,6 +172,7 @@ class V3PreLex { /// Called by VPreproc.cpp to get data from lexer YY_BUFFER_STATE currentBuffer(); int currentStartState(); + string currentUnreadChars(); void dumpSummary(); void dumpStack(); }; diff --git a/src/V3PreLex.l b/src/V3PreLex.l index 8530e2ee5..209fa04b6 100644 --- a/src/V3PreLex.l +++ b/src/V3PreLex.l @@ -1,3 +1,8 @@ +%option noyywrap align interactive +%option stack +%option noc++ +%option prefix="V3PreLex" +%{ /************************************************************************** * DESCRIPTION: Verilator: Flex verilog preprocessor * @@ -20,12 +25,6 @@ * lost characters. **************************************************************************/ -%option noyywrap align interactive -%option stack -%option noc++ -%option prefix="V3PreLex" -%{ - #include "V3PreProc.h" #include "V3PreLex.h" @@ -45,8 +44,8 @@ void yyourtext(const char* textp, size_t size) { yytext=(char*)textp; yyleng=siz static void linenoInc() {LEXP->incLineno();} static bool optPsl() { return V3PreProc::optPsl(); } static bool pedantic() { return LEXP->m_pedantic; } -static void yyerror(char* msg) { LEXP->m_curFilelinep->v3error(msg); } -static void yyerrorf(const char* msg) { LEXP->m_curFilelinep->v3error(msg); } +static void yyerror(char* msg) { LEXP->curFilelinep()->v3error(msg); } +static void yyerrorf(const char* msg) { LEXP->curFilelinep()->v3error(msg); } static void appendDefValue(const char* t, size_t l) { LEXP->appendDefValue(t,l); } static int pslParenLevel() { return LEXP->m_pslParenLevel; } static void pslParenLevelInc() { LEXP->m_pslParenLevel++; } @@ -104,11 +103,11 @@ psl [p]sl /* Optional directives we recognize */ "`__FILE__" { static string rtnfile; - rtnfile = '"'; rtnfile += LEXP->m_curFilelinep->filename().c_str(); + rtnfile = '"'; rtnfile += LEXP->curFilelinep()->filename().c_str(); rtnfile += '"'; yytext=(char*)rtnfile.c_str(); yyleng = rtnfile.length(); return (VP_STRING); } "`__LINE__" { static char buf[10]; - sprintf(buf, "%d",LEXP->m_curFilelinep->lineno()); + sprintf(buf, "%d",LEXP->curFilelinep()->lineno()); yytext = buf; yyleng = strlen(yytext); return (VP_TEXT); } "`error" { if (!pedantic()) return (VP_ERROR); else return(VP_DEFREF); } @@ -361,9 +360,9 @@ int V3PreLex::currentStartState() { } void V3PreLex::lineDirective(const char* textp) { - m_curFilelinep->lineDirective(textp); + curFilelinep()->lineDirective(textp, m_enterExit/*ref*/); // Make sure we have a dependency on whatever file was specified - V3File::addSrcDepend(m_curFilelinep->filename()); + V3File::addSrcDepend(curFilelinep()->filename()); } void V3PreLex::dumpSummary() { diff --git a/src/V3PreProc.cpp b/src/V3PreProc.cpp index 6be05dd96..81b2c5c3c 100644 --- a/src/V3PreProc.cpp +++ b/src/V3PreProc.cpp @@ -675,12 +675,7 @@ void V3PreProcImp::insertUnreadbackAtBol(const string& text) { void V3PreProcImp::addLineComment(int enter_exit_level) { if (lineDirectives()) { - char numbuf[20]; sprintf(numbuf, "%d", m_lexp->m_curFilelinep->lineno()); - char levelbuf[20]; sprintf(levelbuf, "%d", enter_exit_level); - string cmt = ((string)"`line "+numbuf - +" \""+m_lexp->m_curFilelinep->filename()+"\" " - +levelbuf+"\n"); - insertUnreadbackAtBol(cmt); + insertUnreadbackAtBol(m_lexp->curFilelinep()->lineDirectiveStrg(enter_exit_level)); } } @@ -742,7 +737,7 @@ int V3PreProcImp::getRawToken() { if (isEof()) return (VP_EOF); // Snarf next token from the file - m_fileline = m_lexp->m_curFilelinep; // Remember token start location + m_fileline = m_lexp->curFilelinep(); // Remember token start location V3PreLex::s_currentLexp = m_lexp; // Tell parser where to get/put data int tok = yylex(); @@ -799,7 +794,7 @@ int V3PreProcImp::getToken() { goto next_tok; } if (tok==VP_LINE) { - addLineComment(0); + addLineComment(m_lexp->m_enterExit); goto next_tok; } // Deal with some special parser states diff --git a/src/verilog.l b/src/verilog.l index 26aa50531..71b3aaec4 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -53,7 +53,8 @@ extern void yyerrorf(const char* format, ...); void V3ParseImp::ppline (const char* textp) { // Handle `line directive - fileline()->lineDirective(textp); + int enterExit; + fileline()->lineDirective(textp, enterExit/*ref*/); } void V3ParseImp::verilatorCmtLint(const char* textp, bool warnOff) { diff --git a/test_regress/t/t_preproc.out b/test_regress/t/t_preproc.out index d87221979..aa7929b53 100644 --- a/test_regress/t/t_preproc.out +++ b/test_regress/t/t_preproc.out @@ -105,7 +105,7 @@ deep deep "Inside: `nosubst" -"`nosubst" +"`nosubst" x y LLZZ x y @@ -125,7 +125,7 @@ x y LLZZ "a" y $display("left side: \"right side\"") -bar_suffix +bar_suffix more @@ -207,6 +207,20 @@ $display("bits %d %d", $bits(foo), `10); + +`line 162 "t/t_preproc.v" 0 + + + +`line 164 "t/t_preproc.v" 0 + + +`line 165 "t/t_preproc.v" 0 + + + + + @@ -219,9 +233,9 @@ $display("bits %d %d", $bits(foo), `10); -`line 173 "t/t_preproc.v" 0 +`line 181 "t/t_preproc.v" 0 -`line 173 "t/t_preproc.v" 0 +`line 181 "t/t_preproc.v" 0 assign a3 = ~b3 ; @@ -282,8 +296,8 @@ EXP: clxx_scen EXP: do if (start("verilog/inc1.v", 25)) begin message({"Blah-", "clx_scen", " end"}); end while(0); do -`line 231 "t/t_preproc.v" 0 - if (start("t/t_preproc.v", 231)) begin message({"Blah-", "clx_scen", " end"}); end while(0); +`line 239 "t/t_preproc.v" 0 + if (start("t/t_preproc.v", 239)) begin message({"Blah-", "clx_scen", " end"}); end while(0); @@ -294,7 +308,7 @@ do -`line 241 "t/t_preproc.v" 0 +`line 249 "t/t_preproc.v" 0 EXP: This is fooed @@ -304,4 +318,8 @@ EXP: This is fooed_2 This is fooed_2 -`line 250 "t/t_preproc.v" 2 + +np +np + +`line 262 "t/t_preproc.v" 2 diff --git a/test_regress/t/t_preproc.pl b/test_regress/t/t_preproc.pl index 2cd376666..e261e1b5f 100755 --- a/test_regress/t/t_preproc.pl +++ b/test_regress/t/t_preproc.pl @@ -14,7 +14,7 @@ if (!$Self->{v3}) { ok(1); } else { compile ( - v_flags2 => ['-DDEF_A0 -E'], + v_flags2 => ['-DDEF_A0 -DPREDEF_COMMAND_LINE -E'], verilator_make_gcc=>0, stdout_filename => $stdout_filename, ); diff --git a/test_regress/t/t_preproc.v b/test_regress/t/t_preproc.v index 381ccc0a4..99523aff0 100644 --- a/test_regress/t/t_preproc.v +++ b/test_regress/t/t_preproc.v @@ -59,7 +59,7 @@ Line_Preproc_Check `__LINE__ `define nosubst NOT_SUBSTITUTED `define WITHTICK "`nosubst" "Inside: `nosubst" -`WITHTICK +`WITHTICK `define withparam(a, b) a b LLZZ a b `withparam(x,y) @@ -79,10 +79,10 @@ Line_Preproc_Check `__LINE__ $display(`msg(left side, right side)) `define foo(f) f``_suffix -`foo(bar) +`foo(bar) more `define zap(which) \ - $c("Zap(\"",which,"\");"); + $c("Zap(\"",which,"\");"); `zap(bug1); `zap("bug2"); @@ -156,6 +156,14 @@ Line_Preproc_Check `__LINE__ `define bug191(bits) $display("bits %d %d", $bits(foo), `bits); `bug191(10) +//====================================================================== +// 1800-2009 +`define UDALL +`ifndef PREDEF_COMMAND_LINE `error "Test setup error, PREDEF_COMMAND_LINE pre-missing" `endif +`undefineall +`ifdef UDALL `error "undefineall failed" `endif +`ifndef PREDEF_COMMAND_LINE `error "Deleted too much, no PREDEF_COMMAND_LINE" `endif + //====================================================================== // bug202 `define FC_INV3(out, in) \ @@ -245,3 +253,7 @@ EXP: This is fooed_2 `def_fooed_2 //====================================================================== +`define NOPARAM() np +`NOPARAM() +`NOPARAM( ) +//======================================================================