diff --git a/Tmain/extras-field-for-pseudo-tags.d/stdout-expected.txt b/Tmain/extras-field-for-pseudo-tags.d/stdout-expected.txt
index 862fa41775..fb208e6da7 100644
--- a/Tmain/extras-field-for-pseudo-tags.d/stdout-expected.txt
+++ b/Tmain/extras-field-for-pseudo-tags.d/stdout-expected.txt
@@ -26,6 +26,7 @@
!_TAG_ROLE_DESCRIPTION!C!header local /local header/
!_TAG_ROLE_DESCRIPTION!C!header system /system header/
!_TAG_ROLE_DESCRIPTION!C!macro undef /undefined/
+!_TAG_ROLE_DESCRIPTION!C!member initialized /initialized with form '.member = ...'/
main input.c /^int main (void) { return 0; }$/
# option: --format=2
!_TAG_EXTRA_DESCRIPTION pseudo /Include pseudo tags/;" extras:pseudo
@@ -55,4 +56,5 @@ main input.c /^int main (void) { return 0; }$/
!_TAG_ROLE_DESCRIPTION!C!header local /local header/;" extras:pseudo
!_TAG_ROLE_DESCRIPTION!C!header system /system header/;" extras:pseudo
!_TAG_ROLE_DESCRIPTION!C!macro undef /undefined/;" extras:pseudo
+!_TAG_ROLE_DESCRIPTION!C!member initialized /initialized with form '.member = ...'/;" extras:pseudo
main input.c /^int main (void) { return 0; }$/
diff --git a/Tmain/json-output-format.d/stdout-expected.txt b/Tmain/json-output-format.d/stdout-expected.txt
index 597ebe69c2..c271ce7356 100644
--- a/Tmain/json-output-format.d/stdout-expected.txt
+++ b/Tmain/json-output-format.d/stdout-expected.txt
@@ -93,6 +93,7 @@
{"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "C", "kindName": "header", "path": "local", "pattern": "local header"}
{"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "C", "kindName": "header", "path": "system", "pattern": "system header"}
{"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "C", "kindName": "macro", "path": "undef", "pattern": "undefined"}
+{"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "C", "kindName": "member", "path": "initialized", "pattern": "initialized with form '.member = ...'"}
{"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "Go", "kindName": "package", "path": "imported", "pattern": "imported package"}
{"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "Go", "kindName": "unknown", "path": "receiverType", "pattern": "receiver type"}
{"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "Python", "kindName": "module", "path": "imported", "pattern": "imported modules"}
diff --git a/Tmain/list-kinds-full.d/stdout-expected.txt b/Tmain/list-kinds-full.d/stdout-expected.txt
index 25cd1ec121..ad6535cdc9 100644
--- a/Tmain/list-kinds-full.d/stdout-expected.txt
+++ b/Tmain/list-kinds-full.d/stdout-expected.txt
@@ -1,13 +1,14 @@
#LETTER NAME ENABLED REFONLY NROLES MASTER DESCRIPTION
D macroparam no no 0 C parameters inside macro definitions
L label no no 0 C goto labels
+Y unknown no yes 4 C unknown identifier
d macro yes no 2 C macro definitions
e enumerator yes no 0 C enumerators (values inside an enumeration)
f function yes no 0 C function definitions
g enum yes no 0 C enumeration names
h header yes yes 2 C included header files
l local no no 0 C local variables
-m member yes no 0 C struct, and union members
+m member yes no 1 C struct, and union members
p prototype no no 0 C function prototypes
s struct yes no 0 C structure names
t typedef yes no 0 C typedefs
@@ -21,6 +22,7 @@ D macroparam no no 0 C parameters inside macro definitions
L label no no 0 C goto labels
N name no no 0 NONE names imported via using scope::symbol
U using no no 0 NONE using namespace statements
+Y unknown no yes 4 C unknown identifier
Z tparam no no 0 NONE template parameters
c class yes no 0 NONE classes
d macro yes no 2 C macro definitions
@@ -29,7 +31,7 @@ f function yes no 0 C function definitions
g enum yes no 0 C enumeration names
h header yes yes 2 C included header files
l local no no 0 C local variables
-m member yes no 0 C class, struct, and union members
+m member yes no 1 C class, struct, and union members
n namespace yes no 0 NONE namespaces
p prototype no no 0 C function prototypes
s struct yes no 0 C structure names
diff --git a/Tmain/list-roles.d/stdout-expected.txt b/Tmain/list-roles.d/stdout-expected.txt
index 111465ee06..b040755542 100644
--- a/Tmain/list-roles.d/stdout-expected.txt
+++ b/Tmain/list-roles.d/stdout-expected.txt
@@ -18,22 +18,37 @@ Automake d/directory program on directory for PROGRA
Automake d/directory script on directory for SCRIPTS primary
Basic f/function decl on declared
Bats S/script loaded on script loaed with "load" command
+C Y/unknown applied on (maybe macro, function, or member) called or expanded
+C Y/unknown defvar on (maybe type) used for defining variables
+C Y/unknown ref off referenced anyhow
+C Y/unknown value on used as right side value
C d/macro condition off used in part of #if/#ifdef/#elif conditions
C d/macro undef on undefined
C h/header local on local header
C h/header system on system header
+C m/member initialized on initialized with form '.member = ...'
+C++ Y/unknown applied on (maybe macro, function, or member) called or expanded
+C++ Y/unknown defvar on (maybe type) used for defining variables
+C++ Y/unknown ref off referenced anyhow
+C++ Y/unknown value on used as right side value
C++ d/macro condition off used in part of #if/#ifdef/#elif conditions
C++ d/macro undef on undefined
C++ h/header local on local header
C++ h/header system on system header
+C++ m/member initialized on initialized with form '.member = ...'
CPreProcessor d/macro condition off used in part of #if/#ifdef/#elif conditions
CPreProcessor d/macro undef on undefined
CPreProcessor h/header local on local header
CPreProcessor h/header system on system header
+CUDA Y/unknown applied on (maybe macro, function, or member) called or expanded
+CUDA Y/unknown defvar on (maybe type) used for defining variables
+CUDA Y/unknown ref off referenced anyhow
+CUDA Y/unknown value on used as right side value
CUDA d/macro condition off used in part of #if/#ifdef/#elif conditions
CUDA d/macro undef on undefined
CUDA h/header local on local header
CUDA h/header system on system header
+CUDA m/member initialized on initialized with form '.member = ...'
Cobol S/sourcefile copied on copied in source file
CobolFree S/sourcefile copied on copied in source file
CobolVariable S/sourcefile copied on copied in source file
@@ -138,22 +153,37 @@ Automake d/directory program on directory for PROGRA
Automake d/directory script on directory for SCRIPTS primary
Basic f/function decl on declared
Bats S/script loaded on script loaed with "load" command
+C Y/unknown applied on (maybe macro, function, or member) called or expanded
+C Y/unknown defvar on (maybe type) used for defining variables
+C Y/unknown ref off referenced anyhow
+C Y/unknown value on used as right side value
C d/macro condition off used in part of #if/#ifdef/#elif conditions
C d/macro undef on undefined
C h/header local on local header
C h/header system on system header
+C m/member initialized on initialized with form '.member = ...'
+C++ Y/unknown applied on (maybe macro, function, or member) called or expanded
+C++ Y/unknown defvar on (maybe type) used for defining variables
+C++ Y/unknown ref off referenced anyhow
+C++ Y/unknown value on used as right side value
C++ d/macro condition off used in part of #if/#ifdef/#elif conditions
C++ d/macro undef on undefined
C++ h/header local on local header
C++ h/header system on system header
+C++ m/member initialized on initialized with form '.member = ...'
CPreProcessor d/macro condition off used in part of #if/#ifdef/#elif conditions
CPreProcessor d/macro undef on undefined
CPreProcessor h/header local on local header
CPreProcessor h/header system on system header
+CUDA Y/unknown applied on (maybe macro, function, or member) called or expanded
+CUDA Y/unknown defvar on (maybe type) used for defining variables
+CUDA Y/unknown ref off referenced anyhow
+CUDA Y/unknown value on used as right side value
CUDA d/macro condition off used in part of #if/#ifdef/#elif conditions
CUDA d/macro undef on undefined
CUDA h/header local on local header
CUDA h/header system on system header
+CUDA m/member initialized on initialized with form '.member = ...'
Cobol S/sourcefile copied on copied in source file
CobolFree S/sourcefile copied on copied in source file
CobolVariable S/sourcefile copied on copied in source file
@@ -242,11 +272,16 @@ Zsh s/script loaded on loaded
#
# C.*
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef on undefined
-h/header local on local header
-h/header system on system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied on (maybe macro, function, or member) called or expanded
+Y/unknown defvar on (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value on used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef on undefined
+h/header local on local header
+h/header system on system header
+m/member initialized on initialized with form '.member = ...'
#
# all.d
@@ -279,49 +314,74 @@ s/script loaded on loaded
#
# C.* with disabling all roles of all languages
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef off undefined
-h/header local off local header
-h/header system off system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied off (maybe macro, function, or member) called or expanded
+Y/unknown defvar off (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value off used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef off undefined
+h/header local off local header
+h/header system off system header
+m/member initialized off initialized with form '.member = ...'
#
# C.* with disabling all roles of all kinds of all languages
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef off undefined
-h/header local off local header
-h/header system off system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied off (maybe macro, function, or member) called or expanded
+Y/unknown defvar off (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value off used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef off undefined
+h/header local off local header
+h/header system off system header
+m/member initialized off initialized with form '.member = ...'
#
# C.* with enabling all roles of all kinds in all languages
# after disabling system role of header kind of C language
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition on used in part of #if/#ifdef/#elif conditions
-d/macro undef on undefined
-h/header local on local header
-h/header system on system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied on (maybe macro, function, or member) called or expanded
+Y/unknown defvar on (maybe type) used for defining variables
+Y/unknown ref on referenced anyhow
+Y/unknown value on used as right side value
+d/macro condition on used in part of #if/#ifdef/#elif conditions
+d/macro undef on undefined
+h/header local on local header
+h/header system on system header
+m/member initialized on initialized with form '.member = ...'
#
# C.* with enabling all roles in all languages
# after disabling system role of header kind of C language
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition on used in part of #if/#ifdef/#elif conditions
-d/macro undef on undefined
-h/header local on local header
-h/header system on system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied on (maybe macro, function, or member) called or expanded
+Y/unknown defvar on (maybe type) used for defining variables
+Y/unknown ref on referenced anyhow
+Y/unknown value on used as right side value
+d/macro condition on used in part of #if/#ifdef/#elif conditions
+d/macro undef on undefined
+h/header local on local header
+h/header system on system header
+m/member initialized on initialized with form '.member = ...'
#
# C.* with disabling all roles in C language
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef off undefined
-h/header local off local header
-h/header system off system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied off (maybe macro, function, or member) called or expanded
+Y/unknown defvar off (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value off used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef off undefined
+h/header local off local header
+h/header system off system header
+m/member initialized off initialized with form '.member = ...'
#
# Sh.* with disabling all roles in C language
@@ -333,11 +393,16 @@ s/script loaded on loaded
#
# C.* with disabling all roles of all kinds in C language
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef off undefined
-h/header local off local header
-h/header system off system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied off (maybe macro, function, or member) called or expanded
+Y/unknown defvar off (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value off used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef off undefined
+h/header local off local header
+h/header system off system header
+m/member initialized off initialized with form '.member = ...'
#
# Sh.* with disabling all roles of all kinds in C language
@@ -350,11 +415,16 @@ s/script loaded on loaded
# C.* with enabling all roles in C language
# after disabling all roles in all languages
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition on used in part of #if/#ifdef/#elif conditions
-d/macro undef on undefined
-h/header local on local header
-h/header system on system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied on (maybe macro, function, or member) called or expanded
+Y/unknown defvar on (maybe type) used for defining variables
+Y/unknown ref on referenced anyhow
+Y/unknown value on used as right side value
+d/macro condition on used in part of #if/#ifdef/#elif conditions
+d/macro undef on undefined
+h/header local on local header
+h/header system on system header
+m/member initialized on initialized with form '.member = ...'
#
# Sh.* with enabling all roles in C language
@@ -368,11 +438,16 @@ s/script loaded off loaded
# C.* with enabling all roles of all kinds in C language
# after disabling all roles in all languages
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition on used in part of #if/#ifdef/#elif conditions
-d/macro undef on undefined
-h/header local on local header
-h/header system on system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied on (maybe macro, function, or member) called or expanded
+Y/unknown defvar on (maybe type) used for defining variables
+Y/unknown ref on referenced anyhow
+Y/unknown value on used as right side value
+d/macro condition on used in part of #if/#ifdef/#elif conditions
+d/macro undef on undefined
+h/header local on local header
+h/header system on system header
+m/member initialized on initialized with form '.member = ...'
#
# Sh.* with enabling all roles of all kinds in C language
@@ -385,11 +460,16 @@ s/script loaded off loaded
#
# C.* with disabling all roles of {header} kind in C language
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef on undefined
-h/header local off local header
-h/header system off system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied on (maybe macro, function, or member) called or expanded
+Y/unknown defvar on (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value on used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef on undefined
+h/header local off local header
+h/header system off system header
+m/member initialized on initialized with form '.member = ...'
#
# Sh.* with disabling all roles of {header} kind in C language
@@ -401,11 +481,16 @@ s/script loaded on loaded
#
# C.* with disabling all roles of h kind in C language
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef on undefined
-h/header local off local header
-h/header system off system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied on (maybe macro, function, or member) called or expanded
+Y/unknown defvar on (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value on used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef on undefined
+h/header local off local header
+h/header system off system header
+m/member initialized on initialized with form '.member = ...'
#
# Sh.* with disabling all roles of h kind in C language
@@ -418,11 +503,16 @@ s/script loaded on loaded
# C.* with enabling all roles of {header} kind in C language
# after disabling all roles in all languages
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef off undefined
-h/header local on local header
-h/header system on system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied off (maybe macro, function, or member) called or expanded
+Y/unknown defvar off (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value off used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef off undefined
+h/header local on local header
+h/header system on system header
+m/member initialized off initialized with form '.member = ...'
#
# Sh.* with enabling all roles of {header} kind in C language
@@ -436,11 +526,16 @@ s/script loaded off loaded
# C.* with enabling all roles of h kind in C language
# after disabling all roles in all languages
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef off undefined
-h/header local on local header
-h/header system on system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied off (maybe macro, function, or member) called or expanded
+Y/unknown defvar off (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value off used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef off undefined
+h/header local on local header
+h/header system on system header
+m/member initialized off initialized with form '.member = ...'
#
# Sh.* with enabling all roles of h kind in C language
@@ -453,109 +548,169 @@ s/script loaded off loaded
#
# C.* with disabling system role of h kind
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef on undefined
-h/header local on local header
-h/header system off system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied on (maybe macro, function, or member) called or expanded
+Y/unknown defvar on (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value on used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef on undefined
+h/header local on local header
+h/header system off system header
+m/member initialized on initialized with form '.member = ...'
#
# C.* with disabling system role of {header} kind
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef on undefined
-h/header local on local header
-h/header system off system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied on (maybe macro, function, or member) called or expanded
+Y/unknown defvar on (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value on used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef on undefined
+h/header local on local header
+h/header system off system header
+m/member initialized on initialized with form '.member = ...'
#
# C.* with enabling system role of h kind after disabling the role
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef on undefined
-h/header local on local header
-h/header system on system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied on (maybe macro, function, or member) called or expanded
+Y/unknown defvar on (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value on used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef on undefined
+h/header local on local header
+h/header system on system header
+m/member initialized on initialized with form '.member = ...'
#
# C.* with enabling system role of {header} kind after disabling the role
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef on undefined
-h/header local on local header
-h/header system on system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied on (maybe macro, function, or member) called or expanded
+Y/unknown defvar on (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value on used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef on undefined
+h/header local on local header
+h/header system on system header
+m/member initialized on initialized with form '.member = ...'
#
# C.* with disabling system and local roles of h kind
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef on undefined
-h/header local off local header
-h/header system off system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied on (maybe macro, function, or member) called or expanded
+Y/unknown defvar on (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value on used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef on undefined
+h/header local off local header
+h/header system off system header
+m/member initialized on initialized with form '.member = ...'
#
# C.* with disabling system and local roles of {header} kind
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef on undefined
-h/header local off local header
-h/header system off system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied on (maybe macro, function, or member) called or expanded
+Y/unknown defvar on (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value on used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef on undefined
+h/header local off local header
+h/header system off system header
+m/member initialized on initialized with form '.member = ...'
#
# C.* with enabling system and local roles of h kind
# after disabling all roles in all languages
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef off undefined
-h/header local on local header
-h/header system on system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied off (maybe macro, function, or member) called or expanded
+Y/unknown defvar off (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value off used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef off undefined
+h/header local on local header
+h/header system on system header
+m/member initialized off initialized with form '.member = ...'
#
# C.* with enabling system and local roles of {header} kind
# after disabling all roles in all languages
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef off undefined
-h/header local on local header
-h/header system on system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied off (maybe macro, function, or member) called or expanded
+Y/unknown defvar off (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value off used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef off undefined
+h/header local on local header
+h/header system on system header
+m/member initialized off initialized with form '.member = ...'
#
# C.* with disabling local role of h kind and undef role of d kind
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef off undefined
-h/header local off local header
-h/header system on system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied on (maybe macro, function, or member) called or expanded
+Y/unknown defvar on (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value on used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef off undefined
+h/header local off local header
+h/header system on system header
+m/member initialized on initialized with form '.member = ...'
#
# C.* with enabling all roles of header kinds after disabling all roles of the kind
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef on undefined
-h/header local on local header
-h/header system on system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied on (maybe macro, function, or member) called or expanded
+Y/unknown defvar on (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value on used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef on undefined
+h/header local on local header
+h/header system on system header
+m/member initialized on initialized with form '.member = ...'
#
# C.* with enabling all roles of header kinds after disabling all roles of the kinds of C language
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef off undefined
-h/header local on local header
-h/header system on system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied off (maybe macro, function, or member) called or expanded
+Y/unknown defvar off (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value off used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef off undefined
+h/header local on local header
+h/header system on system header
+m/member initialized off initialized with form '.member = ...'
#
# C.* with enabling all roles of header kinds after disabling all roles of the kinds of C language (short notation)
#
-#KIND(L/N) NAME ENABLED DESCRIPTION
-d/macro condition off used in part of #if/#ifdef/#elif conditions
-d/macro undef off undefined
-h/header local on local header
-h/header system on system header
+#KIND(L/N) NAME ENABLED DESCRIPTION
+Y/unknown applied off (maybe macro, function, or member) called or expanded
+Y/unknown defvar off (maybe type) used for defining variables
+Y/unknown ref off referenced anyhow
+Y/unknown value off used as right side value
+d/macro condition off used in part of #if/#ifdef/#elif conditions
+d/macro undef off undefined
+h/header local on local header
+h/header system on system header
+m/member initialized off initialized with form '.member = ...'
diff --git a/Tmain/nested-subparsers.d/stdout-expected.txt b/Tmain/nested-subparsers.d/stdout-expected.txt
index 7f7c014023..f0494c96e0 100644
--- a/Tmain/nested-subparsers.d/stdout-expected.txt
+++ b/Tmain/nested-subparsers.d/stdout-expected.txt
@@ -17,6 +17,7 @@ x external and forward variable declarations [off]
z function parameters inside function or prototype definitions [off]
L goto labels [off]
D parameters inside macro definitions [off]
+Y unknown identifier [off]
#
# list kinds Event
#
@@ -36,13 +37,14 @@ n name
#LETTER NAME ENABLED REFONLY NROLES MASTER DESCRIPTION
D macroparam no no 0 C parameters inside macro definitions
L label no no 0 C goto labels
+Y unknown no yes 4 C unknown identifier
d macro yes no 2 C macro definitions
e enumerator yes no 0 C enumerators (values inside an enumeration)
f function yes no 0 C function definitions
g enum yes no 0 C enumeration names
h header yes yes 2 C included header files
l local no no 0 C local variables
-m member yes no 0 C struct, and union members
+m member yes no 1 C struct, and union members
p prototype no no 0 C function prototypes
s struct yes no 0 C structure names
t typedef yes no 0 C typedefs
diff --git a/Units/parser-c.r/c-reftag-member.d/args.ctags b/Units/parser-c.r/c-reftag-member.d/args.ctags
new file mode 100644
index 0000000000..6e0571e5a0
--- /dev/null
+++ b/Units/parser-c.r/c-reftag-member.d/args.ctags
@@ -0,0 +1,6 @@
+--sort=no
+--extras=+r
+--fields=+rKZ
+--kinds-C=*
+--roles-C.{member}=*
+--roles-C.{unknown}=+{value}{defvar}
diff --git a/Units/parser-c.r/c-reftag-member.d/expected.tags b/Units/parser-c.r/c-reftag-member.d/expected.tags
new file mode 100644
index 0000000000..084b03f12a
--- /dev/null
+++ b/Units/parser-c.r/c-reftag-member.d/expected.tags
@@ -0,0 +1,6 @@
+ops input.c /^static struct ops file_ops = {$/;" unknown roles:defvar
+file_ops input.c /^static struct ops file_ops = {$/;" variable typeref:struct:ops file: roles:def
+read input.c /^ .read = file_read_fn,$/;" member scope:variable:file_ops roles:initialized
+file_read_fn input.c /^ .read = file_read_fn,$/;" unknown scope:variable:file_ops roles:value
+write input.c /^ .write = file_write_fn,$/;" member scope:variable:file_ops roles:initialized
+file_write_fn input.c /^ .write = file_write_fn,$/;" unknown scope:variable:file_ops roles:value
diff --git a/Units/parser-c.r/c-reftag-member.d/input.c b/Units/parser-c.r/c-reftag-member.d/input.c
new file mode 100644
index 0000000000..e49292cadc
--- /dev/null
+++ b/Units/parser-c.r/c-reftag-member.d/input.c
@@ -0,0 +1,4 @@
+static struct ops file_ops = {
+ .read = file_read_fn,
+ .write = file_write_fn,
+};
diff --git a/Units/parser-c.r/c-reftags-unknown-ref.d/args.ctags b/Units/parser-c.r/c-reftags-unknown-ref.d/args.ctags
new file mode 100644
index 0000000000..a56fea51c3
--- /dev/null
+++ b/Units/parser-c.r/c-reftags-unknown-ref.d/args.ctags
@@ -0,0 +1,5 @@
+--sort=no
+--extras=+r
+--fields=+r
+--kinds-C=*
+--roles-C.{unknown}=*
diff --git a/Units/parser-c.r/c-reftags-unknown-ref.d/expected.tags b/Units/parser-c.r/c-reftags-unknown-ref.d/expected.tags
new file mode 100644
index 0000000000..d2687c75f1
--- /dev/null
+++ b/Units/parser-c.r/c-reftags-unknown-ref.d/expected.tags
@@ -0,0 +1,13 @@
+x input.c /^struct x {$/;" s file: roles:def
+y input.c /^ int y;$/;" m struct:x typeref:typename:int file: roles:def
+X input.c /^enum X {$/;" g file: roles:def
+A input.c /^ A, B$/;" e enum:X file: roles:def
+B input.c /^ A, B$/;" e enum:X file: roles:def
+i input.c /^extern int i;$/;" x typeref:typename:int roles:def
+f input.c /^int f(int j)$/;" f typeref:typename:int roles:def
+j input.c /^int f(int j)$/;" z function:f typeref:typename:int file: roles:def
+j input.c /^ if (j == 0)$/;" Y function:f roles:ref
+i input.c /^ return i + B + j + f(0);$/;" Y function:f roles:ref
+B input.c /^ return i + B + j + f(0);$/;" Y function:f roles:ref
+j input.c /^ return i + B + j + f(0);$/;" Y function:f roles:ref
+f input.c /^ return i + B + j + f(0);$/;" Y function:f roles:applied
diff --git a/Units/parser-c.r/c-reftags-unknown-ref.d/input.c b/Units/parser-c.r/c-reftags-unknown-ref.d/input.c
new file mode 100644
index 0000000000..ddb280b25a
--- /dev/null
+++ b/Units/parser-c.r/c-reftags-unknown-ref.d/input.c
@@ -0,0 +1,15 @@
+struct x {
+ int y;
+};
+
+enum X {
+ A, B
+};
+
+extern int i;
+int f(int j)
+{
+ if (j == 0)
+ return 0;
+ return i + B + j + f(0);
+}
diff --git a/Units/parser-cxx.r/bug639644.cpp.d/expected.tags b/Units/parser-cxx.r/bug639644.cpp.d/expected.tags
index 19f59e96e7..2640de8faf 100644
--- a/Units/parser-cxx.r/bug639644.cpp.d/expected.tags
+++ b/Units/parser-cxx.r/bug639644.cpp.d/expected.tags
@@ -1,2 +1,2 @@
-__anon21d591360111 input.h /^{$/;" n
-foo input.h /^ int foo;$/;" v namespace:__anon21d591360111 typeref:typename:int
+__anon21d591360112 input.h /^{$/;" n
+foo input.h /^ int foo;$/;" v namespace:__anon21d591360112 typeref:typename:int
diff --git a/Units/parser-cxx.r/namespace.cpp.d/expected.tags b/Units/parser-cxx.r/namespace.cpp.d/expected.tags
index 2a2ddb6e22..4a0e672ac8 100644
--- a/Units/parser-cxx.r/namespace.cpp.d/expected.tags
+++ b/Units/parser-cxx.r/namespace.cpp.d/expected.tags
@@ -1,15 +1,15 @@
-__anon396601200111 input.cpp /^namespace {$/;" n file: end:8
-anon_f input.cpp /^ void anon_f() { };$/;" f namespace:__anon396601200111 typeref:typename:void end:3
-__anon396601200211 input.cpp /^ namespace {$/;" n namespace:__anon396601200111 file: end:7
-anon_anon_f input.cpp /^ void anon_anon_f() { };$/;" f namespace:__anon396601200111::__anon396601200211 typeref:typename:void end:6
+__anon396601200112 input.cpp /^namespace {$/;" n file: end:8
+anon_f input.cpp /^ void anon_f() { };$/;" f namespace:__anon396601200112 typeref:typename:void end:3
+__anon396601200212 input.cpp /^ namespace {$/;" n namespace:__anon396601200112 file: end:7
+anon_anon_f input.cpp /^ void anon_anon_f() { };$/;" f namespace:__anon396601200112::__anon396601200212 typeref:typename:void end:6
a1 input.cpp /^namespace a1 {$/;" n file: end:24
a1_f input.cpp /^ void a1_f() { }$/;" f namespace:a1 typeref:typename:void end:11
a2 input.cpp /^ namespace a2 {$/;" n namespace:a1 file: end:19
a1_a2_f input.cpp /^ void a1_a2_f() { }$/;" f namespace:a1::a2 typeref:typename:void end:14
a3 input.cpp /^ namespace a3 {$/;" n namespace:a1::a2 file: end:18
a1_a2_a3_f input.cpp /^ void a1_a2_a3_f() { };$/;" f namespace:a1::a2::a3 typeref:typename:void end:17
-__anon396601200311 input.cpp /^ namespace {$/;" n namespace:a1 file: end:23
-a1_anon_f input.cpp /^ void a1_anon_f() { };$/;" f namespace:a1::__anon396601200311 typeref:typename:void end:22
+__anon396601200312 input.cpp /^ namespace {$/;" n namespace:a1 file: end:23
+a1_anon_f input.cpp /^ void a1_anon_f() { };$/;" f namespace:a1::__anon396601200312 typeref:typename:void end:22
b1 input.cpp /^namespace b1::b2 {$/;" n file: end:32
b2 input.cpp /^namespace b1::b2 {$/;" n namespace:b1 file: end:32
b1_b2_f input.cpp /^ void b1_b2_f() { };$/;" f namespace:b1::b2 typeref:typename:void end:27
diff --git a/Units/parser-qtmoc.r/simple-qt-reftag.d/args.ctags b/Units/parser-qtmoc.r/simple-qt-reftag.d/args.ctags
new file mode 100644
index 0000000000..94e926553b
--- /dev/null
+++ b/Units/parser-qtmoc.r/simple-qt-reftag.d/args.ctags
@@ -0,0 +1,6 @@
+--sort=no
+--kinds-C++=+p
+--fields=+lK
+--extras=+r
+--kinds-C++=+{unknown}
+--roles-C++.{unknown}=+{ref}
diff --git a/Units/parser-qtmoc.r/simple-qt-reftag.d/expected.tags b/Units/parser-qtmoc.r/simple-qt-reftag.d/expected.tags
new file mode 100644
index 0000000000..680d452404
--- /dev/null
+++ b/Units/parser-qtmoc.r/simple-qt-reftag.d/expected.tags
@@ -0,0 +1,65 @@
+QFrame input.h /^class ColumnPreferencesFrame : public QFrame$/;" unknown language:C++
+ColumnPreferencesFrame input.h /^class ColumnPreferencesFrame : public QFrame$/;" class language:C++
+Q_OBJECT input.h /^ Q_OBJECT$/;" unknown language:C++ class:ColumnPreferencesFrame
+method0 input.h /^ void method0(void);$/;" prototype language:C++ class:ColumnPreferencesFrame typeref:typename:void
+slots input.h /^private slots:$/;" unknown language:C++ class:ColumnPreferencesFrame
+slot0 input.h /^ void slot0(void);$/;" prototype language:C++ class:ColumnPreferencesFrame typeref:typename:void
+slot0 input.h /^ void slot0(void);$/;" slot language:QtMoc class:ColumnPreferencesFrame typeref:typename:void
+slot1 input.h /^ void slot1(void);$/;" prototype language:C++ class:ColumnPreferencesFrame typeref:typename:void
+slot1 input.h /^ void slot1(void);$/;" slot language:QtMoc class:ColumnPreferencesFrame typeref:typename:void
+slots input.h /^public slots:$/;" unknown language:C++ class:ColumnPreferencesFrame
+slot2 input.h /^ void slot2(void);$/;" prototype language:C++ class:ColumnPreferencesFrame typeref:typename:void
+slot2 input.h /^ void slot2(void);$/;" slot language:QtMoc class:ColumnPreferencesFrame typeref:typename:void
+slot3 input.h /^ void slot3(void);$/;" prototype language:C++ class:ColumnPreferencesFrame typeref:typename:void
+slot3 input.h /^ void slot3(void);$/;" slot language:QtMoc class:ColumnPreferencesFrame typeref:typename:void
+Q_SLOTS input.h /^Q_SLOTS:$/;" unknown language:C++ class:ColumnPreferencesFrame
+slot4 input.h /^ void slot4(void);$/;" prototype language:C++ class:ColumnPreferencesFrame typeref:typename:void
+slot4 input.h /^ void slot4(void);$/;" slot language:QtMoc class:ColumnPreferencesFrame typeref:typename:void
+slot5 input.h /^ void slot5(void);$/;" prototype language:C++ class:ColumnPreferencesFrame typeref:typename:void
+slot5 input.h /^ void slot5(void);$/;" slot language:QtMoc class:ColumnPreferencesFrame typeref:typename:void
+field0 input.h /^ int field0;$/;" member language:C++ class:ColumnPreferencesFrame typeref:typename:int
+method1 input.h /^ virtual void method1(void);$/;" prototype language:C++ class:ColumnPreferencesFrame typeref:typename:void
+Q_SLOTS input.h /^private Q_SLOTS:$/;" unknown language:C++ class:ColumnPreferencesFrame
+slot6 input.h /^ void slot6(void);$/;" prototype language:C++ class:ColumnPreferencesFrame typeref:typename:void
+slot6 input.h /^ void slot6(void);$/;" slot language:QtMoc class:ColumnPreferencesFrame typeref:typename:void
+slot7 input.h /^ void slot7(void);$/;" prototype language:C++ class:ColumnPreferencesFrame typeref:typename:void
+slot7 input.h /^ void slot7(void);$/;" slot language:QtMoc class:ColumnPreferencesFrame typeref:typename:void
+Q_SLOTS input.h /^public Q_SLOTS:$/;" unknown language:C++ class:ColumnPreferencesFrame
+slot8 input.h /^ void slot8(void);$/;" prototype language:C++ class:ColumnPreferencesFrame typeref:typename:void
+slot8 input.h /^ void slot8(void);$/;" slot language:QtMoc class:ColumnPreferencesFrame typeref:typename:void
+slot9 input.h /^ void slot9(void);$/;" prototype language:C++ class:ColumnPreferencesFrame typeref:typename:void
+slot9 input.h /^ void slot9(void);$/;" slot language:QtMoc class:ColumnPreferencesFrame typeref:typename:void
+slots input.h /^slots:$/;" unknown language:C++ class:ColumnPreferencesFrame
+slot10 input.h /^ void slot10(void);$/;" prototype language:C++ class:ColumnPreferencesFrame typeref:typename:void
+slot10 input.h /^ void slot10(void);$/;" slot language:QtMoc class:ColumnPreferencesFrame typeref:typename:void
+slot11 input.h /^ void slot11(void);$/;" prototype language:C++ class:ColumnPreferencesFrame typeref:typename:void
+slot11 input.h /^ void slot11(void);$/;" slot language:QtMoc class:ColumnPreferencesFrame typeref:typename:void
+field1 input.h /^ int field1;$/;" member language:C++ class:ColumnPreferencesFrame typeref:typename:int
+signals input.h /^signals:$/;" unknown language:C++ class:ColumnPreferencesFrame
+signal0 input.h /^ void signal0(void);$/;" prototype language:C++ class:ColumnPreferencesFrame typeref:typename:void
+signal0 input.h /^ void signal0(void);$/;" signal language:QtMoc class:ColumnPreferencesFrame typeref:typename:void
+signal1 input.h /^ void signal1(void);$/;" prototype language:C++ class:ColumnPreferencesFrame typeref:typename:void
+signal1 input.h /^ void signal1(void);$/;" signal language:QtMoc class:ColumnPreferencesFrame typeref:typename:void
+field2 input.h /^ int field2;$/;" member language:C++ class:ColumnPreferencesFrame typeref:typename:int
+method2 input.h /^ virtual void method2(void);$/;" prototype language:C++ class:ColumnPreferencesFrame typeref:typename:void
+Q_SIGNALS input.h /^Q_SIGNALS:$/;" unknown language:C++ class:ColumnPreferencesFrame
+signal2 input.h /^ void signal2(void);$/;" prototype language:C++ class:ColumnPreferencesFrame typeref:typename:void
+signal2 input.h /^ void signal2(void);$/;" signal language:QtMoc class:ColumnPreferencesFrame typeref:typename:void
+signal3 input.h /^ void signal3(void);$/;" prototype language:C++ class:ColumnPreferencesFrame typeref:typename:void
+signal3 input.h /^ void signal3(void);$/;" signal language:QtMoc class:ColumnPreferencesFrame typeref:typename:void
+field3 input.h /^ int field3;$/;" member language:C++ class:ColumnPreferencesFrame typeref:typename:int
+method3 input.h /^ virtual void method3(void);$/;" prototype language:C++ class:ColumnPreferencesFrame typeref:typename:void
+Q_PROPERTY input.h /^ Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged)$/;" unknown language:C++ class:ColumnPreferencesFrame
+QString input.h /^ Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged)$/;" unknown language:C++ class:ColumnPreferencesFrame
+text input.h /^ Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged)$/;" property language:QtMoc class:ColumnPreferencesFrame typeref:typename:QString
+MEMBER input.h /^ Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged)$/;" unknown language:C++ class:ColumnPreferencesFrame
+m_text input.h /^ Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged)$/;" unknown language:C++ class:ColumnPreferencesFrame
+NOTIFY input.h /^ Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged)$/;" unknown language:C++ class:ColumnPreferencesFrame
+textChanged input.h /^ Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged)$/;" unknown language:C++ class:ColumnPreferencesFrame
+Q_PROPERTY input.h /^ Q_PROPERTY( bool ShowNonprinting READ showsNonprinting WRITE setShowsNonprinting )$/;" unknown language:C++ class:ColumnPreferencesFrame
+ShowNonprinting input.h /^ Q_PROPERTY( bool ShowNonprinting READ showsNonprinting WRITE setShowsNonprinting )$/;" property language:QtMoc class:ColumnPreferencesFrame typeref:typename:bool
+READ input.h /^ Q_PROPERTY( bool ShowNonprinting READ showsNonprinting WRITE setShowsNonprinting )$/;" unknown language:C++ class:ColumnPreferencesFrame
+showsNonprinting input.h /^ Q_PROPERTY( bool ShowNonprinting READ showsNonprinting WRITE setShowsNonprinting )$/;" unknown language:C++ class:ColumnPreferencesFrame
+WRITE input.h /^ Q_PROPERTY( bool ShowNonprinting READ showsNonprinting WRITE setShowsNonprinting )$/;" unknown language:C++ class:ColumnPreferencesFrame
+setShowsNonprinting input.h /^ Q_PROPERTY( bool ShowNonprinting READ showsNonprinting WRITE setShowsNonprinting )$/;" unknown language:C++ class:ColumnPreferencesFrame
+field4 input.h /^ int field4;$/;" member language:C++ class:ColumnPreferencesFrame typeref:typename:int
diff --git a/Units/parser-qtmoc.r/simple-qt-reftag.d/input.h b/Units/parser-qtmoc.r/simple-qt-reftag.d/input.h
new file mode 100644
index 0000000000..0503ca7a01
--- /dev/null
+++ b/Units/parser-qtmoc.r/simple-qt-reftag.d/input.h
@@ -0,0 +1,65 @@
+class ColumnPreferencesFrame : public QFrame
+{
+ Q_OBJECT
+ void method0(void);
+
+private slots:
+ void slot0(void);
+ void slot1(void);
+
+public slots:
+ void slot2(void);
+ void slot3(void);
+
+Q_SLOTS:
+ void slot4(void);
+ void slot5(void);
+
+private:
+ int field0;
+
+protected:
+ virtual void method1(void);
+
+private Q_SLOTS:
+ void slot6(void);
+ void slot7(void);
+
+public Q_SLOTS:
+ void slot8(void);
+ void slot9(void);
+
+slots:
+ void slot10(void);
+ void slot11(void);
+
+private:
+ int field1;
+
+signals:
+ void signal0(void);
+ void signal1(void);
+
+private:
+ int field2;
+
+protected:
+ virtual void method2(void);
+
+Q_SIGNALS:
+ void signal2(void);
+ void signal3(void);
+
+private:
+ int field3;
+
+protected:
+ virtual void method3(void);
+
+ Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged)
+ Q_PROPERTY( bool ShowNonprinting READ showsNonprinting WRITE setShowsNonprinting )
+
+private:
+ int field4;
+
+};
diff --git a/misc/mini-geany.expected b/misc/mini-geany.expected
index f075db78b3..3b82d0739e 100644
--- a/misc/mini-geany.expected
+++ b/misc/mini-geany.expected
@@ -17,6 +17,7 @@ x: externvar
z: parameter
L: label
D: macroparam
+Y: unknown
Parsing buffer:
foo line: 1 kind: function lang: C
diff --git a/parsers/cxx/cxx_parser.c b/parsers/cxx/cxx_parser.c
index 6ed9a83dd5..404ff24615 100644
--- a/parsers/cxx/cxx_parser.c
+++ b/parsers/cxx/cxx_parser.c
@@ -873,7 +873,7 @@ bool cxxParserParseEnum(void)
if(pTypeEnd)
{
CXX_DEBUG_ASSERT(pTypeBegin,"Type begin should be also set here");
- pTypeName = cxxTagCheckAndSetTypeField(pTypeBegin,pTypeEnd);
+ pTypeName = cxxTagCheckAndSetTypeField(pTypeBegin,pTypeEnd, false);
}
if(bIsScopedEnum)
diff --git a/parsers/cxx/cxx_parser_function.c b/parsers/cxx/cxx_parser_function.c
index f4e02f554a..40bc5f9db6 100644
--- a/parsers/cxx/cxx_parser_function.c
+++ b/parsers/cxx/cxx_parser_function.c
@@ -1543,6 +1543,7 @@ int cxxParserEmitFunctionTags(
0
);
+ cxxTagUseTokensInRangeAsPartOfDefTags(CORK_NIL,pInfo->pIdentifierStart,pInfo->pIdentifierEnd);
cxxTokenChainDestroyRange(pInfo->pIdentifierChain,pInfo->pIdentifierStart,pInfo->pIdentifierEnd);
CXX_DEBUG_ASSERT(
@@ -1653,7 +1654,7 @@ int cxxParserEmitFunctionTags(
CXXToken * pTokenBeforeParenthesis = pInfo->pParenthesis->pPrev;
cxxTokenChainTake(pInfo->pParenthesisContainerChain,pInfo->pParenthesis);
- pTypeName = cxxTagCheckAndSetTypeField(pInfo->pTypeStart,pInfo->pTypeEnd);
+ pTypeName = cxxTagCheckAndSetTypeField(pInfo->pTypeStart,pInfo->pTypeEnd, false);
cxxTokenChainInsertAfter(
pInfo->pParenthesisContainerChain,
@@ -1664,7 +1665,7 @@ int cxxParserEmitFunctionTags(
pTypeName = NULL;
}
} else {
- pTypeName = cxxTagCheckAndSetTypeField(pInfo->pTypeStart,pInfo->pTypeEnd);
+ pTypeName = cxxTagCheckAndSetTypeField(pInfo->pTypeStart,pInfo->pTypeEnd, false);
}
} else {
pTypeName = NULL;
@@ -1694,6 +1695,7 @@ int cxxParserEmitFunctionTags(
pInfo->pTemplateSpecializationEnd,
0
);
+ /* TODO */
// Tricky. We append it to the specialization chain which will
// be then used by cxxTagHandleTemplateFileds()
@@ -1919,7 +1921,8 @@ void cxxParserEmitFunctionParameterTags(CXXTypedVariableSet * pInfo)
pTypeName = cxxTagCheckAndSetTypeField(
pTypeStart,
- pTypeEnd
+ pTypeEnd,
+ false
);
} else {
// The declaration contains only the identifier!
diff --git a/parsers/cxx/cxx_parser_lambda.c b/parsers/cxx/cxx_parser_lambda.c
index bfc73749c4..9625f5418a 100644
--- a/parsers/cxx/cxx_parser_lambda.c
+++ b/parsers/cxx/cxx_parser_lambda.c
@@ -239,7 +239,7 @@ bool cxxParserHandleLambda(CXXToken * pParenthesis)
markTagExtraBit (tag, XTAG_ANONYMOUS);
if(pTypeStart)
- pTypeName = cxxTagCheckAndSetTypeField(pTypeStart,pTypeEnd);
+ pTypeName = cxxTagCheckAndSetTypeField(pTypeStart,pTypeEnd, false);
else
pTypeName = NULL;
diff --git a/parsers/cxx/cxx_parser_namespace.c b/parsers/cxx/cxx_parser_namespace.c
index 0eb4bdcfd4..48bf9559ea 100644
--- a/parsers/cxx/cxx_parser_namespace.c
+++ b/parsers/cxx/cxx_parser_namespace.c
@@ -141,6 +141,7 @@ bool cxxParserParseNamespace(void)
pLastIdentifier,
CXXTokenChainExtractRangeNoTrailingSpaces
);
+ /* TODO */
cxxTagSetField(
CXXTagCPPFieldAliasedName,
diff --git a/parsers/cxx/cxx_parser_template.c b/parsers/cxx/cxx_parser_template.c
index 71bbd67845..0902a200aa 100644
--- a/parsers/cxx/cxx_parser_template.c
+++ b/parsers/cxx/cxx_parser_template.c
@@ -825,7 +825,8 @@ void cxxParserEmitTemplateParameterTags(void)
CXXToken * pTypeToken = cxxTagCheckAndSetTypeField(
g_cxx.oTemplateParameters.aTypeStarts[i],
- g_cxx.oTemplateParameters.aTypeEnds[i]
+ g_cxx.oTemplateParameters.aTypeEnds[i],
+ false
);
cxxTagCommit(NULL);
diff --git a/parsers/cxx/cxx_parser_tokenizer.c b/parsers/cxx/cxx_parser_tokenizer.c
index f43137bb6c..7e70c3fe00 100644
--- a/parsers/cxx/cxx_parser_tokenizer.c
+++ b/parsers/cxx/cxx_parser_tokenizer.c
@@ -11,6 +11,7 @@
#include "cxx_debug.h"
#include "cxx_keyword.h"
+#include "cxx_reftag.h"
#include "cxx_token.h"
#include "cxx_token_chain.h"
@@ -1214,7 +1215,7 @@ void cxxParserUngetCurrentToken(void)
//
// In some special cases this function may parse more than one token,
// however only a single token will always be returned.
-bool cxxParserParseNextToken(void)
+static bool cxxParserParseNextTokenNoRefTag(void)
{
// The token chain should not be allowed to grow arbitrarily large.
// The token structures are quite big and it's easy to grow up to
@@ -1689,3 +1690,11 @@ bool cxxParserParseNextToken(void)
return true;
}
+
+bool cxxParserParseNextToken(void)
+{
+ bool r = cxxParserParseNextTokenNoRefTag();
+ if(r)
+ cxxReftagEvalNewToken();
+ return r;
+}
diff --git a/parsers/cxx/cxx_parser_typedef.c b/parsers/cxx/cxx_parser_typedef.c
index 34895c0b95..0160339421 100644
--- a/parsers/cxx/cxx_parser_typedef.c
+++ b/parsers/cxx/cxx_parser_typedef.c
@@ -433,7 +433,8 @@ void cxxParserExtractTypedef(
pTypeName = cxxTagCheckAndSetTypeField(
cxxTokenChainFirst(pChain),
- pComma ? pComma->pPrev : cxxTokenChainLast(pChain)
+ pComma ? pComma->pPrev : cxxTokenChainLast(pChain),
+ false
);
}
diff --git a/parsers/cxx/cxx_parser_variable.c b/parsers/cxx/cxx_parser_variable.c
index c63476cdad..e49a3471e6 100644
--- a/parsers/cxx/cxx_parser_variable.c
+++ b/parsers/cxx/cxx_parser_variable.c
@@ -14,6 +14,7 @@
#include "cxx_token.h"
#include "cxx_token_chain.h"
#include "cxx_scope.h"
+#include "cxx_reftag.h"
#include "vstring.h"
#include "read.h"
@@ -67,6 +68,101 @@ CXXToken * cxxParserFindFirstPossiblyNestedAndQualifiedIdentifier(
return cxxTokenChainNextTokenOfType(pId,CXXTokenTypeIdentifier);
}
+static void cxxParserExtractMembersInitialization(CXXTokenChain * pChain, int iScopeCorkIndex)
+{
+ tagEntryInfo *pTag = getEntryInCorkQueue(iScopeCorkIndex);
+ if(!pTag || pTag->kindIndex != CXXTagKindVARIABLE)
+ return;
+
+ // Looking for the pattern:
+ //
+ // { .member = ...
+ //
+ // or
+ //
+ // ; .member = ...
+ //
+ for (CXXToken *t = cxxTokenChainFirst(pChain); t && t != pChain->pTail; t = t->pNext)
+ {
+ if(
+ (cxxTokenTypeIs(t, CXXTokenTypeOpeningBracket)
+ || cxxTokenTypeIs(t, CXXTokenTypeComma)) &&
+ (t->pNext
+ && cxxTokenTypeIs(t->pNext, CXXTokenTypeDotOperator)) &&
+ (t->pNext->pNext
+ && cxxTokenTypeIs(t->pNext->pNext, CXXTokenTypeIdentifier)) &&
+ (t->pNext->pNext->pNext
+ && cxxTokenTypeIs(t->pNext->pNext->pNext, CXXTokenTypeAssignment))
+ )
+ {
+ CXXToken *pIdentifier = t->pNext->pNext;
+ if(pIdentifier->iCorkIndex != CORK_NIL && pIdentifier->bCorkIndexForReftag)
+ {
+ // Tagged with "unknown" kind already. Reset it.
+ cxxReftagReset(pIdentifier->iCorkIndex, iScopeCorkIndex,
+ CXXTagKindMEMBER, CXXTagMemberRoleINITIALIZED, true);
+ }
+ else if(pIdentifier->iCorkIndex == CORK_NIL)
+ {
+ tagEntryInfo oEntry;
+ initRefTagEntry(&oEntry, vStringValue(pIdentifier->pszWord),
+ CXXTagKindMEMBER, CXXTagMemberRoleINITIALIZED);
+ oEntry.lineNumber = pIdentifier->iLineNumber;
+ oEntry.filePosition = pIdentifier->oFilePosition;
+ oEntry.isFileScope = false;
+ // TODO: Other scope field must be filled.
+ oEntry.extensionFields.scopeIndex = iScopeCorkIndex;
+ pIdentifier->iCorkIndex = makeTagEntry(&oEntry);
+ registerEntry(pIdentifier->iCorkIndex);
+ pIdentifier->bCorkIndexForReftag = 1;
+
+ }
+ // Point t to the assignment.
+ t = t->pNext->pNext->pNext;
+
+ // Looking for the pattern:
+ //
+ // = unknown,
+ //
+ // or
+ //
+ // = unknown}
+ //
+ if(t->pNext &&
+ cxxTokenTypeIs(t->pNext, CXXTokenTypeIdentifier) &&
+ t->pNext->pNext &&
+ cxxTokenTypeIsOneOf(t->pNext->pNext,
+ CXXTokenTypeComma|CXXTokenTypeClosingBracket))
+
+ {
+ CXXToken *pIdentifier = t->pNext;
+ if(pIdentifier->iCorkIndex != CORK_NIL && pIdentifier->bCorkIndexForReftag)
+ {
+ cxxReftagReset(pIdentifier->iCorkIndex, iScopeCorkIndex,
+ CXXTagKindUNKNOWN, CXXTagUnknownRoleVALUE,
+ true);
+ }
+ else if(pIdentifier->iCorkIndex == CORK_NIL)
+ {
+ tagEntryInfo oEntry;
+ initRefTagEntry(&oEntry, vStringValue(pIdentifier->pszWord),
+ CXXTagKindUNKNOWN, CXXTagUnknownRoleVALUE);
+ oEntry.lineNumber = pIdentifier->iLineNumber;
+ oEntry.filePosition = pIdentifier->oFilePosition;
+ oEntry.isFileScope = false;
+ // TODO: Other scope field must be filled.
+ oEntry.extensionFields.scopeIndex = iScopeCorkIndex;
+ pIdentifier->iCorkIndex = makeTagEntry(&oEntry);
+ registerEntry(pIdentifier->iCorkIndex);
+ pIdentifier->bCorkIndexForReftag = 1;
+ }
+ t = t->pNext;
+ }
+ }
+ }
+ return;
+}
+
//
// Attempt to extract variable declarations from the chain.
// Returns true if at least one variable was extracted.
@@ -665,6 +761,7 @@ bool cxxParserExtractVariableDeclarations(CXXTokenChain * pChain,unsigned int uF
);
CXXToken * pScopeId = cxxTokenChainExtractRange(pScopeStart,pPartEnd->pPrev,0);
+ /* TODO */
cxxScopePush(
pScopeId,
CXXScopeTypeClass,
@@ -731,7 +828,7 @@ bool cxxParserExtractVariableDeclarations(CXXTokenChain * pChain,unsigned int uF
}
// anything that remains is part of type
- CXXToken * pTypeToken = cxxTagCheckAndSetTypeField(cxxTokenChainFirst(pChain),t->pPrev);
+ CXXToken * pTypeToken = cxxTagCheckAndSetTypeField(cxxTokenChainFirst(pChain),t->pPrev, true);
tag->isFileScope = bKnRStyleParameters ?
true :
@@ -816,11 +913,18 @@ bool cxxParserExtractVariableDeclarations(CXXTokenChain * pChain,unsigned int uF
return bGotVariable;
}
+ // pointing {} of ... = {}
+ CXXToken * pTokenBracketChain = NULL;
if(!cxxTokenTypeIsOneOf(
t,
CXXTokenTypeComma | CXXTokenTypeSemicolon | CXXTokenTypeOpeningBracket
))
{
+ if(iCorkIndex != CORK_NIL &&
+ cxxTokenTypeIs(t, CXXTokenTypeAssignment) &&
+ t->pNext && cxxTokenTypeIs(t->pNext, CXXTokenTypeBracketChain) &&
+ t->pNext->pChain)
+ pTokenBracketChain = t->pNext;
// look for it, but also check for "<" signs: these usually indicate an uncondensed
// template. We give up on them as they are too complicated in this context.
// It's rather unlikely to have multiple declarations with templates after the first one
@@ -845,6 +949,9 @@ bool cxxParserExtractVariableDeclarations(CXXTokenChain * pChain,unsigned int uF
{
if (iCorkIndex != CORK_NIL)
{
+ if(pTokenBracketChain)
+ cxxParserExtractMembersInitialization(pTokenBracketChain->pChain,
+ iCorkIndex);
cxxParserSetEndLineForTagInCorkQueue (iCorkIndex, t->iLineNumber);
iCorkIndex = CORK_NIL;
if(iCorkIndexFQ != CORK_NIL)
@@ -860,6 +967,9 @@ bool cxxParserExtractVariableDeclarations(CXXTokenChain * pChain,unsigned int uF
// Comma. Might have other declarations here.
if (iCorkIndex != CORK_NIL)
{
+ if(pTokenBracketChain)
+ cxxParserExtractMembersInitialization(pTokenBracketChain->pChain,
+ iCorkIndex);
cxxParserSetEndLineForTagInCorkQueue (iCorkIndex, t->iLineNumber);
iCorkIndex = CORK_NIL;
if(iCorkIndexFQ != CORK_NIL)
diff --git a/parsers/cxx/cxx_qtmoc.c b/parsers/cxx/cxx_qtmoc.c
index d02f227e29..b7e49e30b6 100644
--- a/parsers/cxx/cxx_qtmoc.c
+++ b/parsers/cxx/cxx_qtmoc.c
@@ -86,6 +86,7 @@ static void qtMocMakeTagForProperty (CXXToken * pToken, const char *pszType)
{
tagEntryInfo tag;
+ cxxTagUseTokenAsPartOfDefTag(CORK_NIL, pToken);
initTagEntry(&tag,
vStringValue(pToken->pszWord),
K_PROPERTY);
diff --git a/parsers/cxx/cxx_reftag.c b/parsers/cxx/cxx_reftag.c
new file mode 100644
index 0000000000..efd5eba1c6
--- /dev/null
+++ b/parsers/cxx/cxx_reftag.c
@@ -0,0 +1,78 @@
+/*
+* Copyright (c) 2022, Masatake YAMATO
+*
+* This source code is released for free distribution under the terms of the
+* GNU General Public License version 2 or (at your option) any later version.
+*
+* This module contains functions for extracting reference tags
+*/
+
+#include "cxx_reftag.h"
+
+#include "cxx_token.h"
+#include "cxx_parser_internal.h"
+#include "cxx_scope.h"
+#include "read.h"
+
+
+void cxxReftagEvalNewToken(void)
+{
+ if(cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeIdentifier) &&
+ cxxTagKindEnabled(CXXTagKindUNKNOWN) &&
+ cxxTagRoleEnabled(CXXTagKindUNKNOWN, CXXTagUnknownRoleREFERENCED))
+ {
+ // QtMoc subparser calls this function indirectly.
+ // However, "unknown" kind + "ref" role is part of the
+ // base parser like C++. They are not part of the subparser.
+ // So we have to swtich the context for making the reference tag
+ // temporarily here.
+ const bool in_subparser = (g_cxx.eLangType != getInputLanguage());
+ if (in_subparser)
+ pushLanguage(g_cxx.eLangType);
+
+ tagEntryInfo oEntry;
+ initRefTagEntry(&oEntry, vStringValue(g_cxx.pToken->pszWord),
+ CXXTagKindUNKNOWN, CXXTagUnknownRoleREFERENCED);
+ oEntry.extensionFields.scopeIndex = cxxScopeGetDefTag();
+ g_cxx.pToken->iCorkIndex = makeTagEntry(&oEntry);
+ g_cxx.pToken->bCorkIndexForReftag = true;
+
+ if (in_subparser)
+ popLanguage();
+ }
+ else if (cxxTokenTypeIs(g_cxx.pToken,CXXTokenTypeOpeningParenthesis)
+ && cxxTagKindEnabled(CXXTagKindUNKNOWN) &&
+ cxxTagRoleEnabled(CXXTagKindUNKNOWN, CXXTagUnknownRoleAPPLIED))
+ {
+ if(g_cxx.pToken->pPrev && cxxTokenTypeIs(g_cxx.pToken->pPrev,
+ CXXTokenTypeIdentifier))
+ {
+ CXXToken * i = g_cxx.pToken->pPrev;
+ if(i->iCorkIndex != CORK_NIL && i->bCorkIndexForReftag)
+ cxxReftagReset(i->iCorkIndex, CORK_NIL,
+ CXXTagKindUNKNOWN, CXXTagUnknownRoleAPPLIED, false);
+ else
+ ;
+ }
+ }
+}
+
+void cxxReftagReset(int iCorkIndex, int iScopeCorkIndex,
+ int iKindIndex, int iRoleIndex, bool bUpdateScope)
+{
+ tagEntryInfo *pEntry = getEntryInCorkQueue(iCorkIndex);
+ if(pEntry == NULL)
+ return;
+ if (pEntry->placeholder)
+ return;
+
+ clearRoles(pEntry);
+ if(bUpdateScope && pEntry->extensionFields.scopeIndex != CORK_NIL)
+ unregisterEntry(iCorkIndex);
+ if (bUpdateScope)
+ pEntry->extensionFields.scopeIndex = iScopeCorkIndex;
+ pEntry->kindIndex = iKindIndex;
+ assignRole(pEntry, iRoleIndex);
+ if (bUpdateScope)
+ registerEntry(iCorkIndex);
+}
diff --git a/parsers/cxx/cxx_reftag.h b/parsers/cxx/cxx_reftag.h
new file mode 100644
index 0000000000..411b763cb7
--- /dev/null
+++ b/parsers/cxx/cxx_reftag.h
@@ -0,0 +1,21 @@
+#ifndef _cxxReftag_h_
+#define _cxxReftag_h_
+/*
+* Copyright (c) 2022, Masatake YAMATO
+*
+* This source code is released for free distribution under the terms of the
+* GNU General Public License version 2 or (at your option) any later version.
+*
+* This module contains functions for extracting reference tags
+*/
+
+#include "general.h"
+
+void cxxReftagEvalNewToken(void);
+
+// Reset the kind and role of the tag specified with iCorkIndex.
+// The scope of the tag is also updated with iScopeCorkIndex.
+void cxxReftagReset(int iCorkIndex, int iScopeCorkIndex,
+ int iKindIndex, int iRoleIndex, bool bUpdateValue);
+
+#endif //!_cxxReftag_h_
diff --git a/parsers/cxx/cxx_tag.c b/parsers/cxx/cxx_tag.c
index 06832532e2..88d0d55332 100644
--- a/parsers/cxx/cxx_tag.c
+++ b/parsers/cxx/cxx_tag.c
@@ -12,6 +12,7 @@
#include "cxx_debug.h"
#include "cxx_token_chain.h"
#include "cxx_parser_internal.h"
+#include "cxx_reftag.h"
#include "entry.h"
#include "../cpreprocessor.h"
@@ -19,6 +20,27 @@
#include "trashbox.h"
#include "xtag.h"
+#define CXX_COMMON_UNKNOWN_ROLES(__langPrefix) \
+ static roleDefinition __langPrefix##UnknownRoles [] = { \
+ { false, "ref", "referenced anyhow" }, \
+ { true, "value", "used as right side value" }, \
+ { true, "defvar", "(maybe type) used for defining variables" }, \
+ { true, "applied", "(maybe macro, function, or member) called or expanded" }, \
+ }
+
+CXX_COMMON_UNKNOWN_ROLES(C);
+CXX_COMMON_UNKNOWN_ROLES(CXX);
+CXX_COMMON_UNKNOWN_ROLES(CUDA);
+
+#define CXX_COMMON_MEMBER_ROLES(__langPrefix) \
+ static roleDefinition __langPrefix##MemberRoles [] = { \
+ { true, "initialized", "initialized with form '.member = ...'" }, \
+ }
+
+CXX_COMMON_MEMBER_ROLES(C);
+CXX_COMMON_MEMBER_ROLES(CXX);
+CXX_COMMON_MEMBER_ROLES(CUDA);
+
#define CXX_COMMON_MACRO_ROLES(__langPrefix) \
static roleDefinition __langPrefix##MacroRoles [] = { \
RoleTemplateUndef, \
@@ -51,7 +73,9 @@ CXX_COMMON_HEADER_ROLES(CUDA);
.referenceOnly = true, ATTACH_ROLES(_langPrefix##HeaderRoles), .syncWith = _syncWith \
}, \
{ false, 'l', "local", "local variables", .syncWith = _syncWith }, \
- { true, 'm', "member", _szMemberDescription, .syncWith = _syncWith }, \
+ { true, 'm', "member", _szMemberDescription, .syncWith = _syncWith, \
+ .referenceOnly = false, ATTACH_ROLES(_langPrefix##MemberRoles), .syncWith = _syncWith \
+ },\
{ false, 'p', "prototype", "function prototypes", .syncWith = _syncWith }, \
{ true, 's', "struct", "structure names", .syncWith = _syncWith }, \
{ true, 't', "typedef", "typedefs", .syncWith = _syncWith }, \
@@ -60,7 +84,10 @@ CXX_COMMON_HEADER_ROLES(CUDA);
{ false, 'x', "externvar", "external and forward variable declarations", .syncWith = _syncWith }, \
{ false, 'z', "parameter", "function parameters inside function or prototype definitions", .syncWith = _syncWith }, \
{ false, 'L', "label", "goto labels", .syncWith = _syncWith }, \
- { false, 'D', "macroparam", "parameters inside macro definitions", .syncWith = _syncWith }
+ { false, 'D', "macroparam", "parameters inside macro definitions", .syncWith = _syncWith }, \
+ { false, 'Y', "unknown", "unknown identifier", \
+ .referenceOnly = true, ATTACH_ROLES(_langPrefix##UnknownRoles), .syncWith = _syncWith \
+ }
static kindDefinition g_aCXXCKinds [] = {
/* All other than LANG_AUTO are ignored.
@@ -261,7 +288,12 @@ static tagEntryInfo g_oCXXTag;
void cxxTagUseTokenAsPartOfDefTag(int iCorkIndex, CXXToken * pToken)
{
- Assert (pToken->iCorkIndex == CORK_NIL);
+ if (pToken->iCorkIndex != CORK_NIL)
+ {
+ Assert(pToken->bCorkIndexForReftag);
+ pToken->bCorkIndexForReftag = false;
+ markCorkEntryAsPlaceholder(pToken->iCorkIndex, true);
+ }
pToken->iCorkIndex = iCorkIndex;
}
@@ -309,6 +341,7 @@ tagEntryInfo * cxxTagBegin(unsigned int uKind,CXXToken * pToken)
return NULL;
}
+ cxxTagUseTokenAsPartOfDefTag(CORK_NIL, pToken);
initTagEntry(
&g_oCXXTag,
vStringValue(pToken->pszWord),
@@ -505,7 +538,8 @@ static bool cxxTagCheckTypeField(
CXXToken * cxxTagCheckAndSetTypeField(
CXXToken * pTypeStart,
- CXXToken * pTypeEnd
+ CXXToken * pTypeEnd,
+ bool bVardef
)
{
CXX_DEBUG_ASSERT(pTypeStart,"Non null type start is expected here");
@@ -584,6 +618,27 @@ CXXToken * cxxTagCheckAndSetTypeField(
return NULL;
}
+ if (bVardef && pTypeEnd && cxxTokenTypeIs(pTypeEnd, CXXTokenTypeIdentifier) &&
+ cxxTagRoleEnabled(CXXTagKindUNKNOWN, CXXTagUnknownRoleDEFVAR))
+ {
+ CXXToken *t = pTypeEnd;
+ if(t->iCorkIndex != CORK_NIL && t->bCorkIndexForReftag)
+ cxxReftagReset(t->iCorkIndex, CORK_NIL,
+ CXXTagKindUNKNOWN, CXXTagUnknownRoleDEFVAR, false);
+ else if(t->iCorkIndex == CORK_NIL)
+ {
+ tagEntryInfo oEntry;
+ initRefTagEntry(&oEntry, vStringValue(t->pszWord),
+ CXXTagKindUNKNOWN, CXXTagUnknownRoleDEFVAR);
+ oEntry.lineNumber = t->iLineNumber;
+ oEntry.filePosition = t->oFilePosition;
+ oEntry.isFileScope = false;
+ // TODO: Other scope field must be filled.
+ t->iCorkIndex = makeTagEntry(&oEntry);
+ t->bCorkIndexForReftag = 1;
+ }
+ }
+
CXX_DEBUG_PRINT("Type name is '%s'",vStringValue(pTypeName->pszWord));
g_oCXXTag.extensionFields.typeRef[0] = szTypeRef0;
diff --git a/parsers/cxx/cxx_tag.h b/parsers/cxx/cxx_tag.h
index 64e78bdd33..3187f2e904 100644
--- a/parsers/cxx/cxx_tag.h
+++ b/parsers/cxx/cxx_tag.h
@@ -35,10 +35,24 @@ enum CXXTagCommonKind
CXXTagKindPARAMETER,
CXXTagKindLABEL,
CXXTagKindMACROPARAM,
+ CXXTagKindUNKNOWN,
CXXTagCommonKindCount
};
+enum CXXTagUnknownRole
+{
+ CXXTagUnknownRoleREFERENCED,
+ CXXTagUnknownRoleVALUE,
+ CXXTagUnknownRoleDEFVAR,
+ CXXTagUnknownRoleAPPLIED,
+};
+
+enum CXXTagMemberRole
+{
+ CXXTagMemberRoleINITIALIZED,
+};
+
// Tags specific to the CPP language.
enum CXXTagCPPKind
{
@@ -111,7 +125,8 @@ tagEntryInfo * cxxTagBegin(unsigned int uKind,CXXToken * pToken);
// be destroyed after cxxTagCommit() has been called.
CXXToken * cxxTagCheckAndSetTypeField(
CXXToken * pTypeStart,
- CXXToken * pTypeEnd
+ CXXToken * pTypeEnd,
+ bool bVardef
);
typedef enum _CXXTagProperty
@@ -212,6 +227,8 @@ typedef enum {
void cxxTagInitForLanguage(langType eLangType);
// Functions for filling iCorkIndex field of tokens.
+// With specifying CORK_NIL, you can use these functions
+// just for preventing emitting reference tags associated with the token(s).
void cxxTagUseTokensInRangeAsPartOfDefTags(int iCorkIndex, CXXToken * pFrom, CXXToken * pTo);
void cxxTagUseTokenAsPartOfDefTag(int iCorkIndex, CXXToken * pToken);
#endif //!_cxxTag_h_
diff --git a/parsers/cxx/cxx_token.c b/parsers/cxx/cxx_token.c
index 8aa47b7792..c28403c40a 100644
--- a/parsers/cxx/cxx_token.c
+++ b/parsers/cxx/cxx_token.c
@@ -32,6 +32,7 @@ static CXXToken *createToken(void *createArg CTAGS_ATTR_UNUSED)
// is being reused..well.. we always want it
t->pszWord = vStringNew();
t->iCorkIndex = CORK_NIL;
+ t->bCorkIndexForReftag = false;
return t;
}
@@ -56,6 +57,7 @@ static void clearToken(CXXToken *t)
t->pPrev = NULL;
t->iCorkIndex = CORK_NIL;
+ t->bCorkIndexForReftag = false;
}
void cxxTokenAPIInit(void)
@@ -123,6 +125,7 @@ CXXToken * cxxTokenCopy(CXXToken * pToken)
pRetToken->bFollowedBySpace = pToken->bFollowedBySpace;
vStringCat(pRetToken->pszWord,pToken->pszWord);
pRetToken->iCorkIndex = pToken->iCorkIndex;
+ pRetToken->bCorkIndexForReftag = pToken->bCorkIndexForReftag;
return pRetToken;
}
diff --git a/parsers/cxx/cxx_token.h b/parsers/cxx/cxx_token.h
index 573e64b6a1..82c7ea00c2 100644
--- a/parsers/cxx/cxx_token.h
+++ b/parsers/cxx/cxx_token.h
@@ -74,6 +74,7 @@ typedef struct _CXXToken
CXXKeyword eKeyword;
CXXTokenChain * pChain; // this is NOT the parent chain!
unsigned int bFollowedBySpace: 1;
+ unsigned int bCorkIndexForReftag: 1; // iCorkIndex specifies a reference tag?
int iLineNumber;
MIOPos oFilePosition;
@@ -88,6 +89,13 @@ typedef struct _CXXToken
unsigned char uInternalScopeType;
unsigned char uInternalScopeAccess;
+ // When reading an identifier, the parser makes a reference tag
+ // for it. The cork index for the tag is set to this member.
+ // When the parser recognizes the identifier is part of a definition,
+ // the parser invalidate the reference tag with
+ // cxxTagUseTokensInRangeAsPartOfDefTags() or
+ // cxxTagUseTokenAsPartOfDefTag(). These two functions may
+ // set the index for definition tag.
int iCorkIndex;
} CXXToken;
diff --git a/parsers/cxx/cxx_token_chain.c b/parsers/cxx/cxx_token_chain.c
index dbeaaf0dda..481beb5b9d 100644
--- a/parsers/cxx/cxx_token_chain.c
+++ b/parsers/cxx/cxx_token_chain.c
@@ -488,6 +488,7 @@ CXXTokenChain * cxxTokenChainSplitOnComma(CXXTokenChain * tc)
pToken = pToken->pNext;
pNew = cxxTokenChainExtractRange(pStart,pToken,0);
+ /* TODO */
pToken = pToken->pNext; // comma or nothing
}
if(pNew)
@@ -502,6 +503,7 @@ CXXTokenChain * cxxTokenChainSplitOnComma(CXXTokenChain * tc)
{
// finished without comma
CXXToken * pNew = cxxTokenChainExtractRange(pStart,cxxTokenChainLast(tc),0);
+ /* TODO */
if(pNew)
cxxTokenChainAppend(pRet,pNew);
}
diff --git a/source.mak b/source.mak
index f131acedbe..42401e8938 100644
--- a/source.mak
+++ b/source.mak
@@ -277,6 +277,7 @@ PARSER_HEADS = \
parsers/cxx/cxx_keyword.h \
parsers/cxx/cxx_parser_internal.h \
parsers/cxx/cxx_parser.h \
+ parsers/cxx/cxx_reftag.h \
parsers/cxx/cxx_scope.h \
parsers/cxx/cxx_subparser.h \
parsers/cxx/cxx_subparser_internal.h \
@@ -335,6 +336,7 @@ PARSER_SRCS = \
parsers/cxx/cxx_parser_using.c \
parsers/cxx/cxx_parser_variable.c \
parsers/cxx/cxx_qtmoc.c \
+ parsers/cxx/cxx_reftag.c \
parsers/cxx/cxx_scope.c \
parsers/cxx/cxx_subparser.c \
parsers/cxx/cxx_tag.c \
diff --git a/win32/ctags_vs2013.vcxproj b/win32/ctags_vs2013.vcxproj
index 1f54833b6e..574a57038d 100644
--- a/win32/ctags_vs2013.vcxproj
+++ b/win32/ctags_vs2013.vcxproj
@@ -290,6 +290,7 @@
+
@@ -450,6 +451,7 @@
+
diff --git a/win32/ctags_vs2013.vcxproj.filters b/win32/ctags_vs2013.vcxproj.filters
index 0682c7be27..db7a37fe59 100644
--- a/win32/ctags_vs2013.vcxproj.filters
+++ b/win32/ctags_vs2013.vcxproj.filters
@@ -393,6 +393,9 @@
Source Files\parsers\cxx
+
+ Source Files\parsers\cxx
+
Source Files\parsers\cxx
@@ -869,6 +872,9 @@
Header Files
+
+ Header Files
+
Header Files