title: clang tools: how to find the physical end of an expression?
body: <p>I’m building a source-to-source tool with clang. What I want to do is instrument stores made with the binary = operator. Currently, I’m running into problems with rewriting expressions that contain macro invocations. I’ve done some digging around, and I found some info  that helped with my understanding (e.g. <a href="https://stackoverflow.com/questions/24062989/clang-fails-replacing-a-statement-if-it-contains-a-macro">clang fails replacing a statement if it contains a macro</a>). But I’m still not sure how to solve this problem.</p>
  <p>Concretely, suppose you have:</p>
  <pre><code>#define a(x) ((x) * 10 + 1)
   
  class my_class {
      int x;
   
  public:
      int my_function() {
          x = a(0);
          return x;
      }
  };
   
  </code></pre>
  <p>I want to rewrite this into something like this:</p>
  <pre><code>#ifndef _instrument_noclash
  #define _instrument_noclash(name, expr, instance_no)                 \
      (*({                                                             \                                                               
          typeof(expr) *_t_instrument_no_clash##instance_no = &amp;(expr); \
          _t_instrument_no_clash##instance_no;                         \
          }))
  #endif
   
  #define a(x) ((x) * 10 + 1)
   
  class my_class {
          int x;
  public:
          int my_function() {
                  _instrument_noclash(&quot;x&quot;,(this-&gt;x=((0) * 10 + 1)),0);
                  return x;
          }
  };
   
  </code></pre>
  <p>The problem (to me) is simple: <strong>how do I determine the physical location of the ending of the expression on the right hand sign of the = operator?</strong> Without this knowledge, I end up overwriting the end of the statement. Scanning the APIs, it seems like there isn’t a simple way to do this. I’ve tried several ways to get the ending source location:</p>
  <ol>
  <li><code>op-&gt;getEndLoc()</code>, where <code>op</code> is an instance of <code>BinaryOperator</code>. This doesn’t work, because the ending location in the AST is not the same as the physical end location of the expression, due to macro expansion.</li>
  <li><code>sm.getSpellingLoc(op-&gt;getEndLoc())</code>, where <code>sm</code> is the source manager. This just returns <code>op-&gt;getEndLoc()</code>.</li>
  <li><code>sm.getExpansionLoc(op-&gt;getEndLoc())</code>. This is close, but the location returned is the end of the macro name, so the macro arguments are not removed.</li>
  </ol>
  <p>Any suggestions (or easier way to achieve this same goal) are appreciated.</p>