new AST matcher that matches the expected return type of a ReturnStmt by looking at the enclosing function's stated return type; matches against the function's type
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
As mentioned in another review, it's not clear that this rises to the level of need to add it to the general AST matching interfaces. Can you explain the intended in-tree use cases for this?
This is our use case: https://github.com/ajohnson-uoregon/llvm-project/blob/feature-ajohnson/clang-tools-extra/clang-rewrite/MatcherGenCallback.h#L365
I'm not sure if anyone else would want to use this, but it feels like it could be generally useful. Now that I know we can define local matchers though we could do that instead.
Basically, we want to match based on the declared return type of the function, not the actual type of the thing returned, for cases where the thing returned is cast to something else. We used it to reimplement part of clang-tidy's modernize-use-nullptr check; we needed to get the declared (template) return type so we could check if it was a pointer type even though the thing returned was an int.
We haven't gotten around to implementing this yet (and the type code is actually a little broken), but there are other cases where we might want to specifically look for ReturnStmts that return a thing of type X when the function says it returns a thing of type Y, in which case we'd be using both hasType() and hasExpectedReturnType() kind of like this:
returnStmt(allOf( hasReturnValue(hasType(X)), hasExpectedReturnType(Y) ))
I think my preference is to use a local matcher to do this for now; if we find more use cases, we can always lift it into the general matcher framework then. But this feels too special-purpose to add currently.
Basically, we want to match based on the declared return type of the function, not the actual type of the thing returned, for cases where the thing returned is cast to something else. We used it to reimplement part of clang-tidy's modernize-use-nullptr check; we needed to get the declared (template) return type so we could check if it was a pointer type even though the thing returned was an int.
We haven't gotten around to implementing this yet (and the type code is actually a little broken), but there are other cases where we might want to specifically look for ReturnStmts that return a thing of type X when the function says it returns a thing of type Y, in which case we'd be using both hasType() and hasExpectedReturnType() kind of like this:
returnStmt(allOf( hasReturnValue(hasType(X)), hasExpectedReturnType(Y) ))
I think you should be able to do the same thing by traversal though -- the return statement is within a function declaration context, so you can walk up the tree to the functionDecl() (or blockDecl()?) to get to its declared return type information from the return statement itself. You're effectively implementing that same logic with your matcher, and the local matcher may be a cleaner implementation (I've not tried to write the matchers out myself).
clang-format: please reformat the code
34 diff lines are omitted. See full path.