<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>