================ @@ -186,106 +205,202 @@ class MatchDescendantVisitor : public DynamicRecursiveASTVisitor { return DynamicRecursiveASTVisitor::TraverseStmt(Node); } + void set_ast_context(ASTContext &Context) { ActiveASTContext = &Context; } + + void set_handler(const UnsafeBufferUsageHandler &NewHandler) { + Handler = &NewHandler; + } + private: // Sets 'Matched' to true if 'Matcher' matches 'Node' // // Returns 'true' if traversal should continue after this function // returns, i.e. if no match is found or 'Bind' is 'BK_All'. template <typename T> bool match(const T &Node) { - internal::BoundNodesTreeBuilder RecursiveBuilder(*Builder); - - if (Matcher->matches(DynTypedNode::create(Node), Finder, - &RecursiveBuilder)) { - ResultBindings.addMatch(RecursiveBuilder); + if (Matcher->matches(DynTypedNode::create(Node), *ActiveASTContext, + *Handler)) { Matches = true; - if (Bind != internal::ASTMatchFinder::BK_All) + if (!BindAll) return false; // Abort as soon as a match is found. } return true; } - const internal::DynTypedMatcher *const Matcher; - internal::ASTMatchFinder *const Finder; - internal::BoundNodesTreeBuilder *const Builder; - internal::BoundNodesTreeBuilder ResultBindings; - const internal::ASTMatchFinder::BindKind Bind; + CustomMatcher *const Matcher; + /// Defines how bindings are processed on recursive matches. + /// true: Create results for all combinations of bindings that match. + /// false: Stop at the first match and only bind the first match. + const bool BindAll; bool Matches; bool ignoreUnevaluatedContext; + ASTContext *ActiveASTContext; + const UnsafeBufferUsageHandler *Handler; }; // Because we're dealing with raw pointers, let's define what we mean by that. -static auto hasPointerType() { - return hasType(hasCanonicalType(pointerType())); +static auto hasPointerType(const Expr &E) { + return isa<PointerType>(E.getType().getCanonicalType()); } -static auto hasArrayType() { return hasType(hasCanonicalType(arrayType())); } - -AST_MATCHER_P(Stmt, forEachDescendantEvaluatedStmt, internal::Matcher<Stmt>, - innerMatcher) { - const DynTypedMatcher &DTM = static_cast<DynTypedMatcher>(innerMatcher); - - MatchDescendantVisitor Visitor(&DTM, Finder, Builder, ASTMatchFinder::BK_All, - true); - return Visitor.findMatch(DynTypedNode::create(Node)); -} - -AST_MATCHER_P(Stmt, forEachDescendantStmt, internal::Matcher<Stmt>, - innerMatcher) { - const DynTypedMatcher &DTM = static_cast<DynTypedMatcher>(innerMatcher); - - MatchDescendantVisitor Visitor(&DTM, Finder, Builder, ASTMatchFinder::BK_All, - false); - return Visitor.findMatch(DynTypedNode::create(Node)); +static auto hasArrayType(const Expr &E) { + return isa<ArrayType>(E.getType().getCanonicalType()); } // Matches a `Stmt` node iff the node is in a safe-buffer opt-out region -AST_MATCHER_P(Stmt, notInSafeBufferOptOut, const UnsafeBufferUsageHandler *, - Handler) { +static bool notInSafeBufferOptOut(const Stmt &Node, + const UnsafeBufferUsageHandler *Handler) { return !Handler->isSafeBufferOptOut(Node.getBeginLoc()); } -AST_MATCHER_P(Stmt, ignoreUnsafeBufferInContainer, - const UnsafeBufferUsageHandler *, Handler) { +static bool +ignoreUnsafeBufferInContainer(const Stmt &Node, + const UnsafeBufferUsageHandler *Handler) { return Handler->ignoreUnsafeBufferInContainer(Node.getBeginLoc()); } -AST_MATCHER_P(Stmt, ignoreUnsafeLibcCall, const UnsafeBufferUsageHandler *, - Handler) { - if (Finder->getASTContext().getLangOpts().CPlusPlus) +static bool ignoreUnsafeLibcCall(const Stmt &Node, const ASTContext &Ctx, + const UnsafeBufferUsageHandler *Handler) { + if (Ctx.getLangOpts().CPlusPlus) return Handler->ignoreUnsafeBufferInLibcCall(Node.getBeginLoc()); return true; /* Only warn about libc calls for C++ */ } -AST_MATCHER_P(CastExpr, castSubExpr, internal::Matcher<Expr>, innerMatcher) { - return innerMatcher.matches(*Node.getSubExpr(), Finder, Builder); +// Finds any expression 'e' such that `innerMatcher` +// matches 'e' and 'e' is in an Unspecified Lvalue Context. +static void findStmtsInUnspecifiedLvalueContext( + const Stmt *S, const llvm::function_ref<void(const Expr *)> InnerMatcher) { ---------------- ilya-biryukov wrote:
NIT: I find `Matcher` to be a little confusing because it does not actually mirror ClangTidy in the exact manner. Maybe use a different name, e.g. `OnResult` or `OnResultExpr` instead of `InnerMatcher`? https://github.com/llvm/llvm-project/pull/124554 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits