Skip to content

Commit 531e53b

Browse files
thoni56claude
andcommitted
[navigation][fix] Record references to macros inside macro body definitions
When parsing a macro definition like `#define OUTER(x) INNER(x)`, the reference to INNER was not being recorded. References were only recorded during macro expansion, which meant navigation couldn't find them if the outer macro was never expanded during the current parsing session. Now `processDefineDirective` checks if identifiers in the macro body are known macros and records references for them. This enables navigation from a macro definition to find all references, including those inside other macro definitions. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 6a6307a commit 531e53b

12 files changed

Lines changed: 93 additions & 0 deletions

File tree

src/yylex.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,13 @@ protected void processDefineDirective(bool hasArguments) {
10371037
completionPositionFound = true;
10381038
completionStringInMacroBody = symbol->linkName;
10391039
}
1040+
/* Record reference if identifier is a known macro */
1041+
if (lexem == IDENTIFIER) {
1042+
Symbol *referencedMacro = findMacroSymbol(currentLexemStart);
1043+
if (referencedMacro != NULL) {
1044+
handleFoundSymbolReference(referencedMacro, position, UsageUsed, NO_FILE_NUMBER);
1045+
}
1046+
}
10401047
putLexemCodeAndAdvance(lexem, &lexemDestination);
10411048
/* Copy from input to destination (which is in the body buffer...) */
10421049
for (; currentLexemStart<currentInput.read; lexemDestination++,currentLexemStart++)

tests/test_macro_stdint/expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,8 @@ UINT8_MAX
2525
@source.c:23:9
2626
__INT64_C
2727
@source.c:2:10
28+
@source.c:15:22
29+
@source.c:20:21
2830
__UINT64_C
2931
@source.c:3:10
32+
@source.c:26:22
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
include ../Makefile.server
2+
3+
# Test that NEXT finds references to a macro inside another macro's definition.
4+
# INNER_MACRO is defined on line 5, and used inside OUTER_MACRO on line 8.
5+
# PUSH on INNER_MACRO should find the definition, NEXT should find the usage
6+
# inside OUTER_MACRO's body.
7+
8+
$(TEST):
9+
$(CXREF_PROGRAM) -p $(CURDIR) -create > /dev/null
10+
sleep 2
11+
# Create preload files for source files (simulating Emacs buffers)
12+
cp macros.h macros.preload
13+
@$(SERVER_DRIVER) $(EXTRA) commands.input > output.tmp
14+
@$(NORMALIZE) output.tmp > output
15+
$(VERIFY)
16+
17+
trace: EXTRA = --extra '-debug -log=trace'
18+
trace: $(TEST)
19+
20+
GDB_COMMANDS =
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CXREF -xrefactory-II -server
2+
-olcxgetprojectname CURDIR/macros.h
3+
<sync>
4+
-olcxpush -preload CURDIR/macros.h CURDIR/macros.preload -olcursor=79 CURDIR/macros.h -p CURDIR
5+
<sync>
6+
-olcxnext -preload CURDIR/macros.h CURDIR/macros.preload -olcursor=79 CURDIR/macros.h -p CURDIR
7+
<sync>
8+
<exit>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
CXREF -xrefactory-II -server -o server-buffer
2+
-olcxgetprojectname CURDIR/macros.h
3+
end-of-options
4+
5+
<sync>
6+
<set-info len=<n>>test_navigation_macro_to_macro_reference</set-info>
7+
-olcxpush -preload CURDIR/macros.h CURDIR/macros.preload -olcursor=79 CURDIR/macros.h -p CURDIR
8+
end-of-options
9+
10+
<sync>
11+
<goto>
12+
<position-lc line=5 col=8 len=<n>>CURDIR/macros.h</position-lc>
13+
</goto>
14+
-olcxnext -preload CURDIR/macros.h CURDIR/macros.preload -olcursor=79 CURDIR/macros.h -p CURDIR
15+
end-of-options
16+
17+
<sync>
18+
<goto>
19+
<position-lc line=8 col=23 len=<n>>CURDIR/macros.h</position-lc>
20+
</goto>
21+
-exit
22+
end-of-options
23+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef MACROS_H
2+
#define MACROS_H
3+
4+
// First macro - we'll PUSH on this
5+
#define INNER_MACRO(x) ((x) + 1)
6+
7+
// Second macro - uses INNER_MACRO, NEXT should find this reference
8+
#define OUTER_MACRO(y) INNER_MACRO(y)
9+
10+
#endif
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef MACROS_H
2+
#define MACROS_H
3+
4+
// First macro - we'll PUSH on this
5+
#define INNER_MACRO(x) ((x) + 1)
6+
7+
// Second macro - uses INNER_MACRO, NEXT should find this reference
8+
#define OUTER_MACRO(y) INNER_MACRO(y)
9+
10+
#endif
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include "macros.h"
2+
3+
int main() {
4+
int result = OUTER_MACRO(5);
5+
return result;
6+
}

tests/test_token_pasting_with_expansion/expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ EXPAND
66
NUM
77
@source.c:0:0
88
@source.c:1:8
9+
@source.c:2:27
10+
@source.c:2:32
911
@source.c:4:15
1012
NUM##NUM
1113
@source.c:2:31

tests/test_token_pasting_with_expansion_lhs/expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ EXPAND
66
NUM
77
@source.c:0:0
88
@source.c:1:8
9+
@source.c:2:27
910
@source.c:4:19
1011
NUM##num
1112
@source.c:2:31

0 commit comments

Comments
 (0)