aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/ASTMatchers/ASTMatchFinder.cpp91
1 files changed, 6 insertions, 85 deletions
diff --git a/lib/ASTMatchers/ASTMatchFinder.cpp b/lib/ASTMatchers/ASTMatchFinder.cpp
index 3a3c1fb6e1..1af2f09c3e 100644
--- a/lib/ASTMatchers/ASTMatchFinder.cpp
+++ b/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -29,76 +29,6 @@ namespace {
typedef MatchFinder::MatchCallback MatchCallback;
-/// \brief A \c RecursiveASTVisitor that builds a map from nodes to their
-/// parents as defined by the \c RecursiveASTVisitor.
-///
-/// Note that the relationship described here is purely in terms of AST
-/// traversal - there are other relationships (for example declaration context)
-/// in the AST that are better modeled by special matchers.
-///
-/// FIXME: Currently only builds up the map using \c Stmt and \c Decl nodes.
-class ParentMapASTVisitor : public RecursiveASTVisitor<ParentMapASTVisitor> {
-public:
- /// \brief Contains parents of a node.
- typedef SmallVector<ast_type_traits::DynTypedNode, 1> ParentVector;
-
- /// \brief Maps from a node to its parents.
- typedef llvm::DenseMap<const void *, ParentVector> ParentMap;
-
- /// \brief Builds and returns the translation unit's parent map.
- ///
- /// The caller takes ownership of the returned \c ParentMap.
- static ParentMap *buildMap(TranslationUnitDecl &TU) {
- ParentMapASTVisitor Visitor(new ParentMap);
- Visitor.TraverseDecl(&TU);
- return Visitor.Parents;
- }
-
-private:
- typedef RecursiveASTVisitor<ParentMapASTVisitor> VisitorBase;
-
- ParentMapASTVisitor(ParentMap *Parents) : Parents(Parents) {}
-
- bool shouldVisitTemplateInstantiations() const { return true; }
- bool shouldVisitImplicitCode() const { return true; }
- // Disables data recursion. We intercept Traverse* methods in the RAV, which
- // are not triggered during data recursion.
- bool shouldUseDataRecursionFor(clang::Stmt *S) const { return false; }
-
- template <typename T>
- bool TraverseNode(T *Node, bool (VisitorBase::*traverse)(T*)) {
- if (Node == NULL)
- return true;
- if (ParentStack.size() > 0)
- // FIXME: Currently we add the same parent multiple times, for example
- // when we visit all subexpressions of template instantiations; this is
- // suboptimal, bug benign: the only way to visit those is with
- // hasAncestor / hasParent, and those do not create new matches.
- // The plan is to enable DynTypedNode to be storable in a map or hash
- // map. The main problem there is to implement hash functions /
- // comparison operators for all types that DynTypedNode supports that
- // do not have pointer identity.
- (*Parents)[Node].push_back(ParentStack.back());
- ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node));
- bool Result = (this->*traverse)(Node);
- ParentStack.pop_back();
- return Result;
- }
-
- bool TraverseDecl(Decl *DeclNode) {
- return TraverseNode(DeclNode, &VisitorBase::TraverseDecl);
- }
-
- bool TraverseStmt(Stmt *StmtNode) {
- return TraverseNode(StmtNode, &VisitorBase::TraverseStmt);
- }
-
- ParentMap *Parents;
- SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack;
-
- friend class RecursiveASTVisitor<ParentMapASTVisitor>;
-};
-
// We use memoization to avoid running the same matcher on the same
// AST node twice. This pair is the key for looking up match
// result. It consists of an ID of the MatcherInterface (for
@@ -458,12 +388,6 @@ public:
const DynTypedMatcher &Matcher,
BoundNodesTreeBuilder *Builder,
AncestorMatchMode MatchMode) {
- if (!Parents) {
- // We always need to run over the whole translation unit, as
- // \c hasAncestor can escape any subtree.
- Parents.reset(ParentMapASTVisitor::buildMap(
- *ActiveASTContext->getTranslationUnitDecl()));
- }
return matchesAncestorOfRecursively(Node, Matcher, Builder, MatchMode);
}
@@ -506,22 +430,21 @@ private:
assert(Node.getMemoizationData() &&
"Invariant broken: only nodes that support memoization may be "
"used in the parent map.");
- ParentMapASTVisitor::ParentMap::const_iterator I =
- Parents->find(Node.getMemoizationData());
- if (I == Parents->end()) {
+ ASTContext::ParentVector Parents = ActiveASTContext->getParents(Node);
+ if (Parents.empty()) {
assert(false && "Found node that is not in the parent map.");
return false;
}
- for (ParentMapASTVisitor::ParentVector::const_iterator AncestorI =
- I->second.begin(), AncestorE = I->second.end();
+ for (ASTContext::ParentVector::const_iterator AncestorI = Parents.begin(),
+ AncestorE = Parents.end();
AncestorI != AncestorE; ++AncestorI) {
if (Matcher.matches(*AncestorI, this, Builder))
return true;
}
if (MatchMode == ASTMatchFinder::AMM_ParentOnly)
return false;
- for (ParentMapASTVisitor::ParentVector::const_iterator AncestorI =
- I->second.begin(), AncestorE = I->second.end();
+ for (ASTContext::ParentVector::const_iterator AncestorI = Parents.begin(),
+ AncestorE = Parents.end();
AncestorI != AncestorE; ++AncestorI) {
if (matchesAncestorOfRecursively(*AncestorI, Matcher, Builder, MatchMode))
return true;
@@ -574,8 +497,6 @@ private:
// Maps (matcher, node) -> the match result for memoization.
typedef llvm::DenseMap<UntypedMatchInput, MemoizedMatchResult> MemoizationMap;
MemoizationMap ResultCache;
-
- OwningPtr<ParentMapASTVisitor::ParentMap> Parents;
};
// Returns true if the given class is directly or indirectly derived