From 235a224f12b413d672ac6a8291f821cd4f6ebdeb Mon Sep 17 00:00:00 2001 From: malte_langkabel Date: Mon, 6 Mar 2017 16:41:10 +0100 Subject: [PATCH] logic: implemented skipping implicit code in CxxForRangeStatements --- src/lib_cxx/CMakeLists.txt | 2 + src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp | 10 +++-- src/lib_cxx/data/parser/cxx/CxxAstVisitor.h | 3 ++ .../data/parser/cxx/CxxAstVisitorComponent.h | 2 + .../CxxAstVisitorComponentImplicitCode.cpp | 41 +++++++++++++++++++ .../cxx/CxxAstVisitorComponentImplicitCode.h | 26 ++++++++++++ src/test/CxxParserTestSuite.h | 16 ++++++++ 7 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentImplicitCode.cpp create mode 100644 src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentImplicitCode.h diff --git a/src/lib_cxx/CMakeLists.txt b/src/lib_cxx/CMakeLists.txt index f93c0aa3..4d8fa7c1 100644 --- a/src/lib_cxx/CMakeLists.txt +++ b/src/lib_cxx/CMakeLists.txt @@ -53,6 +53,8 @@ add_files( data/parser/cxx/CxxAstVisitorComponentContext.h data/parser/cxx/CxxAstVisitorComponentDeclRefKind.cpp data/parser/cxx/CxxAstVisitorComponentDeclRefKind.h + data/parser/cxx/CxxAstVisitorComponentImplicitCode.cpp + data/parser/cxx/CxxAstVisitorComponentImplicitCode.h data/parser/cxx/CxxAstVisitorComponentIndexer.cpp data/parser/cxx/CxxAstVisitorComponentIndexer.h data/parser/cxx/CxxAstVisitorComponentTypeRefKind.cpp diff --git a/src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp b/src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp index 1bdde658..477f210f 100644 --- a/src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp +++ b/src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp @@ -10,6 +10,7 @@ #include "data/parser/cxx/CxxAstVisitorComponentContext.h" #include "data/parser/cxx/CxxAstVisitorComponentDeclRefKind.h" #include "data/parser/cxx/CxxAstVisitorComponentTypeRefKind.h" +#include "data/parser/cxx/CxxAstVisitorComponentImplicitCode.h" #include "data/parser/cxx/CxxAstVisitorComponentIndexer.h" #include "data/parser/cxx/utilityCxxAstVisitor.h" @@ -52,6 +53,8 @@ CxxAstVisitor::CxxAstVisitor(clang::ASTContext* astContext, clang::Preprocessor* m_components.push_back(m_typeRefKindComponent); m_declRefKindComponent = std::make_shared(this); m_components.push_back(m_declRefKindComponent); + m_implicitCodeComponent = std::make_shared(this); + m_components.push_back(m_implicitCodeComponent); m_indexerComponent = std::make_shared(this, astContext, client, fileRegister); m_components.push_back(m_indexerComponent); } @@ -106,7 +109,7 @@ bool CxxAstVisitor::shouldVisitTemplateInstantiations() const bool CxxAstVisitor::shouldVisitImplicitCode() const { - return true; + return m_implicitCodeComponent->shouldVisitImplicitCode(); } bool CxxAstVisitor::checkIgnoresTypeLoc(const clang::TypeLoc& tl) const @@ -119,8 +122,8 @@ bool CxxAstVisitor::checkIgnoresTypeLoc(const clang::TypeLoc& tl) const (!tl.getAs().isNull()) || (!tl.getAs().isNull()) || (!tl.getAs().isNull()) || - (!tl.getAs().isNull()) - ){ + (!tl.getAs().isNull())) + { return false; } return true; @@ -373,6 +376,7 @@ DEF_TRAVERSE_TYPE_PTR(FunctionDecl, {}, {}) DEF_TRAVERSE_TYPE_PTR(ClassTemplateSpecializationDecl, {}, {}) DEF_TRAVERSE_TYPE_PTR(ClassTemplatePartialSpecializationDecl, {}, {}) DEF_TRAVERSE_TYPE_PTR(DeclRefExpr, {}, {}) +DEF_TRAVERSE_TYPE_PTR(CXXForRangeStmt, {}, {}) DEF_TRAVERSE_TYPE(TemplateSpecializationTypeLoc, {}, {}) DEF_TRAVERSE_TYPE_PTR(UnresolvedLookupExpr, {}, {}) diff --git a/src/lib_cxx/data/parser/cxx/CxxAstVisitor.h b/src/lib_cxx/data/parser/cxx/CxxAstVisitor.h index 7dc19f80..22e2f41b 100644 --- a/src/lib_cxx/data/parser/cxx/CxxAstVisitor.h +++ b/src/lib_cxx/data/parser/cxx/CxxAstVisitor.h @@ -17,6 +17,7 @@ class CxxAstVisitorComponent; class CxxAstVisitorComponentContext; class CxxAstVisitorComponentDeclRefKind; class CxxAstVisitorComponentTypeRefKind; +class CxxAstVisitorComponentImplicitCode; class CxxAstVisitorComponentIndexer; // methods are called in this order: @@ -74,6 +75,7 @@ public: virtual bool TraverseClassTemplateSpecializationDecl(clang::ClassTemplateSpecializationDecl *d); virtual bool TraverseClassTemplatePartialSpecializationDecl(clang::ClassTemplatePartialSpecializationDecl* d); virtual bool TraverseDeclRefExpr(clang::DeclRefExpr* s); + virtual bool TraverseCXXForRangeStmt(clang::CXXForRangeStmt* s); virtual bool TraverseTemplateSpecializationTypeLoc(clang::TemplateSpecializationTypeLoc loc); virtual bool TraverseUnresolvedLookupExpr(clang::UnresolvedLookupExpr* s); virtual bool TraverseTemplateArgumentLoc(const clang::TemplateArgumentLoc& loc); @@ -143,6 +145,7 @@ private: std::shared_ptr m_contextComponent; std::shared_ptr m_declRefKindComponent; std::shared_ptr m_typeRefKindComponent; + std::shared_ptr m_implicitCodeComponent; std::shared_ptr m_indexerComponent; std::shared_ptr m_declNameCache; diff --git a/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponent.h b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponent.h index 4fa45437..a74326f2 100644 --- a/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponent.h +++ b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponent.h @@ -46,6 +46,8 @@ DEF_TRAVERSE_TYPE_PTR(LambdaExpr) DEF_TRAVERSE_TYPE_PTR(DeclRefExpr) +DEF_TRAVERSE_TYPE_PTR(CXXForRangeStmt) + DEF_TRAVERSE_TYPE_PTR(UnresolvedLookupExpr) virtual void beginTraverseCallCommonCallee() {} diff --git a/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentImplicitCode.cpp b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentImplicitCode.cpp new file mode 100644 index 00000000..feaa7f56 --- /dev/null +++ b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentImplicitCode.cpp @@ -0,0 +1,41 @@ +#include "data/parser/cxx/CxxAstVisitorComponentImplicitCode.h" + +CxxAstVisitorComponentImplicitCode::CxxAstVisitorComponentImplicitCode(CxxAstVisitor* astVisitor) + : CxxAstVisitorComponent(astVisitor) +{ +} + +CxxAstVisitorComponentImplicitCode::~CxxAstVisitorComponentImplicitCode() +{ +} + +bool CxxAstVisitorComponentImplicitCode::shouldVisitImplicitCode() const +{ +// return false; + if (!m_stack.empty()) + { + return m_stack.back(); + } + return true; +} + +void CxxAstVisitorComponentImplicitCode::beginTraverseDecl(clang::Decl* d) +{ + m_stack.push_back(true); +} + +void CxxAstVisitorComponentImplicitCode::endTraverseDecl(clang::Decl* d) +{ + m_stack.pop_back(); + +} + +void CxxAstVisitorComponentImplicitCode::beginTraverseCXXForRangeStmt(clang::CXXForRangeStmt* s) +{ + m_stack.push_back(false); +} + +void CxxAstVisitorComponentImplicitCode::endTraverseCXXForRangeStmt(clang::CXXForRangeStmt* s) +{ + m_stack.pop_back(); +} diff --git a/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentImplicitCode.h b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentImplicitCode.h new file mode 100644 index 00000000..6fcb84bd --- /dev/null +++ b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentImplicitCode.h @@ -0,0 +1,26 @@ +#ifndef CXX_AST_VISITOR_COMPONENT_IMPLICIT_CODE_H +#define CXX_AST_VISITOR_COMPONENT_IMPLICIT_CODE_H + +#include "data/parser/cxx/CxxAstVisitorComponent.h" +#include "data/parser/cxx/CxxContext.h" + +// This CxxAstVisitorComponent is responsible for deciding if the AstVisitor should visit implicit code in the current context. +class CxxAstVisitorComponentImplicitCode: public CxxAstVisitorComponent +{ +public: + CxxAstVisitorComponentImplicitCode(CxxAstVisitor* astVisitor); + virtual ~CxxAstVisitorComponentImplicitCode(); + + bool shouldVisitImplicitCode() const; + + virtual void beginTraverseDecl(clang::Decl* d); + virtual void endTraverseDecl(clang::Decl* d); + + virtual void beginTraverseCXXForRangeStmt(clang::CXXForRangeStmt* s); + virtual void endTraverseCXXForRangeStmt(clang::CXXForRangeStmt* s); + +private: + std::vector m_stack; +}; + +#endif // CXX_AST_VISITOR_COMPONENT_IMPLICIT_CODE_H diff --git a/src/test/CxxParserTestSuite.h b/src/test/CxxParserTestSuite.h index 8203db6f..200f9ea9 100644 --- a/src/test/CxxParserTestSuite.h +++ b/src/test/CxxParserTestSuite.h @@ -1272,6 +1272,22 @@ public: TS_ASSERT(utility::containsElement(client->builtinTypes, "bool")); } + void test_cxx_parser_finds_implicit_copy_constructor() + { + std::shared_ptr client = parseCode( + "class TestClass {}\n" + "void foo()\n" + "{\n" + " TestClass a;\n" + " TestClass b(a);\n" + "}\n" + ); + + TS_ASSERT(utility::containsElement(client->methods, "public void TestClass::TestClass() <1:7 <1:7 1:15> 1:7>")); + TS_ASSERT(utility::containsElement(client->methods, "public void TestClass::TestClass(const TestClass &) <1:7 <1:7 1:15> 1:7>")); + TS_ASSERT(utility::containsElement(client->methods, "public void TestClass::TestClass(TestClass &) <1:7 1:15>")); + } + /////////////////////////////////////////////////////////////////////////////// // test finding usages of symbols