summaryrefslogtreecommitdiffstats
path: root/clang/lib/ASTMatchers/ASTMatchFinder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/ASTMatchers/ASTMatchFinder.cpp')
-rw-r--r--clang/lib/ASTMatchers/ASTMatchFinder.cpp44
1 files changed, 26 insertions, 18 deletions
diff --git a/clang/lib/ASTMatchers/ASTMatchFinder.cpp b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
index 8a103f3d89a..8ac35d52284 100644
--- a/clang/lib/ASTMatchers/ASTMatchFinder.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -59,10 +59,12 @@ struct MatchKey {
DynTypedMatcher::MatcherIDType MatcherID;
ast_type_traits::DynTypedNode Node;
BoundNodesTreeBuilder BoundNodes;
+ ast_type_traits::TraversalKind Traversal = ast_type_traits::TK_AsIs;
bool operator<(const MatchKey &Other) const {
- return std::tie(MatcherID, Node, BoundNodes) <
- std::tie(Other.MatcherID, Other.Node, Other.BoundNodes);
+ return std::tie(MatcherID, Node, BoundNodes, Traversal) <
+ std::tie(Other.MatcherID, Other.Node, Other.BoundNodes,
+ Other.Traversal);
}
};
@@ -143,6 +145,8 @@ public:
ScopedIncrement ScopedDepth(&CurrentDepth);
Stmt *StmtToTraverse = StmtNode;
+ if (auto *ExprNode = dyn_cast_or_null<Expr>(StmtNode))
+ StmtToTraverse = Finder->getASTContext().traverseIgnored(ExprNode);
if (Traversal ==
ast_type_traits::TraversalKind::TK_IgnoreImplicitCastsAndParentheses) {
if (Expr *ExprNode = dyn_cast_or_null<Expr>(StmtNode))
@@ -390,6 +394,7 @@ public:
// Matches children or descendants of 'Node' with 'BaseMatcher'.
bool memoizedMatchesRecursively(const ast_type_traits::DynTypedNode &Node,
+ ASTContext &Ctx,
const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder, int MaxDepth,
ast_type_traits::TraversalKind Traversal,
@@ -404,6 +409,7 @@ public:
Key.Node = Node;
// Note that we key on the bindings *before* the match.
Key.BoundNodes = *Builder;
+ Key.Traversal = Ctx.getTraversalKind();
MemoizationMap::iterator I = ResultCache.find(Key);
if (I != ResultCache.end()) {
@@ -446,36 +452,36 @@ public:
// Implements ASTMatchFinder::matchesChildOf.
bool matchesChildOf(const ast_type_traits::DynTypedNode &Node,
- const DynTypedMatcher &Matcher,
+ ASTContext &Ctx, const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
ast_type_traits::TraversalKind Traversal,
BindKind Bind) override {
if (ResultCache.size() > MaxMemoizationEntries)
ResultCache.clear();
- return memoizedMatchesRecursively(Node, Matcher, Builder, 1, Traversal,
+ return memoizedMatchesRecursively(Node, Ctx, Matcher, Builder, 1, Traversal,
Bind);
}
// Implements ASTMatchFinder::matchesDescendantOf.
bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node,
- const DynTypedMatcher &Matcher,
+ ASTContext &Ctx, const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
BindKind Bind) override {
if (ResultCache.size() > MaxMemoizationEntries)
ResultCache.clear();
- return memoizedMatchesRecursively(Node, Matcher, Builder, INT_MAX,
+ return memoizedMatchesRecursively(Node, Ctx, Matcher, Builder, INT_MAX,
ast_type_traits::TraversalKind::TK_AsIs,
Bind);
}
// Implements ASTMatchFinder::matchesAncestorOf.
bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node,
- const DynTypedMatcher &Matcher,
+ ASTContext &Ctx, const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
AncestorMatchMode MatchMode) override {
// Reset the cache outside of the recursive call to make sure we
// don't invalidate any iterators.
if (ResultCache.size() > MaxMemoizationEntries)
ResultCache.clear();
- return memoizedMatchesAncestorOfRecursively(Node, Matcher, Builder,
+ return memoizedMatchesAncestorOfRecursively(Node, Ctx, Matcher, Builder,
MatchMode);
}
@@ -576,7 +582,7 @@ private:
if (EnableCheckProfiling)
Timer.setBucket(&TimeByBucket[MP.second->getID()]);
BoundNodesTreeBuilder Builder;
- if (MP.first.matchesNoKindCheck(DynNode, this, &Builder)) {
+ if (MP.first.matches(DynNode, this, &Builder)) {
MatchVisitor Visitor(ActiveASTContext, MP.second);
Builder.visitMatches(&Visitor);
}
@@ -640,16 +646,19 @@ private:
// allow simple memoization on the ancestors. Thus, we only memoize as long
// as there is a single parent.
bool memoizedMatchesAncestorOfRecursively(
- const ast_type_traits::DynTypedNode &Node, const DynTypedMatcher &Matcher,
- BoundNodesTreeBuilder *Builder, AncestorMatchMode MatchMode) {
+ const ast_type_traits::DynTypedNode &Node, ASTContext &Ctx,
+ const DynTypedMatcher &Matcher, BoundNodesTreeBuilder *Builder,
+ AncestorMatchMode MatchMode) {
// For AST-nodes that don't have an identity, we can't memoize.
if (!Builder->isComparable())
- return matchesAncestorOfRecursively(Node, Matcher, Builder, MatchMode);
+ return matchesAncestorOfRecursively(Node, Ctx, Matcher, Builder,
+ MatchMode);
MatchKey Key;
Key.MatcherID = Matcher.getID();
Key.Node = Node;
Key.BoundNodes = *Builder;
+ Key.Traversal = Ctx.getTraversalKind();
// Note that we cannot use insert and reuse the iterator, as recursive
// calls to match might invalidate the result cache iterators.
@@ -661,8 +670,8 @@ private:
MemoizedMatchResult Result;
Result.Nodes = *Builder;
- Result.ResultOfMatch =
- matchesAncestorOfRecursively(Node, Matcher, &Result.Nodes, MatchMode);
+ Result.ResultOfMatch = matchesAncestorOfRecursively(
+ Node, Ctx, Matcher, &Result.Nodes, MatchMode);
MemoizedMatchResult &CachedResult = ResultCache[Key];
CachedResult = std::move(Result);
@@ -672,6 +681,7 @@ private:
}
bool matchesAncestorOfRecursively(const ast_type_traits::DynTypedNode &Node,
+ ASTContext &Ctx,
const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
AncestorMatchMode MatchMode) {
@@ -705,8 +715,8 @@ private:
return true;
}
if (MatchMode != ASTMatchFinder::AMM_ParentOnly) {
- return memoizedMatchesAncestorOfRecursively(Parent, Matcher, Builder,
- MatchMode);
+ return memoizedMatchesAncestorOfRecursively(Parent, Ctx, Matcher,
+ Builder, MatchMode);
// Once we get back from the recursive call, the result will be the
// same as the parent's result.
}
@@ -804,8 +814,6 @@ private:
/// kind (and derived kinds) so it is a waste to try every matcher on every
/// node.
/// We precalculate a list of matchers that pass the toplevel restrict check.
- /// This also allows us to skip the restrict check at matching time. See
- /// use \c matchesNoKindCheck() above.
llvm::DenseMap<ast_type_traits::ASTNodeKind, std::vector<unsigned short>>
MatcherFiltersMap;
OpenPOWER on IntegriCloud