summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2019-05-12 21:09:32 +0100
committerStephen Kelly <steveire@gmail.com>2019-12-06 23:11:32 +0000
commit0a717d5b5d31fc2d5bc98ca695031fb09e65beb0 (patch)
tree86fc2295619a94015df5a4f5436cb80869c24dbb /clang/lib/AST
parentb4f4e370b59a753a51f11848f54e9705f43cccaf (diff)
downloadbcm5719-llvm-0a717d5b5d31fc2d5bc98ca695031fb09e65beb0.tar.gz
bcm5719-llvm-0a717d5b5d31fc2d5bc98ca695031fb09e65beb0.zip
Make it possible control matcher traversal kind with ASTContext
Summary: This will eventually allow traversal of an AST while ignoring invisible AST nodes. Currently it depends on the available enum values for TraversalKinds. That can be extended to ignore all invisible nodes in the future. Reviewers: klimek, aaron.ballman Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D61837
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/ASTContext.cpp48
1 files changed, 39 insertions, 9 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 10b6718c89b..d6010caa4a2 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -99,6 +99,30 @@ using namespace clang;
enum FloatingRank {
Float16Rank, HalfRank, FloatRank, DoubleRank, LongDoubleRank, Float128Rank
};
+const Expr *ASTContext::traverseIgnored(const Expr *E) const {
+ return traverseIgnored(const_cast<Expr *>(E));
+}
+
+Expr *ASTContext::traverseIgnored(Expr *E) const {
+ if (!E)
+ return nullptr;
+
+ switch (Traversal) {
+ case ast_type_traits::TK_AsIs:
+ return E;
+ case ast_type_traits::TK_IgnoreImplicitCastsAndParentheses:
+ return E->IgnoreParenImpCasts();
+ }
+ llvm_unreachable("Invalid Traversal type!");
+}
+
+ast_type_traits::DynTypedNode
+ASTContext::traverseIgnored(const ast_type_traits::DynTypedNode &N) const {
+ if (const auto *E = N.get<Expr>()) {
+ return ast_type_traits::DynTypedNode::create(*traverseIgnored(E));
+ }
+ return N;
+}
/// \returns location that is relevant when searching for Doc comments related
/// to \p D.
@@ -959,7 +983,7 @@ public:
void ASTContext::setTraversalScope(const std::vector<Decl *> &TopLevelDecls) {
TraversalScope = TopLevelDecls;
- Parents.reset();
+ Parents.clear();
}
void ASTContext::AddDeallocation(void (*Callback)(void *), void *Data) const {
@@ -10397,7 +10421,8 @@ createDynTypedNode(const NestedNameSpecifierLoc &Node) {
class ASTContext::ParentMap::ASTVisitor
: public RecursiveASTVisitor<ASTVisitor> {
public:
- ASTVisitor(ParentMap &Map) : Map(Map) {}
+ ASTVisitor(ParentMap &Map, ASTContext &Context)
+ : Map(Map), Context(Context) {}
private:
friend class RecursiveASTVisitor<ASTVisitor>;
@@ -10467,9 +10492,12 @@ private:
}
bool TraverseStmt(Stmt *StmtNode) {
- return TraverseNode(
- StmtNode, StmtNode, [&] { return VisitorBase::TraverseStmt(StmtNode); },
- &Map.PointerParents);
+ Stmt *FilteredNode = StmtNode;
+ if (auto *ExprNode = dyn_cast_or_null<Expr>(FilteredNode))
+ FilteredNode = Context.traverseIgnored(ExprNode);
+ return TraverseNode(FilteredNode, FilteredNode,
+ [&] { return VisitorBase::TraverseStmt(FilteredNode); },
+ &Map.PointerParents);
}
bool TraverseTypeLoc(TypeLoc TypeLocNode) {
@@ -10487,20 +10515,22 @@ private:
}
ParentMap &Map;
+ ASTContext &Context;
llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack;
};
ASTContext::ParentMap::ParentMap(ASTContext &Ctx) {
- ASTVisitor(*this).TraverseAST(Ctx);
+ ASTVisitor(*this, Ctx).TraverseAST(Ctx);
}
ASTContext::DynTypedNodeList
ASTContext::getParents(const ast_type_traits::DynTypedNode &Node) {
- if (!Parents)
+ std::unique_ptr<ParentMap> &P = Parents[Traversal];
+ if (!P)
// We build the parent map for the traversal scope (usually whole TU), as
// hasAncestor can escape any subtree.
- Parents = std::make_unique<ParentMap>(*this);
- return Parents->getParents(Node);
+ P = std::make_unique<ParentMap>(*this);
+ return P->getParents(Node);
}
bool
OpenPOWER on IntegriCloud