diff options
| author | bloodstalker <thabogre@gmail.com> | 2018-11-07 13:03:20 +0000 | 
|---|---|---|
| committer | bloodstalker <thabogre@gmail.com> | 2018-11-07 13:03:20 +0000 | 
| commit | 70b9ee3e29864367e6e4693864f110e727271b48 (patch) | |
| tree | cc8a3e98384174d2b947a56cb44ba51b9ee4f234 | |
| parent | Initial commit (diff) | |
| download | cgrep-70b9ee3e29864367e6e4693864f110e727271b48.tar.gz cgrep-70b9ee3e29864367e6e4693864f110e727271b48.zip | |
update
| -rw-r--r-- | cgrep.cpp | 234 | ||||
| -rw-r--r-- | compile_commands.json | 7 | ||||
| -rw-r--r-- | makefile | 177 | 
3 files changed, 418 insertions, 0 deletions
| diff --git a/cgrep.cpp b/cgrep.cpp new file mode 100644 index 0000000..4f66876 --- /dev/null +++ b/cgrep.cpp @@ -0,0 +1,234 @@ + +/*first line intentionally left blank.*/ +/*************************************************************************************************/ +//-*-c++-*- +/*Copyright (C) 2018 Farzad Sadeghi + * Licensed under GPL-3.0 + * */ +/*************************************************************************************************/ +/*included modules*/ +/*project headers*/ +/*standard headers*/ +#include <cassert> +#include <cstdlib> +#include <dirent.h> +#include <fstream> +#include <iostream> +#include <regex> +#include <string> +#include <vector> +/*LLVM headers*/ +#include "clang/AST/AST.h" +#include "clang/AST/ASTConsumer.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Basic/LLVM.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendActions.h" +#include "clang/Lex/Lexer.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include "clang/Tooling/CommonOptionsParser.h" +#include "clang/Tooling/Tooling.h" +#include "llvm/Support/raw_ostream.h" +/*************************************************************************************************/ +/*used namespaces*/ +using namespace llvm; +using namespace clang; +using namespace clang::ast_matchers; +using namespace clang::driver; +using namespace clang::tooling; +/*************************************************************************************************/ +namespace { +static llvm::cl::OptionCategory CGrepCat("cgrep options"); +cl::opt<std::string> CO_DIRECTORY("dir", cl::desc(""), cl::init(""), cl::cat(CGrepCat), cl::Optional); +cl::opt<std::string> CO_REGEX("regex", cl::desc(""), cl::init(""), cl::cat(CGrepCat), cl::Optional); +cl::opt<bool> CO_FUNCTION("func", cl::desc(""), cl::init(false), cl::cat(CGrepCat), cl::Optional); +cl::opt<bool> CO_MEM_FUNCTION("memfunc", cl::desc(""), cl::init(false), cl::cat(CGrepCat), cl::Optional); +cl::opt<bool> CO_VAR("var", cl::desc(""), cl::init(false), cl::cat(CGrepCat), cl::Optional); +cl::opt<bool> CO_MEMVAR("memvar", cl::desc(""), cl::init(false), cl::cat(CGrepCat), cl::Optional); +cl::opt<bool> CO_CLASS("class", cl::desc(""), cl::init(false), cl::cat(CGrepCat), cl::Optional); +} +/*************************************************************************************************/ +std::string regex_preprocessor(std::string rx_str) { +  std::string ret_rx_str; +  return ret_rx_str; +} + +void regex_handlaer(std::string rx_str) { +  std::regex regex(regex_preprocessor(rx_str)); +  return void(); +} +/*************************************************************************************************/ +class CalledFunc : public MatchFinder::MatchCallback { +public: +  CalledFunc(Rewriter &Rewrite) : Rewrite(Rewrite) {} + +  virtual void run(const MatchFinder::MatchResult &MR) { +    const FunctionDecl *FD = MR.Nodes.getNodeAs<clang::FunctionDecl>("funcdecl"); +    if (FD) { +      SourceRange SR = FD->getSourceRange(); +      std::string name = FD->getNameAsString(); +    } +  } + +private: +  Rewriter &Rewrite [[maybe_unused]]; +}; +/*************************************************************************************************/ +class CalledVar : public MatchFinder::MatchCallback { +public: +  CalledVar(Rewriter &Rewrite) : Rewrite(Rewrite) {} + +  virtual void run(const MatchFinder::MatchResult &MR) { +    const VarDecl *VD = MR.Nodes.getNodeAs<clang::VarDecl>("vardecl"); +    if (VD) { +      SourceRange SR = VD->getSourceRange(); +      std::string name = VD->getNameAsString(); +    } +  } + +private: +  Rewriter &Rewrite [[maybe_unused]]; +}; +/*************************************************************************************************/ +class FuncDecl : public MatchFinder::MatchCallback { +public: +  FuncDecl(Rewriter &Rewrite) : Rewrite(Rewrite) {} + +  virtual void run(const MatchFinder::MatchResult &MR) {} + +private: +  Rewriter &Rewrite [[maybe_unused]]; +}; +/*************************************************************************************************/ +class VDecl : public MatchFinder::MatchCallback { +public: +  VDecl(Rewriter &Rewrite) : Rewrite(Rewrite) {} + +  virtual void run(const MatchFinder::MatchResult &MR) {} + +private: +  Rewriter &Rewrite [[maybe_unused]]; +}; +/*************************************************************************************************/ +class ClassDecl : public MatchFinder::MatchCallback { +public: +  ClassDecl(Rewriter &Rewrite) : Rewrite(Rewrite) {} + +  virtual void run(const MatchFinder::MatchResult &MR) {} + +private: +  Rewriter &Rewrite [[maybe_unused]]; +}; +/*************************************************************************************************/ +class PPInclusion : public PPCallbacks { +public: +  explicit PPInclusion(SourceManager *SM, Rewriter *Rewrite) +      : SM(*SM), Rewrite(*Rewrite) {} + +  virtual void MacroDefined(const Token &MacroNameTok, +                            const MacroDirective *MD) {} + +  virtual void MacroExpands(const Token &MacroNameTok, +                            const MacroDefinition &MD, SourceRange Range, +                            const MacroArgs *Args) {} + +#if __clang_major__ <= 6 +  virtual void InclusionDirective(SourceLocation HashLoc, +                                  const Token &IncludeTok, StringRef FileName, +                                  bool IsAngled, CharSourceRange FilenameRange, +                                  const FileEntry *File, StringRef SearchPath, +                                  StringRef RelativePath, +                                  const clang::Module *Imported) { +#elif __clang_major__ >= 8 +  virtual void InclusionDirective(SourceLocation HashLoc, +                                  const Token &IncludeTok, StringRef FileName, +                                  bool IsAngled, CharSourceRange FilenameRange, +                                  const FileEntry *File, StringRef SearchPath, +                                  StringRef RelativePath, +                                  const clang::Module *Imported, +                                  SrcMgr::CharacteristicKind FileType) { +#endif +  } + +private: +  const SourceManager &SM [[maybe_unused]]; +  Rewriter &Rewrite [[maybe_unused]]; +}; +/*************************************************************************************************/ +// brief A Clang Diagnostic Consumer that does nothing. +class BlankDiagConsumer : public clang::DiagnosticConsumer { +public: +  BlankDiagConsumer() = default; +  virtual ~BlankDiagConsumer() {} +  virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, +                                const Diagnostic &Info) override {} +}; +/*************************************************************************************************/ +class MyASTConsumer : public ASTConsumer { +public: +  MyASTConsumer(Rewriter &R) +      : funcDeclHandler(R), HandlerForVar(R), HandlerForClass(R), +        HandlerForCalledFunc(R), HandlerForCalledVar(R) { +#if 1 +    Matcher.addMatcher(functionDecl().bind("funcdecl"), &funcDeclHandler); +    Matcher.addMatcher( +        varDecl(anyOf(unless(hasDescendant(expr(anything()))), +                      hasDescendant(expr(anything()).bind("expr")))) +            .bind("vardecl"), +        &HandlerForVar); +    Matcher.addMatcher(recordDecl(isClass()).bind("classdecl"), +                       &HandlerForClass); +    Matcher.addMatcher(declRefExpr().bind("calledvar"), &HandlerForCalledVar); +#endif +  } + +  void HandleTranslationUnit(ASTContext &Context) override { +    Matcher.matchAST(Context); +  } + +private: +  FuncDecl funcDeclHandler; +  VDecl HandlerForVar; +  ClassDecl HandlerForClass; +  CalledFunc HandlerForCalledFunc; +  CalledVar HandlerForCalledVar; +  MatchFinder Matcher; +}; +/*************************************************************************************************/ +class AppFrontendAction : public ASTFrontendAction { +public: +  AppFrontendAction() {} +  ~AppFrontendAction() { delete BDCProto; } + +  void EndSourceFileAction() override { +    std::error_code EC; +    TheRewriter.getEditBuffer(TheRewriter.getSourceMgr().getMainFileID()) +        .write(llvm::outs()); +  } + +  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, +                                                 StringRef file) override { +    CI.getPreprocessor().addPPCallbacks( +        llvm::make_unique<PPInclusion>(&CI.getSourceManager(), &TheRewriter)); +    DiagnosticsEngine &DE = CI.getPreprocessor().getDiagnostics(); +    DE.setClient(BDCProto, false); +    TheRewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts()); +    return llvm::make_unique<MyASTConsumer>(TheRewriter); +  } + +private: +  BlankDiagConsumer *BDCProto = new BlankDiagConsumer; +  Rewriter TheRewriter; +}; +/*************************************************************************************************/ +/*************************************************************************************************/ +/*Main*/ +int main(int argc, const char **argv) { +  CommonOptionsParser op(argc, argv, CGrepCat); +  const std::vector<std::string> &SourcePathList [[maybe_unused]] = op.getSourcePathList(); +  ClangTool Tool(op.getCompilations(), op.getSourcePathList()); +  int ret = Tool.run(newFrontendActionFactory<AppFrontendAction>().get()); +  return ret; +} +/*************************************************************************************************/ diff --git a/compile_commands.json b/compile_commands.json new file mode 100644 index 0000000..0d0753d --- /dev/null +++ b/compile_commands.json @@ -0,0 +1,7 @@ +[ +    { +        "command": "c++ -c -fpic -I/home/bloodstalker/extra/llvm-clang-4/llvm/include -I/home/bloodstalker/extra/llvm-clang-4/build/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -std=c++11 -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wstring-conversion -ffunction-sections -fdata-sections -O2 -fno-exceptions -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/bloodstalker/extra/llvm-clang-4/llvm/tools/clang/include -I/home/bloodstalker/extra/llvm-clang-4/build/tools/clang/include -stdlib=libstdc++ -std=c++17 -fexceptions -o cgrep.o cgrep.cpp",  +        "directory": "/home/bloodstalker/extra/cgrep",  +        "file": "/home/bloodstalker/extra/cgrep/cgrep.cpp" +    } +]
\ No newline at end of file diff --git a/makefile b/makefile new file mode 100644 index 0000000..019f91f --- /dev/null +++ b/makefile @@ -0,0 +1,177 @@ +TARGET=cgrep +SHELL=bash +SHELL?=bash +CC=clang +CC?=clang +CFLAGS=-fpic -std=c11 +CXX=clang++ +CXX?=clang++ +CXX_FLAGS=-fpic +CXX_EXTRA?= +CTAGS_I_PATH?=./ +LD_FLAGS= +EXTRA_LD_FLAGS?= +ADD_SANITIZERS_CC= -g -fsanitize=address -fno-omit-frame-pointer +ADD_SANITIZERS_LD= -g -fsanitize=address +MEM_SANITIZERS_CC= -g -fsanitize=memory -fno-omit-frame-pointer +MEM_SANITIZERS_LD= -g -fsanitize=memory +UB_SANITIZERS_CC= -g -fsanitize=undefined -fno-omit-frame-pointer +UB_SANITIZERS_LD= -g -fsanitize=undefined +COV_CXX= -fprofile-instr-generate -fcoverage-mapping +COV_LD= -fprofile-instr-generate +# BUILD_MODES are=RELEASE(default), DEBUG,ADDSAN,MEMSAN,UBSAN +BUILD_MODE?=RELEASE +OBJ_LIST:=$(patsubst %.cpp, %.o, $(wildcard *.cpp)) +ASM_LIST:=$(patsubst %.cpp, %.dis, $(wildcard *.cpp)) + +LLVM_CONF?=llvm-config +LLVM_CXX_FLAGS=$(shell $(LLVM_CONF) --cxxflags) +LLVM_CXX_FLAGS+=-I$(shell $(LLVM_CONF) --src-root)/tools/clang/include\ + -I$(shell $(LLVM_CONF) --obj-root)/tools/clang/include\ + -stdlib=libstdc++ -std=c++17 -fexceptions +LLVM_LD_FLAGS=-Wl,--start-group -lclangAST -lclangAnalysis -lclangBasic\ + -lclangDriver -lclangEdit -lclangFrontend -lclangFrontendTool\ + -lclangLex -lclangParse -lclangSema -lclangEdit -lclangASTMatchers\ + -lclangRewrite -lclangRewriteFrontend -lclangStaticAnalyzerFrontend\ + -lclangStaticAnalyzerCheckers -lclangStaticAnalyzerCore\ + -lclangSerialization -lclangToolingCore -lclangTooling -lstdc++\ + -lLLVMRuntimeDyld -lm -Wl,--end-group +LLVM_LD_FLAGS+=$(shell $(LLVM_CONF) --ldflags --libs --system-libs) + +CXX_FLAGS+=$(LLVM_CXX_FLAGS) +LD_FLAGS+=$(LLVM_LD_FLAGS) + +MAKEFLAGS+=--warn-undefined-variables +ifeq ($(BUILD_MODE), ADDSAN) +ifeq ($(CXX), g++) +$(error This build mode is only useable with clang++.) +endif +CXX_EXTRA+=$(ADD_SANITIZERS_CC) +EXTRA_LD_FLAGS+=$(ADD_SANITIZERS_LD) +endif + +ifeq ($(BUILD_MODE), MEMSAN) +ifeq ($(CXX), g++) +$(error This build mode is only useable with clang++.) +endif +CXX_EXTRA+=$(MEM_SANITIZERS_CC) +EXTRA_LD_FLAGS+=$(MEM_SANITIZERS_LD) +endif + +ifeq ($(BUILD_MODE), UBSAN) +ifeq ($(CXX), g++) +$(error This build mode is only useable with clang++.) +endif +CXX_EXTRA+=$(UB_SANITIZERS_CC) +EXTRA_LD_FLAGS+=$(UB_SANITIZERS_LD) +endif + +SRCS:=$(wildcard *.cpp) +HDRS:=$(wildcard *.hpp) +CXX_FLAGS+=$(CXX_EXTRA) +LD_FLAGS+=$(EXTRA_LD_FLAGS) + +.DEFAULT:all + +.PHONY:all clean help ASM SO TAGS + +all:$(TARGET) + +everything:$(TARGET) A ASM SO $(TARGET)-dbg TAGS $(TARGET)-cov + +depend:.depend + +.depend:$(SRCS) +	rm -rf .depend +	$(CXX) -MM $(CXX_FLAGS) $^ > ./.depend +	echo $(patsubst %.o:, %.odbg:, $(shell $(CXX) -MM $(CXX_FLAGS) $^)) | sed -r 's/[A-Za-z0-9\-\_]+\.odbg/\n&/g' >> ./.depend +	echo $(patsubst %.o:, %.ocov:, $(shell $(CXX) -MM $(CXX_FLAGS) $^)) | sed -r 's/[A-Za-z0-9\-\_]+\.ocov/\n&/g' >> ./.depend + +-include ./.depend + +.cpp.o: +	$(CXX) $(CXX_FLAGS) -c $< -o $@ + +%.odbg:%.cpp +	$(CXX) $(CXX_FLAGS) -g -c $< -o $@ + +%.ocov:%.cpp +	$(CXX) $(CXX_FLAGS) $(COV_CXX) -c $< -o $@ + +$(TARGET): $(TARGET).o +	$(CXX) $^ $(LD_FLAGS) -o $@ + +$(TARGET)-static: $(TARGET).o +	$(CXX) $^ $(LD_FLAGS) -static -o $@ + +$(TARGET)-dbg: $(TARGET).odbg +	$(CXX) $^ $(LD_FLAGS) -g -o $@ + +$(TARGET)-cov: $(TARGET).ocov +	$(CXX) $^ $(LD_FLAGS) $(COV_LD) -o $@ + +cov: runcov +	@llvm-profdata merge -sparse ./default.profraw -o ./default.profdata +	@llvm-cov show $(TARGET)-cov -instr-profile=default.profdata -ignore-filename-regex=llvm clang + +covrep: runcov +	@llvm-profdata merge -sparse ./default.profraw -o ./default.profdata +	@llvm-cov report $(TARGET)-cov -instr-profile=default.profdata -ignore-filename-regex=llvm -ignore-filename-regex=clang -show-functions autosarpp.cpp + +ASM:$(ASM_LIST) + +SO:$(TARGET).so + +A:$(TARGET).a + +TAGS:tags + +tags:$(SRCS) +	$(shell $(CXX) -c $(shell $(LLVM_CONF) --cxxflags) -I$(shell $(LLVM_CONF) --src-root)/tools/clang/include -I$(shell $(LLVM_CONF) --obj-root)/tools/clang/include -I $(CTAGS_I_PATH) -M $(SRCS)|\ +		sed -e 's/[\\ ]/\n/g'|sed -e '/^$$/d' -e '/\.o:[ \t]*$$/d'|\ +		ctags -L - --c++-kinds=+p --fields=+iaS --extra=+q) + +%.dis: %.o +	objdump -r -d -M intel -S $< > $@ + +$(TARGET).so: $(TARGET).o +	$(CXX) $^ $(LD_FLAGS) -shared -o $@ + +$(TARGET).a: $(TARGET).o +	ar rcs $(TARGET).a $(TARGET).o + +runcov: $(TARGET)-cov +	$(TARGET)-cov ./cgrep.cpp -- + +test: $(TARGET) +	$(TARGET) ./cgrep.cpp -- + +valgrind: $(TARGET) +	- valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all $(TARGET) $(TARGET).cpp -- + +format: +	- clang-format -i $(SRCS) $(HDRS) + +clean: +	rm -f *.o *.dis *.odbg *.ocov *~ $(TARGET) $(TARGET).so $(TARGET)-static $(TARGET)-dbg $(TARGET).a $(TARGET)-cov ./keccak-tiny/*.o ./keccak-tiny/*.ocov ./keccak-tiny/*.odbg + +deepclean: clean +	- rm tags +	- rm .depend + +help: +	@echo "--all is the default target, runs $(TARGET) target" +	@echo "--everything will build everything" +	@echo "--SO will generate the so" +	@echo "--ASM will generate assembly files" +	@echo "--TAGS will generate tags file" +	@echo "--$(TARGET) builds the dynamically-linked executable" +	@echo "--$(TARGET)-dbg will generate the debug build. BUILD_MODE should be set to DEBUG to work" +	@echo "--$(TARGET)-static will statically link the executable to the libraries" +	@echo "--$(TARGET)-cov is the coverage build" +	@echo "--cov will print the line coverage report" +	@echo "--covrep will print the coverage report" +	@echo "--A will build the static library" +	@echo "--TAGS will build the tags file" +	@echo "--clean" +	@echo "--deepclean will clean almost everything" | 
