Skip to content

Commit 0a96308

Browse files
committed
Cxx: scan the cork queue instead of the symtab to fill nth fields
Close #3634. If an enum has so many enumerators, the original code, counting enumerators for filling nth fields, takes a too long time. The new code looks up the last enumerator and calculates a new nth value by incrementing the last nth value. Signed-off-by: Masatake YAMATO <[email protected]>
1 parent 6657a16 commit 0a96308

File tree

5 files changed

+57
-9
lines changed

5 files changed

+57
-9
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0

Tmain/c-large-enum.d/run.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Copyright: 2023 Masatake YAMATO
2+
# License: GPL-2
3+
4+
input=/tmp/c-large-enum.d-input.c
5+
CTAGS="$1 --quiet --options=NONE"
6+
7+
i=0
8+
{
9+
echo "enum E {"
10+
while [ $i -lt 32770 ]; do
11+
printf "X%x," $i
12+
i=$(($i + 1))
13+
done
14+
echo "};"
15+
} > $input
16+
17+
${CTAGS} --sort=no -n --fields= --fields=+"{nth}" -x --_xformat='%{name} %{nth}' "$input" | tail -10
18+
r=$?
19+
20+
rm -f "$input"
21+
22+
exit $r

Tmain/c-large-enum.d/stderr-expected.txt

Whitespace-only changes.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
X7ff8 32760
2+
X7ff9 32761
3+
X7ffa 32762
4+
X7ffb 32763
5+
X7ffc 32764
6+
X7ffd 32765
7+
X7ffe 32766
8+
X7fff 32767
9+
X8000 32767
10+
X8001 32767

parsers/cxx/cxx_tag.c

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -275,12 +275,28 @@ void cxxTagUseTokensInRangeAsPartOfDefTags(int iCorkIndex, CXXToken * pFrom, CXX
275275
}
276276
}
277277

278-
static bool countSameKindEntry(int corkIndex,
279-
tagEntryInfo * entry,
280-
void * data)
278+
static short cxxTagLookBackLastNth(langType iLangType, int iScopeIndex, unsigned int uKind)
281279
{
282-
unsigned int *uKind = data;
283-
return (entry->kindIndex == *uKind);
280+
for (size_t uCount = countEntryInCorkQueue (); uCount > (CORK_NIL + 1); uCount--)
281+
{
282+
int iCorkIndex = (int)(uCount - 1);
283+
tagEntryInfo *pTag = getEntryInCorkQueue(iCorkIndex);
284+
if (iCorkIndex == iScopeIndex)
285+
return 0;
286+
else if (pTag->extensionFields.scopeIndex == iScopeIndex
287+
&& pTag->langType == iLangType
288+
&& pTag->kindIndex == uKind)
289+
{
290+
return pTag->extensionFields.nth + (
291+
/* Over-wrapped; if the value is too large for sizeof(nth),
292+
* Don't increment more. */
293+
((short)(pTag->extensionFields.nth + 1) > 0)
294+
? 1
295+
: 0
296+
);
297+
}
298+
}
299+
return NO_NTH_FIELD;
284300
}
285301

286302
tagEntryInfo * cxxTagBegin(unsigned int uKind,CXXToken * pToken)
@@ -315,10 +331,9 @@ tagEntryInfo * cxxTagBegin(unsigned int uKind,CXXToken * pToken)
315331
{
316332
if (uKind == CXXTagKindMEMBER || uKind == CXXTagKindENUMERATOR
317333
|| uKind == CXXTagKindPARAMETER || uKind == CXXTagCPPKindTEMPLATEPARAM)
318-
g_oCXXTag.extensionFields.nth =
319-
(short) countEntriesInScope(g_oCXXTag.extensionFields.scopeIndex,
320-
true,
321-
countSameKindEntry, &uKind);
334+
g_oCXXTag.extensionFields.nth = cxxTagLookBackLastNth(g_oCXXTag.langType,
335+
g_oCXXTag.extensionFields.scopeIndex,
336+
uKind);
322337
}
323338
}
324339

0 commit comments

Comments
 (0)