Skip to content

Durandin Vladimir. Lab №1. Option №2 #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ add_subdirectory(runtime)

option(CLANG_BUILD_EXAMPLES "Build CLANG example programs by default." OFF)
add_subdirectory(examples)
add_subdirectory(labs)

if(APPLE)
# this line is needed as a cleanup to ensure that any CMakeCaches with the old
Expand Down
9 changes: 9 additions & 0 deletions clang/labs/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FILE(GLOB children RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)
FOREACH(child ${children})
IF(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${child})
add_subdirectory(${child})
ENDIF()
ENDFOREACH()

set(CLANG_TEST_DEPS ${CLANG_TEST_DEPS} PARENT_SCOPE)
message("CLANG_TEST_DEPS ${CLANG_TEST_DEPS}")
10 changes: 10 additions & 0 deletions clang/labs/lab1/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
if(CLANG_PLUGIN_SUPPORT)
FILE(GLOB children RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)
FOREACH(child ${children})
IF(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${child})
add_subdirectory(${child})
ENDIF()
ENDFOREACH()

set(CLANG_TEST_DEPS ${CLANG_TEST_DEPS} PARENT_SCOPE)
endif()
69 changes: 69 additions & 0 deletions clang/labs/lab1/durandin_vladimir/AlwaysInlineAttributePlugin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendPluginRegistry.h"


class AddAlwaysInlineConsumer : public clang::ASTConsumer {
public:
bool HasCondition(clang::Stmt *S) {
if (!S) {
return false;
}

if (llvm::isa<clang::IfStmt>(S) || llvm::isa<clang::SwitchStmt>(S) ||
llvm::isa<clang::WhileStmt>(S) || llvm::isa<clang::DoStmt>(S) ||
llvm::isa<clang::ForStmt>(S)) {
return true;
}

for (clang::Stmt *Child : S->children()) {
if (HasCondition(Child)) {
return true;
}
}

return false;
}

bool HandleTopLevelDecl(clang::DeclGroupRef D) override {
clang::FunctionDecl *FD = nullptr;

for (clang::Decl *Decl : D) {
FD = clang::dyn_cast<clang::FunctionDecl>(Decl);
if (FD) {
if (!HasCondition(FD->getBody())) {
FD->addAttr(
clang::AlwaysInlineAttr::CreateImplicit(FD->getASTContext()));
FD->print(llvm::outs() << "__attribute__((always_inline)) ");
} else
FD->print(llvm::outs());
}
}
return true;
}
};

class AddAlwaysInlineAction : public clang::PluginASTAction {
protected:
std::unique_ptr<clang::ASTConsumer>
CreateASTConsumer(clang::CompilerInstance &Compiler,
llvm::StringRef InFile) override {
return std::make_unique<AddAlwaysInlineConsumer>();
}

bool ParseArgs(const clang::CompilerInstance &CI,
const std::vector<std::string> &args) override {
for (const std::string &arg : args) {
if (arg == "--help") {
llvm::outs() << "This plugin adds the always_inline attribute to "
"functions if they do not have conditions!\n";
return false;
}
}
return true;
}
};

static clang::FrontendPluginRegistry::Add<AddAlwaysInlineAction>
X("AddAlwaysInline", "Adds always_inline to functions without conditions");
14 changes: 14 additions & 0 deletions clang/labs/lab1/durandin_vladimir/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
add_llvm_library(AlwaysInlineAttributePlugin MODULE AlwaysInlineAttributePlugin.cpp PLUGIN_TOOL clang)

if(WIN32 OR CYGWIN)
set(LLVM_LINK_COMPONENTS
Support
)
clang_target_link_libraries(AlwaysInlineAttributePlugin PRIVATE
clangAST
clangBasic
clangFrontend
)
endif()

set(CLANG_TEST_DEPS "AlwaysInlineAttributePlugin" ${CLANG_TEST_DEPS} PARENT_SCOPE)
14 changes: 14 additions & 0 deletions clang/labs/lab1/ivanov_nikita/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
add_llvm_library(clangDepMatcher MODULE deprecatedMatcher.cpp PLUGIN_TOOL clang)

if(WIN32 OR CYGWIN)
set(LLVM_LINK_COMPONENTS
Support
)
clang_target_link_libraries(clangDepMatcher PRIVATE
clangAST
clangBasic
clangFrontend
)
endif()

set(CLANG_TEST_DEPS "clangDepMatcher" ${CLANG_TEST_DEPS} PARENT_SCOPE)
59 changes: 59 additions & 0 deletions clang/labs/lab1/ivanov_nikita/deprecatedMatcher.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendPluginRegistry.h"

using namespace clang;

class DepConsumer : public ASTConsumer {
CompilerInstance &Instance;

public:
explicit DepConsumer(CompilerInstance &CI) : Instance(CI) {}

void HandleTranslationUnit(ASTContext &Context) override {
struct Visitor : public RecursiveASTVisitor<Visitor> {
ASTContext *Context;

Visitor(ASTContext *Context) : Context(Context) {}

bool VisitFunctionDecl(FunctionDecl *Func) {
if (Func->getNameInfo().getAsString().find("deprecated") !=
std::string::npos) {
DiagnosticsEngine &Diags = Context->getDiagnostics();
unsigned DiagID = Diags.getCustomDiagID(
DiagnosticsEngine::Warning, "Deprecated in function name");
Diags.Report(Func->getLocation(), DiagID)
<< Func->getNameInfo().getAsString();
}
return true;
}
} v(&Instance.getASTContext());

v.TraverseDecl(Context.getTranslationUnitDecl());
}
};

class DeprecatedPlugin : public PluginASTAction {
protected:
std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance &Compiler,
llvm::StringRef InFile) override {
return std::make_unique<DepConsumer>(Compiler);
}

bool ParseArgs(const CompilerInstance &Compiler,
const std::vector<std::string> &args) override {
if (!args.empty() && args[0] == "help")
PrintHelp(llvm::errs());

return true;
}

void PrintHelp(llvm::raw_ostream &ros) {
ros << "Deprecated Plugin version 1.0\n";
}
};

static FrontendPluginRegistry::Add<DeprecatedPlugin> X("deprecated-match",
"deprecated match");
14 changes: 14 additions & 0 deletions clang/labs/lab1/kulikov_artem/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
add_llvm_library(DeprecatedWarningPlugin MODULE DeprecatedWarning.cpp PLUGIN_TOOL clang)

if(WIN32 OR CYGWIN)
set(LLVM_LINK_COMPONENTS
Support
)
clang_target_link_libraries(DeprecatedWarningPlugin PRIVATE
clangAST
clangBasic
clangFrontend
)
endif()

set(CLANG_TEST_DEPS "DeprecatedWarningPlugin" ${CLANG_TEST_DEPS} PARENT_SCOPE)
54 changes: 54 additions & 0 deletions clang/labs/lab1/kulikov_artem/DeprecatedWarning.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendPluginRegistry.h"

using namespace clang;

class WarnVisitor : public RecursiveASTVisitor<WarnVisitor> {
public:
explicit WarnVisitor(ASTContext *Context) : Context(Context) {}

bool VisitFunctionDecl(FunctionDecl *Func) {
const char *name_data = Func->getName().data();
if (std::string(name_data).find("deprecated") != std::string::npos) {
DiagnosticsEngine &Diags = Context->getDiagnostics();
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
"Function '%0' contains 'deprecated' in its name");
Diags.Report(Func->getLocation(), DiagID) << name_data;
}
return true;
}

private:
ASTContext *Context;
};

class WarnConsumer : public ASTConsumer {
public:
explicit WarnConsumer(CompilerInstance &CI) : Visitor(&CI.getASTContext()) {}

void HandleTranslationUnit(ASTContext &Context) override {
Visitor.TraverseDecl(Context.getTranslationUnitDecl());
}

private:
WarnVisitor Visitor;
};

class WarnPlugin : public clang::PluginASTAction {
public:
std::unique_ptr<clang::ASTConsumer> CreateASTConsumer (
clang::CompilerInstance &Compiler, llvm::StringRef InFile) override {
return std::unique_ptr<clang::ASTConsumer>(new WarnConsumer(Compiler));
}

protected:
bool ParseArgs(const clang::CompilerInstance &Compiler,
const std::vector<std::string> &args) override {
return true;
}
};

static FrontendPluginRegistry::Add<WarnPlugin>
X("warn-deprecated", "Prints a warning if a function name contains 'deprecated'");
56 changes: 56 additions & 0 deletions clang/test/lab1/durandin_vladimir/always_inline_attr.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// RUN: %clang_cc1 -load %llvmshlibdir/AlwaysInlineAttributePlugin%pluginext -plugin AddAlwaysInline %s 1>&1 | FileCheck %s --check-prefix=SUM
// SUM: __attribute__((always_inline)) int sum(int a, int b) {
// SUM-NEXT: return a + b;
// SUM-NEXT: }
int sum(int a, int b) { return a + b; }

// RUN: %clang_cc1 -load %llvmshlibdir/AlwaysInlineAttributePlugin%pluginext -plugin AddAlwaysInline %s 1>&1 | FileCheck %s --check-prefix=EMPTY
// EMPTY: __attribute__((always_inline)) void checkEmpty() {
// EMPTY-NEXT: }
void checkEmpty() {}

// RUN: %clang_cc1 -load %llvmshlibdir/AlwaysInlineAttributePlugin%pluginext -plugin AddAlwaysInline %s 1>&1 | FileCheck %s --check-prefix=MIN-NESTED
// MIN-NESTED: int min_nested(int a, int b) {
// MIN-NESTED-NEXT: {
// MIN-NESTED-NEXT: if (a < b) {
// MIN-NESTED-NEXT: return a;
// MIN-NESTED-NEXT: } else
// MIN-NESTED-NEXT: return b;
// MIN-NESTED-NEXT: }
// MIN-NESTED-NEXT: }
int min_nested(int a, int b) {
{
if (a < b) {
return a;
} else
return b;
}
}

// CHECK: int min(int a, int b) {
// CHECK-NEXT: if (a < b) {
// CHECK-NEXT: return a;
// CHECK-NEXT: } else
// CHECK-NEXT: return b;
// CHECK-NEXT: }
int min(int a, int b) {
if (a < b) {
return a;
} else
return b;
}


// RUN: %clang_cc1 -load %llvmshlibdir/AlwaysInlineAttributePlugin%pluginext -plugin AddAlwaysInline %s 1>&1 | FileCheck %s --check-prefix=LOOP
// LOOP: void loop() {
// LOOP-NEXT: int counter = 0;
// LOOP-NEXT: for (int i = 0; i < 2; i++) {
// LOOP-NEXT: counter = i;
// LOOP-NEXT: }
// LOOP-NEXT: }
void loop() {
int counter = 0;
for (int i = 0; i < 2; i++) {
counter = i;
}
}
16 changes: 16 additions & 0 deletions clang/test/lab1/ivanov_nikita/dep_matcher.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// RUN: %clang_cc1 -load %llvmshlibdir/clangDepMatcher%pluginext -plugin deprecated-match %s 2>&1 | FileCheck %s --check-prefix=DEPRECATED
// REQUIRES: plugins

// DEPRECATED: warning: Deprecated in function name
void foo_deprecated(int a, int b);

// DEPRECATED: warning: Deprecated in function name
void deprecated(int c);

// DEPRECATED-NOT: warning: Deprecated in function name
void abc();

// RUN: %clang_cc1 -load %llvmshlibdir/clangDepMatcher%pluginext -plugin deprecated-match %s -plugin-arg-deprecated-match help 2>&1 | FileCheck %s --check-prefix=HELP
// REQUIRES: plugins

// HELP: Deprecated Plugin version 1.0
27 changes: 27 additions & 0 deletions clang/test/lab1/kulikov_artem/_demo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// RUN: split-file %s %t
// RUN: %clang_cc1 -load %llvmshlibdir/DeprecatedWarningPlugin%pluginext -add-plugin warn-deprecated -verify %t/bad_one.cpp
// RUN: %clang_cc1 -load %llvmshlibdir/DeprecatedWarningPlugin%pluginext -add-plugin warn-deprecated -verify %t/good_one.cpp

//--- good_one.cpp
// expected-no-diagnostics
int sum(int a, int b) {
return a + b;
}

void deprecate_sum(int a, int b) {
;
}


//--- bad_one.cpp
int _deprecated_sum(int a, int b) { // expected-warning {{Function '_deprecated_sum' contains 'deprecated' in its name}}
return a + b;
}

void _sumdeprecated_(int a, int b) { // expected-warning {{Function '_sumdeprecated_' contains 'deprecated' in its name}}
;
}

void _sum_deprecated(int a, int b) { // expected-warning {{Function '_sum_deprecated' contains 'deprecated' in its name}}
;
}