global init-declarator list not parsed as DeclStmt

Did you ever find any data in clang that can be used to resolve the following? I've got a similar problem and the hack we're using is fragile and unappealing.

<quote author='Brennan Vincent via cfe-dev'>

I am trying to transform all T a, b, c = ...; to single line declarations:

T a;
T b;
T c = ...;

This works well by matching for DeclStmt and iterating through the
DeclGroup. Unfortunately, a global declared T a, b, c = ...; does not
result in such a DeclStmt:

int alone;
int alone2 = 3;

int notalone1, notalone2 = 4;

int main(void)
int lalone;
int lalone2 = 3;

int lnotalone1, lnotalone2 = 4;


clang-check -ast-dump test.c --

TranslationUnitDecl 0x1742960 <<invalid sloc>> <invalid sloc>

-TypedefDecl 0x1742e58 <<invalid sloc>> <invalid sloc> implicit __int128_t


-TypedefDecl 0x1742eb8 <<invalid sloc>> <invalid sloc> implicit

__uint128_t 'unsigned __int128'

-TypedefDecl 0x1743228 <<invalid sloc>> <invalid sloc> implicit

__builtin_va_list '__va_list_tag [1]'

-VarDecl 0x1743288 </tmp/test.c:1:1, col:5> col:5 alone 'int'
-VarDecl 0x1743338 <line:2:1, col:14> col:5 alone2 'int' cinit
`-IntegerLiteral 0x1743398 <col:14> 'int' 3
-VarDecl 0x17433c8 <line:4:1, col:5> col:5 notalone1 'int'
-VarDecl 0x1743438 <col:1, col:28> col:16 notalone2 'int' cinit
`-IntegerLiteral 0x1743498 <col:28> 'int' 4

`-FunctionDecl 0x1743590 <line:6:1, line:13:1> line:6:5 main 'int (void)'
  `-CompoundStmt 0x1789d80 <line:7:1, line:13:1>
    >-DeclStmt 0x1789b90 <line:8:2, col:12>
    > `-VarDecl 0x1789b30 <col:2, col:6> col:6 lalone 'int'
    >-DeclStmt 0x1789c38 <line:9:2, col:17>
    > `-VarDecl 0x1789bb8 <col:2, col:16> col:6 lalone2 'int' cinit
    > `-IntegerLiteral 0x1789c18 <col:16> 'int' 3
    `-DeclStmt 0x1789d68 <line:11:2, col:32>
      >-VarDecl 0x1789c60 <col:2, col:6> col:6 lnotalone1 'int'
      `-VarDecl 0x1789cd0 <col:2, col:31> col:18 lnotalone2 'int' cinit
        `-IntegerLiteral 0x1789d30 <col:31> 'int' 4

clang-check -version

  LLVM version 3.7.0
  Optimized build.
  Built Oct 31 2015 (11:07:58).
  Default target: x86_64-unknown-linux-gnu
  Host CPU: ivybridge

As you can see, each notalone is a VarDecl whereas VarDecl for lnotaloneX
is grouped in a DeclStmt. Is there any other way to find all the
init-declarator lists?


I’ve posted this originally in the mailing list but so far, never came across a solution.

When walking the lexical contents of the TranslationUnit, you could check whether the VarDecl has the same start location as the previous one. If so, it’s part of the same group of declarations. (It’s unfortunate that we don’t have any explicit modeling of this in the AST; we probably should…)

Yes, that’s the unpleasant hack we use that I alluded to.