diff --git a/clang/labs/lab1/kurdina_julia/AddWarning.cpp b/clang/labs/lab1/kurdina_julia/AddWarning.cpp new file mode 100644 index 0000000000000..6ee290dbfa665 --- /dev/null +++ b/clang/labs/lab1/kurdina_julia/AddWarning.cpp @@ -0,0 +1,62 @@ +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendPluginRegistry.h" + +using namespace clang; + +class AddWarningConsumer : public ASTConsumer { + CompilerInstance &Instance; + bool withoutClass; + +public: + AddWarningConsumer(CompilerInstance &Instance, bool withoutClass) + : Instance(Instance), withoutClass(withoutClass) {} + + void HandleTranslationUnit(ASTContext &context) override { + + struct Visitor : public RecursiveASTVisitor { + ASTContext *context; + bool withoutClass; + Visitor(ASTContext *context, bool withoutClass) + : context(context), withoutClass(withoutClass) {} + + bool VisitFunctionDecl(FunctionDecl *FD) { + if (!withoutClass || !FD->isCXXClassMember()) { + std::string name = FD->getNameInfo().getAsString(); + if (name.find("deprecated") != std::string::npos) { + DiagnosticsEngine &diag = context->getDiagnostics(); + unsigned diagID = diag.getCustomDiagID( + DiagnosticsEngine::Warning, "Function or method is deprecated"); + SourceLocation location = FD->getLocation(); + diag.Report(location, diagID); + } + } + return true; + } + } v(&Instance.getASTContext(), withoutClass); + + v.TraverseDecl(context.getTranslationUnitDecl()); + } +}; + +class AddWarningAction : public PluginASTAction { +protected: + bool withoutClass = false; + std::unique_ptr + CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) override { + return std::make_unique(CI, withoutClass); + } + + bool ParseArgs(const CompilerInstance &CI, + const std::vector &args) override { + for (const auto &arg : args) { + if (arg == "-notCheckClass") { + withoutClass = true; + } + } + return true; + } +}; + +static FrontendPluginRegistry::Add X("warn_dep", "warn_dep"); diff --git a/clang/labs/lab1/kurdina_julia/CMakeLists.txt b/clang/labs/lab1/kurdina_julia/CMakeLists.txt new file mode 100644 index 0000000000000..f2e9122a0c45b --- /dev/null +++ b/clang/labs/lab1/kurdina_julia/CMakeLists.txt @@ -0,0 +1,14 @@ +add_llvm_library(addWarning MODULE AddWarning.cpp PLUGIN_TOOL clang) + +if(WIN32 OR CYGWIN) + set(LLVM_LINK_COMPONENTS + Support + ) + clang_target_link_libraries(addWarning PRIVATE + clangAST + clangBasic + clangFrontend + ) +endif() + +set(CLANG_TEST_DEPS "addWarning" ${CLANG_TEST_DEPS} PARENT_SCOPE) \ No newline at end of file diff --git a/clang/test/lab1/kurdina_julia/tests.cpp b/clang/test/lab1/kurdina_julia/tests.cpp new file mode 100644 index 0000000000000..69ac5346fa17a --- /dev/null +++ b/clang/test/lab1/kurdina_julia/tests.cpp @@ -0,0 +1,45 @@ +// RUN: split-file %s %t +// RUN: %clang_cc1 -load %llvmshlibdir/addWarning%pluginext -plugin warn_dep %t/with_notCheckClass.cpp -plugin-arg-warn_dep -notCheckClass 2>&1 | FileCheck %t/with_notCheckClass.cpp +// RUN: %clang_cc1 -load %llvmshlibdir/addWarning%pluginext -plugin warn_dep %t/without_notCheckClass.cpp 2>&1 | FileCheck %t/without_notCheckClass.cpp + +//--- with_notCheckClass.cpp + +// CHECK: warning: Function or method is deprecated +void deprecated(); + +// CHECK: warning: Function or method is deprecated +void function_name_is_deprecated(); + +// CHECK-NOT: warning: Function or method is deprecated +void function(); + +// CHECK-NOT: warning: Function or method is deprecated +void function_depr(); + +class CheckClass { + // CHECK-NOT: warning: Function or method is deprecated + void deprecated(); + // CHECK-NOT: warning: Function or method is deprecated + void function(); +}; + +//--- without_notCheckClass.cpp + +// CHECK: warning: Function or method is deprecated +void deprecated(); + +// CHECK: warning: Function or method is deprecated +void function_name_is_deprecated(); + +// CHECK-NOT: warning: Function or method is deprecated +void function(); + +// CHECK-NOT: warning: Function or method is deprecated +void function_depr(); + +class CheckClass { + // CHECK: warning: Function or method is deprecated + void deprecated(); + // CHECK-NOT: warning: Function or method is deprecated + void function(); +};