From ee103933f3bb24e4cd3e30af76d6571cae66e73c Mon Sep 17 00:00:00 2001 From: Arseny-Korobeinikov Date: Wed, 19 Mar 2025 03:10:03 +0300 Subject: [PATCH 1/5] first_version --- .../korobeinikov_prefix_var/CMakeLists.txt | 18 +++ .../korobeinikov_prefix_var_plugin.cpp | 123 ++++++++++++++++++ .../korobeinikov_prefix_var_test/test.cpp | 23 ++++ 3 files changed, 164 insertions(+) create mode 100644 clang/compiler-course/korobeinikov_prefix_var/CMakeLists.txt create mode 100644 clang/compiler-course/korobeinikov_prefix_var/korobeinikov_prefix_var_plugin.cpp create mode 100644 clang/test/compiler-course/korobeinikov_prefix_var_test/test.cpp diff --git a/clang/compiler-course/korobeinikov_prefix_var/CMakeLists.txt b/clang/compiler-course/korobeinikov_prefix_var/CMakeLists.txt new file mode 100644 index 0000000000000..5736b663a2fe3 --- /dev/null +++ b/clang/compiler-course/korobeinikov_prefix_var/CMakeLists.txt @@ -0,0 +1,18 @@ +set(Title "PrefixVarPlugin") +set(Student "KorobeinikovArseny") +set(Group "FIIT1") +set(TARGET_NAME "${Title}_${Student}_${Group}_ClangAST") + +file(GLOB_RECURSE SOURCES *.cpp *.h *.hpp) +add_llvm_library(${TARGET_NAME} MODULE ${SOURCES} PLUGIN_TOOL clang) + +if(WIN32 OR CYGWIN) + set(LLVM_LINK_COMPONENTS Support) + clang_target_link_libraries(${TARGET_NAME} PRIVATE + clangAST + clangBasic + clangFrontend + ) +endif() + +set(CLANG_TEST_DEPS "${TARGET_NAME}" ${CLANG_TEST_DEPS} PARENT_SCOPE) diff --git a/clang/compiler-course/korobeinikov_prefix_var/korobeinikov_prefix_var_plugin.cpp b/clang/compiler-course/korobeinikov_prefix_var/korobeinikov_prefix_var_plugin.cpp new file mode 100644 index 0000000000000..87c784ffc43c8 --- /dev/null +++ b/clang/compiler-course/korobeinikov_prefix_var/korobeinikov_prefix_var_plugin.cpp @@ -0,0 +1,123 @@ +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendPluginRegistry.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include "llvm/Support/raw_ostream.h" +#include + +namespace { +class PrefixVarVisitor : public clang::RecursiveASTVisitor { +public: + PrefixVarVisitor(clang::ASTContext *context, clang::Rewriter &rewriter) + : m_rewriter(rewriter) {} + + bool VisitVarDecl(clang::VarDecl *var) { + if (!var || var->getNameAsString().empty()) { + return true; + } + std::string prefix; + if (var->hasGlobalStorage() && var->isStaticLocal()) { + prefix = "static_global_"; + } else if (var->isStaticLocal()) { + prefix = "static_"; + } else if (var->isLocalVarDecl()) { + prefix = "local_"; + } else if (var->hasGlobalStorage()) { + prefix = "global_"; + } + + if (!prefix.empty()) { + std::string newName = prefix + var->getNameAsString(); + renameVar(var, newName); + m_renamedVars[var] = newName; + } + return true; + } + + bool VisitParmVarDecl(clang::ParmVarDecl *param) { + if (!param || param->getNameAsString().empty()) { + return true; + } + std::string newName = "param_" + param->getNameAsString(); + renameVar(param, newName); + m_renamedVars[param] = newName; + return true; + } + + bool VisitDeclRefExpr(clang::DeclRefExpr *expr) { + auto *decl = expr->getDecl(); + if (!expr || !decl || decl->getNameAsString().empty()) { + return true; + } + if (auto *var = clang::dyn_cast(decl)) { + auto it = m_renamedVars.find(var); + if (it != m_renamedVars.end()) { + m_rewriter.ReplaceText(expr->getLocation(), + var->getNameAsString().size(), it->second); + } + } + return true; + } + +private: + clang::Rewriter &m_rewriter; + std::unordered_map m_renamedVars; + + void renameVar(clang::VarDecl *var, const std::string &newName) { + m_rewriter.ReplaceText(var->getLocation(), var->getNameAsString().size(), + newName); + } +}; + +class PrefixVarConsumer : public clang::ASTConsumer { +public: + PrefixVarConsumer(clang::ASTContext *context, clang::Rewriter &rewriter) + : m_visitor(context, rewriter), m_rewriter(rewriter) {} + + void HandleTranslationUnit(clang::ASTContext &context) override { + m_visitor.TraverseDecl(context.getTranslationUnitDecl()); + m_rewriter.getEditBuffer(context.getSourceManager().getMainFileID()) + .write(llvm::outs()); + } + +private: + PrefixVarVisitor m_visitor; + clang::Rewriter &m_rewriter; +}; + +class PrefixVarAction : public clang::PluginASTAction { +public: + std::unique_ptr + CreateASTConsumer(clang::CompilerInstance &ci, llvm::StringRef) override { + if (m_shouldExit) { + return nullptr; + } + + m_rewriter.setSourceMgr(ci.getSourceManager(), ci.getLangOpts()); + return std::make_unique(&ci.getASTContext(), m_rewriter); + } + + bool ParseArgs(const clang::CompilerInstance &ci, + const std::vector &args) override { + for (const auto &arg : args) { + if (arg == "--help") { + llvm::outs() << "PrefixVarPlugin_by_Korobeinikov_Arseny:\n" + << "This plugin changes names by adding prefixes to " + "variables and parameters.\n"; + m_shouldExit = true; + return true; + } + } + return true; + } + +private: + clang::Rewriter m_rewriter; + bool m_shouldExit = false; +}; +} // namespace + +static clang::FrontendPluginRegistry::Add + X("PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST", + "Changes names by adding prefixes to variables and parameters"); \ No newline at end of file diff --git a/clang/test/compiler-course/korobeinikov_prefix_var_test/test.cpp b/clang/test/compiler-course/korobeinikov_prefix_var_test/test.cpp new file mode 100644 index 0000000000000..51f6920038f3b --- /dev/null +++ b/clang/test/compiler-course/korobeinikov_prefix_var_test/test.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -load %llvmshlibdir/PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST%pluginext -plugin PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST %s -fsyntax-only 2>&1 | FileCheck --match-full-lines %s + +// CHECK: int global_var1 = 0; +// CHECK-NEXT: int static_global_var2 = 2; +// CHECK-NEXT: int foo(int param_a, int param_b) { +// CHECK-NEXT: static int static_var3 = 0; +// CHECK-NEXT: int local_var4 = 123; +// CHECK-NEXT: ++static_var3; +// CHECK-NEXT: return param_a + param_b + global_var1 + static_var3 + local_var4; +// CHECK-NEXT: } + +int var1 = 0; +int static var2 = 2; +int foo(int a, int b) { + static int var3 = 0; + int var4 = 123; + ++var3; + return a + b + var1 + var3 + var4; +} + +// RUN: %clang_cc1 -load %llvmshlibdir/PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST%pluginext -plugin PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST -plugin-arg-PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST --help -fsyntax-only %s 2>&1 | FileCheck --match-full-lines %s --check-prefix=CHECK-HELP-ARG +// CHECK-HELP: PrefixVarPlugin_by_Korobeinikov_Arseny: +// CHECK-HELP-NEXT: This plugin changes names by adding prefixes to variables and parameters. \ No newline at end of file From 95f247e59096235acde800122a362f824452a540 Mon Sep 17 00:00:00 2001 From: Arseny-Korobeinikov Date: Wed, 19 Mar 2025 03:42:07 +0300 Subject: [PATCH 2/5] fix logic --- .../korobeinikov_prefix_var_plugin.cpp | 4 +--- .../compiler-course/korobeinikov_prefix_var_test/test.cpp | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/clang/compiler-course/korobeinikov_prefix_var/korobeinikov_prefix_var_plugin.cpp b/clang/compiler-course/korobeinikov_prefix_var/korobeinikov_prefix_var_plugin.cpp index 87c784ffc43c8..21f503712576e 100644 --- a/clang/compiler-course/korobeinikov_prefix_var/korobeinikov_prefix_var_plugin.cpp +++ b/clang/compiler-course/korobeinikov_prefix_var/korobeinikov_prefix_var_plugin.cpp @@ -17,9 +17,7 @@ class PrefixVarVisitor : public clang::RecursiveASTVisitor { return true; } std::string prefix; - if (var->hasGlobalStorage() && var->isStaticLocal()) { - prefix = "static_global_"; - } else if (var->isStaticLocal()) { + if (var->isStaticLocal()) { prefix = "static_"; } else if (var->isLocalVarDecl()) { prefix = "local_"; diff --git a/clang/test/compiler-course/korobeinikov_prefix_var_test/test.cpp b/clang/test/compiler-course/korobeinikov_prefix_var_test/test.cpp index 51f6920038f3b..537aa5ba772ee 100644 --- a/clang/test/compiler-course/korobeinikov_prefix_var_test/test.cpp +++ b/clang/test/compiler-course/korobeinikov_prefix_var_test/test.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -load %llvmshlibdir/PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST%pluginext -plugin PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST %s -fsyntax-only 2>&1 | FileCheck --match-full-lines %s // CHECK: int global_var1 = 0; -// CHECK-NEXT: int static_global_var2 = 2; +// CHECK-NEXT: int global_var2 = 2; // CHECK-NEXT: int foo(int param_a, int param_b) { // CHECK-NEXT: static int static_var3 = 0; // CHECK-NEXT: int local_var4 = 123; From e258e830ef7dde672961602dc2d32e1c48633239 Mon Sep 17 00:00:00 2001 From: Arseny-Korobeinikov Date: Wed, 19 Mar 2025 04:23:19 +0300 Subject: [PATCH 3/5] fix test --- ...{test.cpp => korobeinikov_plugin_test.cpp} | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) rename clang/test/compiler-course/korobeinikov_prefix_var_test/{test.cpp => korobeinikov_plugin_test.cpp} (65%) diff --git a/clang/test/compiler-course/korobeinikov_prefix_var_test/test.cpp b/clang/test/compiler-course/korobeinikov_prefix_var_test/korobeinikov_plugin_test.cpp similarity index 65% rename from clang/test/compiler-course/korobeinikov_prefix_var_test/test.cpp rename to clang/test/compiler-course/korobeinikov_prefix_var_test/korobeinikov_plugin_test.cpp index 537aa5ba772ee..4717c06a83c22 100644 --- a/clang/test/compiler-course/korobeinikov_prefix_var_test/test.cpp +++ b/clang/test/compiler-course/korobeinikov_prefix_var_test/korobeinikov_plugin_test.cpp @@ -1,23 +1,23 @@ -// RUN: %clang_cc1 -load %llvmshlibdir/PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST%pluginext -plugin PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST %s -fsyntax-only 2>&1 | FileCheck --match-full-lines %s +// RUN: %clang_cc1 -load %llvmshlibdir/PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST%pluginext -plugin PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST -fsyntax-only %s 2>&1 | FileCheck --match-full-lines %s // CHECK: int global_var1 = 0; -// CHECK-NEXT: int global_var2 = 2; // CHECK-NEXT: int foo(int param_a, int param_b) { -// CHECK-NEXT: static int static_var3 = 0; -// CHECK-NEXT: int local_var4 = 123; -// CHECK-NEXT: ++static_var3; -// CHECK-NEXT: return param_a + param_b + global_var1 + static_var3 + local_var4; +// CHECK-NEXT: static int static_var2 = 0; +// CHECK-NEXT: int local_var3 = 123; +// CHECK-NEXT: ++static_var2; +// CHECK-NEXT: return param_a + param_b + global_var1 + static_var2 + local_var3; // CHECK-NEXT: } +// CHECK-NEXT: int static global_var4 = 0; int var1 = 0; -int static var2 = 2; int foo(int a, int b) { - static int var3 = 0; - int var4 = 123; - ++var3; - return a + b + var1 + var3 + var4; + static int var2 = 0; + int var3 = 123; + ++var2; + return a + b + var1 + var2 + var3; } +int static var4 = 0; -// RUN: %clang_cc1 -load %llvmshlibdir/PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST%pluginext -plugin PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST -plugin-arg-PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST --help -fsyntax-only %s 2>&1 | FileCheck --match-full-lines %s --check-prefix=CHECK-HELP-ARG +// RUN: %clang_cc1 -load %llvmshlibdir/PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST%pluginext -plugin PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST -plugin-arg-PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST --help -fsyntax-only %s 2>&1 | FileCheck --match-full-lines %s --check-prefix=CHECK-HELP // CHECK-HELP: PrefixVarPlugin_by_Korobeinikov_Arseny: // CHECK-HELP-NEXT: This plugin changes names by adding prefixes to variables and parameters. \ No newline at end of file From 682e1039f0b5fd21f969b478ebd1186d3c0fa7dd Mon Sep 17 00:00:00 2001 From: Arseny-Korobeinikov Date: Wed, 19 Mar 2025 04:42:24 +0300 Subject: [PATCH 4/5] try finding error --- .../korobeinikov_prefix_var_plugin.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/clang/compiler-course/korobeinikov_prefix_var/korobeinikov_prefix_var_plugin.cpp b/clang/compiler-course/korobeinikov_prefix_var/korobeinikov_prefix_var_plugin.cpp index 21f503712576e..1513f668aad02 100644 --- a/clang/compiler-course/korobeinikov_prefix_var/korobeinikov_prefix_var_plugin.cpp +++ b/clang/compiler-course/korobeinikov_prefix_var/korobeinikov_prefix_var_plugin.cpp @@ -13,7 +13,7 @@ class PrefixVarVisitor : public clang::RecursiveASTVisitor { : m_rewriter(rewriter) {} bool VisitVarDecl(clang::VarDecl *var) { - if (!var || var->getNameAsString().empty()) { + if (!var || var->getName().empty()) { return true; } std::string prefix; @@ -34,7 +34,7 @@ class PrefixVarVisitor : public clang::RecursiveASTVisitor { } bool VisitParmVarDecl(clang::ParmVarDecl *param) { - if (!param || param->getNameAsString().empty()) { + if (!param || param->getName().empty()) { return true; } std::string newName = "param_" + param->getNameAsString(); @@ -45,7 +45,7 @@ class PrefixVarVisitor : public clang::RecursiveASTVisitor { bool VisitDeclRefExpr(clang::DeclRefExpr *expr) { auto *decl = expr->getDecl(); - if (!expr || !decl || decl->getNameAsString().empty()) { + if (!expr || !decl || decl->getName().empty()) { return true; } if (auto *var = clang::dyn_cast(decl)) { @@ -63,8 +63,7 @@ class PrefixVarVisitor : public clang::RecursiveASTVisitor { std::unordered_map m_renamedVars; void renameVar(clang::VarDecl *var, const std::string &newName) { - m_rewriter.ReplaceText(var->getLocation(), var->getNameAsString().size(), - newName); + m_rewriter.ReplaceText(var->getLocation(), var->getName().size(), newName); } }; From b9b709a8dd8bdd622538d9258b39a15b367125b3 Mon Sep 17 00:00:00 2001 From: Arseny-Korobeinikov Date: Tue, 20 May 2025 02:07:43 +0300 Subject: [PATCH 5/5] fix name plugin --- clang/compiler-course/korobeinikov_prefix_var/CMakeLists.txt | 2 +- .../korobeinikov_prefix_var_plugin.cpp | 2 +- .../korobeinikov_prefix_var_test/korobeinikov_plugin_test.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/compiler-course/korobeinikov_prefix_var/CMakeLists.txt b/clang/compiler-course/korobeinikov_prefix_var/CMakeLists.txt index 5736b663a2fe3..ddd9eca565ff4 100644 --- a/clang/compiler-course/korobeinikov_prefix_var/CMakeLists.txt +++ b/clang/compiler-course/korobeinikov_prefix_var/CMakeLists.txt @@ -1,5 +1,5 @@ set(Title "PrefixVarPlugin") -set(Student "KorobeinikovArseny") +set(Student "Korobeinikov_Arseny") set(Group "FIIT1") set(TARGET_NAME "${Title}_${Student}_${Group}_ClangAST") diff --git a/clang/compiler-course/korobeinikov_prefix_var/korobeinikov_prefix_var_plugin.cpp b/clang/compiler-course/korobeinikov_prefix_var/korobeinikov_prefix_var_plugin.cpp index 1513f668aad02..1dae510f13b53 100644 --- a/clang/compiler-course/korobeinikov_prefix_var/korobeinikov_prefix_var_plugin.cpp +++ b/clang/compiler-course/korobeinikov_prefix_var/korobeinikov_prefix_var_plugin.cpp @@ -116,5 +116,5 @@ class PrefixVarAction : public clang::PluginASTAction { } // namespace static clang::FrontendPluginRegistry::Add - X("PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST", + X("PrefixVarPlugin_Korobeinikov_Arseny_FIIT1_ClangAST", "Changes names by adding prefixes to variables and parameters"); \ No newline at end of file diff --git a/clang/test/compiler-course/korobeinikov_prefix_var_test/korobeinikov_plugin_test.cpp b/clang/test/compiler-course/korobeinikov_prefix_var_test/korobeinikov_plugin_test.cpp index 4717c06a83c22..41da19b7c620b 100644 --- a/clang/test/compiler-course/korobeinikov_prefix_var_test/korobeinikov_plugin_test.cpp +++ b/clang/test/compiler-course/korobeinikov_prefix_var_test/korobeinikov_plugin_test.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -load %llvmshlibdir/PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST%pluginext -plugin PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST -fsyntax-only %s 2>&1 | FileCheck --match-full-lines %s +// RUN: %clang_cc1 -load %llvmshlibdir/PrefixVarPlugin_Korobeinikov_Arseny_FIIT1_ClangAST%pluginext -plugin PrefixVarPlugin_Korobeinikov_Arseny_FIIT1_ClangAST -fsyntax-only %s 2>&1 | FileCheck --match-full-lines %s // CHECK: int global_var1 = 0; // CHECK-NEXT: int foo(int param_a, int param_b) { @@ -18,6 +18,6 @@ int foo(int a, int b) { } int static var4 = 0; -// RUN: %clang_cc1 -load %llvmshlibdir/PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST%pluginext -plugin PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST -plugin-arg-PrefixVarPlugin_Korobeinikov_FIIT1_ClangAST --help -fsyntax-only %s 2>&1 | FileCheck --match-full-lines %s --check-prefix=CHECK-HELP +// RUN: %clang_cc1 -load %llvmshlibdir/PrefixVarPlugin_Korobeinikov_Arseny_FIIT1_ClangAST%pluginext -plugin PrefixVarPlugin_Korobeinikov_Arseny_FIIT1_ClangAST -plugin-arg-PrefixVarPlugin_Korobeinikov_Arseny_FIIT1_ClangAST --help -fsyntax-only %s 2>&1 | FileCheck --match-full-lines %s --check-prefix=CHECK-HELP // CHECK-HELP: PrefixVarPlugin_by_Korobeinikov_Arseny: // CHECK-HELP-NEXT: This plugin changes names by adding prefixes to variables and parameters. \ No newline at end of file