logic: fix recording template parameter as local symbol instead of qualifier (#824)
This commit is contained in:
@@ -75,7 +75,7 @@ void CxxAstVisitorComponentIndexer::beginTraverseNestedNameSpecifierLoc(
|
|||||||
|
|
||||||
if (symbolKind != SYMBOL_KIND_MAX)
|
if (symbolKind != SYMBOL_KIND_MAX)
|
||||||
{
|
{
|
||||||
Id symbolId = getOrCreateSymbolId(recordDecl);
|
const Id symbolId = getOrCreateSymbolId(recordDecl);
|
||||||
m_client->recordSymbolKind(symbolId, symbolKind);
|
m_client->recordSymbolKind(symbolId, symbolKind);
|
||||||
m_client->recordLocation(
|
m_client->recordLocation(
|
||||||
symbolId, getParseLocation(loc.getLocalBeginLoc()), ParseLocationType::QUALIFIER);
|
symbolId, getParseLocation(loc.getLocalBeginLoc()), ParseLocationType::QUALIFIER);
|
||||||
@@ -83,9 +83,22 @@ void CxxAstVisitorComponentIndexer::beginTraverseNestedNameSpecifierLoc(
|
|||||||
}
|
}
|
||||||
else if (const clang::Type* type = loc.getNestedNameSpecifier()->getAsType())
|
else if (const clang::Type* type = loc.getNestedNameSpecifier()->getAsType())
|
||||||
{
|
{
|
||||||
Id symbolId = getOrCreateSymbolId(type);
|
const ParseLocation parseLocation = getParseLocation(loc.getLocalBeginLoc());
|
||||||
m_client->recordLocation(
|
|
||||||
symbolId, getParseLocation(loc.getLocalBeginLoc()), ParseLocationType::QUALIFIER);
|
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());
|
const ParseLocation parseLocation = getParseLocation(loc.getLocation());
|
||||||
if (templateTemplateArgumentName.isDependent())
|
if (templateTemplateArgumentName.isDependent())
|
||||||
{
|
{
|
||||||
m_client->recordLocalSymbol(
|
clang::SourceLocation declLocation;
|
||||||
getLocalSymbolName(
|
if (templateTemplateArgumentName.getAsTemplateDecl())
|
||||||
templateTemplateArgumentName.getAsTemplateDecl()->getLocation()),
|
{
|
||||||
parseLocation);
|
declLocation = templateTemplateArgumentName.getAsTemplateDecl()->getLocation();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
declLocation = loc.getLocation();
|
||||||
|
}
|
||||||
|
m_client->recordLocalSymbol(getLocalSymbolName(declLocation), parseLocation);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -343,8 +362,9 @@ void CxxAstVisitorComponentIndexer::visitFunctionDecl(clang::FunctionDecl* d)
|
|||||||
->isExplicitSpecialization())
|
->isExplicitSpecialization())
|
||||||
{
|
{
|
||||||
// record edge from Foo<int>::bar<float>() to Foo<T>::bar<U>() instead of recording
|
// 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"
|
// an edge from Foo<int>::bar<float>() to Foo<int>::bar<U>() because there is not
|
||||||
// code for Foo<int>::bar<U>() if Foo<int> is an implicit template specialization.
|
// "written" code for Foo<int>::bar<U>() if Foo<int> is an implicit template
|
||||||
|
// specialization.
|
||||||
if (clang::CXXRecordDecl* declaringRecordDecl =
|
if (clang::CXXRecordDecl* declaringRecordDecl =
|
||||||
clang::dyn_cast_or_null<clang::CXXRecordDecl>(d->getParent()))
|
clang::dyn_cast_or_null<clang::CXXRecordDecl>(d->getParent()))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -844,8 +844,8 @@ TEST_CASE("cxx parser finds template argument of dependent non type template par
|
|||||||
// );
|
// );
|
||||||
|
|
||||||
// TS_ASSERT(utility::containsElement<std::wstring>(
|
// TS_ASSERT(utility::containsElement<std::wstring>(
|
||||||
// client->typeUses, // TODO: record edge between vector<int, Alloc<int>> and Alloc<int> (this is
|
// client->typeUses, // TODO: record edge between vector<int, Alloc<int>> and Alloc<int> (this
|
||||||
//an issue because we dont have any typeloc for this edge -.-
|
//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>"));
|
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")
|
TEST_CASE("cxx parser finds use of dependent template specialization type")
|
||||||
{
|
{
|
||||||
std::shared_ptr<TestIntermediateStorage> client = parseCode(
|
std::shared_ptr<TestIntermediateStorage> client = parseCode(
|
||||||
|
|||||||
Reference in New Issue
Block a user