1

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:

  • In my case, the a-variables are always double
  • Searching for the declaration "double a#" is not an option, because the variable may be declared by other means - in fact, they don't even have to be declared as they may first be defined on compilation.
  • the a-variables may be declared/used in other other functions or as globals in code.cpp
  • It is not possible to search for spaces because the algorithm should also detect the three variables in "a3=a1*a2"
3
  • 3
    Most compilers already issue a warning about unused variables or parameters. I don't see a need to do that yourself. Commented Jul 29, 2018 at 9:16
  • It is not the intend to warn about unused variables or parameters. I intentionally omitted the purpose of the code, because it's a bit of a rabbit hole, but in short, I intend to leave the a-variables in code.cpp undeclared, and declare them through commandline as a part of a larger dynamic-compilation project of mine. Commented Jul 29, 2018 at 9:40
  • 1
    Then you should either follow the advise from Jesper's answer, or do your own approach at least with regular expressions, but be aware the latter is still very limited in parsing proper c++ syntax. Commented Jul 29, 2018 at 9:43

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.