<commit_before>#include <iostream>

#include <clang/ASTMatchers/ASTMatchFinder.h>
#include <clang/ASTMatchers/ASTMatchers.h>
#include <clang/Frontend/FrontendActions.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Refactoring.h>
#include <llvm/Support/Signals.h>

namespace
{
class Callback : public clang::ast_matchers::MatchFinder::MatchCallback
{
  public:
    void
    run(const clang::ast_matchers::MatchFinder::MatchResult& result) override
    {
        if (const auto expr =
                result.Nodes.getNodeAs<clang::CXXOperatorCallExpr>("expr"))
        {
            clang::SourceRange range(expr->getExprLoc());
            report(result.Context, "ast-matcher", range.getBegin()) << range;
        }
    }

  private:
    clang::DiagnosticBuilder report(clang::ASTContext* context,
                                    llvm::StringRef string,
                                    clang::SourceLocation location) const
    {
        clang::DiagnosticsEngine& engine = context->getDiagnostics();
        clang::DiagnosticIDs::Level level =
            clang::DiagnosticIDs::Level::Warning;
        if (engine.getWarningsAsErrors())
            level = clang::DiagnosticIDs::Level::Error;
        return engine.Report(
            location,
            engine.getDiagnosticIDs()->getCustomDiagID(level, string));
    }
};

clang::ast_matchers::StatementMatcher makeMatcher()
{
    using namespace clang::ast_matchers;
    // Finds cases like:
    // v[0] == "foo"
    // i.e. operator ==() has an argument, which is a StringVector::operator
    // []() result.
    return cxxOperatorCallExpr(
               hasDescendant(
                   declRefExpr(to(functionDecl(hasName("operator=="))))),
               hasDescendant(cxxOperatorCallExpr(
                   hasDescendant(
                       declRefExpr(to(cxxMethodDecl(hasName("operator[]"))))),
                   hasDescendant(declRefExpr(to(varDecl(
                       hasType(cxxRecordDecl(hasName("StringVector"))))))))))
        .bind("expr");
}

llvm::cl::OptionCategory category("ast-matcher options");
} // namespace

int main(int argc, const char** argv)
{
    llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
    clang::tooling::CommonOptionsParser optionsParser(argc, argv, category);<commit_msg>llvm: ast matcher: expr is a statement, make this a bit more generic<commit_after>#include <iostream>

#include <clang/ASTMatchers/ASTMatchFinder.h>
#include <clang/ASTMatchers/ASTMatchers.h>
#include <clang/Frontend/FrontendActions.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Refactoring.h>
#include <llvm/Support/Signals.h>

namespace
{
class Callback : public clang::ast_matchers::MatchFinder::MatchCallback
{
  public:
    void
    run(const clang::ast_matchers::MatchFinder::MatchResult& result) override
    {
        if (const auto stmt = result.Nodes.getNodeAs<clang::Stmt>("stmt"))
        {
            clang::SourceRange range(stmt->getLocStart());
            report(result.Context, "ast-matcher", range.getBegin()) << range;
        }
    }

  private:
    clang::DiagnosticBuilder report(clang::ASTContext* context,
                                    llvm::StringRef string,
                                    clang::SourceLocation location) const
    {
        clang::DiagnosticsEngine& engine = context->getDiagnostics();
        clang::DiagnosticIDs::Level level =
            clang::DiagnosticIDs::Level::Warning;
        if (engine.getWarningsAsErrors())
            level = clang::DiagnosticIDs::Level::Error;
        return engine.Report(
            location,
            engine.getDiagnosticIDs()->getCustomDiagID(level, string));
    }
};

clang::ast_matchers::StatementMatcher makeMatcher()
{
    using namespace clang::ast_matchers;
    // Finds cases like:
    // v[0] == "foo"
    // i.e. operator ==() has an argument, which is a StringVector::operator
    // []() result.
    return cxxOperatorCallExpr(
               hasDescendant(
                   declRefExpr(to(functionDecl(hasName("operator=="))))),
               hasDescendant(cxxOperatorCallExpr(
                   hasDescendant(
                       declRefExpr(to(cxxMethodDecl(hasName("operator[]"))))),
                   hasDescendant(declRefExpr(to(varDecl(
                       hasType(cxxRecordDecl(hasName("StringVector"))))))))))
        .bind("stmt");
}

llvm::cl::OptionCategory category("ast-matcher options");
} // namespace

int main(int argc, const char** argv)
{
    llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
    clang::tooling::CommonOptionsParser optionsParser(argc, argv, category);
{'fraction_non_alphanumeric': 0.13007955278434746, 'fraction_numerical': 0.0008600301010535369, 'mean_word_length': 2.873438800999167, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2207276', 'n_tokens_mistral': 1329, 'n_tokens_neox': 1331, 'n_words': 221}