diff --git a/src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp b/src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp index 75801d94..93e1259f 100644 --- a/src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp +++ b/src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp @@ -583,6 +583,7 @@ DEF_VISIT_TYPE_PTR(DeclRefExpr) DEF_VISIT_TYPE_PTR(MemberExpr) DEF_VISIT_TYPE_PTR(CXXDependentScopeMemberExpr) DEF_VISIT_TYPE_PTR(CXXConstructExpr) +DEF_VISIT_TYPE_PTR(CXXDeleteExpr) DEF_VISIT_TYPE_PTR(LambdaExpr) DEF_VISIT_TYPE_PTR(MSAsmStmt) DEF_VISIT_CUSTOM_TYPE_PTR(ConstructorInitializer, CXXCtorInitializer) diff --git a/src/lib_cxx/data/parser/cxx/CxxAstVisitor.h b/src/lib_cxx/data/parser/cxx/CxxAstVisitor.h index 97c3cd27..d281d963 100644 --- a/src/lib_cxx/data/parser/cxx/CxxAstVisitor.h +++ b/src/lib_cxx/data/parser/cxx/CxxAstVisitor.h @@ -98,12 +98,19 @@ public: return TraverseAssignCommon(s); \ } OPERATOR(Mul) - OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr) - OPERATOR(And) OPERATOR(Or) OPERATOR(Xor) + OPERATOR(Div) + OPERATOR(Rem) + OPERATOR(Add) + OPERATOR(Sub) + OPERATOR(Shl) + OPERATOR(Shr) + OPERATOR(And) + OPERATOR(Or) + OPERATOR(Xor) #undef OPERATOR - void traverseDeclContextHelper(clang::DeclContext* d); + void traverseDeclContextHelper(clang::DeclContext* d); bool TraverseCallCommon(clang::CallExpr* s); bool TraverseAssignCommon(clang::BinaryOperator* s); @@ -142,6 +149,7 @@ public: virtual bool VisitMemberExpr(clang::MemberExpr* s); virtual bool VisitCXXDependentScopeMemberExpr(clang::CXXDependentScopeMemberExpr* s); virtual bool VisitCXXConstructExpr(clang::CXXConstructExpr* s); + virtual bool VisitCXXDeleteExpr(clang::CXXDeleteExpr* s); virtual bool VisitLambdaExpr(clang::LambdaExpr* s); virtual bool VisitMSAsmStmt(clang::MSAsmStmt* s); virtual bool VisitConstructorInitializer(clang::CXXCtorInitializer* init); diff --git a/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponent.h b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponent.h index a4e39595..e2a90053 100644 --- a/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponent.h +++ b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponent.h @@ -123,6 +123,7 @@ public: void visitMemberExpr(clang::MemberExpr* s) {} void visitCXXDependentScopeMemberExpr(clang::CXXDependentScopeMemberExpr* s) {} void visitCXXConstructExpr(clang::CXXConstructExpr* s) {} + void visitCXXDeleteExpr(clang::CXXDeleteExpr* s) {} void visitLambdaExpr(clang::LambdaExpr* s) {} void visitMSAsmStmt(clang::MSAsmStmt* s) {} diff --git a/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.cpp b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.cpp index d2cd6158..d9b58347 100644 --- a/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.cpp +++ b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.cpp @@ -783,7 +783,7 @@ void CxxAstVisitorComponentIndexer::visitCXXConstructExpr(clang::CXXConstructExp loc = clang::Lexer::GetBeginningOfToken( loc, m_astContext->getSourceManager(), m_astContext->getLangOpts()); - Id symbolId = getOrCreateSymbolId(s->getConstructor()); + const Id symbolId = getOrCreateSymbolId(s->getConstructor()); const ReferenceKind refKind = consumeDeclRefContextKind(); if (refKind == REFERENCE_CALL) @@ -800,6 +800,27 @@ void CxxAstVisitorComponentIndexer::visitCXXConstructExpr(clang::CXXConstructExp } } +void CxxAstVisitorComponentIndexer::visitCXXDeleteExpr(clang::CXXDeleteExpr* s) +{ + if (!s->isArrayForm() && getAstVisitor()->shouldVisitReference(s->getBeginLoc())) + { + if (clang::CXXRecordDecl* recordDecl = s->getDestroyedType()->getAsCXXRecordDecl()) + { + if (clang::CXXDestructorDecl* destructorDecl = recordDecl->getDestructor()) + { + const Id symbolId = getOrCreateSymbolId(destructorDecl); + + m_client->recordReference( + REFERENCE_CALL, + symbolId, + getOrCreateSymbolId( + getAstVisitor()->getComponent()->getContext()), + getParseLocation(s->getBeginLoc())); + } + } + } +} + void CxxAstVisitorComponentIndexer::visitLambdaExpr(clang::LambdaExpr* s) { clang::CXXMethodDecl* methodDecl = s->getCallOperator(); diff --git a/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.h b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.h index 46769eb5..b61796f3 100644 --- a/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.h +++ b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.h @@ -47,6 +47,7 @@ public: void visitDeclRefExpr(clang::DeclRefExpr* s); void visitMemberExpr(clang::MemberExpr* s); void visitCXXConstructExpr(clang::CXXConstructExpr* s); + void visitCXXDeleteExpr(clang::CXXDeleteExpr* s); void visitLambdaExpr(clang::LambdaExpr* s); void visitConstructorInitializer(clang::CXXCtorInitializer* init); diff --git a/src/test/CxxParserTestSuite.cpp b/src/test/CxxParserTestSuite.cpp index c158ff9e..b824733b 100644 --- a/src/test/CxxParserTestSuite.cpp +++ b/src/test/CxxParserTestSuite.cpp @@ -845,7 +845,7 @@ TEST_CASE("cxx parser finds template argument of dependent non type template par // TS_ASSERT(utility::containsElement( // client->typeUses, // TODO: record edge between vector> and Alloc (this -//is an issue because we dont have any typeloc for this edge -.- +// is an issue because we dont have any typeloc for this edge -.- // )); //} @@ -2013,6 +2013,43 @@ TEST_CASE("cxx parser finds explicit constructor call") client->calls, L"int main() -> void App::App() <8:2 8:4>")); } +TEST_CASE("cxx parser finds call of explicitly defined destructor at delete keyword") +{ + std::shared_ptr client = parseCode( + "class Foo\n" + "{\n" + "public:\n" + " Foo() {}\n" + " ~Foo() {}\n" + "}; \n" + "\n" + "void foo()\n" + "{\n" + " Foo* f = new Foo(); \n" + " delete f; \n" + "}\n"); + + REQUIRE(utility::containsElement( + client->calls, L"void foo() -> void Foo::~Foo() <11:2 11:7>")); +} + +TEST_CASE("cxx parser finds call of implicitly defined destructor at delete keyword") +{ + std::shared_ptr client = parseCode( + "class Foo\n" + "{\n" + "}; \n" + "\n" + "void foo()\n" + "{\n" + " Foo* f = new Foo(); \n" + " delete f; \n" + "}\n"); + + REQUIRE(utility::containsElement( + client->calls, L"void foo() -> void Foo::~Foo() <8:2 8:7>")); +} + TEST_CASE("cxx parser finds explicit constructor call of field") { std::shared_ptr client = parseCode(