logic: fix recording template parameter as local symbol instead of qualifier (#824)

This commit is contained in:
Malte Langkabel
2019-12-16 15:53:59 +01:00
committed by Eberhard Graether
parent 362aefaa16
commit 7a48136017
2 changed files with 49 additions and 12 deletions
@@ -75,7 +75,7 @@ void CxxAstVisitorComponentIndexer::beginTraverseNestedNameSpecifierLoc(
if (symbolKind != SYMBOL_KIND_MAX)
{
Id symbolId = getOrCreateSymbolId(recordDecl);
const Id symbolId = getOrCreateSymbolId(recordDecl);
m_client->recordSymbolKind(symbolId, symbolKind);
m_client->recordLocation(
symbolId, getParseLocation(loc.getLocalBeginLoc()), ParseLocationType::QUALIFIER);
@@ -83,9 +83,22 @@ void CxxAstVisitorComponentIndexer::beginTraverseNestedNameSpecifierLoc(
}
else if (const clang::Type* type = loc.getNestedNameSpecifier()->getAsType())
{
Id symbolId = getOrCreateSymbolId(type);
m_client->recordLocation(
symbolId, getParseLocation(loc.getLocalBeginLoc()), ParseLocationType::QUALIFIER);
const ParseLocation parseLocation = getParseLocation(loc.getLocalBeginLoc());
if (const clang::TemplateTypeParmType* tpt =
clang::dyn_cast_or_null<clang::TemplateTypeParmType>(type))
{
clang::TemplateTypeParmDecl* d = tpt->getDecl();
if (d)
{
m_client->recordLocalSymbol(getLocalSymbolName(d->getLocation()), parseLocation);
}
}
else
{
const Id symbolId = getOrCreateSymbolId(type);
m_client->recordLocation(symbolId, parseLocation, ParseLocationType::QUALIFIER);
}
}
}
}
@@ -104,10 +117,16 @@ void CxxAstVisitorComponentIndexer::beginTraverseTemplateArgumentLoc(
const ParseLocation parseLocation = getParseLocation(loc.getLocation());
if (templateTemplateArgumentName.isDependent())
{
m_client->recordLocalSymbol(
getLocalSymbolName(
templateTemplateArgumentName.getAsTemplateDecl()->getLocation()),
parseLocation);
clang::SourceLocation declLocation;
if (templateTemplateArgumentName.getAsTemplateDecl())
{
declLocation = templateTemplateArgumentName.getAsTemplateDecl()->getLocation();
}
else
{
declLocation = loc.getLocation();
}
m_client->recordLocalSymbol(getLocalSymbolName(declLocation), parseLocation);
}
else
{
@@ -343,8 +362,9 @@ void CxxAstVisitorComponentIndexer::visitFunctionDecl(clang::FunctionDecl* d)
->isExplicitSpecialization())
{
// record edge from Foo<int>::bar<float>() to Foo<T>::bar<U>() instead of recording
// an edge from Foo<int>::bar<float>() to Foo<int>::bar<U>() because there is not "written"
// code for Foo<int>::bar<U>() if Foo<int> is an implicit template specialization.
// an edge from Foo<int>::bar<float>() to Foo<int>::bar<U>() because there is not
// "written" code for Foo<int>::bar<U>() if Foo<int> is an implicit template
// specialization.
if (clang::CXXRecordDecl* declaringRecordDecl =
clang::dyn_cast_or_null<clang::CXXRecordDecl>(d->getParent()))
{
+19 -2
View File
@@ -844,8 +844,8 @@ TEST_CASE("cxx parser finds template argument of dependent non type template par
// );
// TS_ASSERT(utility::containsElement<std::wstring>(
// client->typeUses, // TODO: record edge between vector<int, Alloc<int>> and Alloc<int> (this is
//an issue because we dont have any typeloc for this edge -.-
// client->typeUses, // TODO: record edge between vector<int, Alloc<int>> and Alloc<int> (this
//is an issue because we dont have any typeloc for this edge -.-
// ));
//}
@@ -2621,6 +2621,23 @@ TEST_CASE("cxx parser finds typedef in other class that depends on own template
client->typeUses, L"B<int>::type f -> B<int>::type <13:9 13:12>"));
}
TEST_CASE("cxx parser finds usage of template parameter in qualifier of other symbol")
{
std::shared_ptr<TestIntermediateStorage> client = parseCode(
"template <typename T>\n"
"struct find_if_impl;\n"
"\n"
"template <typename R, typename S>\n"
"struct find_if\n"
"{\n"
" template <typename... Ts>\n"
" using f = typename find_if_impl<S>::template f<R::template f, Ts...>;\n"
"};\n");
REQUIRE(utility::containsElement<std::wstring>(
client->localSymbols, L"input.cc<4:20> <8:49 8:49>"));
}
TEST_CASE("cxx parser finds use of dependent template specialization type")
{
std::shared_ptr<TestIntermediateStorage> client = parseCode(