Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

verilog: treat a text-macro as an identifier #3722

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,4 @@ MY_DEFINE input.sv /^`define MY_DEFINE$/;" d
assert_clk input.sv /^`define assert_clk(arg, __clk=clk, __rst_n=rst_n) \\$/;" d
forSkipMacro input.sv /^module forSkipMacro;$/;" m
add_t input.sv /^`define add_t(f) f``_t$/;" d module:forSkipMacro
`add_t input.sv /^ var `add_t(foo) = '0;$/;" r module:forSkipMacro
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--sort=no
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
XXX_TOP input.sv /^`define XXX_TOP foo_top$/;" d
XXX input.sv /^`define XXX foo$/;" d
`XXX input.sv /^module `XXX ();$/;" m
add_t input.sv /^`define add_t(f) f``_t$/;" d module:`XXX
`XXX_TOP input.sv /^module `XXX_TOP();$/;" m
foo input.sv /^class foo;$/;" C
new input.sv /^ function new(string name="...");$/;" f class:foo
name input.sv /^ function new(string name="...");$/;" p function:foo.new
`add_t input.sv /^ var `add_t(foo) = '0;$/;" r class:foo
25 changes: 25 additions & 0 deletions Units/parser-verilog.r/systemverilog-github3712.d/input.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// https://github.com/universal-ctags/ctags/issues/3712

`define XXX_TOP foo_top
`define XXX foo

module `XXX ();
`define add_t(f) f``_t
endmodule

module `XXX_TOP();
`XXX U_XXX (); // cannot be detected
endmodule

class foo;
// from a design pattern in UVM
`xxx_begin(bar) // must be ignored
`xxx_end // must be ignored

function new(string name="...");
super.new(name);
endfunction : new

// from systemverilog-directive.d
var `add_t(foo) = '0;
endclass : foo
20 changes: 16 additions & 4 deletions parsers/verilog.c
Original file line number Diff line number Diff line change
Expand Up @@ -830,14 +830,19 @@ static int skipMacro (int c, tokenInfo *token)
c = processDefine (localToken, c);
}
/* return macro expansion */
else
else if (localToken->kind == K_IDENTIFIER)
{
swapToken (token, localToken);
c = skipWhite (c);
if (c == '(')
c = skipPastMatch ("()");
break;
}
else
{
VERBOSE ("Unexpected input: localToken->kind %d\n", localToken->kind);
break;
}
}
deleteToken (localToken);
return c;
Expand Down Expand Up @@ -877,7 +882,7 @@ static int readWordToken (tokenInfo *const token, int c)

// read a word token starting with "c".
// returns the next charactor of the token read.
// for compiler directives. Since they are line-based, skipWhite() cannot be used.
// For compiler directives which are line-based, skipWhite() cannot be used.
static int readWordTokenNoSkip (tokenInfo *const token, int c)
{
return _readWordToken (token, c, false);
Expand All @@ -894,7 +899,8 @@ static bool isIdentifier (tokenInfo* token)
int c = vStringChar (token->name, i);
if (i == 0)
{
if (c == '`' || !isWordToken (c))
// treat a text-macro as an identifier (#3712)
if (!isWordToken (c))
return false;
}
else
Expand Down Expand Up @@ -2080,14 +2086,20 @@ static void findVerilogTags (void)
default :
if (isWordToken (c))
{
// NoSkip for compiler directives
c = readWordTokenNoSkip (token, c);
if (token->kind == K_DIRECTIVE)
{
// Skip compiler directives which are line-based.
c = skipToNewLine (c);
c = skipWhite (c);
}
else if (token->kind != K_UNDEFINED)
else if ((token->kind == K_UNDEFINED)
|| (token->kind == K_IDENTIFIER && vStringChar(token->name, 0) == '`'))
// ignore an undefined token and text-macro identifier, i.e.`foo(bar) (#3712)
break;
else
// call findTag() after skipping whitespaces
c = findTag (token, skipWhite (c));
}
else
Expand Down