I have a CPP file and I'm using clang to print all variables in global scope. The problem is following: command clang -cc1 -ast-dump filename.cpp
doesn't show some global variables:
|-VarDecl 0x2094370 N 'int' invalid
|-VarDecl 0x20943e0 MAXN 'const int' invalid
|-VarDecl 0x2094470 p 'int' invalid
|-VarDecl 0x20944e0 u '_Bool' invalid
|-VarDecl 0x2094550 ansv 'int' invalid
|-VarDecl 0x20945c0 cost 'int' invalid
My cpp file has following global variables:
size_t N,M;
const size_t MAXN = 40000;
std::vector<std::pair<size_t,size_t> > graph[MAXN],query[MAXN],qr;
size_t p[MAXN], ancestor[MAXN];
bool u[MAXN];
size_t ansv[MAXN];
size_t cost[MAXN];
One can see that ast-dump didn't print some of global variables (for example, all std::vector
variables have been missed). What am i doing wrong?
UPD: full cpp file:
#include<iostream>
#include<vector>
#include<algorithm>
size_t N,M;
const size_t MAXN = 40000;
std::vector<std::pair<size_t,size_t> > graph[MAXN],query[MAXN],qr;
size_t p[MAXN], ancestor[MAXN];
bool u[MAXN];
size_t ansv[MAXN];
size_t cost[MAXN];
size_t find_set(size_t x){
//not important for my problem
}
void unite(size_t a, size_t b, size_t new_ancestor){
//not important for my problem
}
void dfs(size_t v,size_t ct){
//not important for my problem
}
int main(int argc, char* argv[]){
//not important for my problem
}
You are using clang++ -cc1 -ast-dump
which presumes that the input is preprocessed. When I do that, I get errors, because it can't find std::vector
, std::pair
, size_t
, and this is why it says invalid in lines like this one:
|-VarDecl 0x3149810 <testing.cpp:19:1, col:8> col:8 invalid N 'int'
|-VarDecl 0x3149880 <line:20:1, col:14> col:14 invalid MAXN 'const int'
Note the "invalid" in those lines - it means that it's "not a valid declaration".
Part of the compilers error recovery in situations like this is to "assume there is only one variable in each declaration and skip to the next semicolon".
I modified your code to be like this:
namespace std
{
template <typename T>
class vector
{
};
template <typename T1, typename T2>
class pair
{
};
};
typedef int size_t;
size_t N,M;
const size_t MAXN = 40000;
std::vector<std::pair<size_t,size_t> > graph[MAXN],query[MAXN],qr;
size_t p[MAXN], ancestor[MAXN];
bool u[MAXN];
size_t ansv[MAXN];
size_t cost[MAXN];
size_t find_set(size_t x){
//not important for my problem
return 0;
}
void unite(size_t a, size_t b, size_t new_ancestor){
//not important for my problem
}
void dfs(size_t v,size_t ct){
//not important for my problem
}
int main(int argc, char* argv[]){
//not important for my problem
}
at which point I get:
TranslationUnitDecl 0x4916de0 <<invalid sloc>> <invalid sloc>
|-TypedefDecl 0x4917320 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'
|-TypedefDecl 0x4917380 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128'
|-TypedefDecl 0x4917780 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list '__va_list_tag [1]'
|-NamespaceDecl 0x49177d0 <testing.cpp:1:1, line:12:1> line:1:11 std
| |-ClassTemplateDecl 0x4917970 <line:3:5, line:6:5> line:4:11 vector
| | |-TemplateTypeParmDecl 0x4917830 <line:3:15, col:24> col:24 typename T
| | |-CXXRecordDecl 0x49178e0 <line:4:5, line:6:5> line:4:11 class vector definition
| | | `-CXXRecordDecl 0x49588f0 <col:5, col:11> col:11 implicit class vector
| | `-ClassTemplateSpecializationDecl 0x49593b0 <line:3:5, line:6:5> line:4:11 class vector definition
| | |-TemplateArgument type 'class std::pair<int, int>'
| | |-CXXRecordDecl 0x4959750 prev 0x49593b0 <col:5, col:11> col:11 implicit class vector
| | |-CXXConstructorDecl 0x495ff30 <col:11> col:11 implicit used vector 'void (void) throw()' inline
| | | `-CompoundStmt 0x4960260 <col:11>
| | `-CXXConstructorDecl 0x4960090 <col:11> col:11 implicit vector 'void (const class std::vector<class std::pair<int, int> > &)' inline noexcept-unevaluated 0x4960090
| | `-ParmVarDecl 0x49601d0 <col:11> col:11 'const class std::vector<class std::pair<int, int> > &'
| `-ClassTemplateDecl 0x4958b40 <line:8:5, line:11:5> line:9:11 pair
| |-TemplateTypeParmDecl 0x4958980 <line:8:15, col:24> col:24 typename T1
| |-TemplateTypeParmDecl 0x49589f0 <col:28, col:37> col:37 typename T2
| |-CXXRecordDecl 0x4958ab0 <line:9:5, line:11:5> line:9:11 class pair definition
| | `-CXXRecordDecl 0x4958de0 <col:5, col:11> col:11 implicit class pair
| `-ClassTemplateSpecializationDecl 0x4959140 <line:8:5, line:11:5> line:9:11 class pair
| |-TemplateArgument type 'int'
| `-TemplateArgument type 'int'
|-EmptyDecl 0x4958e70 <line:12:2> col:2
|-TypedefDecl 0x4958ea0 <line:14:1, col:13> col:13 referenced size_t 'int'
|-VarDecl 0x4958f20 <line:17:1, col:8> col:8 N 'size_t':'int'
|-VarDecl 0x4958f90 <col:1, col:10> col:10 M 'size_t':'int'
|-VarDecl 0x4959010 <line:18:1, col:21> col:14 referenced MAXN 'const size_t':'const int' cinit
| `-IntegerLiteral 0x4959068 <col:21> 'int' 40000
|-VarDecl 0x4959690 <line:19:1, col:50> col:40 graph 'std::vector<std::pair<size_t, size_t> > [40000]' callinit
| `-CXXConstructExpr 0x4960278 <col:40> 'std::vector<std::pair<size_t, size_t> > [40000]' 'void (void) throw()'
|-VarDecl 0x49603f0 <col:1, col:62> col:52 query 'std::vector<std::pair<size_t, size_t> > [40000]' callinit
| `-CXXConstructExpr 0x4960448 <col:52> 'std::vector<std::pair<size_t, size_t> > [40000]' 'void (void) throw()'
|-VarDecl 0x49604c0 <col:1, col:64> col:64 qr 'std::vector<std::pair<size_t, size_t> >':'class std::vector<class std::pair<int, int> >' callinit
| `-CXXConstructExpr 0x4960518 <col:64> 'std::vector<std::pair<size_t, size_t> >':'class std::vector<class std::pair<int, int> >' 'void (void) throw()'
|-VarDecl 0x4960650 <line:20:1, col:14> col:8 p 'size_t [40000]'
|-VarDecl 0x4960710 <col:1, col:30> col:17 ancestor 'size_t [40000]'
|-VarDecl 0x4960820 <line:21:1, col:12> col:6 u '_Bool [40000]'
|-VarDecl 0x49608e0 <line:22:1, col:17> col:8 ansv 'size_t [40000]'
|-VarDecl 0x49609a0 <line:23:1, col:17> col:8 cost 'size_t [40000]'
|-FunctionDecl 0x4960b10 <line:25:1, line:28:1> line:25:8 find_set 'size_t (size_t)'
| |-ParmVarDecl 0x4960a10 <col:17, col:24> col:24 x 'size_t':'int'
| `-CompoundStmt 0x4960bf8 <col:26, line:28:1>
| `-ReturnStmt 0x4960bd8 <line:27:5, col:12>
| `-IntegerLiteral 0x4960bb8 <col:12> 'int' 0
|-FunctionDecl 0x4960e40 <line:30:1, line:32:1> line:30:6 unite 'void (size_t, size_t, size_t)'
| |-ParmVarDecl 0x4960c30 <col:12, col:19> col:19 a 'size_t':'int'
| |-ParmVarDecl 0x4960ca0 <col:22, col:29> col:29 b 'size_t':'int'
| |-ParmVarDecl 0x4960d10 <col:32, col:39> col:39 new_ancestor 'size_t':'int'
| `-CompoundStmt 0x4960ef8 <col:52, line:32:1>
|-FunctionDecl 0x49618d0 <line:34:1, line:36:1> line:34:6 dfs 'void (size_t, size_t)'
| |-ParmVarDecl 0x4961750 <col:10, col:17> col:17 v 'size_t':'int'
| |-ParmVarDecl 0x49617c0 <col:19, col:26> col:26 ct 'size_t':'int'
| `-CompoundStmt 0x4961980 <col:29, line:36:1>
`-FunctionDecl 0x4961c00 <line:38:1, line:40:1> line:38:5 main 'int (int, char **)'
|-ParmVarDecl 0x49619b0 <col:10, col:14> col:14 argc 'int'
|-ParmVarDecl 0x4961af0 <col:20, col:31> col:26 argv 'char **':'char **'
`-CompoundStmt 0x4961cb0 <col:33, line:40:1>
The correct solution is of course to not use -cc1
, and just use the original file with -c -Xclang -ast-dump
, but that produces a rather large amount of text (all the member functions of vector, pair, iostream, etc, etc). So if you are interested in a particular section, perhaps cut out required parts out of headers and only process the bits you actually need - all depends on what you are actually trying to achieve, of course.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With