Skip to content

Commit

Permalink
Verilog: extract module names used for declaring instances as referen…
Browse files Browse the repository at this point in the history
…ce tags

This one is conceptually based on
universal-ctags/ctags@master...my2817:ctags:master
reported and written by @my2817 at universal-ctags#3469.

The test case is also taken from universal-ctags#3469 submitted by @my2817.
  • Loading branch information
masatake authored and kumarstack55 committed Sep 11, 2022
1 parent a5721f6 commit f5334f9
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 7 deletions.
4 changes: 4 additions & 0 deletions Tmain/list-roles.d/stdout-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ Ruby L/library required on loaded by "require"
Ruby L/library requiredRel on loaded by "require_relative" method
Sh h/heredoc endmarker on end marker
Sh s/script loaded on loaded
SystemVerilog m/module decl on declaring instances
SystemdUnit u/unit After on referred in After key
SystemdUnit u/unit Before on referred in Before key
SystemdUnit u/unit RequiredBy on referred in RequiredBy key
Expand All @@ -108,6 +109,7 @@ Vera d/macro condition off used in part of #if/
Vera d/macro undef on undefined
Vera h/header local on local header
Vera h/header system on system header
Verilog m/module decl on declaring instances

#
# all.*
Expand Down Expand Up @@ -202,6 +204,7 @@ Ruby L/library required on loaded by "require"
Ruby L/library requiredRel on loaded by "require_relative" method
Sh h/heredoc endmarker on end marker
Sh s/script loaded on loaded
SystemVerilog m/module decl on declaring instances
SystemdUnit u/unit After on referred in After key
SystemdUnit u/unit Before on referred in Before key
SystemdUnit u/unit RequiredBy on referred in RequiredBy key
Expand All @@ -218,6 +221,7 @@ Vera d/macro condition off used in part of #if/
Vera d/macro undef on undefined
Vera h/header local on local header
Vera h/header system on system header
Verilog m/module decl on declaring instances

#
# C.*
Expand Down
3 changes: 3 additions & 0 deletions Units/parser-verilog.r/verilog-module-ref.d/args.ctags
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--sort=no
--extras=+r
--fields=+r
10 changes: 10 additions & 0 deletions Units/parser-verilog.r/verilog-module-ref.d/expected.tags
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
test input.v /^module test (\/*AUTOARG*\/);$/;" m roles:def
i_a input.v /^ input i_a, i_b;$/;" p module:test roles:def
i_b input.v /^ input i_a, i_b;$/;" p module:test roles:def
o_c input.v /^ output o_c;$/;" p module:test roles:def
int1 input.v /^ ref1 int1 ();$/;" i module:test typeref:module:ref1 roles:def
ref1 input.v /^ ref1 int1 ();$/;" m module:test roles:decl
int2 input.v /^ ref1 int2 ();$/;" i module:test typeref:module:ref1 roles:def
ref1 input.v /^ ref1 int2 ();$/;" m module:test roles:decl
int3 input.v /^ int3 ();$/;" i module:test typeref:module:ref3 roles:def
ref3 input.v /^ ref3 # (.A (aaa),$/;" m module:test roles:decl
12 changes: 12 additions & 0 deletions Units/parser-verilog.r/verilog-module-ref.d/input.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Taken from #3469 submitted by @my2817
module test (/*AUTOARG*/);
input i_a, i_b;
output o_c;

ref1 int1 ();
ref1 int2 ();
ref3 # (.A (aaa),
.B (bbb))
int3 ();

endmodule // test
22 changes: 22 additions & 0 deletions docs/man/ctags-lang-verilog.7.rst
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,28 @@ because they cannot be overridden.
P3 input.sv /^ parameter P3 = "parameter";$/;" c module:no_parameter_port_list parameter:
L7 input.sv /^ localparam L7 = "localparam";$/;" c module:no_parameter_port_list
Supported Roles
~~~~~~~~~~~~~~~

.. code-block:: console
$ ./ctags --list-roles=SystemVerilog
#KIND(L/N) NAME ENABLED DESCRIPTION
m/module decl on declaring instances
$ ./ctags --list-roles=Verilog
#KIND(L/N) NAME ENABLED DESCRIPTION
m/module decl on declaring instances
The parser extracts names of modules used in instance declarations as
reference tags. ``decl`` is the role for the tags. See "TAG ENTRIES"
section of :ref:`ctags(1) <ctags(1)>` about reference tags and roles.

.. warning::

The support for references in Universal Ctags is still
experimental; the names of the roles may be changed in the future.

TIPS
~~~~

Expand Down
22 changes: 22 additions & 0 deletions man/ctags-lang-verilog.7.rst.in
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,28 @@ because they cannot be overridden.
P3 input.sv /^ parameter P3 = "parameter";$/;" c module:no_parameter_port_list parameter:
L7 input.sv /^ localparam L7 = "localparam";$/;" c module:no_parameter_port_list

Supported Roles
~~~~~~~~~~~~~~~

.. code-block:: console

$ ./ctags --list-roles=SystemVerilog
#KIND(L/N) NAME ENABLED DESCRIPTION
m/module decl on declaring instances

$ ./ctags --list-roles=Verilog
#KIND(L/N) NAME ENABLED DESCRIPTION
m/module decl on declaring instances

The parser extracts names of modules used in instance declarations as
reference tags. ``decl`` is the role for the tags. See "TAG ENTRIES"
section of ctags(1) about reference tags and roles.

.. warning::

The support for references in Universal Ctags is still
experimental; the names of the roles may be changed in the future.

TIPS
~~~~

Expand Down
43 changes: 36 additions & 7 deletions parsers/verilog.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ typedef enum {
K_NETTYPE,
} verilogKind;

typedef enum {
R_MODULE_DECL,
} verilogModuleRole;

typedef struct {
const char *keyword;
verilogKind kind;
Expand Down Expand Up @@ -141,11 +145,20 @@ static int Ungetc;
static int Lang_verilog;
static int Lang_systemverilog;

static roleDefinition VerilogModuleRoles [] = {
{ true, "decl", "declaring instances" },
};

static roleDefinition SystemVerilogModuleRoles [] = {
{ true, "decl", "declaring instances" },
};

static kindDefinition VerilogKinds [] = {
{ true, 'c', "constant", "constants (define, parameter, specparam)" },
{ true, 'e', "event", "events" },
{ true, 'f', "function", "functions" },
{ true, 'm', "module", "modules" },
{ true, 'm', "module", "modules",
.referenceOnly = false, ATTACH_ROLES(VerilogModuleRoles) },
{ true, 'n', "net", "net data types" },
{ true, 'p', "port", "ports" },
{ true, 'r', "register", "variable data types" },
Expand All @@ -158,7 +171,8 @@ static kindDefinition SystemVerilogKinds [] = {
{ true, 'c', "constant", "constants (define, parameter, specparam, enum values)" },
{ true, 'e', "event", "events" },
{ true, 'f', "function", "functions" },
{ true, 'm', "module", "modules" },
{ true, 'm', "module", "modules",
.referenceOnly = false, ATTACH_ROLES(SystemVerilogModuleRoles) },
{ true, 'n', "net", "net data types" },
{ true, 'p', "port", "ports" },
{ true, 'r', "register", "variable data types" },
Expand Down Expand Up @@ -949,7 +963,7 @@ static int dropEndContext (tokenInfo *const token, int c)
}


static void createTagWithTypeRef (tokenInfo *const token, verilogKind kind, tokenInfo *const typeref)
static void createTagFull (tokenInfo *const token, verilogKind kind, int role, tokenInfo *const typeref)
{
tagEntryInfo tag;

Expand Down Expand Up @@ -981,7 +995,10 @@ static void createTagWithTypeRef (tokenInfo *const token, verilogKind kind, toke
}

/* Create tag */
initTagEntry (&tag, vStringValue (token->name), kind);
if (role == ROLE_DEFINITION_INDEX)
initTagEntry (&tag, vStringValue (token->name), kind);
else
initRefTagEntry (&tag, vStringValue (token->name), kind, role);
tag.lineNumber = token->lineNumber;
tag.filePosition = token->filePosition;

Expand Down Expand Up @@ -1011,7 +1028,8 @@ static void createTagWithTypeRef (tokenInfo *const token, verilogKind kind, toke

makeTagEntry (&tag);

if (isXtagEnabled (XTAG_QUALIFIED_TAGS) && currentContext->kind != K_UNDEFINED)
if (isXtagEnabled (XTAG_QUALIFIED_TAGS) && currentContext->kind != K_UNDEFINED
&& role == ROLE_DEFINITION_INDEX)
{
vString *const scopedName = vStringNew ();

Expand All @@ -1027,7 +1045,7 @@ static void createTagWithTypeRef (tokenInfo *const token, verilogKind kind, toke
}

/* Push token as context if it is a container */
if (container)
if (container && role == ROLE_DEFINITION_INDEX)
{
createContext (kind, token->name);

Expand All @@ -1037,7 +1055,7 @@ static void createTagWithTypeRef (tokenInfo *const token, verilogKind kind, toke
for (unsigned int i = 0; i < ptrArrayCount (tagContents); i++)
{
tokenInfo *content = ptrArrayItem (tagContents, i);
createTagWithTypeRef (content, content->kind, NULL);
createTagFull (content, content->kind, ROLE_DEFINITION_INDEX, NULL);
}

/* Drop temporary contexts */
Expand All @@ -1049,11 +1067,21 @@ static void createTagWithTypeRef (tokenInfo *const token, verilogKind kind, toke
vStringClear (token->inheritance);
}

static void createTagWithTypeRef (tokenInfo *const token, verilogKind kind, tokenInfo *const typeref)
{
createTagFull (token, kind, ROLE_DEFINITION_INDEX, typeref);
}

static void createTag (tokenInfo *const token, verilogKind kind)
{
createTagWithTypeRef (token, kind, NULL);
}

static void createRefTag (tokenInfo *const token, verilogKind kind, int role)
{
createTagFull (token, kind, role, NULL);
}

static int skipBlockName (tokenInfo *const token, int c)
{
if (c == ':')
Expand Down Expand Up @@ -1873,6 +1901,7 @@ static int tagIdsInDataDecl (tokenInfo* token, int c, verilogKind kind)
tokenSaved->kind = K_MODULE; // for typeRef field
verbose ("find instance: %s with kind %s\n", vStringValue (token->name), getNameForKind (K_INSTANCE));
createTagWithTypeRef (token, K_INSTANCE, tokenSaved);
createRefTag (tokenSaved, K_MODULE, R_MODULE_DECL);
}
}
c = skipMacro (c, token); // `ifdef, `else, `endif, etc. (before comma)
Expand Down

0 comments on commit f5334f9

Please sign in to comment.