diff --git a/Units/verilog-sv-class.d/args.ctags b/Units/verilog-sv-class.d/args.ctags new file mode 100644 index 0000000000..4b79af67b8 --- /dev/null +++ b/Units/verilog-sv-class.d/args.ctags @@ -0,0 +1,2 @@ +--extra=+q +--fields=+i diff --git a/Units/verilog-sv-class.d/expected.tags b/Units/verilog-sv-class.d/expected.tags new file mode 100644 index 0000000000..64a364d675 --- /dev/null +++ b/Units/verilog-sv-class.d/expected.tags @@ -0,0 +1,35 @@ +BASE input.sv /^ type BASE=supertest #(test)$/;" c class:paramtest2 +BASE input.sv /^class paramtest #(type BASE=supertest #(test)) extends BASE;$/;" c class:paramtest +DEFINE input.sv /^`define DEFINE$/;" c +DEF_VALUE input.sv /^`define DEF_VALUE 1'd100$/;" c +DEF_WITH_EQ input.sv /^`define DEF_WITH_EQ = 1'd100$/;" c +a input.sv /^ extern virtual function void extern_func (input bit a, input b);$/;" p function:test.extern_func +a input.sv /^ function mult (a, input b = 0);$/;" p function:supertest.mult +a input.sv /^ function mult (a, input b = 0);$/;" p function:test.mult +a input.sv /^ reg a;$/;" r class:test +b input.sv /^ extern virtual function void extern_func (input bit a, input b);$/;" p function:test.extern_func +b input.sv /^ function mult (a, input b = 0);$/;" p function:supertest.mult +b input.sv /^ function mult (a, input b = 0);$/;" p function:test.mult +b input.sv /^ logic b;$/;" r class:test +c input.sv /^ logic c;$/;" r class:supertest +extern_func input.sv /^ extern virtual function void extern_func (input bit a, input b);$/;" f class:test +mult input.sv /^ function mult (a, input b = 0);$/;" f class:supertest +mult input.sv /^ function mult (a, input b = 0);$/;" f class:test +paramtest input.sv /^class paramtest #(type BASE=supertest #(test)) extends BASE;$/;" C inherits:BASE +paramtest.BASE input.sv /^class paramtest #(type BASE=supertest #(test)) extends BASE;$/;" c class:paramtest +paramtest2 input.sv /^class paramtest2 #($/;" C +paramtest2.BASE input.sv /^ type BASE=supertest #(test)$/;" c class:paramtest2 +supertest input.sv /^class supertest extends test;$/;" C inherits:test +supertest.c input.sv /^ logic c;$/;" r class:supertest +supertest.mult input.sv /^ function mult (a, input b = 0);$/;" f class:supertest +supertest.mult.a input.sv /^ function mult (a, input b = 0);$/;" p function:supertest.mult +supertest.mult.b input.sv /^ function mult (a, input b = 0);$/;" p function:supertest.mult +test input.sv /^class test;$/;" C +test.a input.sv /^ reg a;$/;" r class:test +test.b input.sv /^ logic b;$/;" r class:test +test.extern_func input.sv /^ extern virtual function void extern_func (input bit a, input b);$/;" f class:test +test.extern_func.a input.sv /^ extern virtual function void extern_func (input bit a, input b);$/;" p function:test.extern_func +test.extern_func.b input.sv /^ extern virtual function void extern_func (input bit a, input b);$/;" p function:test.extern_func +test.mult input.sv /^ function mult (a, input b = 0);$/;" f class:test +test.mult.a input.sv /^ function mult (a, input b = 0);$/;" p function:test.mult +test.mult.b input.sv /^ function mult (a, input b = 0);$/;" p function:test.mult diff --git a/Units/verilog-sv-class.d/input.sv b/Units/verilog-sv-class.d/input.sv new file mode 100644 index 0000000000..6f1aaccde6 --- /dev/null +++ b/Units/verilog-sv-class.d/input.sv @@ -0,0 +1,32 @@ +// Include module declaration in a comment +// module wrong; +// endmodule +`define DEFINE +`define DEF_WITH_EQ = 1'd100 +`define DEF_VALUE 1'd100 + +class test; + reg a; + logic b; + function mult (a, input b = 0); + return a * b; + endfunction : mult + + extern virtual function void extern_func (input bit a, input b); + +endclass : test + +class supertest extends test; + logic c; + function mult (a, input b = 0); + return a * b * 2; + endfunction : mult +endclass : test + +class paramtest #(type BASE=supertest #(test)) extends BASE; +endclass : paramtest + +class paramtest2 #( + type BASE=supertest #(test) +) extends BASE; +endclass : paramtest2 diff --git a/Units/verilog-sv-qualifiers.d/args.ctags b/Units/verilog-sv-qualifiers.d/args.ctags new file mode 100644 index 0000000000..99a08389be --- /dev/null +++ b/Units/verilog-sv-qualifiers.d/args.ctags @@ -0,0 +1 @@ +--extra=+q diff --git a/Units/verilog-sv-qualifiers.d/expected.tags b/Units/verilog-sv-qualifiers.d/expected.tags new file mode 100644 index 0000000000..83f7ec9bba --- /dev/null +++ b/Units/verilog-sv-qualifiers.d/expected.tags @@ -0,0 +1,70 @@ +ext_func input.sv /^extern function ext_func (x, y);$/;" f +ext_func.x input.sv /^extern function ext_func (x, y);$/;" p function:ext_func +ext_func.y input.sv /^extern function ext_func (x, y);$/;" p function:ext_func +ext_local_func input.sv /^extern local function ext_local_func (x, y);$/;" f +ext_local_func.x input.sv /^extern local function ext_local_func (x, y);$/;" p function:ext_local_func +ext_local_func.y input.sv /^extern local function ext_local_func (x, y);$/;" p function:ext_local_func +ext_local_task input.sv /^extern local task ext_local_task (x, y);$/;" t +ext_local_task.x input.sv /^extern local task ext_local_task (x, y);$/;" p task:ext_local_task +ext_local_task.y input.sv /^extern local task ext_local_task (x, y);$/;" p task:ext_local_task +ext_protected_func input.sv /^extern protected function ext_protected_func (x, y);$/;" f +ext_protected_func.x input.sv /^extern protected function ext_protected_func (x, y);$/;" p function:ext_protected_func +ext_protected_func.y input.sv /^extern protected function ext_protected_func (x, y);$/;" p function:ext_protected_func +ext_protected_task input.sv /^extern protected task ext_protected_task (x, y);$/;" t +ext_protected_task.x input.sv /^extern protected task ext_protected_task (x, y);$/;" p task:ext_protected_task +ext_protected_task.y input.sv /^extern protected task ext_protected_task (x, y);$/;" p task:ext_protected_task +ext_pure_virt_func input.sv /^extern pure virtual function ext_pure_virt_func (x);$/;" f +ext_pure_virt_func.x input.sv /^extern pure virtual function ext_pure_virt_func (x);$/;" p function:ext_pure_virt_func +ext_pure_virt_task input.sv /^extern pure virtual task ext_pure_virt_task (x);$/;" t +ext_pure_virt_task.x input.sv /^extern pure virtual task ext_pure_virt_task (x);$/;" p task:ext_pure_virt_task +ext_static_func input.sv /^extern static function ext_static_func (x, y);$/;" f +ext_static_func.x input.sv /^extern static function ext_static_func (x, y);$/;" p function:ext_static_func +ext_static_func.y input.sv /^extern static function ext_static_func (x, y);$/;" p function:ext_static_func +ext_static_task input.sv /^extern static task ext_static_task (x, y);$/;" t +ext_static_task.x input.sv /^extern static task ext_static_task (x, y);$/;" p task:ext_static_task +ext_static_task.y input.sv /^extern static task ext_static_task (x, y);$/;" p task:ext_static_task +ext_task input.sv /^extern task ext_task (x, y);$/;" t +ext_task.x input.sv /^extern task ext_task (x, y);$/;" p task:ext_task +ext_task.y input.sv /^extern task ext_task (x, y);$/;" p task:ext_task +pure_virt_func input.sv /^pure virtual function pure_virt_func (x);$/;" f +pure_virt_func.x input.sv /^pure virtual function pure_virt_func (x);$/;" p function:pure_virt_func +pure_virt_local_func input.sv /^pure virtual local function pure_virt_local_func (x);$/;" f +pure_virt_local_func.x input.sv /^pure virtual local function pure_virt_local_func (x);$/;" p function:pure_virt_local_func +pure_virt_local_task input.sv /^pure virtual local task pure_virt_local_task (x);$/;" t +pure_virt_local_task.x input.sv /^pure virtual local task pure_virt_local_task (x);$/;" p task:pure_virt_local_task +pure_virt_protected_func input.sv /^pure virtual protected function pure_virt_protected_func (x);$/;" f +pure_virt_protected_func.x input.sv /^pure virtual protected function pure_virt_protected_func (x);$/;" p function:pure_virt_protected_func +pure_virt_protected_task input.sv /^pure virtual protected task pure_virt_protected_task (x);$/;" t +pure_virt_protected_task.x input.sv /^pure virtual protected task pure_virt_protected_task (x);$/;" p task:pure_virt_protected_task +pure_virt_static_func input.sv /^pure virtual static function pure_virt_static_func (x);$/;" f +pure_virt_static_func.x input.sv /^pure virtual static function pure_virt_static_func (x);$/;" p function:pure_virt_static_func +pure_virt_static_task input.sv /^pure virtual static task pure_virt_static_task (x);$/;" t +pure_virt_static_task.x input.sv /^pure virtual static task pure_virt_static_task (x);$/;" p task:pure_virt_static_task +pure_virt_task input.sv /^pure virtual task pure_virt_task (x);$/;" t +pure_virt_task.x input.sv /^pure virtual task pure_virt_task (x);$/;" p task:pure_virt_task +x input.sv /^extern function ext_func (x, y);$/;" p function:ext_func +x input.sv /^extern local function ext_local_func (x, y);$/;" p function:ext_local_func +x input.sv /^extern local task ext_local_task (x, y);$/;" p task:ext_local_task +x input.sv /^extern protected function ext_protected_func (x, y);$/;" p function:ext_protected_func +x input.sv /^extern protected task ext_protected_task (x, y);$/;" p task:ext_protected_task +x input.sv /^extern pure virtual function ext_pure_virt_func (x);$/;" p function:ext_pure_virt_func +x input.sv /^extern pure virtual task ext_pure_virt_task (x);$/;" p task:ext_pure_virt_task +x input.sv /^extern static function ext_static_func (x, y);$/;" p function:ext_static_func +x input.sv /^extern static task ext_static_task (x, y);$/;" p task:ext_static_task +x input.sv /^extern task ext_task (x, y);$/;" p task:ext_task +x input.sv /^pure virtual function pure_virt_func (x);$/;" p function:pure_virt_func +x input.sv /^pure virtual local function pure_virt_local_func (x);$/;" p function:pure_virt_local_func +x input.sv /^pure virtual local task pure_virt_local_task (x);$/;" p task:pure_virt_local_task +x input.sv /^pure virtual protected function pure_virt_protected_func (x);$/;" p function:pure_virt_protected_func +x input.sv /^pure virtual protected task pure_virt_protected_task (x);$/;" p task:pure_virt_protected_task +x input.sv /^pure virtual static function pure_virt_static_func (x);$/;" p function:pure_virt_static_func +x input.sv /^pure virtual static task pure_virt_static_task (x);$/;" p task:pure_virt_static_task +x input.sv /^pure virtual task pure_virt_task (x);$/;" p task:pure_virt_task +y input.sv /^extern function ext_func (x, y);$/;" p function:ext_func +y input.sv /^extern local function ext_local_func (x, y);$/;" p function:ext_local_func +y input.sv /^extern local task ext_local_task (x, y);$/;" p task:ext_local_task +y input.sv /^extern protected function ext_protected_func (x, y);$/;" p function:ext_protected_func +y input.sv /^extern protected task ext_protected_task (x, y);$/;" p task:ext_protected_task +y input.sv /^extern static function ext_static_func (x, y);$/;" p function:ext_static_func +y input.sv /^extern static task ext_static_task (x, y);$/;" p task:ext_static_task +y input.sv /^extern task ext_task (x, y);$/;" p task:ext_task diff --git a/Units/verilog-sv-qualifiers.d/input.sv b/Units/verilog-sv-qualifiers.d/input.sv new file mode 100644 index 0000000000..c008f3e06a --- /dev/null +++ b/Units/verilog-sv-qualifiers.d/input.sv @@ -0,0 +1,36 @@ +extern function ext_func (x, y); + +extern static function ext_static_func (x, y); + +extern protected function ext_protected_func (x, y); + +extern local function ext_local_func (x, y); + +extern pure virtual function ext_pure_virt_func (x); + +pure virtual function pure_virt_func (x); + +pure virtual static function pure_virt_static_func (x); + +pure virtual protected function pure_virt_protected_func (x); + +pure virtual local function pure_virt_local_func (x); + + +extern task ext_task (x, y); + +extern static task ext_static_task (x, y); + +extern protected task ext_protected_task (x, y); + +extern local task ext_local_task (x, y); + +extern pure virtual task ext_pure_virt_task (x); + +pure virtual task pure_virt_task (x); + +pure virtual static task pure_virt_static_task (x); + +pure virtual protected task pure_virt_protected_task (x); + +pure virtual local task pure_virt_local_task (x); diff --git a/verilog.c b/verilog.c index 16ee312988..946cbcb10d 100644 --- a/verilog.c +++ b/verilog.c @@ -78,6 +78,7 @@ typedef struct sTokenInfo { int nestLevel; /* Current nest level */ verilogKind lastKind; /* Kind of last found tag */ vString* blockName; /* Current block name */ + vString* inheritance; /* Class inheritance */ boolean singleStat; /* Single statement (ends at next semi-colon) */ } tokenInfo; @@ -179,6 +180,7 @@ static const keywordAssoc KeywordTable [] = { { "shortreal", K_REGISTER, { 1, 0 } }, { "static", K_IGNORE, { 1, 0 } }, { "string", K_REGISTER, { 1, 0 } }, + { "type", K_IGNORE, { 1, 0 } }, { "typedef", K_TYPEDEF, { 1, 0 } }, { "unsigned", K_IGNORE, { 1, 0 } }, { "virtual", K_IGNORE, { 1, 0 } }, @@ -244,7 +246,8 @@ static short hasSimplePortList (tokenInfo const* token) static short isSingleStatement (tokenInfo const* token) { - if (strcmp (vStringValue (token->name), "extern") == 0 ) + if (strcmp (vStringValue (token->name), "extern") == 0 || + strcmp (vStringValue (token->name), "virtual") == 0 ) { return TRUE; } else { @@ -263,6 +266,7 @@ static tokenInfo *newToken (void) token->nestLevel = 0; token->lastKind = K_UNDEFINED; token->blockName = vStringNew (); + token->inheritance = vStringNew (); token->singleStat = FALSE; return token; } @@ -273,6 +277,7 @@ static void deleteToken (tokenInfo * const token) { vStringDelete (token->name); vStringDelete (token->blockName); + vStringDelete (token->inheritance); eFree (token); } } @@ -601,6 +606,11 @@ static void createTag (tokenInfo *const token) tag.extensionFields.scope [1] = vStringValue (currentContext->name); } verbose ("\n"); + if (vStringLength (token->inheritance) > 0) + { + tag.extensionFields.inheritance = vStringValue (token->inheritance); + verbose ("Class %s extends %s\n", vStringValue (token->name), tag.extensionFields.inheritance); + } makeTagEntry (&tag); if (Option.include.qualifiedTags && currentContext->kind != K_UNDEFINED) { @@ -615,6 +625,8 @@ static void createTag (tokenInfo *const token) vStringDelete (scopedName); } + + /* Push token as context if it is a container */ if (isContainer (token)) { tokenInfo *newScope = newToken (); @@ -623,6 +635,9 @@ static void createTag (tokenInfo *const token) newScope->kind = token->kind; createContext (newScope); } + + /* Clear no longer required inheritance information */ + vStringClear (token->inheritance); } static boolean findBlockName (tokenInfo *const token) @@ -814,6 +829,78 @@ static void processTypedef (tokenInfo *const token) createTag (token); } +static void processClass (tokenInfo *const token) +{ + /*Note: At the moment, only identifies typedef name and not its contents */ + int c; + tokenInfo *extra; + tokenInfo *parameters = NULL; + + /* Get identifiers */ + c = skipWhite (vGetc ()); + if (isIdentifierCharacter (c)) + { + readIdentifier (token, c); + c = skipWhite (vGetc ()); + } + + /* Find class parameters list */ + if (c == '#') + { + c = skipWhite (vGetc ()); + if (c == '(') + { + parameters = newToken (); + do + { + c = skipWhite (vGetc ()); + readIdentifier (parameters, c); + updateKind (parameters); + verbose ("Found class parameter %s\n", vStringValue (parameters->name)); + if (parameters->kind == K_UNDEFINED) + { + parameters->kind = K_CONSTANT; + parameters = pushToken (parameters, newToken ()); + c = vGetc(); + while (c != ',' && c != ')' && c != EOF) + { + c = vGetc(); + } + } + } while (c != ')' && c != EOF); + c = vGetc (); + parameters = popToken (parameters); + } + c = skipWhite (vGetc ()); + } + + /* Search for inheritance information */ + if (isIdentifierCharacter (c)) + { + extra = newToken (); + + readIdentifier (extra, c); + c = skipWhite (vGetc ()); + if (strcmp (vStringValue (extra->name), "extends") == 0) + { + readIdentifier (extra, c); + vStringCopy (token->inheritance, extra->name); + verbose ("Inheritance %s\n", vStringValue (token->inheritance)); + } + deleteToken (extra); + } + + /* Use last identifier to create tag */ + createTag (token); + + /* Add parameter list */ + while (parameters) + { + createTag (parameters); + parameters = popToken (parameters); + } +} + static void tagNameList (tokenInfo* token, int c) { verilogKind localKind; @@ -941,6 +1028,10 @@ static void findTag (tokenInfo *const token) { processTypedef (token); } + else if (token->kind == K_CLASS) + { + processClass (token); + } else if (token->kind == K_IGNORE && isSingleStatement (token)) { currentContext->singleStat = TRUE;