<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<div class="moz-cite-prefix">On 23/06/2015 22:21, Richard Smith
wrote:<br>
</div>
<blockquote
cite="mid:CAOfiQqmFKSf4BjdTpmi1TkbpkvnJ3-xwZvSYMUCAW2NPmDv9Cw@mail.gmail.com"
type="cite">
<meta http-equiv="Context-Type" content="text/html; charset=UTF-8">
<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 moz-do-not-send="true" href="mailto:alastair.donaldson@imperial.ac.uk" target="_blank">alastair.donaldson@imperial.ac.uk</a>></span>
wrote:<br>
<blockquote class="gmail_quote">
<div>
<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 moz-do-not-send="true" 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>
</div>
</blockquote>
<br>
I opted for your first suggestion, and it worked like a charm - many
thanks!<br>
<br>
Best wishes<br>
<br>
Ally<br>
<br>
<br>
<blockquote
cite="mid:CAOfiQqmFKSf4BjdTpmi1TkbpkvnJ3-xwZvSYMUCAW2NPmDv9Cw@mail.gmail.com"
type="cite">
<div dir="ltr">
<div class="gmail_extra">
<div class="gmail_quote">
<div> </div>
<blockquote class="gmail_quote">
<div> 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 moz-do-not-send="true" href="https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_loarabia_Clang-2Dtutorial_blob_master_CIrewriter.cpp&d=AwMDaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=CnzuN65ENJ1H9py9XLiRvC_UQz6u3oG6GUNn7_wosSM&m=yBZ2EZYvPO9A0NXwiIE3K-JBiNuKWStaEFP91UAvelE&s=bjAREc0DW6k9xDLgY8o0YnMe18ecZvsDChVpEtwIoPw&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 moz-do-not-send="true" href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a><br>
<a moz-do-not-send="true" 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>
</blockquote>
<br>
</body>
</html>