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