Clang AST Matcher - Matching nested function and method calls

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Clang AST Matcher - Matching nested function and method calls

Louis Dionne via cfe-dev

Hi,

 

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(…)”
to
    “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

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?

 

 

Thanks,

David Lai

 



 


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Clang AST Matcher - Matching nested function and method calls

Louis Dionne via cfe-dev
On Wed, Mar 28, 2018 at 7:32 AM David Lai via cfe-dev <[hidden email]> wrote:

Hi,

 

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(…)”
to
    “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.

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?

 

 

Thanks,

David Lai

 



 

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: Clang AST Matcher - Matching nested function and method calls

Louis Dionne via cfe-dev

Hi,

 

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:

 

Replacements.emplace(source_manager,
    CharSourceRange::getCharRange(call->getExprLoc(),
    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?

 

 

Thanks,

 

David Lai

 

From: Manuel Klimek <[hidden email]>
Date: Wednesday, March 28, 2018 at 1:56 AM
To: David Lai <[hidden email]>
Cc: "[hidden email]" <[hidden email]>
Subject: Re: [cfe-dev] Clang AST Matcher - Matching nested function and method calls

 

Hi,

 

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(…)”
to
    “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.

 

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?

 

 

Thanks,

David Lai

 

 

 

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev