user10150539
user10150539

Reputation:

Check if variables are used in a cpp file

I desire to have my program (main.cpp) read a cpp file (code.cpp), and determine whether certain variables are used. This could easily be done by reading the file and searching for substrings, but this has undesired drawbacks as explained below.

Content of code.cpp

double a4 = 4.0;
int main() {
    double a1 = 1.0;
    double a2 = 2.0; 
    //a3 is inside comment. Therefore a3 does not exist
    double a33 = 3.0; //a33 exists. a3 does not exist
    string s = "a1a2a3"; //a3 still does not exist
    return 0;
}

Content of main.cpp (my current attempt for solving this task)

#include <iostream>
#include <fstream>
using namespace std;

int main() {
    std::ifstream file;
    file.open("code.cpp");
    std::string s;
    while(std::getline(file,s)){
        if (s.find("a1") != std::string::npos)
            cout << "found a1" << endl;
        if (s.find("a2") != std::string::npos)
            cout << "found a2" << endl;
        if (s.find("a3") != std::string::npos)
            cout << "found a3 :(" << endl;
        if (s.find("a4") != std::string::npos)
            cout << "found a4" << endl;
    }
    return 0;
}

Output from main execution:

found a4
found a1
found a2
found a3 :(
found a3 :(
found a1
found a2
found a3 :(

main.cpp is unsuccessful because it detects a3 being a variable used in code.cpp.

Is there any practical method to determine whether variables by certain names exist or are used in a c++ file?

Further information:

Upvotes: 1

Views: 927

Answers (2)

Booo
Booo

Reputation: 503

As Jesper mentioned, you need a C++ parser. To determine whether variables by certain names exist or are used in a c++ file, the easiest is to employ the Clang AST Matcher, instead of implementing a tool yourself.

So install LLVM, Clang, Clang toolings and fire clang-query:

$ clang-query yourcode.cpp
clang-query> match varDecl(hasName("a1"))
Match #1:
/home/yourcode.cpp:3:5: note: "root" binds here
    double a1 = 1.0;
    ^~~~~~~~~~~~~~~
1 match.
clang-query> match varDecl(hasName("a2"))
Match #1:
/home/yourcode.cpp:4:5: note: "root" binds here
    double a2 = 2.0; 
    ^~~~~~~~~~~~~~~
1 match.
clang-query> match varDecl(hasName("a3"))
0 matches.
clang-query> match varDecl(hasName("a4"))
Match #1:
/home/yourcode.cpp:1:1: note: "root" binds here
double a4 = 4.0;
^~~~~~~~~~~~~~~
1 match.

You can do a lot more than this, check the AST Matcher Reference http://clang.llvm.org/docs/LibASTMatchersReference.html

Upvotes: 1

Jesper Juhl
Jesper Juhl

Reputation: 31464

I would build such a tool on top of Clang's libtooling library, since that gives you easy access to a C++ parser and the ability to easily search the AST for whatever your heart desires. Perhaps even easier would be to write it as a ClangTidy check.

Upvotes: 1

Related Questions