aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md14
-rw-r--r--cgrep.cpp57
-rw-r--r--cgrep.roff8
-rw-r--r--compile_commands.json6
-rwxr-xr-xcovrun.sh2
-rw-r--r--test/compile_commands.json4
-rw-r--r--test/main.ast149
-rw-r--r--test/main.cpp7
8 files changed, 158 insertions, 89 deletions
diff --git a/README.md b/README.md
index 425033b..7907da6 100644
--- a/README.md
+++ b/README.md
@@ -38,16 +38,24 @@ For windows builds, cygwin builds are supported. Get llvm and clang along with t
A simple usage example:
```bash
-cgrep -A 1 -B 1 --func --declrefexpr --regex n[aA]m --noclor --nodecl ./cgrep.cpp
+cgrep -A 1 -B 1 --func --declrefexpr --regex n[aA]m --nocolor --nodecl ./myawesomecode.cpp
```
-Please do note that the regex will pass through both C++ and the regex engine, so if you would want to escape `\`, the regex you pass as the command line arg would be `\\\\` instead of the normal `\\`.
-In order for cgrep to work, you need to have a compilation database, tools like `cmake` can generate one for you.
+In order for cgrep to work, you need to have a compilation database, tools like `cmake` can generate one for you.<br/>
+You can, by all means, run cgrep without a compilation databse but whether that works or not really depends on your source file. Can you build your source file with clang without passing it any options?
+If the answer to that is yes, then you can just run cgrep without a compilation databse like so:<br/>
+```bash
+cgrep -A 1 -B 1 --func --declrefexpr --regex n[aA]m --nocolor --nodecl ./myawesomecode.cpp --
+```
+Otherwise you need a compilation database.<br/>
+
+Please do note that the regex will pass through both C++ and the regex engine, so if you would want to escape `\`, the regex you pass as the command line arg would be `\\\\` instead of the normal `\\`.<br/>
If your build tool doesn't do that, you can just use [bear](https://github.com/rizsotto/Bear) or [scan-build](https://github.com/rizsotto/scan-build).
You can also skip the compilation database altogether passing cgrep `--` after the input file name which means you have chosen not to pass it anything.
You can pass the options by hand since cgrep is a Clang instance so it recognizes every option clang has.
cgrep uses ANSI escape sequences for colors so your terminal should support those. In case your terminal does not support ANSI escape sequences, you can silence those using the `--nocolor` option.
+
By default, cgrep will print out the declaration location for a match. In case you don't want those in the output, you can pass cgrep the `--nodecl` switch.
You can use `--extra-arg==--std=` to tell cgrep which C-family language the source file is supposed to be in.
diff --git a/cgrep.cpp b/cgrep.cpp
index 7b2c5c2..8ce5fe7 100644
--- a/cgrep.cpp
+++ b/cgrep.cpp
@@ -41,7 +41,7 @@ cl::opt<bool> CO_CALL("call", cl::desc("Match function calls."),
cl::opt<bool> CO_CXXCALL("cxxcall", cl::desc("Match member function calls."),
cl::init(false), cl::cat(CGrepCat),
cl::Optional); // done
-cl::opt<bool> CO_MEMVAR("memvar", cl::desc("Match member variables."),
+cl::opt<bool> CO_CFIELD("cfield", cl::desc("Match C field declarations."),
cl::init(false), cl::cat(CGrepCat),
cl::Optional); // done
cl::opt<bool> CO_CLASS("class", cl::desc("Match class declrations."),
@@ -50,6 +50,9 @@ cl::opt<bool> CO_CLASS("class", cl::desc("Match class declrations."),
cl::opt<bool> CO_STRUCT("struct", cl::desc("Match structures."),
cl::init(false), cl::cat(CGrepCat),
cl::Optional); // done
+cl::opt<bool> CO_CXXFIELD("cxxfield", cl::desc("Match CXX field member declarations."),
+ cl::init(false), cl::cat(CGrepCat),
+ cl::Optional); // done
cl::opt<bool> CO_UNION("union", cl::desc("Match unions."), cl::init(false),
cl::cat(CGrepCat), cl::Optional); // done
cl::opt<bool> CO_MACRO("macro", cl::desc("Match macro definitions."),
@@ -573,10 +576,10 @@ public:
const NamedDecl *ND = DRE->getFoundDecl();
std::string name = ND->getNameAsString();
SourceLocation SL = DRE->DEVI_GETLOCSTART();
+ SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start");
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))
@@ -667,6 +670,37 @@ private:
Rewriter &Rewrite [[maybe_unused]];
};
/***********************************************************************************************/
+class RecordFieldHandler : public MatchFinder::MatchCallback {
+ public:
+ explicit RecordFieldHandler(Rewriter &Rewrite) : Rewrite(Rewrite) {}
+
+ virtual void run(const MatchFinder::MatchResult &MR) {
+ const FieldDecl *FD = MR.Nodes.getNodeAs<clang::FieldDecl>("recordfielddecl");
+ if (FD) {
+ SourceRange SR = FD->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 = FD->getNameAsString();
+ if (regex_handler(REGEX_PP(CO_REGEX), name)) {
+ ast_type_traits::DynTypedNode DNode =
+ ast_type_traits::DynTypedNode::create(*FD);
+ auto StartLocation = FD->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]];
+};
+/***********************************************************************************************/
class PPInclusion : public PPCallbacks {
public:
explicit PPInclusion(SourceManager *SM, Rewriter *Rewrite)
@@ -756,8 +790,8 @@ public:
: HandlerForVar(R), HandlerForClass(R), HandlerForCalledFunc(R),
HandlerForCXXMethod(R), HandlerForField(R), HandlerForStruct(R),
HandlerForUnion(R), HandlerForNamedDecl(R), HandlerForDeclRefExpr(R),
- HandlerForCallExpr(R), HandlerForCXXCallExpr(R) {
-#if 1
+ HandlerForCallExpr(R), HandlerForCXXCallExpr(R),
+ HandlerForRecordField(R) {
if (CO_FUNCTION || CO_ALL) {
Matcher.addMatcher(functionDecl().bind("funcdecl"),
&HandlerForCalledFunc);
@@ -782,7 +816,7 @@ public:
Matcher.addMatcher(cxxMethodDecl().bind("cxxmethoddecl"),
&HandlerForCXXMethod);
}
- if (CO_MEMVAR || CO_ALL) {
+ if (CO_CFIELD || CO_ALL) {
Matcher.addMatcher(fieldDecl().bind("fielddecl"), &HandlerForField);
}
if (CO_STRUCT || CO_ALL) {
@@ -808,7 +842,9 @@ public:
Matcher.addMatcher(cxxMemberCallExpr().bind("cxxcallexpr"),
&HandlerForCXXCallExpr);
}
-#endif
+ if (CO_CXXFIELD || CO_ALL) {
+ Matcher.addMatcher(fieldDecl(hasParent(cxxRecordDecl())).bind("recordfielddecl"), &HandlerForRecordField);
+ }
}
void HandleTranslationUnit(ASTContext &Context) override {
@@ -827,13 +863,14 @@ private:
DeclRefExprHandler HandlerForDeclRefExpr;
CallExprHandler HandlerForCallExpr;
CXXCallExprHandler HandlerForCXXCallExpr;
+ RecordFieldHandler HandlerForRecordField;
MatchFinder Matcher;
};
/***********************************************************************************************/
-class AppFrontendAction : public ASTFrontendAction {
+class CgrepFrontendAction : public ASTFrontendAction {
public:
- AppFrontendAction() {}
- ~AppFrontendAction() { delete BDCProto; }
+ CgrepFrontendAction() {}
+ ~CgrepFrontendAction() { delete BDCProto; }
void EndSourceFileAction() override {
std::error_code EC;
@@ -870,7 +907,7 @@ private:
int main(int argc, const char **argv) {
CommonOptionsParser op(argc, argv, CGrepCat);
ClangTool Tool(op.getCompilations(), op.getSourcePathList());
- int ret = Tool.run(newFrontendActionFactory<AppFrontendAction>().get());
+ int ret = Tool.run(newFrontendActionFactory<CgrepFrontendAction>().get());
#if 0
listDirs(CO_RECURSIVE);
#endif
diff --git a/cgrep.roff b/cgrep.roff
index a66b2e0..f2793e7 100644
--- a/cgrep.roff
+++ b/cgrep.roff
@@ -58,6 +58,10 @@ Match class declarations.
Matches member function calls.
.TP
+\fB--cxxfield\fP
+Match CXX field declarations.
+
+.TP
\fB--declrefexpr\fP
Matches declrefexpr.
.br
@@ -112,8 +116,8 @@ cgrep.
Match member function declarations.
.TP
-\fB--memvar\fP
-Match member variable declarations.
+\fB--cfield\fP
+Match C field declations.
.TP
\fB--nameddecl\fP
diff --git a/compile_commands.json b/compile_commands.json
index 2803ad9..9c2f5ec 100644
--- a/compile_commands.json
+++ b/compile_commands.json
@@ -1,7 +1,7 @@
[
{
- "command": "c++ -c -include-pch pch.hpp.gch -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",
- "directory": "/home/bloodstalker/extra/cgrep",
- "file": "/home/bloodstalker/extra/cgrep/cgrep.cpp"
+ "command": "c++ -c -include-pch pch.hpp.gch -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",
+ "directory": "/home/bloodstalker/devi/hell2/cgrep",
+ "file": "/home/bloodstalker/devi/hell2/cgrep/cgrep.cpp"
}
] \ No newline at end of file
diff --git a/covrun.sh b/covrun.sh
index 53e3726..ed0fce1 100755
--- a/covrun.sh
+++ b/covrun.sh
@@ -9,7 +9,7 @@ LLVM_PROFILE_FILE="five.profraw" "./cgrep-cov" -A 1 -B 1 --class --regex and ./c
LLVM_PROFILE_FILE="six.profraw" "./cgrep-cov" -A 1 -B 1 --struct --union --regex n[aA]m ./cgrep.cpp
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="nine.profraw" "./cgrep-cov" -A 1 -B 1 --cfield --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
LLVM_PROFILE_FILE="twelve.profraw" "./cgrep-cov" --dir ./ --regex run --func ./cgrep.cpp
diff --git a/test/compile_commands.json b/test/compile_commands.json
index 4f584fd..9808839 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/extra/cgrep/test",
- "file": "/home/bloodstalker/extra/cgrep/test/main.cpp"
+ "directory": "/home/bloodstalker/devi/hell2/cgrep/test",
+ "file": "/home/bloodstalker/devi/hell2/cgrep/test/main.cpp"
}
] \ No newline at end of file
diff --git a/test/main.ast b/test/main.ast
index 02edebb..d03244f 100644
--- a/test/main.ast
+++ b/test/main.ast
@@ -1,40 +1,42 @@
-TranslationUnitDecl 0x6bd18f8 <<invalid sloc>> <invalid sloc>
-|-TypedefDecl 0x6bd21d0 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'
-| `-BuiltinType 0x6bd1e90 '__int128'
-|-TypedefDecl 0x6bd2238 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128'
-| `-BuiltinType 0x6bd1eb0 'unsigned __int128'
-|-TypedefDecl 0x6bd2568 <<invalid sloc>> <invalid sloc> implicit __NSConstantString '__NSConstantString_tag'
-| `-RecordType 0x6bd2310 '__NSConstantString_tag'
-| `-CXXRecord 0x6bd2288 '__NSConstantString_tag'
-|-TypedefDecl 0x6c0c340 <<invalid sloc>> <invalid sloc> implicit __builtin_ms_va_list 'char *'
-| `-PointerType 0x6bd25c0 'char *'
-| `-BuiltinType 0x6bd1990 'char'
-|-TypedefDecl 0x6c0c668 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list '__va_list_tag [1]'
-| `-ConstantArrayType 0x6c0c610 '__va_list_tag [1]' 1
-| `-RecordType 0x6c0c420 '__va_list_tag'
-| `-CXXRecord 0x6c0c390 '__va_list_tag'
-|-CXXRecordDecl 0x6c0c6b8 <main.cpp:2:1, line:12:1> line:2:7 referenced class myClass definition
-| |-DefinitionData standard_layout has_user_declared_ctor can_const_default_init
-| | |-DefaultConstructor exists non_trivial user_provided
+TranslationUnitDecl 0x7e63838 <<invalid sloc>> <invalid sloc>
+|-TypedefDecl 0x7e64110 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'
+| `-BuiltinType 0x7e63dd0 '__int128'
+|-TypedefDecl 0x7e64180 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128'
+| `-BuiltinType 0x7e63df0 'unsigned __int128'
+|-TypedefDecl 0x7e644f8 <<invalid sloc>> <invalid sloc> implicit __NSConstantString '__NSConstantString_tag'
+| `-RecordType 0x7e64270 '__NSConstantString_tag'
+| `-CXXRecord 0x7e641d8 '__NSConstantString_tag'
+|-TypedefDecl 0x7e64590 <<invalid sloc>> <invalid sloc> implicit __builtin_ms_va_list 'char *'
+| `-PointerType 0x7e64550 'char *'
+| `-BuiltinType 0x7e638d0 'char'
+|-TypedefDecl 0x7ea1338 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list '__va_list_tag [1]'
+| `-ConstantArrayType 0x7ea12e0 '__va_list_tag [1]' 1
+| `-RecordType 0x7e64680 '__va_list_tag'
+| `-CXXRecord 0x7e645e8 '__va_list_tag'
+|-CXXRecordDecl 0x7ea1390 <main.cpp:2:1, line:12:1> line:2:7 referenced class myClass definition
+| |-DefinitionData standard_layout has_user_declared_ctor
+| | |-DefaultConstructor exists trivial
| | |-CopyConstructor simple trivial has_const_param implicit_has_const_param
| | |-MoveConstructor
| | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
| | |-MoveAssignment
| | `-Destructor non_trivial user_declared
-| |-CXXRecordDecl 0x6c0c7c8 <col:1, col:7> col:7 implicit referenced class myClass
-| |-AccessSpecDecl 0x6c0c850 <line:3:3, col:9> col:3 public
-| |-CXXConstructorDecl 0x6c0c920 <line:4:5, col:13> col:5 used myClass 'void ()'
-| |-CXXDestructorDecl 0x6c0ca10 <line:5:5, col:14> col:5 used ~myClass 'void () noexcept'
-| |-CXXMethodDecl 0x6c0cb48 <line:7:5, col:27> col:10 used myMehtod1 'void ()'
-| | `-CompoundStmt 0x6c0ce28 <col:26, col:27>
-| |-CXXMethodDecl 0x6c0cc70 <line:8:5, col:27> col:10 used myMehtod2 'void ()'
-| | `-CompoundStmt 0x6c0ce38 <col:26, col:27>
-| |-AccessSpecDecl 0x6c0cd08 <line:9:3, col:10> col:3 private
-| |-FieldDecl 0x6c0cd48 <line:10:5, col:9> col:9 a 'int'
-| |-FieldDecl 0x6c0cda8 <line:11:5, col:11> col:11 b 'float'
-| `-CXXConstructorDecl 0x6c3b9a8 <line:2:7> col:7 implicit constexpr myClass 'void (const myClass &)' inline default trivial noexcept-unevaluated 0x6c3b9a8
-| `-ParmVarDecl 0x6c3bad0 <col:7> col:7 'const myClass &'
-|-CXXRecordDecl 0x6c0ce48 <line:14:1, line:17:1> line:14:8 struct myStruct definition
+| |-CXXRecordDecl 0x7ea14a8 <col:1, col:7> col:7 implicit referenced class myClass
+| |-AccessSpecDecl 0x7ea1538 <line:3:3, col:9> col:3 public
+| |-CXXConstructorDecl 0x7ea15e8 <line:4:5, col:23> col:5 used myClass 'void () noexcept' default trivial
+| | `-CompoundStmt 0x7ed1488 <col:23>
+| |-CXXDestructorDecl 0x7ea16d8 <line:5:5, col:17> col:5 used ~myClass 'void () noexcept'
+| | `-CompoundStmt 0x7ea1b88 <col:16, col:17>
+| |-CXXMethodDecl 0x7ea1858 <line:7:5, col:27> col:10 used myMehtod1 'void ()'
+| | `-CompoundStmt 0x7ea1b98 <col:26, col:27>
+| |-CXXMethodDecl 0x7ea1990 <line:8:5, col:27> col:10 used myMehtod2 'void ()'
+| | `-CompoundStmt 0x7ea1ba8 <col:26, col:27>
+| |-AccessSpecDecl 0x7ea1a30 <line:9:3, col:10> col:3 private
+| |-FieldDecl 0x7ea1a70 <line:10:5, col:9> col:9 a 'int'
+| |-FieldDecl 0x7ea1ad8 <line:11:5, col:11> col:11 b 'float'
+| `-CXXConstructorDecl 0x7ed1308 <line:2:7> col:7 implicit constexpr myClass 'void (const myClass &)' inline default trivial noexcept-unevaluated 0x7ed1308
+| `-ParmVarDecl 0x7ed1418 <col:7> col:7 'const myClass &'
+|-CXXRecordDecl 0x7ea1bb8 <line:14:1, line:17:1> line:14:8 struct myStruct definition
| |-DefinitionData empty standard_layout has_user_declared_ctor can_const_default_init
| | |-DefaultConstructor exists non_trivial user_provided defaulted_is_constexpr
| | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
@@ -42,39 +44,50 @@
| | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
| | |-MoveAssignment
| | `-Destructor non_trivial user_declared
-| |-CXXRecordDecl 0x6c0cf58 <col:1, col:8> col:8 implicit referenced struct myStruct
-| |-CXXConstructorDecl 0x6c0d048 <line:15:3, col:12> col:3 myStruct 'void ()'
-| `-CXXDestructorDecl 0x6c0d138 <line:16:3, col:13> col:3 ~myStruct 'void ()' noexcept-unevaluated 0x6c0d138
-|-FunctionDecl 0x6c0d2a8 <line:19:1, col:21> col:6 myFunc1 'void ()'
-| `-CompoundStmt 0x6c3b590 <col:20, col:21>
-|-FunctionDecl 0x6c3b630 <line:20:1, col:21> col:6 myFunc2 'void ()'
-| `-CompoundStmt 0x6c3b6c8 <col:20, col:21>
-`-FunctionDecl 0x6c3b868 <line:22:1, line:31:1> line:22:5 main 'int (int, char **)'
- |-ParmVarDecl 0x6c3b6f0 <col:11, col:15> col:15 argc 'int'
- |-ParmVarDecl 0x6c3b790 <col:21, col:28> col:28 argv 'char **'
- `-CompoundStmt 0x6c3c038 <col:34, line:31:1>
- |-DeclStmt 0x6c3bba0 <line:23:3, col:13>
- | `-VarDecl 0x6c3b920 <col:3, col:11> col:11 used mc 'myClass' callinit
- | `-CXXConstructExpr 0x6c3bb38 <col:11> 'myClass' 'void ()'
- |-CXXMemberCallExpr 0x6c3bc18 <line:24:3, col:16> 'void'
- | `-MemberExpr 0x6c3bbe0 <col:3, col:6> '<bound member function type>' .myMehtod1 0x6c0cb48
- | `-DeclRefExpr 0x6c3bbb8 <col:3> 'myClass' lvalue Var 0x6c3b920 'mc' 'myClass'
- |-CXXMemberCallExpr 0x6c3bca0 <line:25:3, col:16> 'void'
- | `-MemberExpr 0x6c3bc68 <col:3, col:6> '<bound member function type>' .myMehtod2 0x6c0cc70
- | `-DeclRefExpr 0x6c3bc40 <col:3> 'myClass' lvalue Var 0x6c3b920 'mc' 'myClass'
- |-DeclStmt 0x6c3bd40 <line:26:3, col:8>
- | `-VarDecl 0x6c3bce0 <col:3, col:7> col:7 used a 'int'
- |-DeclStmt 0x6c3bdd0 <line:27:3, col:10>
- | `-VarDecl 0x6c3bd70 <col:3, col:9> col:9 b 'float'
- |-DeclStmt 0x6c3bef0 <line:28:3, col:10>
- | |-VarDecl 0x6c3be00 <col:3, col:7> col:7 used c 'int'
- | `-VarDecl 0x6c3be78 <col:3, col:9> col:9 used d 'int'
- |-BinaryOperator 0x6c3bfd8 <line:29:3, col:9> 'int' lvalue '='
- | |-DeclRefExpr 0x6c3bf08 <col:3> 'int' lvalue Var 0x6c3bce0 'a' 'int'
- | `-BinaryOperator 0x6c3bfb0 <col:7, col:9> 'int' '+'
- | |-ImplicitCastExpr 0x6c3bf80 <col:7> 'int' <LValueToRValue>
- | | `-DeclRefExpr 0x6c3bf30 <col:7> 'int' lvalue Var 0x6c3be00 'c' 'int'
- | `-ImplicitCastExpr 0x6c3bf98 <col:9> 'int' <LValueToRValue>
- | `-DeclRefExpr 0x6c3bf58 <col:9> 'int' lvalue Var 0x6c3be78 'd' 'int'
- `-ReturnStmt 0x6c3c020 <line:30:3, col:10>
- `-IntegerLiteral 0x6c3c000 <col:10> 'int' 0
+| |-CXXRecordDecl 0x7ea1cd8 <col:1, col:8> col:8 implicit referenced struct myStruct
+| |-CXXConstructorDecl 0x7ea1dd0 <line:15:3, col:12> col:3 myStruct 'void ()'
+| `-CXXDestructorDecl 0x7ea1ec0 <line:16:3, col:13> col:3 ~myStruct 'void ()' noexcept-unevaluated 0x7ea1ec0
+|-CXXRecordDecl 0x7ea1fa0 <line:19:1, line:22:1> line:19:7 union myUnion definition
+| |-DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal has_variant_members
+| | |-DefaultConstructor exists trivial needs_implicit
+| | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
+| | |-MoveConstructor exists simple trivial needs_implicit
+| | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
+| | |-MoveAssignment exists simple trivial needs_implicit
+| | `-Destructor simple irrelevant trivial needs_implicit
+| |-CXXRecordDecl 0x7ea20b8 <col:1, col:7> col:7 implicit union myUnion
+| |-FieldDecl 0x7ea2160 <line:20:3, col:7> col:7 a 'int'
+| `-FieldDecl 0x7ea21c8 <line:21:3, col:10> col:10 b 'double'
+|-FunctionDecl 0x7ed0dc8 <line:24:1, col:21> col:6 myFunc1 'void ()'
+| `-CompoundStmt 0x7ed0eb0 <col:20, col:21>
+|-FunctionDecl 0x7ed0f58 <line:25:1, col:21> col:6 myFunc2 'void ()'
+| `-CompoundStmt 0x7ed0ff8 <col:20, col:21>
+`-FunctionDecl 0x7ed11b0 <line:27:1, line:36:1> line:27:5 main 'int (int, char **)'
+ |-ParmVarDecl 0x7ed1020 <col:11, col:15> col:15 argc 'int'
+ |-ParmVarDecl 0x7ed10d0 <col:21, col:28> col:28 argv 'char **'
+ `-CompoundStmt 0x7ed1918 <col:34, line:36:1>
+ |-DeclStmt 0x7ed14c0 <line:28:3, col:13>
+ | `-VarDecl 0x7ed1270 <col:3, col:11> col:11 used mc 'myClass' callinit destroyed
+ | `-CXXConstructExpr 0x7ed1498 <col:11> 'myClass' 'void () noexcept'
+ |-CXXMemberCallExpr 0x7ed1528 <line:29:3, col:16> 'void'
+ | `-MemberExpr 0x7ed14f8 <col:3, col:6> '<bound member function type>' .myMehtod1 0x7ea1858
+ | `-DeclRefExpr 0x7ed14d8 <col:3> 'myClass' lvalue Var 0x7ed1270 'mc' 'myClass'
+ |-CXXMemberCallExpr 0x7ed1598 <line:30:3, col:16> 'void'
+ | `-MemberExpr 0x7ed1568 <col:3, col:6> '<bound member function type>' .myMehtod2 0x7ea1990
+ | `-DeclRefExpr 0x7ed1548 <col:3> 'myClass' lvalue Var 0x7ed1270 'mc' 'myClass'
+ |-DeclStmt 0x7ed1638 <line:31:3, col:8>
+ | `-VarDecl 0x7ed15d0 <col:3, col:7> col:7 used a 'int'
+ |-DeclStmt 0x7ed16d0 <line:32:3, col:10>
+ | `-VarDecl 0x7ed1668 <col:3, col:9> col:9 b 'float'
+ |-DeclStmt 0x7ed1800 <line:33:3, col:10>
+ | |-VarDecl 0x7ed1700 <col:3, col:7> col:7 used c 'int'
+ | `-VarDecl 0x7ed1780 <col:3, col:9> col:9 used d 'int'
+ |-BinaryOperator 0x7ed18c8 <line:34:3, col:9> 'int' lvalue '='
+ | |-DeclRefExpr 0x7ed1818 <col:3> 'int' lvalue Var 0x7ed15d0 'a' 'int'
+ | `-BinaryOperator 0x7ed18a8 <col:7, col:9> 'int' '+'
+ | |-ImplicitCastExpr 0x7ed1878 <col:7> 'int' <LValueToRValue>
+ | | `-DeclRefExpr 0x7ed1838 <col:7> 'int' lvalue Var 0x7ed1700 'c' 'int'
+ | `-ImplicitCastExpr 0x7ed1890 <col:9> 'int' <LValueToRValue>
+ | `-DeclRefExpr 0x7ed1858 <col:9> 'int' lvalue Var 0x7ed1780 'd' 'int'
+ `-ReturnStmt 0x7ed1908 <line:35:3, col:10>
+ `-IntegerLiteral 0x7ed18e8 <col:10> 'int' 0
diff --git a/test/main.cpp b/test/main.cpp
index 5c2ceb8..87b7eae 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -19,6 +19,13 @@ struct myStruct {
union myUnion {
int a;
double b;
+ int app;
+};
+
+struct verymuchStruct {
+ int myinteger;
+ int yourinteger;
+ int ourinteger;
};
void myFunc1(void) {}