Creating a list of global variables from a C ++ source file

Now I'm working on a problem, its operator will generate a text file with a list of all declared global variables in the .CPP file.

I came up with a few ideas, the first one:

Try using ctags, so I wrote a few short scripts:

while read line do echo $line printf "%s" $line >> report.txt ctags -x --c++-kinds=v --file-scope=no "{$line}" | sort | sed "/const/d" | awk '{printf " %s", $1}' >> report.txt printf "\n" >> report.txt done < cpp_source_file_list.txt 

This piece of code gets the name of the .cpp file of the source file from cpp_source_file_list.txt, scans it for global variables (ignoring const) and writes the report "filename [variable list]. The main problem I encountered is that ctags is very strange ignores in some cases STL types.

For example, it may exclude the string vike "vector v;" but includes "std :: vector v;".

Is there any way to fix this problem? An attempt to use the additional key ctags -I./id.txt and manually enumerate the list of identifiers, but it also leads to incorrect results.

The second way:

Use the nm command, for example:

 nm builtsource.o | grep '[0-9A-Fa-f]* [BCDGRS]' 

But in this case, I get unnecessary information, for example:

 0000000000603528 BM 0000000000603548 BN 0000000000603578 B _ZSt3cin@ @GLIBCXX_3.4 <- (!) 0000000000603579 B _ZSt4cout@ @GLIBCXX_3.4 <- (!) 0000000000603748 B t 

And now I have no idea how to implement one of these methods to get the correct information about the list of declared global variables from an arbitrary .cpp source file. I would be glad to hear any suggestion on this issue.

+4
source share
3 answers

You might be able to use Doxygen to implement this. Doxygen can parse a C ++ file and generate an XML file that captures all the variables found in the file. In particular, if you specify the following configuration parameters:

 EXTRACT_ALL= YES GENERATE_TAGFILE= doxygen.tag 

Given the input file, for example:

 #include <vector> using namespace std; std::vector<int> s1; vector s2; 

You can create a doxygen.tag output file with the following contents:

 <?xml version='1.0' encoding='ISO-8859-1' standalone='yes' ?> <tagfile> <compound kind="file"> <name>input.cpp</name> <path>C:/Users/haney/tmp/tmp55/</path> <filename>input_8cpp</filename> <namespace>std</namespace> <member kind="variable"> <type>std::vector&lt; int &gt;</type> <name>s1</name> <anchorfile>input_8cpp.html</anchorfile> <anchor>93b3bd32f5b6bff31bc4052716ddd444</anchor> <arglist></arglist> </member> <member kind="variable"> <type>vector</type> <name>s2</name> <anchorfile>input_8cpp.html</anchorfile> <anchor>8feb4a508135e43a72f227568b755a07</anchor> <arglist></arglist> </member> </compound> <compound kind="namespace"> <name>std</name> <filename>namespacestd.html</filename> </compound> </tagfile> 

Once you have the XML file, you can extract the information you are looking for.

+1
source

Another possibility would be to develop a GCC plugin or a MELT extension for this exact purpose. You will need to understand some details of the internal representations of GCC (Gimple and Tree).

The advantage of configuring GCC (with a C plugin or extension in MELT) is that you work with the exact internal components of the compiler (after preprocessing and parsing). However, this will require several efforts from you.

0
source

You can use GCC-XML , possibly with something else on top (like pygccxml ) to make navigation easier. I have successfully used this combination for similar code retrieval purposes.

0
source

Source: https://habr.com/ru/post/1391624/


All Articles