I found that gcc support a strange function definition like:
static void add_define P3(char *, name, int, nargs, char *, exps)
Which compile with -D__USE_FIXED_PROTOTYPES__. And my taglist plugins of vim couldn't give correct result. I tried to figure out in man page of ctags but I couldn't find it.
EDIT Yes, this is strange. The macro is
#define P3(t1, v1, t2, v2, t3, v3) (t1 v1, t2 v2, t3 v3)
and the comment tells that this is
ANSI/K&R compatibility stuff.
It's intend to suite xlc, the c compiler of AIX.
With the macro definition as shown:
#define P3(t1, v1, t2, v2, t3, v3) (t1 v1, t2 v2, t3 v3)
this declaration:
static void add_define P3(char *, name, int, nargs, char *, exps);
(I've added a trailing semicolon) expands to this:
static void add_define(char *name, int nargs, char *exps);
which is a perfectly ordinary function prototype (assuming a trailing semicolon).
There's probably an alternate version of that macro, something like this:
#define P3(t1, v1, t2, v2, t3, v3) \
(v1, v2, v3) \
t1 v1; \
t2 v2; \
t3 v3;
that would expand to:
static void add_define(name, nargs, exps)
char *name;
int nargs;
char *exps
which is a K&R-style non-prototype function declaration.
Likely there's something like:
#ifdef __STDC__
#define P3(t1, v1, t2, v2, t3, v3) (t1 v1, t2 v2, t3 v3)
#else
#define P3(t1, v1, t2, v2, t3, v3) \
(v1, v2, v3) \
t1 v1; \
t2 v2; \
t3 v3;
#endif
along with similar macros P0, P1, P2, etc., for different numbers of parameters. Or perhaps, as you imply in your question, it uses a user-defined macro __USE_FIXED_PROTOTYPES__
rather than __STDC__
.
This would allow a single declaration to automatically expand either to a modern prototype or to a K&R-style declaration; the latter would be necessary only with very old pre-ANSI compilers.
To answer the question in the title (finally!), ctags
operates on non-preprocessed C source. A quick experiment with the GNU ctags
shows that it's not particularly clever about interpreting macros that obscure the basic syntax. It will generate tag entries for the macro definitions themselves, but it won't recognize
static void add_define P3(char *, name, int, nargs, char *, exps) {
/* ... */
}
as a function definition. (You could run the source file through the preprocessor, but then the tags would refer to the preprocessed file, which is not particularly useful.) In principle, ctags
should understand the complete C syntax, including the preprocessor; in practice, it doesn't.
If you want to have ctags
generate tags for your source file, you'll need to get rid of the macros and write recognizable prototypes. You won't be able to compile the modified source with a pre-ANSI compiler, but these days that's very unlikely to be a problem. If you're in a position to do this, the resulting code should be easier to maintain.
Or, since the output generated by ctags
is reasonably simple, it shouldn't be too difficult to manually add the relevant tags to the tags
file (though maintaining it automatically could be difficult).