[clang-tools-extra] r358273 - [clangd] Add TemplateArgumentList into Symbol

Kadir Cetinkaya via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 12 03:09:24 PDT 2019


Author: kadircet
Date: Fri Apr 12 03:09:24 2019
New Revision: 358273

URL: http://llvm.org/viewvc/llvm-project?rev=358273&view=rev
Log:
[clangd] Add TemplateArgumentList into Symbol

Summary:
Part of re-landing rC356541 with 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.

Reviewers: ioeric, ilya-biryukov, gribozavr

Subscribers: MaskRay, jkorous, arphaman, jdoerfert, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D59640

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

Modified: clang-tools-extra/trunk/clangd/index/Serialization.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Serialization.cpp?rev=358273&r1=358272&r2=358273&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/Serialization.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/Serialization.cpp Fri Apr 12 03:09:24 2019
@@ -282,6 +282,7 @@ void writeSymbol(const Symbol &Sym, cons
   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.TemplateSpecializationArgs), OS);
   writeLocation(Sym.Definition, Strings, OS);
   writeLocation(Sym.CanonicalDeclaration, Strings, OS);
   writeVar(Sym.References, OS);
@@ -309,6 +310,7 @@ Symbol readSymbol(Reader &Data, llvm::Ar
   Sym.SymInfo.Lang = static_cast<index::SymbolLanguage>(Data.consume8());
   Sym.Name = Data.consumeString(Strings);
   Sym.Scope = Data.consumeString(Strings);
+  Sym.TemplateSpecializationArgs = Data.consumeString(Strings);
   Sym.Definition = readLocation(Data, Strings);
   Sym.CanonicalDeclaration = readLocation(Data, Strings);
   Sym.References = Data.consumeVar();

Modified: clang-tools-extra/trunk/clangd/index/Symbol.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Symbol.h?rev=358273&r1=358272&r2=358273&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/Symbol.h (original)
+++ clang-tools-extra/trunk/clangd/index/Symbol.h Fri Apr 12 03:09:24 2019
@@ -63,6 +63,10 @@ struct Symbol {
   /// candidate list. For example, "(X x, Y y) const" is a function signature.
   /// Only set when the symbol is indexed for completion.
   llvm::StringRef Signature;
+  /// 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 TemplateSpecializationArgs;
   /// What to insert when completing this symbol, after the symbol name.
   /// This is in LSP snippet syntax (e.g. "({$0})" for a no-args function).
   /// (When snippets are disabled, the symbol name alone is used).
@@ -143,6 +147,7 @@ llvm::raw_ostream &operator<<(llvm::raw_
 template <typename Callback> void visitStrings(Symbol &S, const Callback &CB) {
   CB(S.Name);
   CB(S.Scope);
+  CB(S.TemplateSpecializationArgs);
   CB(S.Signature);
   CB(S.CompletionSnippetSuffix);
   CB(S.Documentation);

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=358273&r1=358272&r2=358273&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/SymbolCollector.cpp Fri Apr 12 03:09:24 2019
@@ -524,9 +524,11 @@ const Symbol *SymbolCollector::addDeclar
   Symbol S;
   S.ID = std::move(ID);
   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:
   // for consistency with CodeCompletionString and a clean name/signature split.
+  std::tie(S.Scope, S.Name) = splitQualifiedName(QName);
+  std::string TemplateSpecializationArgs = printTemplateSpecializationArgs(ND);
+  S.TemplateSpecializationArgs = TemplateSpecializationArgs;
 
   // We collect main-file symbols, but do not use them for code completion.
   if (!IsMainFileOnly && isIndexedForCodeCompletion(ND, Ctx))

Modified: clang-tools-extra/trunk/clangd/index/YAMLSerialization.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/YAMLSerialization.cpp?rev=358273&r1=358272&r2=358273&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/YAMLSerialization.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/YAMLSerialization.cpp Fri Apr 12 03:09:24 2019
@@ -193,6 +193,8 @@ template <> struct MappingTraits<Symbol>
     IO.mapOptional("Origin", NSymbolOrigin->Origin);
     IO.mapOptional("Flags", NSymbolFlag->Flag);
     IO.mapOptional("Signature", Sym.Signature);
+    IO.mapOptional("TemplateSpecializationArgs",
+                   Sym.TemplateSpecializationArgs);
     IO.mapOptional("CompletionSnippetSuffix", Sym.CompletionSnippetSuffix);
     IO.mapOptional("Documentation", Sym.Documentation);
     IO.mapOptional("ReturnType", Sym.ReturnType);

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=358273&r1=358272&r2=358273&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp (original)
+++ clang-tools-extra/trunk/unittests/clangd/SymbolCollectorTests.cpp Fri Apr 12 03:09:24 2019
@@ -51,6 +51,9 @@ MATCHER_P(Snippet, S, "") {
   return (arg.Name + arg.CompletionSnippetSuffix).str() == S;
 }
 MATCHER_P(QName, Name, "") { return (arg.Scope + arg.Name).str() == Name; }
+MATCHER_P(TemplateArgs, TemplArgs, "") {
+  return arg.TemplateSpecializationArgs == TemplArgs;
+}
 MATCHER_P(DeclURI, P, "") {
   return StringRef(arg.CanonicalDeclaration.FileURI) == P;
 }
@@ -412,6 +415,71 @@ TEST_F(SymbolCollectorTest, Template) {
                         ForCodeCompletion(false))));
 }
 
+TEST_F(SymbolCollectorTest, TemplateArgs) {
+  Annotations Header(R"(
+    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,
+      AllOf(
+          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)))));
+}
+
 TEST_F(SymbolCollectorTest, ObjCSymbols) {
   const std::string Header = R"(
     @interface Person




More information about the cfe-commits mailing list