Skip to content

Commit

Permalink
Cxx: add "initialized" role to "member" kind
Browse files Browse the repository at this point in the history
    struct opt file_ops {
      .read  = file_read,
      .write = file_write,
    };

The parser extracts "read" and "write" with "initialized"
role of "member" kind.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
  • Loading branch information
masatake committed Dec 3, 2022
1 parent 0e49c79 commit 25a5d78
Show file tree
Hide file tree
Showing 11 changed files with 285 additions and 154 deletions.
2 changes: 2 additions & 0 deletions Tmain/extras-field-for-pseudo-tags.d/stdout-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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; }$/
1 change: 1 addition & 0 deletions Tmain/json-output-format.d/stdout-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
{"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "C!header", "path": "local", "pattern": "local header"}
{"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "C!header", "path": "system", "pattern": "system header"}
{"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "C!macro", "path": "undef", "pattern": "undefined"}
{"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "C!member", "path": "initialized", "pattern": "initialized with form '.member = ...'"}
{"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "Go!package", "path": "imported", "pattern": "imported package"}
{"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "Go!unknown", "path": "receiverType", "pattern": "receiver type"}
{"_type": "ptag", "name": "TAG_ROLE_DESCRIPTION", "parserName": "Python!module", "path": "imported", "pattern": "imported modules"}
Expand Down
4 changes: 2 additions & 2 deletions Tmain/list-kinds-full.d/stdout-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,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 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
Expand All @@ -31,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
Expand Down
331 changes: 181 additions & 150 deletions Tmain/list-roles.d/stdout-expected.txt

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Tmain/nested-subparsers.d/stdout-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,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 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
Expand Down
5 changes: 5 additions & 0 deletions Units/parser-c.r/c-reftag-member.d/args.ctags
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
--sort=no
--extras=+r
--fields=+rKZ
--kinds-C=*
--roles-C.{member}=*
3 changes: 3 additions & 0 deletions Units/parser-c.r/c-reftag-member.d/expected.tags
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
read input.c /^ .read = file_read_fn,$/;" member scope:variable:file_ops roles:initialized
write input.c /^ .write = file_write_fn,$/;" member scope:variable:file_ops roles:initialized
file_ops input.c /^static struct ops file_ops = {$/;" variable typeref:struct:ops file: roles:def
4 changes: 4 additions & 0 deletions Units/parser-c.r/c-reftag-member.d/input.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
static struct ops file_ops = {
.read = file_read_fn,
.write = file_write_fn,
};
69 changes: 69 additions & 0 deletions parsers/cxx/cxx_parser_variable.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,62 @@ 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.
cxxTagResetRefTag(pIdentifier->iCorkIndex, iScopeCorkIndex,
CXXTagKindMEMBER, CXXTagMemberRoleINITIALIZED);
}
else if(pIdentifier->iCorkIndex == CORK_NIL)
{
tagEntryInfo oEntry;
initRefTagEntry(&oEntry, vStringValue(t->pszWord),
CXXTagKindMEMBER, CXXTagMemberRoleINITIALIZED);
oEntry.lineNumber = t->iLineNumber;
oEntry.filePosition = t->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;
}
}
return;
}

//
// Attempt to extract variable declarations from the chain.
// Returns true if at least one variable was extracted.
Expand Down Expand Up @@ -800,11 +856,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
Expand All @@ -829,6 +892,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)
Expand All @@ -844,6 +910,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)
Expand Down
13 changes: 12 additions & 1 deletion parsers/cxx/cxx_tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ 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, \
Expand Down Expand Up @@ -60,7 +69,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 }, \
Expand Down
5 changes: 5 additions & 0 deletions parsers/cxx/cxx_tag.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ enum CXXTagUnknownRole
CXXTagUnknownRoleREFERENCED,
};

enum CXXTagMemberRole
{
CXXTagMemberRoleINITIALIZED,
};

// Tags specific to the CPP language.
enum CXXTagCPPKind
{
Expand Down

0 comments on commit 25a5d78

Please sign in to comment.