<commit_before>#include "template_parser.h"

#include "clang/Frontend/FrontendPluginRegistry.h"
#include "clang/AST/AST.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "llvm/Support/raw_ostream.h"

#include <iostream>
#include <vector>
#include <string>
#include <regex>
#include <cassert>

//////////////////////////////
// CUSTOMIZE THESE VARIABLES
//////////////////////////////

// if this is defined, only template info will be printed
//#define TEMPLATE_FILTER_STD
static int TemplatePrintThreshold = 10;
static int TEMPLATED_FUNCTION_PRINT_THRESHOLD = 100;

using namespace clang;
using namespace clang::ast_matchers;
using namespace clang::tooling;
using namespace clang::comments;
using namespace std;

int matched_classes_returned = 0;

namespace {

std::string get_canonical_name_for_decl(const TypeDecl *decl) {
  if (decl == nullptr) {
    llvm::report_fatal_error("null type decl to get_canonical_name_for_decl");
  }
  return decl->getTypeForDecl()->getCanonicalTypeInternal().getAsString();
}

int print_logging = 1;

struct ClassTemplate;
vector<std::unique_ptr<ClassTemplate>> class_templates;
struct ClassTemplate {
  std::string name;
  const ClassTemplateDecl *decl;
  int instantiations = 0;

  ClassTemplate(const ClassTemplateDecl *decl) : decl(decl) {
    name = decl->getQualifiedNameAsString();
  }

  void instantiated() { instantiations++; }

  static ClassTemplate &get_or_create(const ClassTemplateDecl *decl) {
    for (auto &tmpl : class_templates) {
      if (tmpl->decl == decl) {
        return *tmpl;
      }
    }
    class_templates.emplace_back(make_unique<ClassTemplate>(decl));
    return *class_templates.back();
  }
};

class ClassHandler : public MatchFinder::MatchCallback {
private:
  CompilerInstance &ci;
  SourceManager &source_manager;

public:
  ClassHandler(CompilerInstance &CI)
      : ci(CI), source_manager(CI.getSourceManager()) {}

  /**
         * This runs per-match from MyASTConsumer, but always on the same
   * ClassHandler object
         */
  virtual void run(const MatchFinder::MatchResult &Result) override {

    matched_classes_returned++;

    if (matched_classes_returned % 10000 == 0) {
      cerr << endl
           << "### MATCHER RESULT " << matched_classes_returned << " ###"
           << endl;
    }

    if (const ClassTemplateSpecializationDecl *klass =
            Result.Nodes.getNodeAs<clang::ClassTemplateSpecializationDecl>(
                "class")) {
      auto class_name = get_canonical_name_for_decl(klass);

      bool print_logging = false;

      if (std::regex_search(class_name,
                            std::regex("^(class|struct)\\s+v8toolkit"))) {
        //		if (std::regex_search(class_name,
        // std::regex("remove_reference"))) {
        print_logging = true;
        cerr << "Got class " << class_name << endl;
      }

#ifdef TEMPLATE_FILTER_STD
      if (std::regex_search(class_name, std::regex("^std::"))) {
        if (print_logging)
          cerr << "Filtering out because in std::" << endl;
        return;
      }
#endif

      auto tmpl = klass->getSpecializedTemplate();
      if (print_logging) {
        cerr << "got specialized template " << tmpl->getQualifiedNameAsString()
             << endl;
      }

#ifdef TEMPLATE_FILTER_STD
      if (std::regex_search(tmpl->getQualifiedNameAsString(),
                            std::regex("^std::"))) {
        return;
      }
#endif

      ClassTemplate::get_or_create(tmpl).instantiated();
    }
  }
};

// Implementation of the ASTConsumer interface for reading an AST produced
// by the Clang parser. It registers a couple of matchers and runs them on
// the AST.
class MyASTConsumer : public ASTConsumer {
public:
  MyASTConsumer(CompilerInstance &CI) : HandlerForClass(CI) {
    Matcher.addMatcher(
        decl(anyOf(classTemplateSpecializationDecl().bind("class"),
                   cxxMethodDecl().bind("method"))),
        &HandlerForClass);
  }

  void HandleTranslationUnit(ASTContext &Context) override {
    // Run the matchers when we have the whole TU parsed.
    Matcher.matchAST(Context);
  }

private:
  ClassHandler HandlerForClass;
  MatchFinder Matcher;
};

// This is the class that is registered with LLVM.  PluginASTAction is-a
// ASTFrontEndAction<commit_msg>remove more dead code<commit_after>#include "template_parser.h"

#include "clang/Frontend/FrontendPluginRegistry.h"
#include "clang/AST/AST.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "llvm/Support/raw_ostream.h"

#include <iostream>
#include <vector>
#include <string>
#include <regex>
#include <cassert>

using namespace clang;
using namespace clang::ast_matchers;
using namespace clang::tooling;
using namespace clang::comments;
using namespace std;

static int TemplatePrintThreshold = 10;

int matched_classes_returned = 0;

namespace {

std::string get_canonical_name_for_decl(const TypeDecl *decl) {
  if (decl == nullptr) {
    llvm::report_fatal_error("null type decl to get_canonical_name_for_decl");
  }
  return decl->getTypeForDecl()->getCanonicalTypeInternal().getAsString();
}

struct ClassTemplate;
vector<std::unique_ptr<ClassTemplate>> class_templates;
struct ClassTemplate {
  std::string name;
  const ClassTemplateDecl *decl;
  int instantiations = 0;

  ClassTemplate(const ClassTemplateDecl *decl) : decl(decl) {
    name = decl->getQualifiedNameAsString();
  }

  void instantiated() { instantiations++; }

  static ClassTemplate &get_or_create(const ClassTemplateDecl *decl) {
    for (auto &tmpl : class_templates) {
      if (tmpl->decl == decl) {
        return *tmpl;
      }
    }
    class_templates.emplace_back(make_unique<ClassTemplate>(decl));
    return *class_templates.back();
  }
};

class ClassHandler : public MatchFinder::MatchCallback {
private:
  CompilerInstance &ci;
  SourceManager &source_manager;

public:
  ClassHandler(CompilerInstance &CI)
      : ci(CI), source_manager(CI.getSourceManager()) {}

  /**
         * This runs per-match from MyASTConsumer, but always on the same
   * ClassHandler object
         */
  virtual void run(const MatchFinder::MatchResult &Result) override {

    matched_classes_returned++;

    if (matched_classes_returned % 10000 == 0) {
      cerr << endl
           << "### MATCHER RESULT " << matched_classes_returned << " ###"
           << endl;
    }

    if (const ClassTemplateSpecializationDecl *klass =
            Result.Nodes.getNodeAs<clang::ClassTemplateSpecializationDecl>(
                "class")) {
      auto class_name = get_canonical_name_for_decl(klass);

      bool print_logging = false;

      if (std::regex_search(class_name,
                            std::regex("^(class|struct)\\s+v8toolkit"))) {
        //		if (std::regex_search(class_name,
        // std::regex("remove_reference"))) {
        print_logging = true;
        cerr << "Got class " << class_name << endl;
      }

      auto tmpl = klass->getSpecializedTemplate();
      if (print_logging) {
        cerr << "got specialized template " << tmpl->getQualifiedNameAsString()
             << endl;
      }

      ClassTemplate::get_or_create(tmpl).instantiated();
    }
  }
};

// Implementation of the ASTConsumer interface for reading an AST produced
// by the Clang parser. It registers a couple of matchers and runs them on
// the AST.
class MyASTConsumer : public ASTConsumer {
public:
  MyASTConsumer(CompilerInstance &CI) : HandlerForClass(CI) {
    Matcher.addMatcher(
        decl(anyOf(classTemplateSpecializationDecl().bind("class"),
                   cxxMethodDecl().bind("method"))),
        &HandlerForClass);
  }

  void HandleTranslationUnit(ASTContext &Context) override {
    // Run the matchers when we have the whole TU parsed.
    Matcher.matchAST(Context);
  }

private:
  ClassHandler HandlerForClass;
  MatchFinder Matcher;
};

// This is the class that is registered with LLVM.  PluginASTAction is-a
// ASTFrontEndAction
{'fraction_non_alphanumeric': 0.12157945271243399, 'fraction_numerical': 0.0031204992798847817, 'mean_word_length': 3.5436205016357687, 'pattern_counts': {'":': 0, '<': 69, '<?xml version=': 0, '>': 34, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1271736', 'n_tokens_mistral': 2572, 'n_tokens_neox': 2487, 'n_words': 561}