But when I'm writing C++ code, it does not work well, mostly because
of overloaded functions and class derivation. I realize of course
that C++ syntax does not make it easy.
Is there a way to jump to the right member function definition
(with CTRL-] or any other way) when that function is overloaded
or when that member function is defined in base and derived class?
Here is an example:
--- 8< --- cut here --- 8< --- cut here --- 8< ---
1 struct base {
2 void method1(int a);
3 };
4
5 void base::method1(int a) {
6 // ...
7 }
8
9 struct derived : base {
10 void method1(int a);
11
12 void method2(int a);
13 void method2(int a, int b);
14 };
15
16 void derived::method1(int a) {
17 // ...
18 }
19
20 void derived::method2(int a) {
21 // ...
22 }
23
24 void derived::method2(int a, int b) {
25 // ...
26 }
27
28 int main() {
29 base b;
30 derived d;
31
32 b.method1(0); // CTRL-] should jump to base::method1(int a)
33 d.method1(0); // CTRL-] should jump to derived::method1(int a)
34
35 d.method2(0); // CTRL-] should jump to derived::method2(int a)
36 d.method2(0, 0); // CTRL-] should jump to derived::method2(int a, int b)
37
38 return 0;
39 }
--- 8< --- cut here --- 8< --- cut here --- 8< ---
I create a tag file with:
$ find . -name '*.cpp' |
ctags -L - --language-force=c++ --c++-kinds=+p \
--fields=+iaS --extra=+f+q -f tags
And in my ~/.vimrc, I have "set tags=tags"
If cursor is on 'method2' at line 36 of above example, pressing CTRL-]
jumps to line 12 (instead of line 24).
If instead of pressing CTRL-] at line 36, I press g CTRL-], Vim
proposes the 4 possible jumps...
1 FSC p method2 bar.cpp
struct:derived access:public signature:(int a)
void method2(int a);
2 FSC p method2 bar.cpp
struct:derived access:public signature:(int a, int b)
void method2(int a, int b);
3 F C f method2 bar.cpp
class:derived signature:(int a)
void derived::method2(int a) {
4 F C f method2 bar.cpp
class:derived signature:(int a, int b)
void derived::method2(int a, int b) {
... and I have to select manually select where to jump, which is not
always as simple as in this sample case.
-> So my question: is there any better way to use ctags (or any other
tool or plugin) to jump to function definitions when writing C++ code
with Vim?
I'm using:
- vim-7.1.293
- cscope-15.6
- exuberant ctags-5.7
I'm also using the following plugins. Though very useful, they don't
do what I really want:
- omnicomplete (from Vissale Neang)
- taglist (from Yegappan Lakshmanan)
Thanks
-- Dominique
>[...]
>
>I'm also using the following plugins. Though very useful, they don't
>do what I really want:
>
>- omnicomplete (from Vissale Neang)
>
>
>
omnicomplete has to have this information, just a matter of getting to it.
-ap
--
:wq
> When writing C code, I'm very happy with exuberant ctags or cscope
> integration in Vim to jump to function definitions by pressing CTRL-]
> (or g CTRL-]).
>
> But when I'm writing C++ code, it does not work well, mostly because
> of overloaded functions and class derivation. I realize of course
> that C++ syntax does not make it easy.
I've been pondering about this problem and I had the
following idea:
How about using the output of objdump on the linked ELF
to find the information where to jump?
Let's take the example I gave in the original message:
So when pressing CTRL-] on 'method2' on line bar.cpp:36,
how can we find where to jump? method2 called at line
bar.cpp:36 is defined in 4 different places, but the correct
place where to jump should be line bar.cpp:24.
If I compile with -g and run objdump, I see this:
--- 8< --- cut here --- 8< --- cut here --- 8< ---
$ g++ -g bar.cpp
$ objdump --disassemble --source \
--line-numbers --demangle \
--no-show-raw-insn a.out
[...snip...]
/home/dope/bar.cpp:36
d.method2(0, 0); // CTRL-] should jump to derived::method2(int a, int b)
80483a6: movl $0x0,0x8(%esp)
80483ae: movl $0x0,0x4(%esp)
80483b6: lea 0xfffffffa(%ebp),%eax
80483b9: mov %eax,(%esp)
80483bc: call 8048356 <derived::method2(int, int)>
[...snip...]
--- 8< --- cut here --- 8< --- cut here --- 8< ---
So method2 called at line bar.cpp:36 (where CTRL ] is pressed)
is defined at address 0x8048356. If I search for this address
"^ 8048356" in the output of objdump, I see this:
--- 8< --- cut here --- 8< --- cut here --- 8< ---
/home/dope/bar.cpp:24
void derived::method2(int a, int b) {
8048356: push %ebp
--- 8< --- cut here --- 8< --- cut here --- 8< ---
Bingo! This is exactly the information we need.
CTRL ] can then jump to line bar.cpp:24 (which is
indeed the correct place where to jump).
It is an exact method without requiring heuristics
to parse complex c++ code. If speed matters,
it could be made fast if we index the output of
objdump by:
- source file + line number, to find bar.cpp:36 where
CTRL ] is pressed in O(log(n))
- and by address, to find address of callee (8048356
in my example) in O(log(n)).
That could really help c++ developers who use Vim.
-- Dominique
Also, you need to use objdump on the linked executable (not the *.o)
to get the proper address of the function where to jump to.
-- Dominique