From 1bb16deb3b4d141abc51fc8501e9f63e69fff9ba Mon Sep 17 00:00:00 2001 From: mlangkabel Date: Mon, 30 Sep 2019 11:39:48 +0200 Subject: [PATCH] logic: fixed bug where explicit template specialization records edge pointing to self --- src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp | 62 ++++++++++++++++++- src/test/CxxParserTestSuite.h | 5 +- 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp b/src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp index f761b3c6..ce7d243c 100644 --- a/src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp +++ b/src/lib_cxx/data/parser/cxx/CxxAstVisitor.cpp @@ -350,7 +350,67 @@ bool CxxAstVisitor::TraverseCXXConstructExpr(clang::CXXConstructExpr* s) DEF_TRAVERSE_TYPE_PTR(CXXTemporaryObjectExpr, {}, {}) DEF_TRAVERSE_TYPE_PTR(LambdaExpr, {}, {}) DEF_TRAVERSE_TYPE_PTR(FunctionDecl, {}, {}) -DEF_TRAVERSE_TYPE_PTR(ClassTemplateSpecializationDecl, {}, {}) + +// same as base::TraverseClassTemplateSpecializationDecl but without traversing the typeloc of the template specialitation itself +bool CxxAstVisitor::TraverseClassTemplateSpecializationDecl(clang::ClassTemplateSpecializationDecl *D) +{ + FOREACH_COMPONENT(beginTraverseClassTemplateSpecializationDecl(D)); + + bool ShouldVisitChildren = true; + bool ReturnValue = true; + if (ReturnValue && !shouldTraversePostOrder()) + { + if (!WalkUpFromClassTemplateSpecializationDecl(D)) + { + ReturnValue = false; + } + } + + if (ReturnValue) + { + if (clang::TypeSourceInfo *TSI = D->getTypeAsWritten()) + { + clang::TypeLoc::TypeLocClass ccccc = TSI->getTypeLoc().getTypeLocClass(); + const clang::TemplateSpecializationTypeLoc tstl = TSI->getTypeLoc().getAs(); + if (!tstl.isNull()) + { + for (unsigned I = 0, E = tstl.getNumArgs(); I != E; ++I) + { + if (!TraverseTemplateArgumentLoc(tstl.getArgLoc(I))) + { + ReturnValue = false; + } + } + } + } + } + + if (ReturnValue) + { + if (!TraverseNestedNameSpecifierLoc(D->getQualifierLoc())) + { + ReturnValue = false; + } + } + + if (ReturnValue && ShouldVisitChildren) + { + traverseDeclContextHelper(clang::dyn_cast(D)); + } + + if (ReturnValue && shouldTraversePostOrder()) + { + if (!WalkUpFromClassTemplateSpecializationDecl(D)) + { + return false; + } + } + + FOREACH_COMPONENT(endTraverseClassTemplateSpecializationDecl(D)); + + return ReturnValue; + } + DEF_TRAVERSE_TYPE_PTR(ClassTemplatePartialSpecializationDecl, {}, {}) DEF_TRAVERSE_TYPE_PTR(DeclRefExpr, {}, {}) DEF_TRAVERSE_TYPE_PTR(CXXForRangeStmt, {}, {}) diff --git a/src/test/CxxParserTestSuite.h b/src/test/CxxParserTestSuite.h index 555129b3..4abae419 100644 --- a/src/test/CxxParserTestSuite.h +++ b/src/test/CxxParserTestSuite.h @@ -3508,8 +3508,7 @@ public: "};\n" ); - TS_ASSERT_EQUALS(client->typeUses.size(), 2); // TODO: this should be 1, so fix the bug where explicit specialization records a typeuse on self - // TODO: FIXME: type uses: L"A<1> -> A<1> <6:7 6:7>" + TS_ASSERT_EQUALS(client->typeUses.size(), 1); } void test_cxx_parser_finds_no_template_argument_for_builtin_non_type_bool_template_parameter_of_explicit_template_specialization() @@ -3525,7 +3524,7 @@ public: "};\n" ); - TS_ASSERT_EQUALS(client->typeUses.size(), 2); // TODO: this should be 1, so fix the bug where explicit specialization records a typeuse on self + TS_ASSERT_EQUALS(client->typeUses.size(), 1); } void test_cxx_parser_finds_non_type_custom_pointer_template_argument_of_explicit_template_specialization()