From e6f28490f1def7e31c4ff36a731f584368935e34 Mon Sep 17 00:00:00 2001 From: bloodstalker Date: Sat, 7 Mar 2020 18:22:35 +0330 Subject: more bug fixes as we're getting ready for the first release. still not sure how to handle the test result evaluation. --- README.md | 3 +++ cgrep.cpp | 49 ++++++++++++++++++++++++++++++++-------------- covrun.sh | 4 +++- makefile | 6 ++++-- test/compile_commands.json | 6 +++--- test/main.cpp | 9 +++++++-- testscript/main.py | 18 +++++++++++++++++ 7 files changed, 72 insertions(+), 23 deletions(-) create mode 100755 testscript/main.py diff --git a/README.md b/README.md index fbf487a..4fff3ff 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,9 @@ For an up-to-date list, you can run `cgrep --help` or look at the man page. `cgrep` is a clang tool, so it will accept all valid clang command line options. +## Example +You can run the coverage report, `make covrep`, to see some examples. Before running make sure to generate the compilation databases for `cgrep.cpp` and `./test/main.cpp`. The paths need to be right for your system. Please note that even though cgrep's source file is small, the actual code itself isn't. cgrep is clang. So cgrep will be relatively slow in the examples since its running on a Very big codebase. + ## Known Issues `cgrep` will not print out warnings or errors related to the source code so please make sure that clang can successfully build your file before running cgrep on it. diff --git a/cgrep.cpp b/cgrep.cpp index d2039e8..452f3e7 100644 --- a/cgrep.cpp +++ b/cgrep.cpp @@ -158,10 +158,6 @@ static std::string get_line_from_file(SourceManager &SM, 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; @@ -268,6 +264,12 @@ void output_handler(const MatchFinder::MatchResult &MR, SourceRange SR, SourceRange ND_SR = ND->getSourceRange(); get_line_from_file(SM, MR, ND_SR); } + + const CallExpr *CE = DTN.get(); + if (nullptr != CE) { + SourceRange CE_SR = CE->getDirectCallee()->getSourceRange(); + get_line_from_file(SM, MR, CE_SR); + } } } else { std::cout << line << "\n"; @@ -486,7 +488,10 @@ public: if (regex_handler(REGEX_PP(CO_REGEX), name)) { ast_type_traits::DynTypedNode DNode = ast_type_traits::DynTypedNode::create(*RD); - output_handler(MR, SR, *MR.SourceManager, true, DNode); + auto StartLocation = RD->getLocation(); + auto EndLocation = StartLocation.getLocWithOffset(name.size() - 1); + auto Range = SourceRange(StartLocation, EndLocation); + output_handler(MR, Range, *MR.SourceManager, true, DNode); } } } @@ -514,7 +519,10 @@ public: if (regex_handler(REGEX_PP(CO_REGEX), name)) { ast_type_traits::DynTypedNode DNode = ast_type_traits::DynTypedNode::create(*RD); - output_handler(MR, SR, *MR.SourceManager, true, DNode); + auto StartLocation = RD->getLocation(); + auto EndLocation = StartLocation.getLocWithOffset(name.size() - 1); + auto Range = SourceRange(StartLocation, EndLocation); + output_handler(MR, Range, *MR.SourceManager, true, DNode); } } } @@ -576,6 +584,9 @@ public: if (regex_handler(REGEX_PP(CO_REGEX), name)) { ast_type_traits::DynTypedNode DTN = ast_type_traits::DynTypedNode::create(*ND); + auto StartLocation = ND->getLocation(); + auto EndLocation = StartLocation.getLocWithOffset(name.size() - 1); + auto Range = SourceRange(StartLocation, EndLocation); output_handler(MR, SourceRange(SL, SLE), *MR.SourceManager, false, DTN); } } @@ -607,8 +618,11 @@ public: 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, DTN); + ast_type_traits::DynTypedNode::create(*CE); + auto StartLocation = CE->getExprLoc(); + auto EndLocation = StartLocation.getLocWithOffset(name.size() - 1); + auto Range = SourceRange(StartLocation, EndLocation); + output_handler(MR, Range, *MR.SourceManager, false, DTN); } } } @@ -641,7 +655,10 @@ public: if (regex_handler(REGEX_PP(CO_REGEX), name)) { ast_type_traits::DynTypedNode DNode = ast_type_traits::DynTypedNode::create(*CE); - output_handler(MR, SR, *MR.SourceManager, true, DNode); + auto StartLocation = CE->getExprLoc(); + auto EndLocation = StartLocation.getLocWithOffset(name.size() - 1); + auto Range = SourceRange(StartLocation, EndLocation); + output_handler(MR, Range, *MR.SourceManager, false, DNode); } } } @@ -655,6 +672,11 @@ public: explicit PPInclusion(SourceManager *SM, Rewriter *Rewrite) : SM(*SM), Rewrite(*Rewrite) {} + virtual bool FileNotFound(StringRef FileName, SmallVectorImpl&RecoveryPath) { + std::cerr << CC_RED << "Header not found: " << FileName.str() << CC_NORMAL << "\n"; + exit(1); + } + virtual void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) { if (CO_MACRO) { @@ -675,7 +697,9 @@ public: virtual void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range, - const MacroArgs *Args) {} + const MacroArgs *Args) { + + } #if __clang_major__ <= 6 virtual void InclusionDirective(SourceLocation HashLoc, @@ -693,11 +717,6 @@ public: const clang::Module *Imported, SrcMgr::CharacteristicKind FileType) { #endif - // FIXME-we are not checking whether the header has been found. - // this callback will be called when there is a header inclusion directive - // in the source file we are running through, not when the header is found. - // if the header is not there, we'll be dereferencing a null pointer - // somewhere and segfault. if (CO_HEADER) { CheckSLValidity(HashLoc); SourceLocation SL = diff --git a/covrun.sh b/covrun.sh index 46f8fcf..6fb6c71 100755 --- a/covrun.sh +++ b/covrun.sh @@ -2,7 +2,7 @@ LLVM_PROFILE_FILE="one.profraw" "./cgrep-cov" -A 1 -B 1 --func --var --regex n[aA]m ./cgrep.cpp LLVM_PROFILE_FILE="one.profraw" "./cgrep-cov" -A 1 -B 1 --func --var --awk --regex n[aA]m ./cgrep.cpp -LLVM_PROFILE_FILE="two.profraw" "./cgrep-cov" -A 1 -B 1 --func --declrefexpr --regex n[aA]m --nocolor --nodecl ./cgrep.cpp +LLVM_PROFILE_FILE="two.profraw" "./cgrep-cov" -A 1 -B 1 --func --declrefexpr --regex n[aA]m --nocolor ./cgrep.cpp LLVM_PROFILE_FILE="three.profraw" "./cgrep-cov" -A 1 -B 1 --func --declrefexpr --memfunc --call --cxxcall --var --regex run ./cgrep.cpp LLVM_PROFILE_FILE="four.profraw" "./cgrep-cov" -A 1 -B 1 --macro --header --regex n[aA]m ./cgrep.cpp LLVM_PROFILE_FILE="five.profraw" "./cgrep-cov" -A 1 -B 1 --class --regex and ./cgrep.cpp @@ -10,3 +10,5 @@ LLVM_PROFILE_FILE="six.profraw" "./cgrep-cov" -A 1 -B 1 --struct --union --regex LLVM_PROFILE_FILE="seven.profraw" "./cgrep-cov" -A 1 -B 1 --nameddecl --regex n[aA]m ./cgrep.cpp LLVM_PROFILE_FILE="eight.profraw" "./cgrep-cov" -A 1 -B 1 --cxxcall --call --regex add ./cgrep.cpp LLVM_PROFILE_FILE="nine.profraw" "./cgrep-cov" -A 1 -B 1 --memvar --regex ite ./cgrep.cpp +LLVM_PROFILE_FILE="ten.profraw" "./cgrep-cov" --union --regex [Uu]nion ./test/main.cpp +LLVM_PROFILE_FILE="eleven.profraw" "./cgrep-cov" --struct --regex [sS]truct ./test/main.cpp diff --git a/makefile b/makefile index 0edf949..1daca58 100644 --- a/makefile +++ b/makefile @@ -132,11 +132,13 @@ $(TARGET)-cov: $(TARGET).ocov ./cfe-extra/cfe_extra.ocov $(CXX) $^ $(LD_FLAGS) $(COV_LD) -o $@ cov: runcov - @llvm-profdata merge -sparse ./one.profraw ./two.profraw ./three.profraw ./four.profraw ./five.profraw ./six.profraw ./seven.profraw ./eight.profraw ./nine.profraw -o ./cgrep.profdata + @llvm-profdata merge -sparse ./one.profraw ./two.profraw ./three.profraw ./four.profraw ./five.profraw ./six.profraw ./seven.profraw \ + ./eight.profraw ./nine.profraw ./ten.profraw ./eleven.profraw -o ./cgrep.profdata @llvm-cov show $(TARGET)-cov -instr-profile=cgrep.profdata -ignore-filename-regex=llvm clang covrep: runcov - @llvm-profdata merge -sparse ./one.profraw ./two.profraw ./three.profraw ./four.profraw ./five.profraw ./six.profraw ./seven.profraw ./eight.profraw ./nine.profraw -o ./cgrep.profdata + @llvm-profdata merge -sparse ./one.profraw ./two.profraw ./three.profraw ./four.profraw ./five.profraw ./six.profraw ./seven.profraw \ + ./eight.profraw ./nine.profraw ./ten.profraw ./eleven.profraw -o ./cgrep.profdata @llvm-cov report $(TARGET)-cov -instr-profile=cgrep.profdata -ignore-filename-regex=llvm -ignore-filename-regex=clang -show-functions cgrep.cpp ASM:$(ASM_LIST) diff --git a/test/compile_commands.json b/test/compile_commands.json index a12a8fc..4f584fd 100644 --- a/test/compile_commands.json +++ b/test/compile_commands.json @@ -1,7 +1,7 @@ [ { - "command": "c++ -c -std=c++11 -fpic -o main.o main.cpp", - "directory": "/home/bloodstalker/devi/abbatoir/hole114", - "file": "/home/bloodstalker/devi/abbatoir/hole114/main.cpp" + "command": "c++ -c -std=c++11 -fpic -o main.o main.cpp", + "directory": "/home/bloodstalker/extra/cgrep/test", + "file": "/home/bloodstalker/extra/cgrep/test/main.cpp" } ] \ No newline at end of file diff --git a/test/main.cpp b/test/main.cpp index 815a48d..5c2ceb8 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -1,8 +1,8 @@ class myClass { public: - myClass(); - ~myClass(); + myClass() = default; + ~myClass() {} void myMehtod1(void) {} void myMehtod2(void) {} @@ -16,6 +16,11 @@ struct myStruct { ~myStruct(); }; +union myUnion { + int a; + double b; +}; + void myFunc1(void) {} void myFunc2(void) {} diff --git a/testscript/main.py b/testscript/main.py new file mode 100755 index 0000000..4990d10 --- /dev/null +++ b/testscript/main.py @@ -0,0 +1,18 @@ +#!/usr/bin/python3 +# _*_ coding=utf-8 _*_ + +import argparse + +class Argparser(object): + def __init__(self): + parser = argparse.ArgumentParser() + parser.add_argument("--string", type=str, help="string") + parser.add_argument("--bool", action="store_true", help="bool", default=False) + parser.add_argument("--dbg", action="store_true", help="debug", default=False) + self.args = parser.parse_args() + +def main(): + argparser = Argparser() + +if __name__ == "__main__": + main() -- cgit v1.2.3