From 6468a599dc3e900f128c09e5d6efdb0135613bd7 Mon Sep 17 00:00:00 2001 From: bloodstalker Date: Fri, 10 Jan 2020 13:35:55 +0330 Subject: fixed the declaration prints. fixed the coloring of matches for non-declarations. --- .travis.yml | 42 +++++++------- appveyor.yml | 2 +- cgrep.cpp | 180 ++++++++++++++++++++++++++++++++++++++++++++--------------- makefile | 3 +- pch.hpp | 2 +- 5 files changed, 159 insertions(+), 70 deletions(-) diff --git a/.travis.yml b/.travis.yml index d674cf4..6644b09 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ addons: - wget https://apt.llvm.org/llvm.sh - chmod +x llvm.sh - sudo ./llvm.sh 10 - - sudo apt-get install llvm-10-dev libclang-common-10-dev libclang-10-dev -y + - sudo apt-get install llvm-10-dev libclang-common-10-dev libclang-10-dev libboost-system-dev libboost-filesystem-dev -y - git submodule init - git submodule update build_command: @@ -29,7 +29,7 @@ matrix: name: llvm5 sudo: required language: cpp - before_script: + before_script: - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y - sudo add-apt-repository ppa:fkrull/deadsnakes -y - sudo apt-get update -y @@ -37,11 +37,11 @@ matrix: - echo "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-5.0 main" | sudo tee -a /etc/apt/sources.list - sudo apt-get update -qq - travis_retry sudo apt-get install clang-5.0 libclang-5.0-dev libclang-common-5.0-dev libllvm5.0 llvm-5.0-dev llvm-5.0 llvm-5.0-runtime -y - - sudo apt-get install gcc-4.9 g++-4.9 + - sudo apt-get install gcc-4.9 g++-4.9 libboost-system-dev libboost-filesystem-dev -y - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 60 --slave /usr/bin/g++ g++ /usr/bin/g++-4.9 - git submodule init - git submodule update - script: + script: - make CXX=clang-5.0 LLVM_CONF=llvm-config-5.0 after_success: - bash run.sh @@ -49,16 +49,16 @@ matrix: name: llvm6 sudo: required language: cpp - before_script: + before_script: - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y - sudo apt-get update -y - wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key|sudo apt-key add - - echo "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-6.0 main" | sudo tee -a /etc/apt/sources.list - sudo apt-get update -qq - - travis_retry sudo apt-get install clang-6.0 libclang-6.0-dev libclang-common-6.0-dev libllvm6.0 llvm-6.0-dev llvm-6.0 llvm-6.0-runtime -y + - travis_retry sudo apt-get install clang-6.0 libclang-6.0-dev libclang-common-6.0-dev libllvm6.0 llvm-6.0-dev llvm-6.0 llvm-6.0-runtime libboost-system-dev libboost-filesystem-dev -y - git submodule init - git submodule update - script: + script: - make CXX=clang-6.0 LLVM_CONF=llvm-config-6.0 after_success: - ./run.sh @@ -66,17 +66,17 @@ matrix: name: llvm7 sudo: required language: cpp - before_script: + before_script: - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y - sudo apt-get update -y - sudo apt-get install libstdc++-7-dev -y - sudo wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - - sudo add-apt-repository "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-7 main" - - sudo apt-get update - - sudo apt-get install clang-7 llvm-7-dev libclang-common-7-dev libclang-7-dev -y + - sudo apt-get update + - sudo apt-get install clang-7 llvm-7-dev libclang-common-7-dev libclang-7-dev libboost-system-dev libboost-filesystem-dev -y - git submodule init - git submodule update - script: + script: - make CXX=clang-7 LLVM_CONF=llvm-config-7 after_success: bash run.sh @@ -84,17 +84,17 @@ matrix: name: llvm8 sudo: required language: cpp - before_script: + before_script: - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y - sudo apt-get update -y - sudo apt-get install libstdc++-7-dev -y - wget https://apt.llvm.org/llvm.sh - chmod +x llvm.sh - sudo ./llvm.sh 8 - - sudo apt-get install llvm-8-dev libclang-common-8-dev libclang-8-dev -y + - sudo apt-get install llvm-8-dev libclang-common-8-dev libclang-8-dev libboost-system-dev libboost-filesystem-dev -y - git submodule init - git submodule update - script: + script: - make CXX=clang-8 LLVM_CONF=llvm-config-8 after_success: bash run.sh @@ -102,17 +102,17 @@ matrix: name: llvm9 sudo: required language: cpp - before_script: + before_script: - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y - sudo apt-get update -y - sudo apt-get install libstdc++-7-dev -y - sudo wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - - sudo add-apt-repository "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main" - - sudo apt-get update - - sudo apt-get install clang-9 llvm-9-dev libclang-common-9-dev libclang-9-dev -y + - sudo apt-get update + - sudo apt-get install clang-9 llvm-9-dev libclang-common-9-dev libclang-9-dev libboost-system-dev libboost-filesystem-dev -y - git submodule init - git submodule update - script: + script: - make CXX=clang-9 LLVM_CONF=llvm-config-9 after_success: bash run.sh @@ -120,17 +120,17 @@ matrix: name: llvm10 sudo: required language: cpp - before_script: + before_script: - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y - sudo apt-get update -y - sudo apt-get install libstdc++-7-dev -y - wget https://apt.llvm.org/llvm.sh - chmod +x llvm.sh - sudo ./llvm.sh 10 - - sudo apt-get install llvm-10-dev libclang-common-10-dev libclang-10-dev -y + - sudo apt-get install llvm-10-dev libclang-common-10-dev libclang-10-dev libboost-system-dev libboost-filesystem-dev -y - git submodule init - git submodule update - script: + script: - make CXX=clang-10 LLVM_CONF=llvm-config-10 after_success: bash run.sh diff --git a/appveyor.yml b/appveyor.yml index 2a7fa98..39e7b8c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,7 +9,7 @@ environment: install: #- '%CYG_ROOT%\%CYG_SETUP% -gnqINDo -R "%CYG_ROOT%" -s "%CYG_MIRROR%" -l "%CYG_CACHE%" -P make,libclang-devel,libllvm-devel,clang > NULL 2>&1' - - '%CYG_ROOT%\%CYG_SETUP% -qI -R "%CYG_ROOT%" -s "%CYG_MIRROR%" -P make,libclang-devel,libllvm-devel,clang,libiconv-devel' + - '%CYG_ROOT%\%CYG_SETUP% -qI -R "%CYG_ROOT%" -s "%CYG_MIRROR%" -P make,libclang-devel,libllvm-devel,clang,libiconv-devel,libboost_system,libboost_filesystem' - '%CYG_ROOT%\bin\cygcheck -dc cygwin' - 'cd %APPVEYOR_BUILD_FOLDER%' - 'git submodule init' diff --git a/cgrep.cpp b/cgrep.cpp index 12d667a..5c65aa0 100644 --- a/cgrep.cpp +++ b/cgrep.cpp @@ -1,28 +1,29 @@ /*first line intentionally left blank.*/ -/*************************************************************************************************/ +/***********************************************************************************************/ //-*-c++-*- /*Copyright (C) 2018 Farzad Sadeghi * Licensed under GPL-3.0 * */ -/*************************************************************************************************/ +/***********************************************************************************************/ /*included modules*/ #include "./cfe-extra/cfe_extra.h" #include "./pch.hpp" -/*************************************************************************************************/ +/***********************************************************************************************/ /*used namespaces*/ using namespace llvm; using namespace clang; using namespace clang::ast_matchers; using namespace clang::driver; using namespace clang::tooling; -/*************************************************************************************************/ +using namespace boost::filesystem; +/***********************************************************************************************/ namespace { static llvm::cl::OptionCategory CGrepCat("cgrep options"); cl::opt CO_RECURSIVE( "dir", cl::desc("recursively goes through all the files and directories. assumes " - "compilation databases are present for all source files."), + "compilation databases are present for all source files."), cl::init(""), cl::cat(CGrepCat), cl::Optional); // done cl::opt CO_REGEX("regex", cl::desc("the regex to match against"), cl::init(""), cl::cat(CGrepCat), @@ -90,7 +91,7 @@ cl::opt CO_B( cl::desc("same as grep, howm many lines before the matched line to print"), cl::init(0), cl::cat(CGrepCat), cl::Optional); // done } // namespace -/*************************************************************************************************/ +/***********************************************************************************************/ #if 1 #define REGEX_PP(RX_STR) RX_STR #endif @@ -118,22 +119,49 @@ cl::opt CO_B( #define YELLOW "\033[1;33m" #define NORMAL "\033[0m" #define CLEAR "\033[2J" +/***********************************************************************************************/ +//forwartd declarations +static ClangTool build_cgrep_instance(int argc, const char** argv); +static int run_cgrep_instance(ClangTool cgrepToolInstance); +/***********************************************************************************************/ +static std::string get_line_from_file(SourceManager &SM, const MatchFinder::MatchResult & MR, SourceRange SR) { + std::string Result = ""; + + std::ifstream mainfile; + std::string mainfile_str = MR.SourceManager->getFilename(SR.getBegin()).str(); + mainfile.open(mainfile_str); + auto linenumber = MR.SourceManager->getSpellingLineNumber(SR.getBegin()); + auto columnnumber_start = MR.SourceManager->getSpellingColumnNumber(SR.getBegin()) - 1; + auto columnnumber_end = MR.SourceManager->getSpellingColumnNumber(SR.getEnd()) - 1; + + std::string line; + unsigned line_nu = 0; + + while (getline(mainfile, line)) { + line_nu++; + if (line_nu == linenumber) { + Result = line; + std::cout << GREEN << "\n" << mainfile_str << ":" << linenumber << ":" << line << "\t <---declared here" << NORMAL << "\n"; + } + } + + return Result; +} /** * @brief recursively goes through all the directories starting from path * * @param path */ -#if 0 -static void dig(std::string path) { - for (const auto &entry : std::filesystem::directory_iterator(path)) { - std::cout << entry.path() << "\n"; - if (true == entry.is_directory()) { - dig(entry.path()); - } - } +static void dig(boost::filesystem::path dir, int argc, const char** argv) { + for (const auto &entry : boost::filesystem::directory_iterator(dir)) { + if (true == is_directory(entry)) { + auto cgrepInstance = build_cgrep_instance(argc, argv); + run_cgrep_instance(cgrepInstance); + dig(entry.path(), argc, argv); + } + } } -#endif /** * @brief does some preprocessing on the regex string we get as input @@ -201,6 +229,57 @@ void output_handler(const MatchFinder::MatchResult &MR, SourceRange SR, mainfile.close(); } +void output_handler(const MatchFinder::MatchResult &MR, SourceRange SR, + SourceManager &SM, bool isdecl, ast_type_traits::DynTypedNode &DTN) { + std::ifstream mainfile; + mainfile.open(MR.SourceManager->getFilename(SR.getBegin()).str()); + auto linenumber = MR.SourceManager->getSpellingLineNumber(SR.getBegin()); + auto columnnumber_start = + MR.SourceManager->getSpellingColumnNumber(SR.getBegin()) - 1; + auto columnnumber_end = + MR.SourceManager->getSpellingColumnNumber(SR.getEnd()) - 1; + if (CO_AWK) { + std::cout << MAGENTA << SR.getBegin().printToString(SM) << ":" + << SR.getEnd().printToString(SM) << NORMAL << "\n"; + std::cout << RED << MR.SourceManager->getFilename(SR.getBegin()).str() + << ":" << linenumber << ":" << columnnumber_start + << NORMAL; + } else { + unsigned line_range_begin = linenumber - CO_B; + unsigned line_range_end = linenumber + CO_A; + std::string line; + unsigned line_nu = 0; + while (getline(mainfile, line)) { + line_nu++; + if (line_nu >= line_range_begin && line_nu <= line_range_end) { + if (line_nu == linenumber) { + std::cout << RED << MR.SourceManager->getFilename(SR.getBegin()).str() + << ":" << linenumber << ":" << columnnumber_start << ":" + << NORMAL; + for (unsigned i = 0; i < line.length(); ++i) { + if (i >= columnnumber_start && i <= columnnumber_end) { + std::cout << RED << line[i] << NORMAL; + } else { + std::cout << line[i]; + } + } + if (isdecl) { + std::cout << GREEN << "\t<---declared here" << NORMAL; + } else { + const NamedDecl * ND = DTN.get(); + if (nullptr != ND) { + SourceRange ND_SR = ND->getSourceRange(); + get_line_from_file(SM, MR, ND_SR); + } + } + } else { + } + } + } + } + std::cout << "\n"; + mainfile.close(); +} /** * @brief Gets the list of all directories and sub-directories starting from a * base directory. @@ -225,7 +304,7 @@ std::vector listDirs(std::string path) { } return dummy; } -/*************************************************************************************************/ +/***********************************************************************************************/ class FunctionHandler : public MatchFinder::MatchCallback { public: FunctionHandler(Rewriter &Rewrite) : Rewrite(Rewrite) {} @@ -258,7 +337,7 @@ public: private: Rewriter &Rewrite [[maybe_unused]]; }; -/*************************************************************************************************/ +/***********************************************************************************************/ class FieldHandler : public MatchFinder::MatchCallback { public: FieldHandler(Rewriter &Rewrite) : Rewrite(Rewrite) {} @@ -280,12 +359,6 @@ public: auto EndLocation = StartLocation.getLocWithOffset(name.size() - 1); auto Range = SourceRange(StartLocation, EndLocation); output_handler(MR, Range, *MR.SourceManager, true); - std::cout - << YELLOW - << MR.SourceManager->getSpellingColumnNumber(FD->getLocation()) - << ":" - << MR.SourceManager->getSpellingColumnNumber(FD->DEVI_GETLOCEND()) - << NORMAL << "\n"; } } } @@ -293,7 +366,7 @@ public: private: Rewriter &Rewrite [[maybe_unused]]; }; -/*************************************************************************************************/ +/***********************************************************************************************/ class CXXMethodHandler : public MatchFinder::MatchCallback { public: CXXMethodHandler(Rewriter &Rewrite) : Rewrite(Rewrite) {} @@ -353,7 +426,7 @@ public: private: Rewriter &Rewrite [[maybe_unused]]; }; -/*************************************************************************************************/ +/***********************************************************************************************/ class VDecl : public MatchFinder::MatchCallback { public: VDecl(Rewriter &Rewrite) : Rewrite(Rewrite) {} @@ -382,7 +455,7 @@ public: private: Rewriter &Rewrite [[maybe_unused]]; }; -/*************************************************************************************************/ +/***********************************************************************************************/ class ClassDecl : public MatchFinder::MatchCallback { public: ClassDecl(Rewriter &Rewrite) : Rewrite(Rewrite) {} @@ -411,7 +484,7 @@ public: private: Rewriter &Rewrite [[maybe_unused]]; }; -/*************************************************************************************************/ +/***********************************************************************************************/ class StructHandler : public MatchFinder::MatchCallback { public: StructHandler(Rewriter &Rewrite) : Rewrite(Rewrite) {} @@ -437,7 +510,7 @@ public: private: Rewriter &Rewrite [[maybe_unused]]; }; -/*************************************************************************************************/ +/***********************************************************************************************/ class UnionHandler : public MatchFinder::MatchCallback { public: UnionHandler(Rewriter &Rewrite) : Rewrite(Rewrite) {} @@ -463,7 +536,7 @@ public: private: Rewriter &Rewrite [[maybe_unused]]; }; -/*************************************************************************************************/ +/***********************************************************************************************/ class NamedDeclHandler : public MatchFinder::MatchCallback { public: NamedDeclHandler(Rewriter &Rewrite) : Rewrite(Rewrite) {} @@ -492,7 +565,7 @@ public: private: Rewriter &Rewrite [[maybe_unused]]; }; -/*************************************************************************************************/ +/***********************************************************************************************/ class DeclRefExprHandler : public MatchFinder::MatchCallback { public: DeclRefExprHandler(Rewriter &Rewrite) : Rewrite(Rewrite) {} @@ -501,19 +574,20 @@ public: const DeclRefExpr *DRE = MR.Nodes.getNodeAs("declrefexpr"); if (DRE) { + const NamedDecl *ND = DRE->getFoundDecl(); + std::string name = ND->getNameAsString(); SourceLocation SL = DRE->DEVI_GETLOCSTART(); - SourceLocation SLE = DRE->DEVI_GETLOCEND(); + SourceLocation SLE = SL.getLocWithOffset(name.length() - 1); + //SourceLocation SLE = DRE->DEVI_GETLOCEND(); CheckSLValidity(SL); SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start"); if (Devi::IsTheMatchInSysHeader(CO_SYSHDR, MR, SL)) return void(); if (!Devi::IsTheMatchInMainFile(CO_MAINFILE, MR, SL)) return void(); - const NamedDecl *ND = DRE->getFoundDecl(); - std::string name = ND->getNameAsString(); - std::cout << BLUE << name << NORMAL << "\n"; if (regex_handler(REGEX_PP(CO_REGEX), name)) { - output_handler(MR, SourceRange(SL, SLE), *MR.SourceManager, false); + ast_type_traits::DynTypedNode DTN = ast_type_traits::DynTypedNode::create(*ND); + output_handler(MR, SourceRange(SL, SLE), *MR.SourceManager, false, DTN); } } } @@ -521,7 +595,7 @@ public: private: Rewriter &Rewrite [[maybe_unused]]; }; -/*************************************************************************************************/ +/***********************************************************************************************/ class CallExprHandler : public MatchFinder::MatchCallback { public: CallExprHandler(Rewriter &Rewrite) : Rewrite(Rewrite) {} @@ -542,6 +616,7 @@ public: return void(); std::string name = ND->getNameAsString(); if (regex_handler(REGEX_PP(CO_REGEX), name)) { + ast_type_traits::DynTypedNode DTN = ast_type_traits::DynTypedNode::create(*ND); output_handler(MR, SourceRange(SL, SLE), *MR.SourceManager, false); } } @@ -550,7 +625,7 @@ public: private: Rewriter &Rewrite [[maybe_unused]]; }; -/*************************************************************************************************/ +/***********************************************************************************************/ class CXXCallExprHandler : public MatchFinder::MatchCallback { public: CXXCallExprHandler(Rewriter &Rewrite) : Rewrite(Rewrite) {} @@ -580,7 +655,7 @@ public: private: Rewriter &Rewrite [[maybe_unused]]; }; -/*************************************************************************************************/ +/***********************************************************************************************/ class PPInclusion : public PPCallbacks { public: explicit PPInclusion(SourceManager *SM, Rewriter *Rewrite) @@ -651,7 +726,7 @@ private: const SourceManager &SM [[maybe_unused]]; Rewriter &Rewrite [[maybe_unused]]; }; -/*************************************************************************************************/ +/***********************************************************************************************/ /// @brief A Clang Diagnostic Consumer that does nothing since we don't want /// clang to print out diag info. class BlankDiagConsumer : public clang::DiagnosticConsumer { @@ -661,7 +736,7 @@ public: virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) override {} }; -/*************************************************************************************************/ +/***********************************************************************************************/ class MyASTConsumer : public ASTConsumer { public: MyASTConsumer(Rewriter &R) @@ -741,7 +816,7 @@ private: CXXCallExprHandler HandlerForCXXCallExpr; MatchFinder Matcher; }; -/*************************************************************************************************/ +/***********************************************************************************************/ class AppFrontendAction : public ASTFrontendAction { public: AppFrontendAction() {} @@ -777,8 +852,23 @@ private: BlankDiagConsumer *BDCProto = new BlankDiagConsumer; Rewriter TheRewriter; }; -/*************************************************************************************************/ -/*************************************************************************************************/ +/***********************************************************************************************/ +static ClangTool build_cgrep_instance(int argc, const char** argv) +{ + CommonOptionsParser op(argc, argv, CGrepCat); + ClangTool cgrepInstance(op.getCompilations(), op.getSourcePathList()); + + return cgrepInstance; +} + +static int run_cgrep_instance(ClangTool cgrepToolInstance) +{ + int ret = cgrepToolInstance.run(newFrontendActionFactory().get()); + + return ret; +} + +/***********************************************************************************************/ /*Main*/ int main(int argc, const char **argv) { CommonOptionsParser op(argc, argv, CGrepCat); @@ -788,9 +878,9 @@ int main(int argc, const char **argv) { int ret = Tool.run(newFrontendActionFactory().get()); #if 0 if ("" != CO_RECURSIVE) { - dig(CO_RECURSIVE); + dig(CO_RECURSIVE, argc, argv); } #endif return ret; } -/*************************************************************************************************/ +/***********************************************************************************************/ diff --git a/makefile b/makefile index e403348..a90f752 100644 --- a/makefile +++ b/makefile @@ -18,7 +18,7 @@ endif CXX_EXTRA?= CTAGS_I_PATH?=./ #LD_FLAGS= -lstdc++fs -LD_FLAGS= +LD_FLAGS= -lboost_system -lboost_filesystem EXTRA_LD_FLAGS?= ADD_SANITIZERS_CC= -g -fsanitize=address -fno-omit-frame-pointer ADD_SANITIZERS_LD= -g -fsanitize=address @@ -38,7 +38,6 @@ 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\ -std=c++17 -fexceptions -#LLVM_LD_FLAGS=-Wl,--start-group $(shell $(LLVM_CONF) --libs) -Wl, --end-group LLVM_LD_FLAGS=-Wl,--start-group -lclangAST -lclangAnalysis -lclangBasic\ -lclangDriver -lclangEdit -lclangFrontend -lclangFrontendTool\ -lclangLex -lclangParse -lclangSema -lclangEdit -lclangASTMatchers\ diff --git a/pch.hpp b/pch.hpp index c3e90f7..bc8fe48 100644 --- a/pch.hpp +++ b/pch.hpp @@ -18,4 +18,4 @@ #include #include #include -//#include +#include -- cgit v1.2.3