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