kadircet created this revision.
kadircet added reviewers: ioeric, ilya-biryukov, gribozavr.
Herald added subscribers: cfe-commits, jdoerfert, arphaman, jkorous, MaskRay.
Herald added a project: clang.

Part of re-landing rC356541 <https://reviews.llvm.org/rC356541> with D59599 
<https://reviews.llvm.org/D59599>. Changes the way we store
template arguments, previous patch was storing them inside Name field of Symbol.
Which was violating the assumption:

  Symbol::Scope+Symbol::Name == clang::clangd::printQualifiedName

which was made in multiple places inside codebase. This patch instead moves
those arguments into their own field. Currently the field is meant to be
human-readable, can be made structured if need be.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D59640

Files:
  clang-tools-extra/clangd/index/Serialization.cpp
  clang-tools-extra/clangd/index/Symbol.h
  clang-tools-extra/clangd/index/SymbolCollector.cpp
  clang-tools-extra/unittests/clangd/SymbolCollectorTests.cpp

Index: clang-tools-extra/unittests/clangd/SymbolCollectorTests.cpp
===================================================================
--- clang-tools-extra/unittests/clangd/SymbolCollectorTests.cpp
+++ clang-tools-extra/unittests/clangd/SymbolCollectorTests.cpp
@@ -51,6 +51,9 @@
   return (arg.Name + arg.CompletionSnippetSuffix).str() == S;
 }
 MATCHER_P(QName, Name, "") { return (arg.Scope + arg.Name).str() == Name; }
+MATCHER_P(TemplateArgs, TemplArgs, "") {
+  return arg.TemplateArgumentList == TemplArgs;
+}
 MATCHER_P(DeclURI, P, "") {
   return StringRef(arg.CanonicalDeclaration.FileURI) == P;
 }
@@ -394,23 +397,80 @@
   Annotations Header(R"(
     // 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>;
+    template <class X> class $barclasstemp[[Bar]] {};
+    template <class T, class U, template<typename> class Z, int Q>
+    struct [[Tmpl]] { T $xdecl[[x]] = 0; };
+
+    // template-template, non-type and type full spec
+    template <> struct $specdecl[[Tmpl]]<int, bool, Bar, 3> {};
+
+    // template-template, non-type and type partial spec
+    template <class U, int T> struct $partspecdecl[[Tmpl]]<bool, U, Bar, T> {};
+    // instantiation
+    extern template struct Tmpl<float, bool, Bar, 8>;
+    // instantiation
+    template struct Tmpl<double, bool, Bar, 2>;
+
+    template <typename ...> class $fooclasstemp[[Foo]] {};
+    // parameter-packs full spec
+    template<> class $parampack[[Foo]]<Bar<int>, int, double> {};
+    // parameter-packs partial spec
+    template<class T> class $parampackpartial[[Foo]]<T, T> {};
+
+    template <int ...> class $bazclasstemp[[Baz]] {};
+    // non-type parameter-packs full spec
+    template<> class $parampacknontype[[Baz]]<3, 5, 8> {};
+    // non-type parameter-packs partial spec
+    template<int T> class $parampacknontypepartial[[Baz]]<T, T> {};
+
+    template <template <class> class ...> class $fozclasstemp[[Foz]] {};
+    // template-template parameter-packs full spec
+    template<> class $parampacktempltempl[[Foz]]<Bar, Bar> {};
+    // template-template parameter-packs partial spec
+    template<template <class> class T>
+    class $parampacktempltemplpartial[[Foz]]<T, T> {};
   )");
   runSymbolCollector(Header.code(), /*Main=*/"");
-  EXPECT_THAT(Symbols,
-              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))));
+  EXPECT_THAT(Symbols.size(), 14U);
+  EXPECT_THAT(
+      Symbols,
+      AllOf(
+          Contains(AllOf(QName("Tmpl"), DeclRange(Header.range()),
+                         ForCodeCompletion(true))),
+          Contains(AllOf(QName("Bar"), DeclRange(Header.range("barclasstemp")),
+                         ForCodeCompletion(true))),
+          Contains(AllOf(QName("Foo"), DeclRange(Header.range("fooclasstemp")),
+                         ForCodeCompletion(true))),
+          Contains(AllOf(QName("Baz"), DeclRange(Header.range("bazclasstemp")),
+                         ForCodeCompletion(true))),
+          Contains(AllOf(QName("Foz"), DeclRange(Header.range("fozclasstemp")),
+                         ForCodeCompletion(true))),
+          Contains(AllOf(QName("Tmpl"), TemplateArgs("<int, bool, Bar, 3>"),
+                         DeclRange(Header.range("specdecl")),
+                         ForCodeCompletion(false))),
+          Contains(AllOf(QName("Tmpl"), TemplateArgs("<bool, U, Bar, T>"),
+                         DeclRange(Header.range("partspecdecl")),
+                         ForCodeCompletion(false))),
+          Contains(AllOf(QName("Foo"), TemplateArgs("<Bar<int>, int, double>"),
+                         DeclRange(Header.range("parampack")),
+                         ForCodeCompletion(false))),
+          Contains(AllOf(QName("Foo"), TemplateArgs("<T, T>"),
+                         DeclRange(Header.range("parampackpartial")),
+                         ForCodeCompletion(false))),
+          Contains(AllOf(QName("Baz"), TemplateArgs("<3, 5, 8>"),
+                         DeclRange(Header.range("parampacknontype")),
+                         ForCodeCompletion(false))),
+          Contains(AllOf(QName("Baz"), TemplateArgs("<T, T>"),
+                         DeclRange(Header.range("parampacknontypepartial")),
+                         ForCodeCompletion(false))),
+          Contains(AllOf(QName("Foz"), TemplateArgs("<Bar, Bar>"),
+                         DeclRange(Header.range("parampacktempltempl")),
+                         ForCodeCompletion(false))),
+          Contains(AllOf(QName("Foz"), TemplateArgs("<T, T>"),
+                         DeclRange(Header.range("parampacktempltemplpartial")),
+                         ForCodeCompletion(false))),
+          Contains(AllOf(QName("Tmpl::x"), DeclRange(Header.range("xdecl")),
+                         ForCodeCompletion(false)))));
 }
 
 TEST_F(SymbolCollectorTest, ObjCSymbols) {
Index: clang-tools-extra/clangd/index/SymbolCollector.cpp
===================================================================
--- clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -523,6 +523,8 @@
 
   Symbol S;
   S.ID = std::move(ID);
+  std::string TemplateArgumentList = printTemplateArgsAsWritten(ND);
+  S.TemplateArgumentList = TemplateArgumentList;
   std::string QName = printQualifiedName(ND);
   std::tie(S.Scope, S.Name) = splitQualifiedName(QName);
   // FIXME: this returns foo:bar: for objective-C methods, we prefer only foo:
Index: clang-tools-extra/clangd/index/Symbol.h
===================================================================
--- clang-tools-extra/clangd/index/Symbol.h
+++ clang-tools-extra/clangd/index/Symbol.h
@@ -42,6 +42,10 @@
   llvm::StringRef Name;
   /// The containing namespace. e.g. "" (global), "ns::" (top-level namespace).
   llvm::StringRef Scope;
+  /// Argument list in human-readable format, will be displayed to help
+  /// disambiguate between different specializations of a template. Empty for
+  /// non-specializations. Example: "<int, bool, 3>"
+  llvm::StringRef TemplateArgumentList;
   /// The location of the symbol's definition, if one was found.
   /// This just covers the symbol name (e.g. without class/function body).
   SymbolLocation Definition;
@@ -143,6 +147,7 @@
 template <typename Callback> void visitStrings(Symbol &S, const Callback &CB) {
   CB(S.Name);
   CB(S.Scope);
+  CB(S.TemplateArgumentList);
   CB(S.Signature);
   CB(S.CompletionSnippetSuffix);
   CB(S.Documentation);
Index: clang-tools-extra/clangd/index/Serialization.cpp
===================================================================
--- clang-tools-extra/clangd/index/Serialization.cpp
+++ clang-tools-extra/clangd/index/Serialization.cpp
@@ -282,6 +282,7 @@
   OS.write(static_cast<uint8_t>(Sym.SymInfo.Lang));
   writeVar(Strings.index(Sym.Name), OS);
   writeVar(Strings.index(Sym.Scope), OS);
+  writeVar(Strings.index(Sym.TemplateArgumentList), OS);
   writeLocation(Sym.Definition, Strings, OS);
   writeLocation(Sym.CanonicalDeclaration, Strings, OS);
   writeVar(Sym.References, OS);
@@ -309,6 +310,7 @@
   Sym.SymInfo.Lang = static_cast<index::SymbolLanguage>(Data.consume8());
   Sym.Name = Data.consumeString(Strings);
   Sym.Scope = Data.consumeString(Strings);
+  Sym.TemplateArgumentList = Data.consumeString(Strings);
   Sym.Definition = readLocation(Data, Strings);
   Sym.CanonicalDeclaration = readLocation(Data, Strings);
   Sym.References = Data.consumeVar();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to