[cfe-dev] ASTMatcher for assert()

Manuel Klimek klimek at google.com
Fri Jun 6 05:56:15 PDT 2014


On Tue, Jun 3, 2014 at 5:36 PM, Alex Horn <alex.horn at cs.ox.ac.uk> wrote:

> Hello,
>
> I am struggling to replace "assert(c)" macro calls by "BAR(c)" where c
> is some integer expression and BAR is a function.
>
> The problem manifests itself in RefactoringTool::applyAllReplacements
> which returns false, thereby causing the tool to skip replacements.
>
> I am using the following ASTMatcher:
>
> StatementMatcher makeAssertMatcher() {
>   return
> callExpr(callee(functionDecl(hasName("__builtin_expect")))).bind("AssertBindId");
> }
>
> Note: callExpr(callee(functionDecl(hasName("assert"))) won't work here
> because assert() is a macro according to the assert.h and cassert
> headers.
>
> Here's an example match using clang-query:
>
> example.cpp:
>
>   #include <assert.h>
>   int main() {
>     assert(false);
>     return 0;
>   }
>
> $ clang-query> match
> callExpr(callee(functionDecl(hasName("__builtin_expect"))))
>
>   Match #1:
>
>   example.cpp:4:3: note: "AssertBindId" binds here
>     assert(false);
>     ^~~~~~~~~~~~~
>   /usr/include/assert.h:93:6: note: expanded from macro 'assert'
>       (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__,
> __LINE__, #e) : (void)0)
>        ^~~~~~~~~~~~~~~~~~~~~~~~~
>   1 match.
>
> But I cannot find the correct way to rewrite the match; the following
> replacement is skipped (i.e. see line 295 in Refactoring.cpp):
>
>   const CallExpr *E = Result.Nodes.getNodeAs<CallExpr>("AssertBindId");
>   SourceManager &SM = *Result.SourceManager;
>   SourceLocation LocBegin = E->getLocStart();
>   Replace->insert(tooling::Replacement(SM, LocBegin,
>     /* number of letters in assert */ 6, "BAR"));
>
> What is the correct way (if any) to rewrite call expressions of macros
> such as "assert()"?
>

You need to get the expansion location:
SourceLocation ExpLocBegin = SM.getExpansionLoc(LocBegin);
Replace->insert(tooling::Replacement(SM, ExpLocBegin, 6, "BAR"));

Something like this should do the trick...
Cheers,
/Manuel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140606/6f997cdb/attachment.html>


More information about the cfe-dev mailing list