diff --git a/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.cpp b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.cpp index a0333024..d2cd6158 100644 --- a/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.cpp +++ b/src/lib_cxx/data/parser/cxx/CxxAstVisitorComponentIndexer.cpp @@ -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(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::bar() to Foo::bar() instead of recording - // an edge from Foo::bar() to Foo::bar() because there is not "written" - // code for Foo::bar() if Foo is an implicit template specialization. + // an edge from Foo::bar() to Foo::bar() because there is not + // "written" code for Foo::bar() if Foo is an implicit template + // specialization. if (clang::CXXRecordDecl* declaringRecordDecl = clang::dyn_cast_or_null(d->getParent())) { diff --git a/src/test/CxxParserTestSuite.cpp b/src/test/CxxParserTestSuite.cpp index 2a2026f6..c158ff9e 100644 --- a/src/test/CxxParserTestSuite.cpp +++ b/src/test/CxxParserTestSuite.cpp @@ -844,8 +844,8 @@ TEST_CASE("cxx parser finds template argument of dependent non type template par // ); // TS_ASSERT(utility::containsElement( -// client->typeUses, // TODO: record edge between vector> and Alloc (this is -//an issue because we dont have any typeloc for this edge -.- +// client->typeUses, // TODO: record edge between vector> and Alloc (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::type f -> B::type <13:9 13:12>")); } +TEST_CASE("cxx parser finds usage of template parameter in qualifier of other symbol") +{ + std::shared_ptr client = parseCode( + "template \n" + "struct find_if_impl;\n" + "\n" + "template \n" + "struct find_if\n" + "{\n" + " template \n" + " using f = typename find_if_impl::template f;\n" + "};\n"); + + REQUIRE(utility::containsElement( + 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 client = parseCode(