From 2948f61947b9790a29d34fc48d8e5683467919db Mon Sep 17 00:00:00 2001 From: bloodstalker Date: Thu, 4 Jun 2020 18:55:14 +0430 Subject: added a new switch:recorddecl. the test script is still WIP. --- README.md | 1 + cgrep.cpp | 43 +++++++++++++++++++++++++++++-- cgrep.roff | 4 +++ compile_commands.json | 4 +-- test/callexpr.cpp | 34 ++++++++++++++++++++++++ test/classdecl.cpp | 19 ++++++++++++++ test/compile_commands.json | 64 ++++++++++++++++++++++++++++++++++++++++++++-- test/cxxmembercallexpr.cpp | 28 ++++++++++++++++++++ test/cxxmethoddecl.cpp | 15 +++++++++++ test/cxxrecorddecl.cpp | 15 +++++++++++ test/declrefexpr.cpp | 20 +++++++++++++++ test/fielddecl.cpp | 27 +++++++++++++++++++ test/function.cpp | 20 +++++++++++++++ test/main.cpp | 29 +++++++++++---------- test/makefile | 2 +- test/nameddecldef.cpp | 21 +++++++++++++++ test/structdecl.cpp | 14 ++++++++++ test/test_list.md | 22 ++++++++++++++++ test/uniondecdef.cpp | 14 ++++++++++ test/vardecl.cpp | 21 +++++++++++++++ testscript/main.py | 14 ++++++++++ 21 files changed, 410 insertions(+), 21 deletions(-) create mode 100644 test/callexpr.cpp create mode 100644 test/classdecl.cpp create mode 100644 test/cxxmembercallexpr.cpp create mode 100644 test/cxxmethoddecl.cpp create mode 100644 test/cxxrecorddecl.cpp create mode 100644 test/declrefexpr.cpp create mode 100644 test/fielddecl.cpp create mode 100644 test/function.cpp create mode 100644 test/nameddecldef.cpp create mode 100644 test/structdecl.cpp create mode 100644 test/test_list.md create mode 100644 test/uniondecdef.cpp create mode 100644 test/vardecl.cpp diff --git a/README.md b/README.md index 51ff3ea..3a12352 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,7 @@ For an up-to-date list, you can run `cgrep --help` or look at the man page. --nocolor - For terminals that don't supprt ANSI escape sequences. The default is to false. --nodecl - For switches that are not declarations, don't print declarations. Defaults to false. -p= - Build path + --recorddecl - Match a record declaration. --regex= - The regex to match against. --struct - Match structures. --syshdr - Match identifiers in system header as well. Defaults to false. diff --git a/cgrep.cpp b/cgrep.cpp index c1142f8..9f685ad 100644 --- a/cgrep.cpp +++ b/cgrep.cpp @@ -76,6 +76,10 @@ cl::opt CO_CXXFIELD("cxxfield", cl::desc("Match CXX field member declarations."), cl::init(false), cl::cat(CGrepCat), cl::Optional); // done +cl::opt CO_RECORD("recorddecl", + cl::desc("Match a record declaration."), + cl::init(false), cl::cat(CGrepCat), + cl::Optional); // done cl::opt CO_UNION("union", cl::desc("Match unions."), cl::init(false), cl::cat(CGrepCat), cl::Optional); // done cl::opt CO_MACRO("macro", cl::desc("Match macro definitions."), @@ -700,6 +704,38 @@ public: } } +private: + Rewriter &Rewrite [[maybe_unused]]; +}; +/***********************************************************************************************/ +class RecordHandler : public MatchFinder::MatchCallback { +public: + explicit RecordHandler(Rewriter &Rewrite) : Rewrite(Rewrite) {} + + virtual void run(const MatchFinder::MatchResult &MR) { + const RecordDecl *RD = + MR.Nodes.getNodeAs("recorddecl"); + if (RD) { + SourceRange SR = RD->getSourceRange(); + SourceLocation SL = SR.getBegin(); + 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(); + std::string name = RD->getNameAsString(); + if (regex_handler(REGEX_PP(CO_REGEX), name)) { + ast_type_traits::DynTypedNode DNode = + ast_type_traits::DynTypedNode::create(*RD); + auto StartLocation = RD->getLocation(); + auto EndLocation = StartLocation.getLocWithOffset(name.size() - 1); + auto Range = SourceRange(StartLocation, EndLocation); + output_handler(MR, Range, *MR.SourceManager, true, DNode); + } + } + } + private: Rewriter &Rewrite [[maybe_unused]]; }; @@ -754,7 +790,6 @@ public: } } - private: MatchFinder Matcher; Rewriter &Rewrite [[maybe_unused]]; @@ -921,7 +956,7 @@ public: HandlerForCXXMethod(R), HandlerForField(R), HandlerForStruct(R), HandlerForUnion(R), HandlerForNamedDecl(R), HandlerForDeclRefExpr(R), HandlerForCallExpr(R), HandlerForCXXCallExpr(R), - HandlerForRecordField(R) { + HandlerForRecordField(R), HandlerForRecord(R) { if (CO_FUNCTION || CO_ALL) { Matcher.addMatcher(functionDecl().bind("funcdecl"), &HandlerForCalledFunc); @@ -977,6 +1012,9 @@ public: fieldDecl(hasParent(cxxRecordDecl())).bind("recordfielddecl"), &HandlerForRecordField); } + if (CO_RECORD || CO_ALL) { + Matcher.addMatcher(recordDecl().bind("recorddecl"), &HandlerForRecord); + } } void HandleTranslationUnit(ASTContext &Context) override { @@ -996,6 +1034,7 @@ private: CallExprHandler HandlerForCallExpr; CXXCallExprHandler HandlerForCXXCallExpr; RecordFieldHandler HandlerForRecordField; + RecordHandler HandlerForRecord; MatchFinder Matcher; }; /***********************************************************************************************/ diff --git a/cgrep.roff b/cgrep.roff index 908c344..817b4ed 100644 --- a/cgrep.roff +++ b/cgrep.roff @@ -61,6 +61,10 @@ Matches member function calls. \fB--cxxfield\fP Match CXX field declarations. +.TP +\fB--crecord\fP +Match a record declarations. + .TP \fB--declrefexpr\fP Matches declrefexpr. diff --git a/compile_commands.json b/compile_commands.json index 598f647..be334e9 100644 --- a/compile_commands.json +++ b/compile_commands.json @@ -1,11 +1,11 @@ [ { - "command": "c++ -c -fpic -I/home/bloodstalker/extra/llvm-clang-4/llvm/include -I/home/bloodstalker/extra/llvm-clang-4/build/include -std=c++14 -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 -std=c++17 -fexceptions -o cgrep.o cgrep.cpp", + "command": "c++ -c -fpic -I/usr/local/include -std=c++14 -fno-exceptions -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/bloodstalker/extra/llvm-11/llvm-project/llvm/tools/clang/include -I/usr/local/tools/clang/include -std=c++17 -fexceptions -o cgrep.o cgrep.cpp", "directory": "/home/bloodstalker/extra/cgrep", "file": "/home/bloodstalker/extra/cgrep/cgrep.cpp" }, { - "command": "c++ -c -fpic -I/home/bloodstalker/extra/llvm-clang-4/llvm/include -I/home/bloodstalker/extra/llvm-clang-4/build/include -std=c++14 -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 -std=c++17 -fexceptions -o cfe-extra/cfe_extra.o cfe-extra/cfe_extra.cpp", + "command": "c++ -c -fpic -I/usr/local/include -std=c++14 -fno-exceptions -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/bloodstalker/extra/llvm-11/llvm-project/llvm/tools/clang/include -I/usr/local/tools/clang/include -std=c++17 -fexceptions -o cfe-extra/cfe_extra.o cfe-extra/cfe_extra.cpp", "directory": "/home/bloodstalker/extra/cgrep", "file": "/home/bloodstalker/extra/cgrep/cfe-extra/cfe_extra.cpp" } diff --git a/test/callexpr.cpp b/test/callexpr.cpp new file mode 100644 index 0000000..db96709 --- /dev/null +++ b/test/callexpr.cpp @@ -0,0 +1,34 @@ + +namespace callexpr_ns{ +int testFunction(int a, int b) { return a + b; } + +class testClass { +public: + testClass() = default; + int testMemberFunction(int a, int b) { return a + b; } + +private: + /* data */ +}; + +struct testStruct { +public: + testStruct() = default; + int a; + int b; + char *c; + int testMemberFunctionn(int a, int b) { return a + b; } +}; +} // namespace + +int __attribute__((weak)) main(int argc, char *argv[]) { + int a = 10; + int b = 10; + callexpr_ns::testFunction(a, b); + callexpr_ns::testClass tc; + tc.testMemberFunction(a, b); + callexpr_ns::testStruct ts; + ts.testMemberFunctionn(a, b); + + return 0; +} diff --git a/test/classdecl.cpp b/test/classdecl.cpp new file mode 100644 index 0000000..70e3625 --- /dev/null +++ b/test/classdecl.cpp @@ -0,0 +1,19 @@ + +namespace classdecl_ns{ +class testClass { +public: + testClass(); + virtual ~testClass(); + +private: +}; + +#define classdeclmacro classDeclMacroExpanded +class anotherTestClass { +public: + anotherTestClass(); + virtual ~anotherTestClass(); + +private: +}; +}; // namespace diff --git a/test/compile_commands.json b/test/compile_commands.json index 9808839..2a845d6 100644 --- a/test/compile_commands.json +++ b/test/compile_commands.json @@ -1,7 +1,67 @@ [ + { + "command": "c++ -c -std=c++11 -fpic -o fielddecl.o fielddecl.cpp", + "directory": "/home/bloodstalker/extra/cgrep/test", + "file": "/home/bloodstalker/extra/cgrep/test/fielddecl.cpp" + }, + { + "command": "c++ -c -std=c++11 -fpic -o cxxmethoddecl.o cxxmethoddecl.cpp", + "directory": "/home/bloodstalker/extra/cgrep/test", + "file": "/home/bloodstalker/extra/cgrep/test/cxxmethoddecl.cpp" + }, + { + "command": "c++ -c -std=c++11 -fpic -o vardecl.o vardecl.cpp", + "directory": "/home/bloodstalker/extra/cgrep/test", + "file": "/home/bloodstalker/extra/cgrep/test/vardecl.cpp" + }, + { + "command": "c++ -c -std=c++11 -fpic -o cxxmembercallexpr.o cxxmembercallexpr.cpp", + "directory": "/home/bloodstalker/extra/cgrep/test", + "file": "/home/bloodstalker/extra/cgrep/test/cxxmembercallexpr.cpp" + }, + { + "command": "c++ -c -std=c++11 -fpic -o nameddecldef.o nameddecldef.cpp", + "directory": "/home/bloodstalker/extra/cgrep/test", + "file": "/home/bloodstalker/extra/cgrep/test/nameddecldef.cpp" + }, + { + "command": "c++ -c -std=c++11 -fpic -o cxxrecorddecl.o cxxrecorddecl.cpp", + "directory": "/home/bloodstalker/extra/cgrep/test", + "file": "/home/bloodstalker/extra/cgrep/test/cxxrecorddecl.cpp" + }, + { + "command": "c++ -c -std=c++11 -fpic -o structdecl.o structdecl.cpp", + "directory": "/home/bloodstalker/extra/cgrep/test", + "file": "/home/bloodstalker/extra/cgrep/test/structdecl.cpp" + }, + { + "command": "c++ -c -std=c++11 -fpic -o callexpr.o callexpr.cpp", + "directory": "/home/bloodstalker/extra/cgrep/test", + "file": "/home/bloodstalker/extra/cgrep/test/callexpr.cpp" + }, + { + "command": "c++ -c -std=c++11 -fpic -o uniondecdef.o uniondecdef.cpp", + "directory": "/home/bloodstalker/extra/cgrep/test", + "file": "/home/bloodstalker/extra/cgrep/test/uniondecdef.cpp" + }, + { + "command": "c++ -c -std=c++11 -fpic -o declrefexpr.o declrefexpr.cpp", + "directory": "/home/bloodstalker/extra/cgrep/test", + "file": "/home/bloodstalker/extra/cgrep/test/declrefexpr.cpp" + }, + { + "command": "c++ -c -std=c++11 -fpic -o function.o function.cpp", + "directory": "/home/bloodstalker/extra/cgrep/test", + "file": "/home/bloodstalker/extra/cgrep/test/function.cpp" + }, { "command": "c++ -c -std=c++11 -fpic -o main.o main.cpp", - "directory": "/home/bloodstalker/devi/hell2/cgrep/test", - "file": "/home/bloodstalker/devi/hell2/cgrep/test/main.cpp" + "directory": "/home/bloodstalker/extra/cgrep/test", + "file": "/home/bloodstalker/extra/cgrep/test/main.cpp" + }, + { + "command": "c++ -c -std=c++11 -fpic -o classdecl.o classdecl.cpp", + "directory": "/home/bloodstalker/extra/cgrep/test", + "file": "/home/bloodstalker/extra/cgrep/test/classdecl.cpp" } ] \ No newline at end of file diff --git a/test/cxxmembercallexpr.cpp b/test/cxxmembercallexpr.cpp new file mode 100644 index 0000000..8d34dd5 --- /dev/null +++ b/test/cxxmembercallexpr.cpp @@ -0,0 +1,28 @@ + +namespace cxxmembercallexpr_ns{ +class testClass { +public: + testClass() = default; + int testFunction(int a, int b) { return a + b; } + +private: +}; + +struct testStruct { +public: + testStruct() = default; + int testFunction(int a, int b) { + return a + b; + }; +}; +} // namespace + +int __attribute__((weak)) main(int argc, char *argv[]) { + int a = 10; + int b = 10; + cxxmembercallexpr_ns::testClass tc; + tc.testFunction(a, b); + cxxmembercallexpr_ns::testStruct ts; + ts.testFunction(a, b); + return 0; +} diff --git a/test/cxxmethoddecl.cpp b/test/cxxmethoddecl.cpp new file mode 100644 index 0000000..55e1e2f --- /dev/null +++ b/test/cxxmethoddecl.cpp @@ -0,0 +1,15 @@ + +namespace cxxmethoddecl_ns{ +#define cxxmethoddeclmacro cxxMethodTwo +class testClass { +public: + testClass(); + virtual ~testClass(); + + void cxxMethodOne(void); + void cxxMethodOne(int a); + void cxxmethoddeclmacro(void); + +private: +}; +}; // namespace diff --git a/test/cxxrecorddecl.cpp b/test/cxxrecorddecl.cpp new file mode 100644 index 0000000..961bf28 --- /dev/null +++ b/test/cxxrecorddecl.cpp @@ -0,0 +1,15 @@ + +namespace cxxrecorddecl_ns{ +class testClass { +public: + testClass(); + virtual ~testClass(); + +private: + /* data */ +}; + +struct testStruct { + /* data */ +}; +}; // namespace diff --git a/test/declrefexpr.cpp b/test/declrefexpr.cpp new file mode 100644 index 0000000..c184577 --- /dev/null +++ b/test/declrefexpr.cpp @@ -0,0 +1,20 @@ + +namespace declrefexpr_ns{ + +class testClass { +public: + testClass() = default; + int a; + +private: +}; +} // namespace + +int __attribute__((weak)) main(int argc, char *argv[]) { + int a; + int b; + declrefexpr_ns::testClass tc; + tc.a = 10; + + return a + b; +} diff --git a/test/fielddecl.cpp b/test/fielddecl.cpp new file mode 100644 index 0000000..6646afd --- /dev/null +++ b/test/fielddecl.cpp @@ -0,0 +1,27 @@ + +namespace fielddecl_ns{ +#define fieldmacro fieldthree + +struct testStruct { + int fieldone; + float fieldtwo; + int fieldmacro; +}; + +union testUnion { + int fieldone; + bool fieldtwo; +}; + +class testClass { +public: + testClass(void); + virtual ~testClass(); + + void myMethod(void); + +private: + int an_arg; + int another_arg; +}; +} // namespace diff --git a/test/function.cpp b/test/function.cpp new file mode 100644 index 0000000..83878e7 --- /dev/null +++ b/test/function.cpp @@ -0,0 +1,20 @@ + +namespace function_ns{ +void MyFunc(void) { return; } + +class yolo { +public: + yolo() = default; + yolo(int a) : a(a) {} + virtual ~yolo(); + + void yolofunc(void) { return; } + +private: + int a; +}; + +#define MFunc macroedFunc + +void MFunc(void) { return; } +} // namespace diff --git a/test/main.cpp b/test/main.cpp index 87b7eae..c48f5fb 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -1,14 +1,15 @@ -class myClass { - public: - myClass() = default; - ~myClass() {} - - void myMehtod1(void) {} - void myMehtod2(void) {} - private: - int a; - float b; +class myClassmain { +public: + myClassmain() = default; + ~myClassmain() {} + + void myMehtod1(void) {} + void myMehtod2(void) {} + +private: + int a; + float b; }; struct myStruct { @@ -31,13 +32,13 @@ struct verymuchStruct { void myFunc1(void) {} void myFunc2(void) {} -int main (int argc, char** argv) { - myClass mc; +int main(int argc, char **argv) { + myClassmain mc; mc.myMehtod1(); mc.myMehtod2(); int a; float b; - int c,d; - a = c+d; + int c, d; + a = c + d; return 0; } diff --git a/test/makefile b/test/makefile index 127064d..7184126 100644 --- a/test/makefile +++ b/test/makefile @@ -79,7 +79,7 @@ depend:.depend %.ocov:%.cpp $(CXX) $(CXX_FLAGS) $(COV_CXX) -c $< -o $@ -$(TARGET): $(TARGET).o +$(TARGET): $(OBJ_LIST) $(CXX) $(LD_FLAGS) $^ -o $@ $(TARGET)-static: $(TARGET).o diff --git a/test/nameddecldef.cpp b/test/nameddecldef.cpp new file mode 100644 index 0000000..f4360af --- /dev/null +++ b/test/nameddecldef.cpp @@ -0,0 +1,21 @@ + +namespace nameddecldef_ns{ +int testVar; +struct testStruct { + int a; + int b; + char *c; +}; + +void testFunction(void); +void testFunction(void) { return; } + +class testClass { +public: + testClass(); + virtual ~testClass(); + +private: + int myPrivate; +}; +}; // namespace diff --git a/test/structdecl.cpp b/test/structdecl.cpp new file mode 100644 index 0000000..4fa57d4 --- /dev/null +++ b/test/structdecl.cpp @@ -0,0 +1,14 @@ + +namespace structdecl_ns{ +struct testStruct { + int a; + float b; + char c[10]; +}; + +#define structdeclmacro structDeclMacroExpanded +struct structdeclmacro { + int d; + double e; +}; +} // namespace diff --git a/test/test_list.md b/test/test_list.md new file mode 100644 index 0000000..e39ea5e --- /dev/null +++ b/test/test_list.md @@ -0,0 +1,22 @@ + +## Test List + +- [x] function declaration +- [x] field declratation +- [x] cxx method declaration +- [x] variable declaration +- [x] class declaration +- [x] struct declaration +- [x] union declaration/definition +- [x] named declaration/definition +- [x] declaration reference expression +- [x] call expression +- [x] cxx member call expression +- [x] cxx record declaration +- [] macro definition +- [] header inclusion directive + +## Cross Test List + +* macro expansion behaviour +* overload diff --git a/test/uniondecdef.cpp b/test/uniondecdef.cpp new file mode 100644 index 0000000..ebded31 --- /dev/null +++ b/test/uniondecdef.cpp @@ -0,0 +1,14 @@ + +namespace uniondecl_ns{ +union testUnion { + int reg; + bool b1; + bool b2; +}; + +#define uniondecdefmacro unionDecDefMacroExpanded +union uniondecdefmacro { + int reggie; + int bubu; +}; +}; // namespace diff --git a/test/vardecl.cpp b/test/vardecl.cpp new file mode 100644 index 0000000..3f17a21 --- /dev/null +++ b/test/vardecl.cpp @@ -0,0 +1,21 @@ + +namespace vardecl_ns{ +int a; + +int testFunction(int a, int b); +int testFunction(int a, int b) { return a + b; } + +class testClass { +public: + testClass(int a) : a(a) {} + virtual ~testClass(); + + void cxxMethod(double a) {} + +private: + int a; +}; + +#define vardeclmacro varDeclMacroExpanded +int vardeclmacro; +}; // namespace diff --git a/testscript/main.py b/testscript/main.py index 1015b21..285f993 100755 --- a/testscript/main.py +++ b/testscript/main.py @@ -24,6 +24,20 @@ cgrep_test_args = [ "--struct --regex [sS]truct ./test/main.cpp", "--dir ./ --regex run --func",] +cgrep_test_args_2 = [ + "--regex test --func", + "--regex test --fielddecl", + "--regex test --memfunc", + "--regex test --var", + "--regex test --class", + "--regex test --struct", + "--regex test --union", + "--regex test --nameddecl", + "--regex test --declrefexpr", + "--regex test --call", + "--regex test --cxxcall", + "--regex test --", + ] class Argparser(object): def __init__(self): -- cgit v1.2.3