kadircet updated this revision to Diff 191460. kadircet marked 2 inline comments as done. kadircet added a comment.
- Address comments Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D59354/new/ https://reviews.llvm.org/D59354 Files: clang-tools-extra/clangd/AST.cpp clang-tools-extra/clangd/index/MemIndex.cpp clang-tools-extra/clangd/index/dex/Dex.cpp clang-tools-extra/unittests/clangd/DexTests.cpp clang-tools-extra/unittests/clangd/IndexTests.cpp clang-tools-extra/unittests/clangd/SymbolCollectorTests.cpp clang/lib/AST/TypePrinter.cpp
Index: clang/lib/AST/TypePrinter.cpp =================================================================== --- clang/lib/AST/TypePrinter.cpp +++ clang/lib/AST/TypePrinter.cpp @@ -1632,6 +1632,21 @@ return A.getArgument(); } +static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP, + llvm::raw_ostream &OS) { + A.print(PP, OS); +} + +static void printArgument(const TemplateArgumentLoc &A, + const PrintingPolicy &PP, llvm::raw_ostream &OS) { + const auto &Kind = A.getArgument().getKind(); + assert(Kind != TemplateArgument::Null && + "TemplateArgumentKind can not be null!"); + if (Kind == TemplateArgument::ArgKind::Type) + return A.getTypeSourceInfo()->getType().print(OS, PP); + return A.getArgument().print(PP, OS); +} + template<typename TA> static void printTo(raw_ostream &OS, ArrayRef<TA> Args, const PrintingPolicy &Policy, bool SkipBrackets) { @@ -1653,7 +1668,7 @@ } else { if (!FirstArg) OS << Comma; - Argument.print(Policy, ArgOS); + printArgument(Arg, Policy, ArgOS); } StringRef ArgString = ArgOS.str(); Index: clang-tools-extra/unittests/clangd/SymbolCollectorTests.cpp =================================================================== --- clang-tools-extra/unittests/clangd/SymbolCollectorTests.cpp +++ clang-tools-extra/unittests/clangd/SymbolCollectorTests.cpp @@ -394,23 +394,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<int, bool, Bar, 3>"), + DeclRange(Header.range("specdecl")), + ForCodeCompletion(false))), + Contains(AllOf(QName("Tmpl<bool, U, Bar, T>"), + DeclRange(Header.range("partspecdecl")), + ForCodeCompletion(false))), + Contains(AllOf(QName("Foo<Bar<int>, int, double>"), + DeclRange(Header.range("parampack")), + ForCodeCompletion(false))), + Contains(AllOf(QName("Foo<T, T>"), + DeclRange(Header.range("parampackpartial")), + ForCodeCompletion(false))), + Contains(AllOf(QName("Baz<3, 5, 8>"), + DeclRange(Header.range("parampacknontype")), + ForCodeCompletion(false))), + Contains(AllOf(QName("Baz<T, T>"), + DeclRange(Header.range("parampacknontypepartial")), + ForCodeCompletion(false))), + Contains(AllOf(QName("Foz<Bar, Bar>"), + DeclRange(Header.range("parampacktempltempl")), + ForCodeCompletion(false))), + Contains(AllOf(QName("Foz<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/unittests/clangd/IndexTests.cpp =================================================================== --- clang-tools-extra/unittests/clangd/IndexTests.cpp +++ clang-tools-extra/unittests/clangd/IndexTests.cpp @@ -187,35 +187,30 @@ SymbolSlab::Builder B; Symbol S = symbol("TempSpec"); - S.ID = SymbolID("0"); B.insert(S); - S = symbol("TempSpec"); - S.ID = SymbolID("1"); + S = symbol("TempSpec<int, bool>"); S.SymInfo.Properties = static_cast<index::SymbolPropertySet>( index::SymbolProperty::TemplateSpecialization); B.insert(S); - S = symbol("TempSpec"); - S.ID = SymbolID("2"); + S = symbol("TempSpec<int, U>"); 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)); + Req.Query = "TempSpec"; + EXPECT_THAT(match(*I, Req), + UnorderedElementsAre("TempSpec", "TempSpec<int, bool>", + "TempSpec<int, U>")); + + Req.Query = "TempSpec<int"; + EXPECT_THAT(match(*I, Req), + UnorderedElementsAre("TempSpec<int, bool>", "TempSpec<int, U>")); } TEST(MergeIndexTest, Lookup) { Index: clang-tools-extra/unittests/clangd/DexTests.cpp =================================================================== --- clang-tools-extra/unittests/clangd/DexTests.cpp +++ clang-tools-extra/unittests/clangd/DexTests.cpp @@ -714,35 +714,30 @@ SymbolSlab::Builder B; Symbol S = symbol("TempSpec"); - S.ID = SymbolID("0"); B.insert(S); - S = symbol("TempSpec"); - S.ID = SymbolID("1"); + S = symbol("TempSpec<int, bool>"); S.SymInfo.Properties = static_cast<index::SymbolPropertySet>( index::SymbolProperty::TemplateSpecialization); B.insert(S); - S = symbol("TempSpec"); - S.ID = SymbolID("2"); + S = symbol("TempSpec<int, U>"); 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)); + Req.Query = "TempSpec"; + EXPECT_THAT(match(*I, Req), + UnorderedElementsAre("TempSpec", "TempSpec<int, bool>", + "TempSpec<int, U>")); + + Req.Query = "TempSpec<int"; + EXPECT_THAT(match(*I, Req), + UnorderedElementsAre("TempSpec<int, bool>", "TempSpec<int, U>")); } } // namespace Index: clang-tools-extra/clangd/index/dex/Dex.cpp =================================================================== --- clang-tools-extra/clangd/index/dex/Dex.cpp +++ clang-tools-extra/clangd/index/dex/Dex.cpp @@ -86,15 +86,6 @@ 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); } Index: clang-tools-extra/clangd/index/MemIndex.cpp =================================================================== --- clang-tools-extra/clangd/index/MemIndex.cpp +++ clang-tools-extra/clangd/index/MemIndex.cpp @@ -38,15 +38,6 @@ 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; Index: clang-tools-extra/clangd/AST.cpp =================================================================== --- clang-tools-extra/clangd/AST.cpp +++ clang-tools-extra/clangd/AST.cpp @@ -11,9 +11,12 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/TemplateBase.h" +#include "clang/AST/TypeLoc.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Index/USRGeneration.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ScopedPrinter.h" @@ -50,6 +53,22 @@ return SM.getSpellingLoc(D->getLocation()); } +static llvm::Optional<llvm::ArrayRef<TemplateArgumentLoc>> +getTemplateSpecializationArgLocs(const NamedDecl &ND) { + if (auto *Func = llvm::dyn_cast<FunctionDecl>(&ND)) { + if (auto *Args = Func->getTemplateSpecializationArgsAsWritten()) + return Args->arguments(); + } else if (auto *Cls = + llvm::dyn_cast<ClassTemplatePartialSpecializationDecl>(&ND)) { + if (auto *Args = Cls->getTemplateArgsAsWritten()) + return Args->arguments(); + } else if (auto *Var = llvm::dyn_cast<VarTemplateSpecializationDecl>(&ND)) + return Var->getTemplateArgsInfo().arguments(); + // We return None for ClassTemplateSpecializationDecls because it does not + // contain TemplateArgumentLoc information. + return llvm::None; +} + std::string printQualifiedName(const NamedDecl &ND) { std::string QName; llvm::raw_string_ostream OS(QName); @@ -60,6 +79,19 @@ // namespaces to query: the preamble doesn't have a dedicated list. Policy.SuppressUnwrittenScope = true; ND.printQualifiedName(OS, Policy); + if (auto Args = getTemplateSpecializationArgLocs(ND)) + printTemplateArgumentList(OS, *Args, Policy); + else if (auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND)) { + if (auto STL = Cls->getTypeAsWritten() + ->getTypeLoc() + .getAs<TemplateSpecializationTypeLoc>()) { + llvm::SmallVector<TemplateArgumentLoc, 8> ArgLocs; + ArgLocs.reserve(STL.getNumArgs()); + for (unsigned I = 0; I < STL.getNumArgs(); ++I) + ArgLocs.push_back(STL.getArgLoc(I)); + printTemplateArgumentList(OS, ArgLocs, Policy); + } + } OS.flush(); assert(!StringRef(QName).startswith("::")); return QName;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits