<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Jun 6, 2014 at 4:10 PM, Alex Horn <span dir="ltr"><<a href="mailto:alex.horn@cs.ox.ac.uk" target="_blank">alex.horn@cs.ox.ac.uk</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Thanks for the effective response. This helped on the right track and<br>
I've successfully used SourceManager::getImmediateExpansionRange() to<br>
insert BAR and its surrounding parenthesis correctly.<br>
<br>
As a directly related issue: The proposed technique of using the<br>
expansion range does the trick but of course requires that "-cc1<br>
-rewrite-macros" is _not_ invoked prior to rewriting "assert()"<br>
macros. However, this is problematic when other rewrites in the same<br>
RefactoringTool _do_ rely on macros having been rewritten. This poses<br>
the question whether these things can coexist in the same<br>
RefactoringTool. In particular, is it possible to call the<br>
RewriteMacros functionality only after certain matches have completed?<br>
<br>
To ask the same thing differently, what is the preferred way to<br>
compose ASTMatchers and cc1 drivers such as RewriteMacros?<br></blockquote><div><br></div><div>I wouldn't combine them. Why not write all tools to work on the non-macro-rewritten code? (you can get macros yourself via the PPCallbacks interface).</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5"><br>
On 6 June 2014 13:56, Manuel Klimek <<a href="mailto:klimek@google.com">klimek@google.com</a>> wrote:<br>
> On Tue, Jun 3, 2014 at 5:36 PM, Alex Horn <<a href="mailto:alex.horn@cs.ox.ac.uk">alex.horn@cs.ox.ac.uk</a>> wrote:<br>
>><br>
>> Hello,<br>
>><br>
>> I am struggling to replace "assert(c)" macro calls by "BAR(c)" where c<br>
>> is some integer expression and BAR is a function.<br>
>><br>
>> The problem manifests itself in RefactoringTool::applyAllReplacements<br>
>> which returns false, thereby causing the tool to skip replacements.<br>
>><br>
>> I am using the following ASTMatcher:<br>
>><br>
>> StatementMatcher makeAssertMatcher() {<br>
>>   return<br>
>> callExpr(callee(functionDecl(hasName("__builtin_expect")))).bind("AssertBindId");<br>
>> }<br>
>><br>
>> Note: callExpr(callee(functionDecl(hasName("assert"))) won't work here<br>
>> because assert() is a macro according to the assert.h and cassert<br>
>> headers.<br>
>><br>
>> Here's an example match using clang-query:<br>
>><br>
>> example.cpp:<br>
>><br>
>>   #include <assert.h><br>
>>   int main() {<br>
>>     assert(false);<br>
>>     return 0;<br>
>>   }<br>
>><br>
>> $ clang-query> match<br>
>> callExpr(callee(functionDecl(hasName("__builtin_expect"))))<br>
>><br>
>>   Match #1:<br>
>><br>
>>   example.cpp:4:3: note: "AssertBindId" binds here<br>
>>     assert(false);<br>
>>     ^~~~~~~~~~~~~<br>
>>   /usr/include/assert.h:93:6: note: expanded from macro 'assert'<br>
>>       (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__,<br>
>> __LINE__, #e) : (void)0)<br>
>>        ^~~~~~~~~~~~~~~~~~~~~~~~~<br>
>>   1 match.<br>
>><br>
>> But I cannot find the correct way to rewrite the match; the following<br>
>> replacement is skipped (i.e. see line 295 in Refactoring.cpp):<br>
>><br>
>>   const CallExpr *E = Result.Nodes.getNodeAs<CallExpr>("AssertBindId");<br>
>>   SourceManager &SM = *Result.SourceManager;<br>
>>   SourceLocation LocBegin = E->getLocStart();<br>
>>   Replace->insert(tooling::Replacement(SM, LocBegin,<br>
>>     /* number of letters in assert */ 6, "BAR"));<br>
>><br>
>> What is the correct way (if any) to rewrite call expressions of macros<br>
>> such as "assert()"?<br>
><br>
><br>
> You need to get the expansion location:<br>
> SourceLocation ExpLocBegin = SM.getExpansionLoc(LocBegin);<br>
> Replace->insert(tooling::Replacement(SM, ExpLocBegin, 6, "BAR"));<br>
><br>
> Something like this should do the trick...<br>
> Cheers,<br>
> /Manuel<br>
</div></div></blockquote></div><br></div></div>