diff --git a/clang/compiler-course/Shpynov_N_ClangAST_var2/CMakeLists.txt b/clang/compiler-course/Shpynov_N_ClangAST_var2/CMakeLists.txt new file mode 100644 index 0000000000000..9aea83bbf11cf --- /dev/null +++ b/clang/compiler-course/Shpynov_N_ClangAST_var2/CMakeLists.txt @@ -0,0 +1,18 @@ +set(Title "ClangAST_var2") +set(Student "Shpynov_Nikita") +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/Shpynov_N_ClangAST_var2/Shpynov_N_ClangAST.cpp b/clang/compiler-course/Shpynov_N_ClangAST_var2/Shpynov_N_ClangAST.cpp new file mode 100644 index 0000000000000..089c311429417 --- /dev/null +++ b/clang/compiler-course/Shpynov_N_ClangAST_var2/Shpynov_N_ClangAST.cpp @@ -0,0 +1,78 @@ +#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" + +using namespace clang; +namespace { +class MaybeUnusedVisitor : public RecursiveASTVisitor { +private: + ASTContext &Context; + Rewriter &rewriter; + +public: + explicit MaybeUnusedVisitor(ASTContext &context, Rewriter &RW) + : Context(context), rewriter(RW) {} + bool VisitVarDecl(VarDecl *VarDec) { + if (VarDec->isUsed() || VarDec->hasAttr()) + return false; + SourceLocation loc = VarDec->getBeginLoc(); + if (!Rewriter::isRewritable(loc)) + return false; + rewriter.InsertTextBefore(loc, "[[maybe_unused]] "); + return true; + } + bool VisitParmVarDecl(ParmVarDecl *ParDec) { + if (ParDec->isUsed() || ParDec->hasAttr()) + return false; + SourceLocation loc = ParDec->getBeginLoc(); + if (!Rewriter::isRewritable(loc)) + return false; + rewriter.InsertTextBefore(loc, "[[maybe_unused]] "); + return true; + } +}; + +class MaybeUnusedASTConsumer : public ASTConsumer { +private: + MaybeUnusedVisitor p_visitor; + +public: + explicit MaybeUnusedASTConsumer(ASTContext &context, Rewriter &R) + : p_visitor(context, R) {} + + void HandleTranslationUnit(ASTContext &Context) override { + p_visitor.TraverseDecl(Context.getTranslationUnitDecl()); + } +}; + +class MaybeUnusedAction : public PluginASTAction { +private: + Rewriter rewriter; + +public: + std::unique_ptr CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef) override { + rewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts()); + return std::make_unique(CI.getASTContext(), + rewriter); + } + + bool ParseArgs(const CompilerInstance &CI, + const std::vector &args) override { + return true; + } + + void EndSourceFileAction() override { + SourceManager &SM = rewriter.getSourceMgr(); + rewriter.getEditBuffer(SM.getMainFileID()).write(llvm::outs()); + } +}; +} // namespace + +static clang::FrontendPluginRegistry::Add + X("ClangAST_var2_Shpynov_Nikita_FIIT1_ClangAST", + "Automatically inserts [[maybe_unused]] attribute on every potentially " + "unused variable or parameter"); diff --git a/clang/test/compiler-course/Shpynov_N_ClangAST_var2_test/Shpynov_N_ClangAST_test.cpp b/clang/test/compiler-course/Shpynov_N_ClangAST_var2_test/Shpynov_N_ClangAST_test.cpp new file mode 100644 index 0000000000000..fc7aace947b5f --- /dev/null +++ b/clang/test/compiler-course/Shpynov_N_ClangAST_var2_test/Shpynov_N_ClangAST_test.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -load %llvmshlibdir/ClangAST_var2_Shpynov_Nikita_FIIT1_ClangAST%pluginext -plugin ClangAST_var2_Shpynov_Nikita_FIIT1_ClangAST %s -fsyntax-only 2>&1 | FileCheck %s + +// CHECK:\[\[maybe_unused\]\] int d = 0; + +// CHECK:int foo(int a, int b, \[\[maybe_unused\]\] int c) { +// CHECK-NEXT:\[\[maybe_unused\]\] double value = 0.0; +// CHECK-NEXT: return a + b; + +// CHECK: \[\[maybe_unused\]\] int e = 0; +int d = 0; + +int foo(int a, int b, int c) { + double value = 0.0; + return a + b; +} + +int e = 0;