From b68f101e8152773d8a0823db9011abf296030d7a Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 17 Sep 2023 19:49:38 -0400 Subject: [PATCH] Support preprocessing __LINE__ --- docs/guide/extensions.rst | 13 ++++++++++--- src/V3FileLine.cpp | 5 ++++- test_regress/t/t_preproc.out | 17 +++++++++++------ test_regress/t/t_preproc_comments.out | 17 +++++++++++------ test_regress/t/t_preproc_inc3.vh | 6 +++++- 5 files changed, 41 insertions(+), 17 deletions(-) diff --git a/docs/guide/extensions.rst b/docs/guide/extensions.rst index 5994fb770..26e1bc425 100644 --- a/docs/guide/extensions.rst +++ b/docs/guide/extensions.rst @@ -17,14 +17,21 @@ or "`ifdef`"'s may break other tools. .. option:: `__LINE__ - The :option:`\`__LINE__` define expands to the current filename as a - string, like C++'s __LINE__. This Verilator feature added in 2006 was - incorporated into IEEE 1800-2009. + The :option:`\`__LINE__` define expands to the current line number like + C++'s __LINE__. This Verilator feature added in 2006 was incorporated + into IEEE 1800-2009. .. option:: `error [string] This will report an error when encountered, like C++'s #error. +.. option:: `line + + As a special case `\`line \`__LINE__ "filename"` allows setting the + filename, without changing the line number. This is used for some + internal tests, so that debugging can leave the line numbers correctly + referring to the test file's line numbers. + .. option:: """ [string] """ A triple-quoted block specifies a string that may include newlines and diff --git a/src/V3FileLine.cpp b/src/V3FileLine.cpp index f3a0fb6de..87b7115a5 100644 --- a/src/V3FileLine.cpp +++ b/src/V3FileLine.cpp @@ -221,7 +221,10 @@ void FileLine::lineDirective(const char* textp, int& enterExitRef) { bool fail = false; const char* const ln = textp; while (*textp && !std::isspace(*textp)) ++textp; - if (std::isdigit(*ln)) { + if (0 == strncmp(ln, "`__LINE__", strlen("`__LINE__"))) { + // Special case - see docs - don't change other than accounting for `line itself + lineno(lineno() + 1); + } if (std::isdigit(*ln)) { lineno(std::atoi(ln)); } else { fail = true; diff --git a/test_regress/t/t_preproc.out b/test_regress/t/t_preproc.out index 1aa204271..6e09e8fcd 100644 --- a/test_regress/t/t_preproc.out +++ b/test_regress/t/t_preproc.out @@ -23,29 +23,34 @@ At file "t/t_preproc_inc2.vh" line 5 `line 7 "t/t_preproc_inc2.vh" 0 `line 1 "t/t_preproc_inc3.vh" 1 -`line 2 "inc3_a_filename_from_line_directive" 0 +`line 2 "t/t_preproc_inc3.vh" 0 -`line 7 "inc3_a_filename_from_line_directive" 0 +`line 6 "t/t_preproc_inc3.vh" 0 - At file "inc3_a_filename_from_line_directive" line 11 + At file "t/t_preproc_inc3.vh" line 10 +`line 12 "inc3_a_filename_from_line_directive_with_LINE" 0 + At file "inc3_a_filename_from_line_directive_with_LINE" line 12 +`line 100 "inc3_a_filename_from_line_directive" 0 + At file "inc3_a_filename_from_line_directive" line 100 -`line 13 "inc3_a_filename_from_line_directive" 0 + +`line 103 "inc3_a_filename_from_line_directive" 0 -`line 16 "inc3_a_filename_from_line_directive" 0 +`line 106 "inc3_a_filename_from_line_directive" 0 -`line 20 "inc3_a_filename_from_line_directive" 2 +`line 110 "inc3_a_filename_from_line_directive" 2 `line 7 "t/t_preproc_inc2.vh" 0 diff --git a/test_regress/t/t_preproc_comments.out b/test_regress/t/t_preproc_comments.out index 4c6a565ab..ba69fa2c0 100644 --- a/test_regress/t/t_preproc_comments.out +++ b/test_regress/t/t_preproc_comments.out @@ -23,29 +23,34 @@ At file "t/t_preproc_inc2.vh" line 5 `line 7 "t/t_preproc_inc2.vh" 0 `line 1 "t/t_preproc_inc3.vh" 1 -`line 2 "inc3_a_filename_from_line_directive" 0 // DESCRIPTION: Verilog::Preproc: Example source code +`line 2 "t/t_preproc_inc3.vh" 0 // This file ONLY is placed under the Creative Commons Public Domain, for // any use, without warranty, 2000-2007 by Wilson Snyder. // SPDX-License-Identifier: CC0-1.0 -`line 7 "inc3_a_filename_from_line_directive" 0 +`line 6 "t/t_preproc_inc3.vh" 0 // FOO - At file "inc3_a_filename_from_line_directive" line 11 + At file "t/t_preproc_inc3.vh" line 10 +`line 12 "inc3_a_filename_from_line_directive_with_LINE" 0 + At file "inc3_a_filename_from_line_directive_with_LINE" line 12 +`line 100 "inc3_a_filename_from_line_directive" 0 + At file "inc3_a_filename_from_line_directive" line 100 -`line 13 "inc3_a_filename_from_line_directive" 0 + +`line 103 "inc3_a_filename_from_line_directive" 0 // guard -`line 16 "inc3_a_filename_from_line_directive" 0 +`line 106 "inc3_a_filename_from_line_directive" 0 -`line 20 "inc3_a_filename_from_line_directive" 2 +`line 110 "inc3_a_filename_from_line_directive" 2 `line 7 "t/t_preproc_inc2.vh" 0 diff --git a/test_regress/t/t_preproc_inc3.vh b/test_regress/t/t_preproc_inc3.vh index 0abaf0e7a..9d3d91ac4 100644 --- a/test_regress/t/t_preproc_inc3.vh +++ b/test_regress/t/t_preproc_inc3.vh @@ -1,4 +1,3 @@ -`line 2 "inc3_a_filename_from_line_directive" 0 // DESCRIPTION: Verilog::Preproc: Example source code // This file ONLY is placed under the Creative Commons Public Domain, for // any use, without warranty, 2000-2007 by Wilson Snyder. @@ -9,6 +8,11 @@ `define _EMPTY // FOO At file `__FILE__ line `__LINE__ +`line `__LINE__ "inc3_a_filename_from_line_directive_with_LINE" 0 + At file `__FILE__ line `__LINE__ +`line 100 "inc3_a_filename_from_line_directive" 0 + At file `__FILE__ line `__LINE__ + `else `error "INC2 File already included once" `endif // guard