Please allow me to resend former sample: #define Z(a) a #define Y Z #define X(p) p + Y X(1)(2); The flow is: 1) `X' -- leader macro token by macro_start_expand. 2) `(', `1', `)' -- macro tokens, by cb_lex_token. 3) macro_end_arg. 4) `1', `+' -- macro replacement tokens, by symdb_cpp_token. 5) `(', `2', `)' -- macro tokens, by cb_lex_token. 6) macro_end_arg. 7) `2' -- macro replacement tokens, by symdb_cpp_token. 8) macro_end_expand.
The thing I emphasized here is cb_lex_token is set by macro_start_expand intern -- it isn't valid anytime. So buff = funlike_invocation_p (pfile, node, &pragma_buff, ... if (buff == NULL) { ... } if macro_start_expand is moved to the clause block `buff != NULL', it's too later to set cb_lex_token because funlike_invocation_p has read some macro tokens. Of course I can remove macro_end_arg totally, because from the sample, it's the fact that macro tokens aren't always before any macro replacement tokens. But macro_end_expand must be prepared to deal with cancel case. BTW, currently it isn't necessary to my plugin to collect macro tokens, so if gcc doesn't support collect macro token event, macro_start_expand and macro_end_expand can be moved into enter_macro_context and _cpp_pop_context individually. Yunfeng