1

I am new to Clang libTooling development.

consider the following variable declaration

int i, j, k = 10;
^              ^  

For my project requirement, I want to capture the whole declaration expression including "i", "j" and "k".

How to capture the complete declaration expression including all variables with clang libTooling?

What I am experiencing is that I do not get the visitor for complete expression instead I get the visitor for individual variable declaration.

Is this the expected behavior in clang libTooling OR am I missing something?

Please suggest me the correct way to capture single line multiple declarations or any workaround? Any kind of help will be really appreciated.

Thanks, Hemant

Danh
  • 5,916
  • 7
  • 30
  • 45
Hemant
  • 767
  • 6
  • 20
  • I am not sure if there is a built-in way to capture the whole battery of declarations for a single line in libclang API, but perhaps you could work around this by comparing the source code locations of these to recognize when some variables are declared in the same line. – Argenet Dec 27 '16 at 06:59
  • That I can definitely do, but the purpose behind it is to follow parsing order followed in Java and C#. As there is no built-in way, I have to manually traverse the VarDecl which I wanted to avoid. – Hemant Dec 27 '16 at 07:10

1 Answers1

2

To solve the described problem you could for instance write a recursive AST visitor that visits DeclStmt nodes (not only VarDecl). Check this site to see how to write such a visitor: http://clang.llvm.org/docs/RAVFrontendAction.html

The reason why you should visit DeclStmt nodes and not only VarDecl nodes can be explained by having a look at the AST representation of your declaration statement:

    |-DeclStmt 0x35dbfc8 <line:3:1, col:17>
    | |-VarDecl 0x35dbe48 <col:1, col:5> col:5 i 'int'
    | |-VarDecl 0x35dbeb8 <col:1, col:8> col:8 j 'int'
    | `-VarDecl 0x35dbf28 <col:1, col:15> col:11 k 'int' cinit
    |   `-IntegerLiteral 0x35dbf88 <col:15> 'int' 10

As you can see the DeclStmt "captures" all the VarDecl nodes (and the initialization, if given). Once your visitor visits the DeclStmt you can check with the isSingleDecl() member function if your declaration refers to a single declaration or not. If not (as in your case) you can retrieve an iterator to the different VarDecl nodes with decl_begin(), decl_end(), etc.

  • This will work only for local variables. For global variables and class members, AST doesn't show any common DeclStmt. – Hemant Dec 28 '16 at 04:51
  • Any update? Maybe using clang_getCursorExtent()? I think the 'START' location of i, j and k will be the same... still needs parsing on the user-side, but minimal. – Rami Rosenbaum Feb 10 '19 at 09:13