[cfe-dev] Clang AST Matcher - Matching nested function and method calls

David Lai via cfe-dev cfe-dev at lists.llvm.org
Tue Apr 3 23:38:05 PDT 2018


Thanks for your help! I was able to write the matcher with nested “on” statements.

However, I am having trouble correctly retrieving the argument “foo” in SCB. Right now, I am retrieving it like:

std::string Buffer;
llvm::raw_string_ostream Stream(Buffer);

callArg->getArg(0)->prettyPrint(Stream, nullptr, result.Context->getPrintingPolicy())

and printing Stream.str() gives me “this->foo”, whereas I want to retrieve “foo” by itself. I have tried using the different Ignore functions (IgnoreCasts, IgnoreImplicit, etc), but none of them have worked.

Ultimately, I want to write a replacement like:

    Lexer::getLocForEndOfToken(call->getExprLoc(), 0, source_manager, context.getLangOpts()),
   “via(“ + argument + “).get”);

where argument is “foo”. Furthermore, using prettyPrint function for this seems kind of hacky as well, what is the proper way to retrieve the argument name?


David Lai

From: Manuel Klimek <klimek at google.com>
Date: Wednesday, March 28, 2018 at 1:56 AM
To: David Lai <dlai at fb.com>
Cc: "cfe-dev at lists.llvm.org" <cfe-dev at lists.llvm.org>
Subject: Re: [cfe-dev] Clang AST Matcher - Matching nested function and method calls

On Wed, Mar 28, 2018 at 7:32 AM David Lai via cfe-dev <cfe-dev at lists.llvm.org<mailto:cfe-dev at lists.llvm.org>> wrote:

I am quite new to clang AST matchers and wondering if you could help me with a match. I am writing a matcher to generate replacements.
Consider this,
SomeClientBuilder SCB(Foo& f) {
  return SomeClientBuilder.setFoo(f);

class SomeClientBuilder {
  Fruit apple(…);
  Fruit pear(…);

I would like to change
    “return SCB(foo).apple(req).get(…)”
    “return SCB().pear(req).via(foo).get(…)”

I would like to create a matcher that:
    - matches SCB so it has 1 argument of type Foo
    - matches method named apple() and is a method in SomeClientBuilder

After many attempts, I came up with two matchers.

1. cxxMemberCallExpr(callee(cxxMethodDecl(hasName("apple"), ofClass(cxxRecordDecl(hasName("SomeClientBuilder "))))))
    - this matcher does not restrict SCB to have 1 argument of type Foo

You should be able to compine this with the "on" matcher for cxxMemberCallExpr.
See http://clang.llvm.org/docs/LibASTMatchersReference.html<https://urldefense.proofpoint.com/v2/url?u=http-3A__clang.llvm.org_docs_LibASTMatchersReference.html&d=DwMFaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=RTaV7ZjEllVE-LoIBoiXow&m=4ARLvd38CywT-pqlZDgtWgtvsxJ8t_6QGD757MYfADA&s=-qaJ9Lnz5kkDFR7yAS7zO-y6K6-v0rie9r-yZD3dr20&e=>

on() takes an expr matcher as argument, with which you can match the nested call expr.

2. callExpr(callee(functionDecl(hasName("SCB"))), argumentCountIs(1), hasArgument(0, hasType(cxxRecordDecl(hasName("Foo")))))
    - this matcher does not match the “apple()” methods

I have tried combining the matchers together with no success. What do you think would be the best way to accomplish what I want to do?

David Lai

cfe-dev mailing list
cfe-dev at lists.llvm.org<mailto:cfe-dev at lists.llvm.org>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20180404/378da1db/attachment.html>

More information about the cfe-dev mailing list