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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits