How to walk identifiers of multi-variable declaration (int i, j; )?


I'm interested in transforming:

int i, j;


int i;
int j;

However, they both end up with the same AST:

separate declaration statements:

clang -Xclang -ast-dump -fsyntax-only /tmp/decl.cpp

TranslationUnitDecl 0x49539c0 <<invalid sloc>> <invalid sloc>

-VarDecl 0x4954380 </tmp/decl.cpp:1:1, col:5> col:5 i 'int'

`-VarDecl 0x49543f0 <line:2:1, col:5> col:5 j 'int'

combined declaration statement:

clang -Xclang -ast-dump -fsyntax-only /tmp/decl2.cpp

TranslationUnitDecl 0x39579c0 <<invalid sloc>> <invalid sloc>

-VarDecl 0x3958380 </tmp/decl2.cpp:1:1, col:5> col:5 i 'int'

`-VarDecl 0x39583f0 <col:1, col:8> col:8 j 'int'

What's worse is that the source range for the VarDecl 'j' contains the
identifier 'i'!

Given that the single declaration statement declaring both i and j
isn't distinctly represented in the AST, how do I even detect such a
thing and extract each individual variable identifier from the single
statement without walking all the tokens all over again? (For
something declaring pointers to members, this could be a complex chain
of tokens.)

I hacked up something that matched varDecls() and did something like:

  LastSourceLoc = empty;

  if (LastSourceLoc == match.LocStart) {
    diag("multiple variables declared");
  LastSourceLoc = match.LocStart;

which sorta worked in that it issued a diagnostic on the right line,
but then when attempting to build a replacement string, there didn't
seem to be anything better than re-walking all the tokens in the
varDecl again, which feels lame.

I thought *everything* about the source files was represented in the AST,
but this one leaves me stumped as to how to identify that two VarDecls
came from the same statement by directly querying the AST.

What's the best way to do this?