17

I'm refactoring some code in C++, and I want to deprecate some old methods. My current method for finding all of the methods looks like this:

  1. Comment out the original method in the source file in which I'm working.
  2. Try to compile the code.
  3. If a compiler error is found, then make a note comment out the call and try to recompile.
  4. Once the compile has completed successfully, I've found all of the calls.

This totally sucks. I've also tried grepping source for the name of the function calls, but I sometimes run into problems with functions of the same name with different arguments, so my compilation makes the C++ compiler resolve the names for me. I've found this question for C#, but my code base is entirely implemented in C++.

Is there a better way to find all of the callers of a class method or function in C++? I'm using GCC on Unix systems, but cross-platform solutions would be superlative.

Community
  • 1
  • 1
James Thompson
  • 46,512
  • 18
  • 65
  • 82
  • I'd love to hear of a good solution, but it seems to me you'd have to duplicate the entire front end. That's pretty much what it would take to construct the symbol table. – David Thornley Jul 16 '09 at 21:51
  • 1
    Try [CodeQuery](https://github.com/ruben2020/codequery). It combined the best of cscope and ctags, to produce better source code information of C++. Disclaimer: It's my open source project. – ruben2020 Jun 06 '13 at 14:06

9 Answers9

36

GCC allows you to decorate variables, functions, and methods with __attribute__((deprecated)), which will cause a warning on all callsites (unless -Wno-deprecated-declarations is given).

class A {
public:
    A() __attribute__((deprecated)) {}
};
int main() {
    A a;
}
$ g++ test.c
test.cc: In function ‘int main()’:
test.cc:6: warning: ‘A::A()’ is deprecated (declared at test.cc:3)
ephemient
  • 198,619
  • 38
  • 280
  • 391
  • 1
    Nice. Since the OQ is using GCC (and no mention of other platforms), this is what I'd do. – T.E.D. Jul 16 '09 at 21:57
  • 9
    For anyone using visual studio, there is similar functionality with #pragma deprecated(functionname). See http://msdn.microsoft.com/en-us/library/044swk7y.aspx – Eclipse Jul 16 '09 at 22:02
  • This is the right answer for me, because I'm refactoring I won't need the attributes to be cross-platform. Good stuff! – James Thompson Jul 17 '09 at 06:37
  • 5
    One nice thing about GCC's attribute syntax is that it requires double-parens to use; this makes it very easy to `#ifndef __GNUC__ #define __attribute__(x) /* nothing */ #endif` stub out the attributes in other compilers. – ephemient Jul 17 '09 at 13:27
10

Eclipse can do this without any plugins. It can be a useful tool for stuff like this even if you don't want to use it for your day-to-day editor.

  1. Download, install, and run the Eclipse CDT.
  2. Go under File, New, C++ Project. Enter a project name and choose an Empty Makefile project from the Project Type tree view. Uncheck "Use default location" and enter the folder where your project is kept.
  3. Click Next, then click Finish.
  4. Eclipse will automatically start indexing your project. If it really is a Makefile project, and since you're using g++, you can do a full clean then build from within Eclipse (under the Project menu), and it should automatically use your existing makefiles and automatically discover your include directories and other project settings.
  5. Find the prototype of the overloaded function in a source file, right-click on it, choose References, and choose Project. Eclipse will find all references to that function, and only to that particular overload of that function, within your project.

You can also use Eclipse's built-in refactoring support to rename overloaded functions so that they're no longer overloaded. Eclipse is also fully cross-platform; you can use features like its indexer, search references, and refactoring even for projects that are maintained and built in other IDEs.

Josh Kelley
  • 56,064
  • 19
  • 146
  • 246
6

One option is to run your entire project through a program like Cscope. Which essentially parses the entire source code of your project and builds a database that allows for easy searching of things like all of a function's callers, all references, etc.

I know it works fairly well for C, and they claim it works decently for C++. KScope is a KDE GUI front end for it.

Falaina
  • 6,625
  • 29
  • 31
  • 2
    Drat. I was hopeful until I read your "they claim it works decently for C++". Based on your post, I thought you were speaking from first hand experience. I am a huge fan of cscope for C code, even big, complex C code, but I've had very mixed results with C++. I guess instead of lamenting I should try to fix cscope, since it's on Sourceforge after all... – Dan Jul 17 '09 at 00:00
4

I think what you want is to look at a call graph. See this question for some good suggestions on how to do that.

Community
  • 1
  • 1
MattK
  • 10,195
  • 1
  • 32
  • 41
4

For anyone wanting to do this in Visual Studio under windows....

Visual Assist is really good. It helps a lot with many C++ refactorings, Call graphs, renaming, automatically creating header definitions or generation methods from definitions, etc etc. It's not perfect, nothing like the quality of Java/C# refactoring tools, but really good for C++!!

Keith Nicholas
  • 43,549
  • 15
  • 93
  • 156
3

This plugin for Eclipse might be the right tool: CallGraph View

Velociraptors
  • 2,012
  • 16
  • 22
2

That's pretty much how I do it. If your code is all in once place a "grep" (or find | grep combo) might do the trick too.

One caviat: This method will very often miss instances that are not conditionally compiled into your current configuration. If your code makes use of #ifdefs to support multiple configurations, a thorough person will try to compile with every configuration to catch all instances.

T.E.D.
  • 44,016
  • 10
  • 73
  • 134
  • That's a really good point. Luckily we don't have too many ifdef's in our code, and I don't expect many for this particular refactoring project, but that's another reason why I need a better trick. :) – James Thompson Jul 16 '09 at 23:09
2

If you let the Eclipse CDT index your source base, then you should be able to view the calling hierarchy for any function and even perform some refactoring.

You can download the Eclipse IDE for C/C++ Developers (hopefully you can find a port for your particular *NIX) and follow their instructions to get going.

David Citron
  • 43,219
  • 21
  • 62
  • 72
2

In visual studio, right click on the function name and click "Call Browser" > Show Callers graph

Then in the display window there should be a folder called "Calls to function" that contains all the places that call that function, each of which you can double click on to go to them in the code.

DShook
  • 14,833
  • 9
  • 45
  • 55