[cfe-dev] Adding balanced parentheses to statements

Alastair Donaldson alastair.donaldson at imperial.ac.uk
Tue Jun 23 13:05:31 PDT 2015


Dear all

I am trying to use the Rewriter class to do something conceptually 
pretty straightforward to a source file.  What I actually want to do is 
pretty specific, but if I could work out how to do the following it 
would be obvious how to solve my problem:

- for every Stmt node in the AST, replace the source code associated 
with the Stmt with:

     open(x) original_source_code_for_Stmt close(x)

where x is a number chosen uniquely for the Stmt node.

For instance, if the Stmt is the expression:

x + y

then I would like to end up with something like:

open(2) open(0) x close(0) + open(1) y close(1) close(2)

I hope my objective makes sense.

What I've tried to do is write a class that extends RecursiveASTVisitor, 
equipped with a Rewriter field, "TheRewriter", and an int field, 
"counter".  The Rewriter should allow me to rewrite the source code.  
The counter is used to give each open and close a unique x.  I'm 
assuming for now that all my code is in one source file.

I've tried two things:

   bool TraverseStmt(Stmt *s) {
     bool result = RecursiveASTVisitor::TraverseStmt(s);
     std::stringstream ss_start;
     ss_start << "open(" << counter << ")";
     TheRewriter.InsertTextAfter(s->getLocStart(), ss_start.str());
     std::stringstream ss_end;
     ss_end << "close(" << counter << ")";
     TheRewriter.InsertTextAfterToken(s->getLocEnd(), ss_end.str());
     counter++;
     return result;
   }

(This is what seemed natural to me from the clang APIs)

and also:

   bool TraverseStmt(Stmt *s) {
     bool result = RecursiveASTVisitor::TraverseStmt(s);
     std::stringstream ss_start;
     ss_start << "open(" << counter << ")";
     TheRewriter.InsertTextAfter(s->getLocStart(), ss_start.str());
     int offset = Lexer::MeasureTokenLength(s->getLocEnd(), 
TheRewriter.getSourceMgr(), TheRewriter.getLangOpts()) + 1;
     auto END1 = s->getLocEnd().getLocWithOffset(offset);
     std::stringstream ss_end;
     ss_end << "close(" << counter << ")";
     TheRewriter.InsertTextBefore(END1, ss_end.str());
     counter++;
     return result;
   }

(I came up with this after reading this source code from Robert Ankeney: 
https://github.com/loarabia/Clang-tutorial/blob/master/CIrewriter.cpp)

However, neither work - my parentheses end up being unbalanced.

I think the problem may be that in an expression such as:

x + y

the sub-expressions "y" and "x + y" have the same end source location.  
But I cannot figure out how to get around this.

I'd be really grateful if anyone can give me a pointer here.

Best wishes

Ally Donaldson




More information about the cfe-dev mailing list