aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rw-r--r--cgrep.cpp49
-rwxr-xr-xcovrun.sh4
-rw-r--r--makefile6
-rw-r--r--test/compile_commands.json6
-rw-r--r--test/main.cpp9
-rwxr-xr-xtestscript/main.py18
7 files changed, 72 insertions, 23 deletions
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<CallExpr>();
+ 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<char>&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()