[PATCH] D19357: [ASTMatchers] New matcher forFunction
Samuel Benzaquen via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 21 07:55:15 PDT 2016
sbenza added a comment.
Thanks for doing this!
I think we want the version that iterates all parents.
Otherwise it will have problems with templates.
That is, you won't know which `FunctionDecl` you will get: the template or the instantiation. And you might need one or the other specifically.
================
Comment at: include/clang/ASTMatchers/ASTMatchers.h:5124
@@ +5123,3 @@
+/// but does match 'return > 0'
+AST_MATCHER_P(Stmt, forFunction, internal::Matcher<FunctionDecl>,
+ InnerMatcher) {
----------------
I think this matcher works for Decls too, but we can leave it like this until we need the polymorphism.
================
Comment at: include/clang/ASTMatchers/ASTMatchers.h:5127
@@ +5126,3 @@
+ const auto &Parents = Finder->getASTContext().getParents(Node);
+ assert(!Parents.empty() && "Found node that is not in the parent map.");
+
----------------
You should not assert() this.
Parents can be empty if the statement is not inside a function. eg a global variable initializer.
================
Comment at: include/clang/ASTMatchers/ASTMatchers.h:5132
@@ +5131,3 @@
+ while(!Stack.empty()) {
+ const auto &CurNode = Stack.back();
+ Stack.pop_back();
----------------
If you are taking from the back, use a vector<> instead.
Or SmallVector<> to avoid allocation in most cases.
================
Comment at: include/clang/ASTMatchers/ASTMatchers.h:5134
@@ +5133,3 @@
+ Stack.pop_back();
+ if(const auto *DeclNode = CurNode.get<Decl>()) {
+ if(const auto *FuncDeclNode = dyn_cast<FunctionDecl>(DeclNode)) {
----------------
Just call `CurNode.get<FunctionDecl>`. It'll do the dyn_cast for you.
================
Comment at: include/clang/ASTMatchers/ASTMatchers.h:5139
@@ +5138,3 @@
+ }
+ }
+ }
----------------
We should check for `LambdaExpr` here too, and try to match against `LambdaExpr::getCallOperator()`
================
Comment at: include/clang/ASTMatchers/ASTMatchers.h:5141
@@ +5140,3 @@
+ }
+ const auto *StmtNode = CurNode.get<Stmt>();
+ if(StmtNode&&!isa<LambdaExpr>(StmtNode)) {
----------------
You don't need to get a Stmt. getParents() works with DynTypedNodes.
There might be some non-stmt nodes in the middle, like variable declarations.
================
Comment at: include/clang/ASTMatchers/ASTMatchers.h:5142
@@ +5141,3 @@
+ const auto *StmtNode = CurNode.get<Stmt>();
+ if(StmtNode&&!isa<LambdaExpr>(StmtNode)) {
+ for(const auto &Parent: Finder->getASTContext().getParents(*StmtNode))
----------------
We should also not traverse FunctionDecls.
Eg:
```
void F() {
struct S {
void F2() {
}
};
}
```
So, on each node: if is a FunctionDecl or a LambdaExpr run the matcher, otherwise traverse.
================
Comment at: unittests/ASTMatchers/ASTMatchersTest.cpp:5581
@@ +5580,3 @@
+ " typedef PosVec *iterator;"
+ " typedef const PosVec *const_iterator;"
+ " iterator begin();"
----------------
All of this is kind of unnecessary for the test.
The function could just be:
```
PosVec& operator=(const PosVec&) {
auto x = [] { return 1; };
return *this;
}
```
================
Comment at: unittests/ASTMatchers/ASTMatchersTest.cpp:5596
@@ +5595,3 @@
+ has(unaryOperator(hasOperatorName("*"))))));
+ EXPECT_FALSE(
+ matches(
----------------
`EXPECT_TRUE(notMatches(...`
================
Comment at: unittests/ASTMatchers/ASTMatchersTest.cpp:5601
@@ +5600,3 @@
+ has(binaryOperator(hasOperatorName(">"))))));
+ llvm::errs()<<"d";
+}
----------------
Please add test cases for the changes suggested to the matcher.
http://reviews.llvm.org/D19357
More information about the cfe-commits
mailing list