logic: fix recording template parameter as local symbol instead of qualifier (#824)
This commit is contained in:
committed by
Eberhard Graether
parent
362aefaa16
commit
7a48136017
@@ -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()))
|
||||
{
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user