Search code examples
c++functiondebuggingsignaturetrace

Search for function with specific signature call?


Assume I have some C++ functions:

void A(int i) {
/* some code */
}

void A(string s) {
/* some code */
}

void A(string s, int i) {
/* some code */
}

Assume the first call makes 80% of the A() calls, the second makes 15% and the last makes 5%.

I want to static trace the calls. If I am interested in in the first kind of call, no problem, most of the string search results of "A(" will be of type 1, but if I ONLY want type 2 or type 3, I will have a lot of unneeded noise from type 1.

For type 3, regular expressions can help if I look for a following string that has exactly 2 comas between parenthesis A(*,*,*) (I don't actually know the programming syntax for RE)

But for type 2 this won't work.

Is there any technique I can use to find a function call by its signature?

Edit: What I mean by "trace" is understanding the current codebase by finding all the call points of the needed function.


Solution

  • For type 3, regular expressions can help if I look for a following string that has exactly 2 comas between parenthesis A(,,*) (I don't actually know the programming syntax for RE)

    But for type 2 this won't work.

    Is there any technique I can use to find a function call by its signature?

    Well besides you search your files using some regex (with e.g. Notepad++ file search, egrep or similar), and assuming that you're able to change the source code where these functions are declared / defined, you may use some compiler standard feature like the [[deprecated]] attribute:

       void A(int i) {
       /* some code */
       }
    
       [[deprecated]] void A(string s) {
    // ^^^^^^^^^^^^^^
       /* some code */
       }
    
       [[deprecated]] void A(string s, int i) {
    // ^^^^^^^^^^^^^^
       /* some code */
       }
    

    This will show you warnings when these functions are used:

    int main() {
        A(5);
        A("Hello");
        A("Hello",42);
    }
    
    main.cpp:9:25: note: declared here
         [[deprecated]] void A(string s) {
                             ^
    main.cpp:20:18: warning: 'void A(std::__cxx11::string)' is deprecated [-Wdeprecated-declarations]
             A("Hello");
                      ^
    main.cpp:9:25: note: declared here
         [[deprecated]] void A(string s) {
                             ^
    main.cpp:21:21: warning: 'void A(std::__cxx11::string, int)' is deprecated [-Wdeprecated-declarations]
             A("Hello",42);
                         ^
    main.cpp:13:25: note: declared here
         [[deprecated]] void A(string s, int i) {
                             ^
    main.cpp:21:21: warning: 'void A(std::__cxx11::string, int)' is deprecated [-Wdeprecated-declarations]
             A("Hello",42);
                         ^
    main.cpp:13:25: note: declared here
         [[deprecated]] void A(string s, int i) {
                             ^
    

    See an online example compiled with g++.

    You can even decorate that with a message for your coworkers maintaining the code base:

       [[deprecated("Get rid of these performance killing calls."
                    " Use A(A::getPrecomputedHash(s)) instead.")]] 
          void A(string s) {
          }