<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Jun 23, 2015 at 2:09 PM, Alastair Donaldson <span dir="ltr"><<a href="mailto:alastair.donaldson@imperial.ac.uk" target="_blank">alastair.donaldson@imperial.ac.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div bgcolor="#FFFFFF" text="#000000">
<div>Dear Richard<span class=""><br>
<br>
On 23/06/2015 21:55, Richard Smith wrote:<br>
</span></div><span class="">
<blockquote type="cite">
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">On Tue, Jun 23, 2015 at 1:05 PM,
Alastair Donaldson <span dir="ltr"><<a href="mailto:alastair.donaldson@imperial.ac.uk" target="_blank">alastair.donaldson@imperial.ac.uk</a>></span>
wrote:<br>
<blockquote class="gmail_quote">Dear all<br>
<br>
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:<br>
<br>
- for every Stmt node in the AST, replace the source code
associated with the Stmt with:<br>
<br>
open(x) original_source_code_for_Stmt close(x)<br>
<br>
where x is a number chosen uniquely for the Stmt node.<br>
<br>
For instance, if the Stmt is the expression:<br>
<br>
x + y<br>
<br>
then I would like to end up with something like:<br>
<br>
open(2) open(0) x close(0) + open(1) y close(1) close(2)<br>
<br>
I hope my objective makes sense.<br>
<br>
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.<br>
<br>
I've tried two things:<br>
<br>
bool TraverseStmt(Stmt *s) {<br>
bool result = RecursiveASTVisitor::TraverseStmt(s);<br>
std::stringstream ss_start;<br>
ss_start << "open(" << counter <<
")";<br>
TheRewriter.InsertTextAfter(s->getLocStart(),
ss_start.str());<br>
std::stringstream ss_end;<br>
ss_end << "close(" << counter <<
")";<br>
TheRewriter.InsertTextAfterToken(s->getLocEnd(),
ss_end.str());<br>
</blockquote>
<div><br>
</div>
<div>InsertTextAfter and InsertTextAfterToken return a bool
indicating whether the insertion was possible (false on
success, true on failure). You could use that to isolate
which particular call is failing.</div>
</div>
</div>
</div>
</blockquote>
<br></span>
Thanks for this suggestion. However, the calls do not fail: all the
"open" and "close" strings are emitted. They are just not
balanced. For example, I see this:<br>
<br>
open(8)(open(0)open(1)open(7)d close(1)close(0)+
open(6)(open(2)open(3)open(5)d close(3)close(2)/
open(4)2)close(5)close(4))close(7)close(6);close(8)<br>
<br>
for the expression:<br>
<br>
(d + (d / 2))<br>
<br>
So you can see that all the opens have matching closes. It's just
that they are not balanced.<br>
<br>
Does this bring anything else to mind?<br></div></blockquote><div><br></div><div>Oh, I see what you mean now. The problem seems to be that you're adding the "open" string for the outer statement after the open string for its first substatement. Try this:</div><div><br></div><div>InsertTextAfter(s->getLocStart(), ...);</div><div>TraverseStmt(s);</div><div>InsertTextAfterToken(s->getLocEnd(), ...);</div><div><br></div><div>(or change your first InsertTextAfter to InsertTextBefore).</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div bgcolor="#FFFFFF" text="#000000">
Many thanks<br>
<br>
Ally<div><div class="h5"><br>
<br>
<br>
<blockquote type="cite">
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">
<div><br>
</div>
<div>That said, the only cases where the above calls would
currently fail are if they're given a location for which
TheRewriter.isRewritable returns false. That only happens
if the location provided is within a macro expansion.
Could that be the case in your failing examples?</div>
<div> </div>
<blockquote class="gmail_quote">
counter++;<br>
return result;<br>
}<br>
<br>
(This is what seemed natural to me from the clang APIs)<br>
<br>
and also:<br>
<br>
bool TraverseStmt(Stmt *s) {<br>
bool result = RecursiveASTVisitor::TraverseStmt(s);<br>
std::stringstream ss_start;<br>
ss_start << "open(" << counter <<
")";<br>
TheRewriter.InsertTextAfter(s->getLocStart(),
ss_start.str());<br>
int offset =
Lexer::MeasureTokenLength(s->getLocEnd(),
TheRewriter.getSourceMgr(), TheRewriter.getLangOpts()) +
1;<br>
auto END1 =
s->getLocEnd().getLocWithOffset(offset);<br>
std::stringstream ss_end;<br>
ss_end << "close(" << counter <<
")";<br>
TheRewriter.InsertTextBefore(END1, ss_end.str());<br>
counter++;<br>
return result;<br>
}<br>
<br>
(I came up with this after reading this source code from
Robert Ankeney: <a href="https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_loarabia_Clang-2Dtutorial_blob_master_CIrewriter.cpp&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=CnzuN65ENJ1H9py9XLiRvC_UQz6u3oG6GUNn7_wosSM&m=CVOU6zXScLwcoR9bLkl4D1lZtdLFDTvn_Pgane9RgOo&s=6derIkD2Al_0P4eQZQunbGpUNacvE-2MHQZropekXjI&e=" rel="noreferrer" target="_blank">https://github.com/loarabia/Clang-tutorial/blob/master/CIrewriter.cpp</a>)<br>
<br>
However, neither work - my parentheses end up being
unbalanced.<br>
<br>
I think the problem may be that in an expression such as:<br>
<br>
x + y<br>
<br>
the sub-expressions "y" and "x + y" have the same end
source location. But I cannot figure out how to get
around this.<br>
<br>
I'd be really grateful if anyone can give me a pointer
here.<br>
<br>
Best wishes<br>
<br>
Ally Donaldson<br>
<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
</blockquote>
</div>
<br>
</div>
</div>
</blockquote>
<br>
</div></div></div>
</blockquote></div><br></div></div>