/* returns the first parent of input d that is of type Stmt */ const Stmt* getStmtParent(const Decl *d, ASTContext *Context){ const Stmt* ret = NULL; if(!d) { return ret; } const ASTContext::DynTypedNodeList parents = Context->getParents(*d); if(parents.size() > 0){ ret = parents[0].get<Stmt>(); } return ret; }
/* returns the first parent of input s that is of type Decl */ const Decl* getDeclParent(const Stmt* s, ASTContext *Context){ const Decl* ret = NULL; if(!s){ return ret; } const ASTContext::DynTypedNodeList parents = Context->getParents(*s); if(parents.size() > 0){ ret = parents[0].get<Decl>(); } return ret; }
AST_MATCHER_P(Expr, hasParentIgnoringImpCasts, ast_matchers::internal::Matcher<Expr>, InnerMatcher) { const Expr *E = &Node; do { ASTContext::DynTypedNodeList Parents = Finder->getASTContext().getParents(*E); if (Parents.size() != 1) return false; E = Parents[0].get<Expr>(); if (!E) return false; } while (isa<ImplicitCastExpr>(E)); return InnerMatcher.matches(*E, Finder, Builder); }
// Returns the Stmt nodes that are parents of 'S', skipping any potential // intermediate non-Stmt nodes. // // In almost all cases, this function returns a single parent or no parents at // all. // // The case that a Stmt has multiple parents is rare but does actually occur in // the parts of the AST that we're interested in. Specifically, InitListExpr // nodes cause ASTContext::getParent() to return multiple parents for certain // nodes in their subtree because RecursiveASTVisitor visits both the syntactic // and semantic forms of InitListExpr, and the parent-child relationships are // different between the two forms. static SmallVector<const Stmt *, 1> getParentStmts(const Stmt *S, ASTContext *Context) { SmallVector<const Stmt *, 1> Result; ASTContext::DynTypedNodeList Parents = Context->getParents(*S); SmallVector<ast_type_traits::DynTypedNode, 1> NodesToProcess(Parents.begin(), Parents.end()); while (!NodesToProcess.empty()) { ast_type_traits::DynTypedNode Node = NodesToProcess.back(); NodesToProcess.pop_back(); if (const auto *S = Node.get<Stmt>()) { Result.push_back(S); } else { Parents = Context->getParents(Node); NodesToProcess.append(Parents.begin(), Parents.end()); } } return Result; }