[clang-tools-extra] r356125 - [clangd] Store explicit template specializations in index for code navigation purposes
Kadir Cetinkaya via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 14 01:35:17 PDT 2019
Author: kadircet
Date: Thu Mar 14 01:35:17 2019
New Revision: 356125
URL: http://llvm.org/viewvc/llvm-project?rev=356125&view=rev
Log:
[clangd] Store explicit template specializations in index for code navigation purposes
Summary:
This introduces ~4k new symbols, and ~10k refs for LLVM. We need that
information for providing better code navigation support:
- When references for a class template is requested, we should return these specializations as well.
- When children of a specialization is requested, we should be able to query for those symbols(instead of just class template)
Number of symbols: 378574 -> 382784
Number of refs: 5098857 -> 5110689
Reviewers: hokein, gribozavr
Reviewed By: gribozavr
Subscribers: nridge, ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59083
Modified:
clang-tools-extra/trunk/clangd/CodeComplete.cpp
clang-tools-extra/trunk/clangd/index/MemIndex.cpp
clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp
clang-tools-extra/trunk/clangd/index/dex/Dex.cpp
clang-tools-extra/trunk/unittests/clangd/DexTests.cpp
clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp
clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp
Modified: clang-tools-extra/trunk/clangd/CodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CodeComplete.cpp?rev=356125&r1=356124&r2=356125&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/CodeComplete.cpp (original)
+++ clang-tools-extra/trunk/clangd/CodeComplete.cpp Thu Mar 14 01:35:17 2019
@@ -1510,6 +1510,13 @@ private:
}
};
+template <class T> bool isExplicitTemplateSpecialization(const NamedDecl &ND) {
+ if (const auto *TD = dyn_cast<T>(&ND))
+ if (TD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
+ return true;
+ return false;
+}
+
} // namespace
clang::CodeCompleteOptions CodeCompleteOptions::getClangCompleteOpts() const {
@@ -1603,6 +1610,13 @@ bool isIndexedForCodeCompletion(const Na
};
return false;
};
+ // We only complete symbol's name, which is the same as the name of the
+ // *primary* template in case of template specializations.
+ if (isExplicitTemplateSpecialization<FunctionDecl>(ND) ||
+ isExplicitTemplateSpecialization<CXXRecordDecl>(ND) ||
+ isExplicitTemplateSpecialization<VarDecl>(ND))
+ return false;
+
if (InTopLevelScope(ND))
return true;
Modified: clang-tools-extra/trunk/clangd/index/MemIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/MemIndex.cpp?rev=356125&r1=356124&r2=356125&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/MemIndex.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/MemIndex.cpp Thu Mar 14 01:35:17 2019
@@ -11,6 +11,7 @@
#include "Logger.h"
#include "Quality.h"
#include "Trace.h"
+#include "clang/Index/IndexSymbol.h"
namespace clang {
namespace clangd {
@@ -37,6 +38,15 @@ bool MemIndex::fuzzyFind(
for (const auto Pair : Index) {
const Symbol *Sym = Pair.second;
+ // FIXME: Enable fuzzy find on template specializations once we start
+ // storing template arguments in the name. Currently we only store name for
+ // class template, which would cause duplication in the results.
+ if (Sym->SymInfo.Properties &
+ (static_cast<index::SymbolPropertySet>(
+ index::SymbolProperty::TemplateSpecialization) |
+ static_cast<index::SymbolPropertySet>(
+ index::SymbolProperty::TemplatePartialSpecialization)))
+ continue;
// Exact match against all possible scopes.
if (!Req.AnyScope && !llvm::is_contained(Req.Scopes, Sym->Scope))
continue;
Modified: clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp?rev=356125&r1=356124&r2=356125&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp Thu Mar 14 01:35:17 2019
@@ -221,13 +221,6 @@ RefKind toRefKind(index::SymbolRoleSet R
return static_cast<RefKind>(static_cast<unsigned>(RefKind::All) & Roles);
}
-template <class T> bool explicitTemplateSpecialization(const NamedDecl &ND) {
- if (const auto *TD = dyn_cast<T>(&ND))
- if (TD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
- return true;
- return false;
-}
-
} // namespace
SymbolCollector::SymbolCollector(Options Opts) : Opts(std::move(Opts)) {}
@@ -279,10 +272,6 @@ bool SymbolCollector::shouldCollectSymbo
if (!isa<RecordDecl>(DeclCtx))
return false;
}
- if (explicitTemplateSpecialization<FunctionDecl>(ND) ||
- explicitTemplateSpecialization<CXXRecordDecl>(ND) ||
- explicitTemplateSpecialization<VarDecl>(ND))
- return false;
// Avoid indexing internal symbols in protobuf generated headers.
if (isPrivateProtoDecl(ND))
Modified: clang-tools-extra/trunk/clangd/index/dex/Dex.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/dex/Dex.cpp?rev=356125&r1=356124&r2=356125&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/dex/Dex.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/dex/Dex.cpp Thu Mar 14 01:35:17 2019
@@ -86,6 +86,15 @@ void Dex::buildIndex() {
llvm::DenseMap<Token, std::vector<DocID>> TempInvertedIndex;
for (DocID SymbolRank = 0; SymbolRank < Symbols.size(); ++SymbolRank) {
const auto *Sym = Symbols[SymbolRank];
+ // FIXME: Enable fuzzy find on template specializations once we start
+ // storing template arguments in the name. Currently we only store name for
+ // class template, which would cause duplication in the results.
+ if (Sym->SymInfo.Properties &
+ (static_cast<index::SymbolPropertySet>(
+ index::SymbolProperty::TemplateSpecialization) |
+ static_cast<index::SymbolPropertySet>(
+ index::SymbolProperty::TemplatePartialSpecialization)))
+ continue;
for (const auto &Token : generateSearchTokens(*Sym))
TempInvertedIndex[Token].push_back(SymbolRank);
}
Modified: clang-tools-extra/trunk/unittests/clangd/DexTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/DexTests.cpp?rev=356125&r1=356124&r2=356125&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/DexTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/DexTests.cpp Thu Mar 14 01:35:17 2019
@@ -710,6 +710,41 @@ TEST(DexTest, PreferredTypesBoosting) {
EXPECT_THAT(match(I, Req), ElementsAre("t2"));
}
+TEST(DexTest, TemplateSpecialization) {
+ SymbolSlab::Builder B;
+
+ Symbol S = symbol("TempSpec");
+ S.ID = SymbolID("0");
+ B.insert(S);
+
+ S = symbol("TempSpec");
+ S.ID = SymbolID("1");
+ S.SymInfo.Properties = static_cast<index::SymbolPropertySet>(
+ index::SymbolProperty::TemplateSpecialization);
+ B.insert(S);
+
+ S = symbol("TempSpec");
+ S.ID = SymbolID("2");
+ S.SymInfo.Properties = static_cast<index::SymbolPropertySet>(
+ index::SymbolProperty::TemplatePartialSpecialization);
+ B.insert(S);
+
+ auto I = dex::Dex::build(std::move(B).build(), RefSlab());
+ FuzzyFindRequest Req;
+ Req.Query = "TempSpec";
+ Req.AnyScope = true;
+
+ std::vector<Symbol> Symbols;
+ I->fuzzyFind(Req, [&Symbols](const Symbol &Sym) { Symbols.push_back(Sym); });
+ EXPECT_EQ(Symbols.size(), 1U);
+ EXPECT_FALSE(Symbols.front().SymInfo.Properties &
+ static_cast<index::SymbolPropertySet>(
+ index::SymbolProperty::TemplateSpecialization));
+ EXPECT_FALSE(Symbols.front().SymInfo.Properties &
+ static_cast<index::SymbolPropertySet>(
+ index::SymbolProperty::TemplatePartialSpecialization));
+}
+
} // namespace
} // namespace dex
} // namespace clangd
Modified: clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp?rev=356125&r1=356124&r2=356125&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/IndexTests.cpp Thu Mar 14 01:35:17 2019
@@ -13,6 +13,8 @@
#include "index/Index.h"
#include "index/MemIndex.h"
#include "index/Merge.h"
+#include "index/Symbol.h"
+#include "clang/Index/IndexSymbol.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@@ -181,6 +183,41 @@ TEST(MemIndexTest, Lookup) {
EXPECT_THAT(lookup(*I, SymbolID("ns::nonono")), UnorderedElementsAre());
}
+TEST(MemIndexTest, TemplateSpecialization) {
+ SymbolSlab::Builder B;
+
+ Symbol S = symbol("TempSpec");
+ S.ID = SymbolID("0");
+ B.insert(S);
+
+ S = symbol("TempSpec");
+ S.ID = SymbolID("1");
+ S.SymInfo.Properties = static_cast<index::SymbolPropertySet>(
+ index::SymbolProperty::TemplateSpecialization);
+ B.insert(S);
+
+ S = symbol("TempSpec");
+ S.ID = SymbolID("2");
+ S.SymInfo.Properties = static_cast<index::SymbolPropertySet>(
+ index::SymbolProperty::TemplatePartialSpecialization);
+ B.insert(S);
+
+ auto I = MemIndex::build(std::move(B).build(), RefSlab());
+ FuzzyFindRequest Req;
+ Req.Query = "TempSpec";
+ Req.AnyScope = true;
+
+ std::vector<Symbol> Symbols;
+ I->fuzzyFind(Req, [&Symbols](const Symbol &Sym) { Symbols.push_back(Sym); });
+ EXPECT_EQ(Symbols.size(), 1U);
+ EXPECT_FALSE(Symbols.front().SymInfo.Properties &
+ static_cast<index::SymbolPropertySet>(
+ index::SymbolProperty::TemplateSpecialization));
+ EXPECT_FALSE(Symbols.front().SymInfo.Properties &
+ static_cast<index::SymbolPropertySet>(
+ index::SymbolProperty::TemplatePartialSpecialization));
+}
+
TEST(MergeIndexTest, Lookup) {
auto I = MemIndex::build(generateSymbols({"ns::A", "ns::B"}), RefSlab()),
J = MemIndex::build(generateSymbols({"ns::B", "ns::C"}), RefSlab());
Modified: clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp?rev=356125&r1=356124&r2=356125&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp Thu Mar 14 01:35:17 2019
@@ -392,17 +392,25 @@ TEST_F(SymbolCollectorTest, FileLocal) {
TEST_F(SymbolCollectorTest, Template) {
Annotations Header(R"(
- // Template is indexed, specialization and instantiation is not.
- template <class T> struct [[Tmpl]] {T $xdecl[[x]] = 0;};
- template <> struct Tmpl<int> {};
- extern template struct Tmpl<float>;
- template struct Tmpl<double>;
+ // Primary template and explicit specialization are indexed, instantiation
+ // is not.
+ template <class T, class U> struct [[Tmpl]] {T $xdecl[[x]] = 0;};
+ template <> struct $specdecl[[Tmpl]]<int, bool> {};
+ template <class U> struct $partspecdecl[[Tmpl]]<bool, U> {};
+ extern template struct Tmpl<float, bool>;
+ template struct Tmpl<double, bool>;
)");
runSymbolCollector(Header.code(), /*Main=*/"");
EXPECT_THAT(Symbols,
- UnorderedElementsAreArray(
- {AllOf(QName("Tmpl"), DeclRange(Header.range())),
- AllOf(QName("Tmpl::x"), DeclRange(Header.range("xdecl")))}));
+ UnorderedElementsAre(
+ AllOf(QName("Tmpl"), DeclRange(Header.range()),
+ ForCodeCompletion(true)),
+ AllOf(QName("Tmpl"), DeclRange(Header.range("specdecl")),
+ ForCodeCompletion(false)),
+ AllOf(QName("Tmpl"), DeclRange(Header.range("partspecdecl")),
+ ForCodeCompletion(false)),
+ AllOf(QName("Tmpl::x"), DeclRange(Header.range("xdecl")),
+ ForCodeCompletion(false))));
}
TEST_F(SymbolCollectorTest, ObjCSymbols) {
More information about the cfe-commits
mailing list