sammccall updated this revision to Diff 229910. sammccall added a comment. add fixme
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70325/new/ https://reviews.llvm.org/D70325 Files: clang-tools-extra/clangd/AST.cpp clang-tools-extra/clangd/AST.h clang-tools-extra/clangd/XRefs.cpp clang-tools-extra/clangd/unittests/XRefsTests.cpp
Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -910,16 +910,15 @@ }}, // Constructor of partially-specialized class template {R"cpp( - template<typename> struct X; + template<typename, typename=void> struct X; template<typename T> struct X<T*>{ [[^X]](); }; )cpp", [](HoverInfo &HI) { HI.NamespaceScope = ""; HI.Name = "X"; - HI.LocalScope = "X::"; // FIXME: Should be X<T *>:: + HI.LocalScope = "X<T *>::"; // FIXME: X<T *, void>:: HI.Kind = SymbolKind::Constructor; - HI.Type = "void ()"; // FIXME: Should be None - HI.ReturnType = "void"; // FIXME: Should be None or X<T*> + HI.ReturnType = "X<T *>"; HI.Definition = "X()"; HI.Parameters.emplace(); }}, @@ -1020,8 +1019,8 @@ HI.Type = "enum Color"; HI.Value = "1"; }}, - // FIXME: We should use the Decl referenced, even if it comes from an - // implicit instantiation. + // FIXME: We should use the Decl referenced, even if from an implicit + // instantiation. Then the scope would be Add<1, 2> and the value 3. {R"cpp( template<int a, int b> struct Add { static constexpr int result = a + b; @@ -1034,7 +1033,7 @@ HI.Kind = SymbolKind::Property; HI.Type = "const int"; HI.NamespaceScope = ""; - HI.LocalScope = "Add::"; + HI.LocalScope = "Add<a, b>::"; }}, {R"cpp( const char *[[ba^r]] = "1234"; Index: clang-tools-extra/clangd/XRefs.cpp =================================================================== --- clang-tools-extra/clangd/XRefs.cpp +++ clang-tools-extra/clangd/XRefs.cpp @@ -414,12 +414,12 @@ static std::string getLocalScope(const Decl *D) { std::vector<std::string> Scopes; const DeclContext *DC = D->getDeclContext(); - auto GetName = [](const Decl *D) { - const NamedDecl *ND = dyn_cast<NamedDecl>(D); - std::string Name = ND->getNameAsString(); - // FIXME(sammccall): include template params/specialization args?. - if (!Name.empty()) - return Name; + auto GetName = [](const TypeDecl *D) { + if (!D->getDeclName().isEmpty()) { + PrintingPolicy Policy = D->getASTContext().getPrintingPolicy(); + Policy.SuppressScope = true; + return declaredType(D).getAsString(Policy); + } if (auto RD = dyn_cast<RecordDecl>(D)) return ("(anonymous " + RD->getKindName() + ")").str(); return std::string(""); @@ -566,6 +566,51 @@ Req, [&](const Symbol &S) { Hover.Documentation = S.Documentation; }); } +// Populates Type, ReturnType, and Parameters for function-like decls. +static void fillFunctionTypeAndParams(HoverInfo &HI, const Decl *D, + const FunctionDecl *FD, + const PrintingPolicy &Policy) { + HI.Parameters.emplace(); + for (const ParmVarDecl *PVD : FD->parameters()) { + HI.Parameters->emplace_back(); + auto &P = HI.Parameters->back(); + if (!PVD->getType().isNull()) { + P.Type.emplace(); + llvm::raw_string_ostream OS(*P.Type); + PVD->getType().print(OS, Policy); + } else { + std::string Param; + llvm::raw_string_ostream OS(Param); + PVD->dump(OS); + OS.flush(); + elog("Got param with null type: {0}", Param); + } + if (!PVD->getName().empty()) + P.Name = PVD->getNameAsString(); + if (PVD->hasDefaultArg()) { + P.Default.emplace(); + llvm::raw_string_ostream Out(*P.Default); + PVD->getDefaultArg()->printPretty(Out, nullptr, Policy); + } + } + + if (const auto* CCD = llvm::dyn_cast<CXXConstructorDecl>(FD)) { + // Constructor's "return type" is the class type. + HI.ReturnType = declaredType(CCD->getParent()).getAsString(Policy); + // Don't provide any type for the constructor itself. + } else if (const auto* CDD = llvm::dyn_cast<CXXDestructorDecl>(FD)){ + HI.ReturnType = "void"; + } else { + HI.ReturnType = FD->getReturnType().getAsString(Policy); + + QualType FunctionType = FD->getType(); + if (const VarDecl *VD = llvm::dyn_cast<VarDecl>(D)) // Lambdas + FunctionType = VD->getType().getDesugaredType(D->getASTContext()); + HI.Type = FunctionType.getAsString(Policy); + } + // FIXME: handle variadics. +} + /// Generate a \p Hover object given the declaration \p D. static HoverInfo getHoverContents(const Decl *D, const SymbolIndex *Index) { HoverInfo HI; @@ -601,45 +646,7 @@ // Fill in types and params. if (const FunctionDecl *FD = getUnderlyingFunction(D)) { - HI.ReturnType.emplace(); - { - llvm::raw_string_ostream OS(*HI.ReturnType); - FD->getReturnType().print(OS, Policy); - } - - HI.Parameters.emplace(); - for (const ParmVarDecl *PVD : FD->parameters()) { - HI.Parameters->emplace_back(); - auto &P = HI.Parameters->back(); - if (!PVD->getType().isNull()) { - P.Type.emplace(); - llvm::raw_string_ostream OS(*P.Type); - PVD->getType().print(OS, Policy); - } else { - std::string Param; - llvm::raw_string_ostream OS(Param); - PVD->dump(OS); - OS.flush(); - elog("Got param with null type: {0}", Param); - } - if (!PVD->getName().empty()) - P.Name = PVD->getNameAsString(); - if (PVD->hasDefaultArg()) { - P.Default.emplace(); - llvm::raw_string_ostream Out(*P.Default); - PVD->getDefaultArg()->printPretty(Out, nullptr, Policy); - } - } - - HI.Type.emplace(); - llvm::raw_string_ostream TypeOS(*HI.Type); - // Lambdas - if (const VarDecl *VD = llvm::dyn_cast<VarDecl>(D)) - VD->getType().getDesugaredType(D->getASTContext()).print(TypeOS, Policy); - // Functions - else - FD->getType().print(TypeOS, Policy); - // FIXME: handle variadics. + fillFunctionTypeAndParams(HI, D, FD, Policy); } else if (const auto *VD = dyn_cast<ValueDecl>(D)) { HI.Type.emplace(); llvm::raw_string_ostream OS(*HI.Type); Index: clang-tools-extra/clangd/AST.h =================================================================== --- clang-tools-extra/clangd/AST.h +++ clang-tools-extra/clangd/AST.h @@ -111,6 +111,11 @@ /// void foo() -> returns null NestedNameSpecifierLoc getQualifierLoc(const NamedDecl &ND); +// Returns a type corresponding to a declaration of that type. +// Unlike the method on ASTContext, attempts to preserve the type as-written +// (i.e. vector<T*> rather than vector<type-parameter-0-0 *>. +QualType declaredType(const TypeDecl *D); + } // namespace clangd } // namespace clang Index: clang-tools-extra/clangd/AST.cpp =================================================================== --- clang-tools-extra/clangd/AST.cpp +++ clang-tools-extra/clangd/AST.cpp @@ -246,6 +246,12 @@ printNamespaceScope(Context) ); } +QualType declaredType(const TypeDecl *D) { + if (const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D)) + if (const auto *TSI = CTSD->getTypeAsWritten()) + return TSI->getType(); + return D->getASTContext().getTypeDeclType(D); +} } // namespace clangd } // namespace clang
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits