logic: template related fixes

* fixed recording template member specializations of methods as explicit nodes
* fixed template members variables sometimes recorded as functions with call edges
This commit is contained in:
mlangkabel
2017-11-06 17:11:15 +01:00
parent ad20275dae
commit 595f918f4d
14 changed files with 75 additions and 46 deletions
@@ -593,6 +593,7 @@ DEF_VISIT_TYPE_PTR(TemplateTemplateParmDecl)
DEF_VISIT_TYPE(TypeLoc)
DEF_VISIT_TYPE_PTR(DeclRefExpr)
DEF_VISIT_TYPE_PTR(MemberExpr)
DEF_VISIT_TYPE_PTR(CXXDependentScopeMemberExpr)
DEF_VISIT_TYPE_PTR(CXXConstructExpr)
DEF_VISIT_TYPE_PTR(LambdaExpr)
DEF_VISIT_CUSTOM_TYPE_PTR(ConstructorInitializer, CXXCtorInitializer)
@@ -134,6 +134,7 @@ public:
virtual bool VisitDeclRefExpr(clang::DeclRefExpr* s);
virtual bool VisitMemberExpr(clang::MemberExpr* s);
virtual bool VisitCXXDependentScopeMemberExpr(clang::CXXDependentScopeMemberExpr* s);
virtual bool VisitCXXConstructExpr(clang::CXXConstructExpr* s);
virtual bool VisitLambdaExpr(clang::LambdaExpr* s);
virtual bool VisitConstructorInitializer(clang::CXXCtorInitializer* init);
@@ -113,6 +113,7 @@ DEF_TRAVERSE_TYPE_PTR(CXXTemporaryObjectExpr)
virtual void visitInitListExpr(clang::InitListExpr* s) {}
virtual void visitDeclRefExpr(clang::DeclRefExpr* s) {}
virtual void visitMemberExpr(clang::MemberExpr* s) {}
virtual void visitCXXDependentScopeMemberExpr(clang::CXXDependentScopeMemberExpr* s) {}
virtual void visitCXXConstructExpr(clang::CXXConstructExpr* s) {}
virtual void visitLambdaExpr(clang::LambdaExpr* s) {}
@@ -164,6 +164,11 @@ void CxxAstVisitorComponentDeclRefKind::visitMemberExpr(clang::MemberExpr* s)
m_childRefKind = REFERENCE_USAGE;
}
void CxxAstVisitorComponentDeclRefKind::visitCXXDependentScopeMemberExpr(clang::CXXDependentScopeMemberExpr* s)
{
m_childRefKind = REFERENCE_USAGE;
}
void CxxAstVisitorComponentDeclRefKind::saveAll()
{
m_oldThisRefKinds.push_back(m_thisRefKind);
@@ -63,6 +63,8 @@ public:
virtual void visitMemberExpr(clang::MemberExpr* s);
virtual void visitCXXDependentScopeMemberExpr(clang::CXXDependentScopeMemberExpr* s);
private:
void saveAll();
void restoreAll();
@@ -32,10 +32,18 @@ bool utility::isImplicit(const clang::Decl* d)
}
else if (const clang::FunctionDecl* fd = clang::dyn_cast_or_null<clang::FunctionDecl>(d))
{
if (fd->isTemplateInstantiation() && fd->getTemplateSpecializationKind() != clang::TSK_ExplicitSpecialization) // or undefined??
if (
fd->isTemplateInstantiation() &&
fd->getTemplateSpecializationKind() != clang::TSK_ExplicitSpecialization) // or undefined??
{
return true;
}
else if (
fd->getMemberSpecializationInfo() &&
fd->getMemberSpecializationInfo()->getTemplateSpecializationKind() == clang::TSK_ExplicitSpecialization)
{
return false;
}
}
return isImplicit(clang::dyn_cast_or_null<clang::Decl>(d->getDeclContext()));
+20
View File
@@ -2156,6 +2156,26 @@ public:
));
}
void test_cxx_parser_finds_usage_of_member_in_dependent_scope_member_expression()
{
std::shared_ptr<TestParserClient> client = parseCode(
"template <typename T>\n"
"class A\n"
"{\n"
" T m_t;\n"
"\n"
" void foo()\n"
" {\n"
" m_t.run();\n"
" }\n"
"};\n"
);
TS_ASSERT(utility::containsElement<std::string>(
client->usages, "void A<typename T>::foo() -> A<typename T>::T A<typename T>::m_t <8:3 8:5>"
));
}
void test_cxx_parser_finds_return_type_use_in_function()
{
std::shared_ptr<TestParserClient> client = parseCode(