Move TraversalKind enum to ast_type_traits
Summary: Make it usable outside of ASTMatchFinder. This will make it possible to use this enum to control whether certain implicit nodes are skipped while AST dumping for example. Reviewers: klimek, aaron.ballman Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D61836 llvm-svn: 360920
This commit is contained in:
parent
f8f788b205
commit
d147cea3b9
4 changed files with 31 additions and 36 deletions
|
@ -38,6 +38,16 @@ struct PrintingPolicy;
|
|||
|
||||
namespace ast_type_traits {
|
||||
|
||||
/// Defines how we descend a level in the AST when we pass
|
||||
/// through expressions.
|
||||
enum TraversalKind {
|
||||
/// Will traverse any child nodes.
|
||||
TK_AsIs,
|
||||
|
||||
/// Will not traverse implicit casts and parentheses.
|
||||
TK_IgnoreImplicitCastsAndParentheses
|
||||
};
|
||||
|
||||
/// Kind identifier.
|
||||
///
|
||||
/// It can be constructed from any node kind and allows for runtime type
|
||||
|
|
|
@ -950,15 +950,6 @@ const bool IsBaseType<T>::value;
|
|||
/// all nodes, as all nodes have ancestors.
|
||||
class ASTMatchFinder {
|
||||
public:
|
||||
/// Defines how we descend a level in the AST when we pass
|
||||
/// through expressions.
|
||||
enum TraversalKind {
|
||||
/// Will traverse any child nodes.
|
||||
TK_AsIs,
|
||||
|
||||
/// Will not traverse implicit casts and parentheses.
|
||||
TK_IgnoreImplicitCastsAndParentheses
|
||||
};
|
||||
|
||||
/// Defines how bindings are processed on recursive matches.
|
||||
enum BindKind {
|
||||
|
@ -989,11 +980,9 @@ public:
|
|||
BoundNodesTreeBuilder *Builder) = 0;
|
||||
|
||||
template <typename T>
|
||||
bool matchesChildOf(const T &Node,
|
||||
const DynTypedMatcher &Matcher,
|
||||
bool matchesChildOf(const T &Node, const DynTypedMatcher &Matcher,
|
||||
BoundNodesTreeBuilder *Builder,
|
||||
TraversalKind Traverse,
|
||||
BindKind Bind) {
|
||||
ast_type_traits::TraversalKind Traverse, BindKind Bind) {
|
||||
static_assert(std::is_base_of<Decl, T>::value ||
|
||||
std::is_base_of<Stmt, T>::value ||
|
||||
std::is_base_of<NestedNameSpecifier, T>::value ||
|
||||
|
@ -1042,7 +1031,7 @@ protected:
|
|||
virtual bool matchesChildOf(const ast_type_traits::DynTypedNode &Node,
|
||||
const DynTypedMatcher &Matcher,
|
||||
BoundNodesTreeBuilder *Builder,
|
||||
TraversalKind Traverse,
|
||||
ast_type_traits::TraversalKind Traverse,
|
||||
BindKind Bind) = 0;
|
||||
|
||||
virtual bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node,
|
||||
|
@ -1290,7 +1279,7 @@ public:
|
|||
bool matches(const T &Node, ASTMatchFinder *Finder,
|
||||
BoundNodesTreeBuilder *Builder) const override {
|
||||
return Finder->matchesChildOf(Node, this->InnerMatcher, Builder,
|
||||
ASTMatchFinder::TK_AsIs,
|
||||
ast_type_traits::TraversalKind::TK_AsIs,
|
||||
ASTMatchFinder::BK_First);
|
||||
}
|
||||
};
|
||||
|
@ -1313,7 +1302,7 @@ class ForEachMatcher : public WrapperMatcherInterface<T> {
|
|||
BoundNodesTreeBuilder* Builder) const override {
|
||||
return Finder->matchesChildOf(
|
||||
Node, this->InnerMatcher, Builder,
|
||||
ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
|
||||
ast_type_traits::TraversalKind::TK_IgnoreImplicitCastsAndParentheses,
|
||||
ASTMatchFinder::BK_All);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -83,20 +83,12 @@ public:
|
|||
// descendants of a traversed node. max_depth is the maximum depth
|
||||
// to traverse: use 1 for matching the children and INT_MAX for
|
||||
// matching the descendants.
|
||||
MatchChildASTVisitor(const DynTypedMatcher *Matcher,
|
||||
ASTMatchFinder *Finder,
|
||||
BoundNodesTreeBuilder *Builder,
|
||||
int MaxDepth,
|
||||
ASTMatchFinder::TraversalKind Traversal,
|
||||
MatchChildASTVisitor(const DynTypedMatcher *Matcher, ASTMatchFinder *Finder,
|
||||
BoundNodesTreeBuilder *Builder, int MaxDepth,
|
||||
ast_type_traits::TraversalKind Traversal,
|
||||
ASTMatchFinder::BindKind Bind)
|
||||
: Matcher(Matcher),
|
||||
Finder(Finder),
|
||||
Builder(Builder),
|
||||
CurrentDepth(0),
|
||||
MaxDepth(MaxDepth),
|
||||
Traversal(Traversal),
|
||||
Bind(Bind),
|
||||
Matches(false) {}
|
||||
: Matcher(Matcher), Finder(Finder), Builder(Builder), CurrentDepth(0),
|
||||
MaxDepth(MaxDepth), Traversal(Traversal), Bind(Bind), Matches(false) {}
|
||||
|
||||
// Returns true if a match is found in the subtree rooted at the
|
||||
// given AST node. This is done via a set of mutually recursive
|
||||
|
@ -151,7 +143,8 @@ public:
|
|||
|
||||
ScopedIncrement ScopedDepth(&CurrentDepth);
|
||||
Stmt *StmtToTraverse = StmtNode;
|
||||
if (Traversal == ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses) {
|
||||
if (Traversal ==
|
||||
ast_type_traits::TraversalKind::TK_IgnoreImplicitCastsAndParentheses) {
|
||||
if (Expr *ExprNode = dyn_cast_or_null<Expr>(StmtNode))
|
||||
StmtToTraverse = ExprNode->IgnoreParenImpCasts();
|
||||
}
|
||||
|
@ -299,7 +292,7 @@ private:
|
|||
BoundNodesTreeBuilder ResultBindings;
|
||||
int CurrentDepth;
|
||||
const int MaxDepth;
|
||||
const ASTMatchFinder::TraversalKind Traversal;
|
||||
const ast_type_traits::TraversalKind Traversal;
|
||||
const ASTMatchFinder::BindKind Bind;
|
||||
bool Matches;
|
||||
};
|
||||
|
@ -393,7 +386,8 @@ public:
|
|||
bool memoizedMatchesRecursively(const ast_type_traits::DynTypedNode &Node,
|
||||
const DynTypedMatcher &Matcher,
|
||||
BoundNodesTreeBuilder *Builder, int MaxDepth,
|
||||
TraversalKind Traversal, BindKind Bind) {
|
||||
ast_type_traits::TraversalKind Traversal,
|
||||
BindKind Bind) {
|
||||
// For AST-nodes that don't have an identity, we can't memoize.
|
||||
if (!Node.getMemoizationData() || !Builder->isComparable())
|
||||
return matchesRecursively(Node, Matcher, Builder, MaxDepth, Traversal,
|
||||
|
@ -427,7 +421,8 @@ public:
|
|||
bool matchesRecursively(const ast_type_traits::DynTypedNode &Node,
|
||||
const DynTypedMatcher &Matcher,
|
||||
BoundNodesTreeBuilder *Builder, int MaxDepth,
|
||||
TraversalKind Traversal, BindKind Bind) {
|
||||
ast_type_traits::TraversalKind Traversal,
|
||||
BindKind Bind) {
|
||||
MatchChildASTVisitor Visitor(
|
||||
&Matcher, this, Builder, MaxDepth, Traversal, Bind);
|
||||
return Visitor.findMatch(Node);
|
||||
|
@ -441,7 +436,7 @@ public:
|
|||
bool matchesChildOf(const ast_type_traits::DynTypedNode &Node,
|
||||
const DynTypedMatcher &Matcher,
|
||||
BoundNodesTreeBuilder *Builder,
|
||||
TraversalKind Traversal,
|
||||
ast_type_traits::TraversalKind Traversal,
|
||||
BindKind Bind) override {
|
||||
if (ResultCache.size() > MaxMemoizationEntries)
|
||||
ResultCache.clear();
|
||||
|
@ -456,7 +451,8 @@ public:
|
|||
if (ResultCache.size() > MaxMemoizationEntries)
|
||||
ResultCache.clear();
|
||||
return memoizedMatchesRecursively(Node, Matcher, Builder, INT_MAX,
|
||||
TK_AsIs, Bind);
|
||||
ast_type_traits::TraversalKind::TK_AsIs,
|
||||
Bind);
|
||||
}
|
||||
// Implements ASTMatchFinder::matchesAncestorOf.
|
||||
bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node,
|
||||
|
|
|
@ -76,7 +76,7 @@ AST_POLYMORPHIC_MATCHER_P(polymorphicHas,
|
|||
internal::Matcher<Decl>, AMatcher) {
|
||||
return Finder->matchesChildOf(
|
||||
Node, AMatcher, Builder,
|
||||
ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
|
||||
ast_type_traits::TraversalKind::TK_IgnoreImplicitCastsAndParentheses,
|
||||
ASTMatchFinder::BK_First);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue