This is an archive of the discontinued LLVM Phabricator instance.

add isAtPosition narrowing matcher for parmVarDecl
ClosedPublic

Authored by oontvoo on May 26 2020, 7:32 PM.

Diff Detail

Event Timeline

oontvoo created this revision.May 26 2020, 7:32 PM

P.S: Please ignore the child revision ... accidentally committed it to the wrong branch. I've fixed the git branches locally but can't figure out how to tell phabricator ...

Please run clang/docs/tools/dump_ast_matchers.py to update the docs.

clang/include/clang/ASTMatchers/ASTMatchers.h
7053

Could you move it closer to other parameter-related matchers, maybe near the definition of forEachArgumentWithParam?

clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
2650

Could you change some tests to have a function declaration instead of definition?

aaron.ballman added a subscriber: aaron.ballman.

Does the hasParameter() matcher not already do this?

ymandel added inline comments.May 27 2020, 5:57 AM
clang/include/clang/ASTMatchers/ASTMatchers.h
7049

I think that hasAncestor will keep going up the chain of ancestors if it fails the match on the first surrounding functionDecl. That could make this matcher very expensive. Why hasParent (or, whatever combination of hasParent and other matchers needed to precisely describe the immediately surrounding functionDecl)?

7050

Note that "this_decl" might be in use the by the caller (unlikely, but possible). I'd suggest something less user friendly instead (for example, prefixing with the name of the matcher). That said, any binding inside a manager runs risk of conflict, because we don't have any scoping or fresh-name generation facilities, so any name will run some risk.

oontvoo updated this revision to Diff 266615.May 27 2020, 11:47 AM
oontvoo marked 7 inline comments as done.
  • Added docs
  • Make it work with {block,objcMethod}Decl too. More tests

Does the hasParameter() matcher not already do this?

Yes, it does. But we'd like it to be able to match on the parmVarDecl().

clang/include/clang/ASTMatchers/ASTMatchers.h
7049

Why [not] hasParent ?

The direct parent of the param is a TypeLoc, so I thought hasAncestor() was more convenient. But I've changed it to two nested hasParent() now.

7053

Moved it to after hasAncestor.
(Can't move to near forEachArgumentWithParam because that's before hasAncestor and hasParent, which are needed by this)

Does the hasParameter() matcher not already do this?

Yes, it does. But we'd like it to be able to match on the parmVarDecl().

I'm sorry if I'm being dense, but hasParameter traverses to the ParmVarDecl, so I'm not certain I understand why this new matcher is needed as a public matcher. It seems like you can already accomplish this without adding a second API to do effectively the same thing: functionDecl(hasParameter(0, parmVarDecl().bind("param"))), can't you?

oontvoo updated this revision to Diff 266642.May 27 2020, 1:07 PM

Remove unrelated doc generated by the script

Does the hasParameter() matcher not already do this?

Yes, it does. But we'd like it to be able to match on the parmVarDecl().

I'm sorry if I'm being dense, but hasParameter traverses to the ParmVarDecl, so I'm not certain I understand why this new matcher is needed as a public matcher. It seems like you can already accomplish this without adding a second API to do effectively the same thing: functionDecl(hasParameter(0, parmVarDecl().bind("param"))), can't you?

Ah, I didn't mean to say it wasn't *already possible* to do any of this.

It would be *very* nice to have this (at least to some of us, that I know of). (make the logic a lot simpler in a few custom matchers).

oontvoo updated this revision to Diff 266714.May 27 2020, 6:19 PM

use helper for examining the node instead of nested matchers

oontvoo updated this revision to Diff 266735.May 27 2020, 9:38 PM

More tests for Block

I'm sorry if I'm being dense, but hasParameter traverses to the ParmVarDecl, so I'm not certain I understand why this new matcher is needed as a public matcher. It seems like you can already accomplish this without adding a second API to do effectively the same thing: functionDecl(hasParameter(0, parmVarDecl().bind("param"))), can't you?

It is syntax sugar, true. Note that the proposed matcher is a narrowing matcher for parmVarDecl(), while your suggestion is a narrowing matcher for functionDecl(), so it is not an entirely apples-to-apples comparison. Think about use cases like: declRefExpr(to(parmVarDecl(at(...)))). To rewrite that with hasParameter(), we have to use hasAncestor to find the functionDecl first, and then compare the AST node pointers. So while it is possible to express this proposed operation today, it requires a complex matcher for such a conceptually simple operation.

clang/include/clang/ASTMatchers/ASTMatchers.h
4621

Identifiers with double underscores are reserved. Also, this file typically does not define helpers.

My best suggestion is to define a local lambda in the AST_MATCHER_P, or just copy the code three times -- there is not that much duplication.

gribozavr2 added inline comments.May 27 2020, 10:41 PM
clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
2672

Please use matchesObjC / notMatchesObjC.

oontvoo updated this revision to Diff 266887.May 28 2020, 8:32 AM
oontvoo marked 2 inline comments as done.

Change tests to us no/matchesObjC

I'm sorry if I'm being dense, but hasParameter traverses to the ParmVarDecl, so I'm not certain I understand why this new matcher is needed as a public matcher. It seems like you can already accomplish this without adding a second API to do effectively the same thing: functionDecl(hasParameter(0, parmVarDecl().bind("param"))), can't you?

It is syntax sugar, true. Note that the proposed matcher is a narrowing matcher for parmVarDecl(), while your suggestion is a narrowing matcher for functionDecl(), so it is not an entirely apples-to-apples comparison. Think about use cases like: declRefExpr(to(parmVarDecl(at(...)))). To rewrite that with hasParameter(), we have to use hasAncestor to find the functionDecl first, and then compare the AST node pointers. So while it is possible to express this proposed operation today, it requires a complex matcher for such a conceptually simple operation.

Thank you, that clarifies the need nicely for me!

Is there a reason we want to support blocks but not lambdas?

Also, you need to update Registry.cpp to add this to the list of dynamic matchers.

Is there a reason we want to support blocks but not lambdas?

Lambdas are supported (see tests). Lambdas generate classes with regular function decls, so there's no surprise there.

Also, you need to update Registry.cpp to add this to the list of dynamic matchers.

Good point. @oontvoo

oontvoo updated this revision to Diff 266999.May 28 2020, 12:50 PM

Updated Registry

I'm sorry if I'm being dense, but hasParameter traverses to the ParmVarDecl, so I'm not certain I understand why this new matcher is needed as a public matcher. It seems like you can already accomplish this without adding a second API to do effectively the same thing: functionDecl(hasParameter(0, parmVarDecl().bind("param"))), can't you?

It is syntax sugar, true. Note that the proposed matcher is a narrowing matcher for parmVarDecl(), while your suggestion is a narrowing matcher for functionDecl(), so it is not an entirely apples-to-apples comparison. Think about use cases like: declRefExpr(to(parmVarDecl(at(...)))). To rewrite that with hasParameter(), we have to use hasAncestor to find the functionDecl first, and then compare the AST node pointers. So while it is possible to express this proposed operation today, it requires a complex matcher for such a conceptually simple operation.

Thank you, that clarifies the need nicely for me!

Is there a reason we want to support blocks but not lambdas?

Yes, the implementation does support lambdas

Also, you need to update Registry.cpp to add this to the list of dynamic matchers.

Done

oontvoo updated this revision to Diff 267008.May 28 2020, 1:01 PM

Move matcher to near forEachArgumentWithParam

gribozavr2 accepted this revision.May 28 2020, 1:02 PM
This revision is now accepted and ready to land.May 28 2020, 1:02 PM