[clang-tools-extra] [clangd] Support symbolTags for document symbol (PR #113669)

via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 29 19:10:55 PST 2024


https://github.com/chouzz updated https://github.com/llvm/llvm-project/pull/113669

>From 02124e4cfd7dbc395d4974c7561d5f110980aaa5 Mon Sep 17 00:00:00 2001
From: chouzz <zhouhua258 at outlook.com>
Date: Fri, 25 Oct 2024 17:42:04 +0800
Subject: [PATCH 1/5] [clangd] Support symbolTags for document symbol

---
 clang-tools-extra/clangd/AST.cpp              | 63 ++++++++++++++
 clang-tools-extra/clangd/AST.h                | 31 +++++++
 clang-tools-extra/clangd/FindSymbols.cpp      | 30 +++++++
 clang-tools-extra/clangd/Protocol.h           | 29 ++++++-
 .../clangd/SemanticHighlighting.cpp           | 85 -------------------
 5 files changed, 151 insertions(+), 87 deletions(-)

diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp
index f3eee1c6335f98..52578699b159b8 100644
--- a/clang-tools-extra/clangd/AST.cpp
+++ b/clang-tools-extra/clangd/AST.cpp
@@ -169,6 +169,69 @@ bool isImplementationDetail(const Decl *D) {
                             D->getASTContext().getSourceManager());
 }
 
+// Whether T is const in a loose sense - is a variable with this type readonly?
+bool isConst(QualType T) {
+  if (T.isNull())
+    return false;
+  T = T.getNonReferenceType();
+  if (T.isConstQualified())
+    return true;
+  if (const auto *AT = T->getAsArrayTypeUnsafe())
+    return isConst(AT->getElementType());
+  if (isConst(T->getPointeeType()))
+    return true;
+  return false;
+}
+
+bool isConst(const Decl *D) {
+  if (llvm::isa<EnumConstantDecl>(D) || llvm::isa<NonTypeTemplateParmDecl>(D))
+    return true;
+  if (llvm::isa<FieldDecl>(D) || llvm::isa<VarDecl>(D) ||
+      llvm::isa<MSPropertyDecl>(D) || llvm::isa<BindingDecl>(D)) {
+    if (isConst(llvm::cast<ValueDecl>(D)->getType()))
+      return true;
+  }
+  if (const auto *OCPD = llvm::dyn_cast<ObjCPropertyDecl>(D)) {
+    if (OCPD->isReadOnly())
+      return true;
+  }
+  if (const auto *MPD = llvm::dyn_cast<MSPropertyDecl>(D)) {
+    if (!MPD->hasSetter())
+      return true;
+  }
+  if (const auto *CMD = llvm::dyn_cast<CXXMethodDecl>(D)) {
+    if (CMD->isConst())
+      return true;
+  }
+  return false;
+}
+
+bool isStatic(const Decl *D) {
+  if (const auto *CMD = llvm::dyn_cast<CXXMethodDecl>(D))
+    return CMD->isStatic();
+  if (const VarDecl *VD = llvm::dyn_cast<VarDecl>(D))
+    return VD->isStaticDataMember() || VD->isStaticLocal();
+  if (const auto *OPD = llvm::dyn_cast<ObjCPropertyDecl>(D))
+    return OPD->isClassProperty();
+  if (const auto *OMD = llvm::dyn_cast<ObjCMethodDecl>(D))
+    return OMD->isClassMethod();
+  return false;
+}
+
+bool isAbstract(const Decl *D) {
+  if (const auto *CMD = llvm::dyn_cast<CXXMethodDecl>(D))
+    return CMD->isPureVirtual();
+  if (const auto *CRD = llvm::dyn_cast<CXXRecordDecl>(D))
+    return CRD->hasDefinition() && CRD->isAbstract();
+  return false;
+}
+
+bool isVirtual(const Decl *D) {
+  if (const auto *CMD = llvm::dyn_cast<CXXMethodDecl>(D))
+    return CMD->isVirtual();
+  return false;
+}
+
 SourceLocation nameLocation(const clang::Decl &D, const SourceManager &SM) {
   auto L = D.getLocation();
   // For `- (void)foo` we want `foo` not the `-`.
diff --git a/clang-tools-extra/clangd/AST.h b/clang-tools-extra/clangd/AST.h
index fb0722d697cd06..b7eb7ddedc1666 100644
--- a/clang-tools-extra/clangd/AST.h
+++ b/clang-tools-extra/clangd/AST.h
@@ -152,6 +152,37 @@ bool isImplicitTemplateInstantiation(const NamedDecl *D);
 ///   explicit specialization.
 bool isExplicitTemplateSpecialization(const NamedDecl *D);
 
+// Whether T is const in a loose sense - is a variable with this type readonly?
+bool isConst(QualType T);
+
+// Whether D is const in a loose sense (should it be highlighted as such?)
+// FIXME: This is separate from whether *a particular usage* can mutate D.
+//        We may want V in V.size() to be readonly even if V is mutable.
+bool isConst(const Decl *D);
+
+// "Static" means many things in C++, only some get the "static" modifier.
+//
+// Meanings that do:
+// - Members associated with the class rather than the instance.
+//   This is what 'static' most often means across languages.
+// - static local variables
+//   These are similarly "detached from their context" by the static keyword.
+//   In practice, these are rarely used inside classes, reducing confusion.
+//
+// Meanings that don't:
+// - Namespace-scoped variables, which have static storage class.
+//   This is implicit, so the keyword "static" isn't so strongly associated.
+//   If we want a modifier for these, "global scope" is probably the concept.
+// - Namespace-scoped variables/functions explicitly marked "static".
+//   There the keyword changes *linkage* , which is a totally different concept.
+//   If we want to model this, "file scope" would be a nice modifier.
+//
+// This is confusing, and maybe we should use another name, but because "static"
+// is a standard LSP modifier, having one with that name has advantages.
+bool isStatic(const Decl *D);
+bool isAbstract(const Decl *D);
+bool isVirtual(const Decl *D);
+
 /// Returns a nested name specifier loc of \p ND if it was present in the
 /// source, e.g.
 ///     void ns::something::foo() -> returns 'ns::something'
diff --git a/clang-tools-extra/clangd/FindSymbols.cpp b/clang-tools-extra/clangd/FindSymbols.cpp
index 84bcbc1f2ddd3f..adb9b63fdca7e3 100644
--- a/clang-tools-extra/clangd/FindSymbols.cpp
+++ b/clang-tools-extra/clangd/FindSymbols.cpp
@@ -187,6 +187,35 @@ std::string getSymbolName(ASTContext &Ctx, const NamedDecl &ND) {
   return printName(Ctx, ND);
 }
 
+std::vector<SymbolTag> getSymbolTags(const NamedDecl &ND)
+{
+  std::vector<SymbolTag> Tags;
+  if (ND.isDeprecated()) 
+    Tags.push_back(SymbolTag::Deprecated);
+  if (isConst(&ND)) 
+      Tags.push_back(SymbolTag::Constant);
+  if (isStatic(&ND)) 
+      Tags.push_back(SymbolTag::Static);
+  if (const FieldDecl *FD = dyn_cast<FieldDecl>(&ND)) {
+    switch (FD->getAccess()) {
+      case AS_public:
+        Tags.push_back(SymbolTag::Public);
+        break;
+      case AS_protected:
+        Tags.push_back(SymbolTag::Protected);
+        break;
+      case AS_private:
+        Tags.push_back(SymbolTag::Private);
+        break;
+      default:
+        break;
+    }
+  } 
+  if (isVirtual(&ND))
+      Tags.push_back(SymbolTag::Virtual);
+  return Tags;
+}
+
 std::string getSymbolDetail(ASTContext &Ctx, const NamedDecl &ND) {
   PrintingPolicy P(Ctx.getPrintingPolicy());
   P.SuppressScope = true;
@@ -241,6 +270,7 @@ std::optional<DocumentSymbol> declToSym(ASTContext &Ctx, const NamedDecl &ND) {
   SI.range = Range{sourceLocToPosition(SM, SymbolRange->getBegin()),
                    sourceLocToPosition(SM, SymbolRange->getEnd())};
   SI.detail = getSymbolDetail(Ctx, ND);
+  SI.tags = getSymbolTags(ND);
 
   SourceLocation NameLoc = ND.getLocation();
   SourceLocation FallbackNameLoc;
diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h
index 5b28095758198d..48d8c81d4ad0ce 100644
--- a/clang-tools-extra/clangd/Protocol.h
+++ b/clang-tools-extra/clangd/Protocol.h
@@ -1090,6 +1090,30 @@ struct CodeAction {
 };
 llvm::json::Value toJSON(const CodeAction &);
 
+enum class SymbolTag { 
+  Deprecated = 1 ,
+  Private = 2,
+  Package = 3,
+  Protected = 4,
+  Public = 5,
+  Internal= 6,
+  File = 7,
+  Static = 8,
+  Abstract = 9,
+  Final = 10,
+  Sealed = 11,
+  Constant = 12,
+  Transient = 13,
+  Volatile = 14,
+  Synchronized = 15,
+  Virtual = 16,
+  Nullable = 17,
+  NonNull = 18,
+  Declaration = 19,
+  Definition = 20,
+  ReadOnly = 21,
+};
+llvm::json::Value toJSON(SymbolTag);
 /// Represents programming constructs like variables, classes, interfaces etc.
 /// that appear in a document. Document symbols can be hierarchical and they
 /// have two ranges: one that encloses its definition and one that points to its
@@ -1107,6 +1131,9 @@ struct DocumentSymbol {
   /// Indicates if this symbol is deprecated.
   bool deprecated = false;
 
+  /// Tags for this symbol, e.g public, private, static, const etc.
+  std::vector<SymbolTag> tags;
+
   /// The range enclosing this symbol not including leading/trailing whitespace
   /// but everything else like comments. This information is typically used to
   /// determine if the clients cursor is inside the symbol to reveal in the
@@ -1558,8 +1585,6 @@ struct ResolveTypeHierarchyItemParams {
 bool fromJSON(const llvm::json::Value &, ResolveTypeHierarchyItemParams &,
               llvm::json::Path);
 
-enum class SymbolTag { Deprecated = 1 };
-llvm::json::Value toJSON(SymbolTag);
 
 /// The parameter of a `textDocument/prepareCallHierarchy` request.
 struct CallHierarchyPrepareParams : public TextDocumentPositionParams {};
diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index e6d16af2495fec..035bd75c59bb59 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -192,91 +192,6 @@ std::optional<HighlightingKind> kindForType(const Type *TP,
   return std::nullopt;
 }
 
-// Whether T is const in a loose sense - is a variable with this type readonly?
-bool isConst(QualType T) {
-  if (T.isNull())
-    return false;
-  T = T.getNonReferenceType();
-  if (T.isConstQualified())
-    return true;
-  if (const auto *AT = T->getAsArrayTypeUnsafe())
-    return isConst(AT->getElementType());
-  if (isConst(T->getPointeeType()))
-    return true;
-  return false;
-}
-
-// Whether D is const in a loose sense (should it be highlighted as such?)
-// FIXME: This is separate from whether *a particular usage* can mutate D.
-//        We may want V in V.size() to be readonly even if V is mutable.
-bool isConst(const Decl *D) {
-  if (llvm::isa<EnumConstantDecl>(D) || llvm::isa<NonTypeTemplateParmDecl>(D))
-    return true;
-  if (llvm::isa<FieldDecl>(D) || llvm::isa<VarDecl>(D) ||
-      llvm::isa<MSPropertyDecl>(D) || llvm::isa<BindingDecl>(D)) {
-    if (isConst(llvm::cast<ValueDecl>(D)->getType()))
-      return true;
-  }
-  if (const auto *OCPD = llvm::dyn_cast<ObjCPropertyDecl>(D)) {
-    if (OCPD->isReadOnly())
-      return true;
-  }
-  if (const auto *MPD = llvm::dyn_cast<MSPropertyDecl>(D)) {
-    if (!MPD->hasSetter())
-      return true;
-  }
-  if (const auto *CMD = llvm::dyn_cast<CXXMethodDecl>(D)) {
-    if (CMD->isConst())
-      return true;
-  }
-  return false;
-}
-
-// "Static" means many things in C++, only some get the "static" modifier.
-//
-// Meanings that do:
-// - Members associated with the class rather than the instance.
-//   This is what 'static' most often means across languages.
-// - static local variables
-//   These are similarly "detached from their context" by the static keyword.
-//   In practice, these are rarely used inside classes, reducing confusion.
-//
-// Meanings that don't:
-// - Namespace-scoped variables, which have static storage class.
-//   This is implicit, so the keyword "static" isn't so strongly associated.
-//   If we want a modifier for these, "global scope" is probably the concept.
-// - Namespace-scoped variables/functions explicitly marked "static".
-//   There the keyword changes *linkage* , which is a totally different concept.
-//   If we want to model this, "file scope" would be a nice modifier.
-//
-// This is confusing, and maybe we should use another name, but because "static"
-// is a standard LSP modifier, having one with that name has advantages.
-bool isStatic(const Decl *D) {
-  if (const auto *CMD = llvm::dyn_cast<CXXMethodDecl>(D))
-    return CMD->isStatic();
-  if (const VarDecl *VD = llvm::dyn_cast<VarDecl>(D))
-    return VD->isStaticDataMember() || VD->isStaticLocal();
-  if (const auto *OPD = llvm::dyn_cast<ObjCPropertyDecl>(D))
-    return OPD->isClassProperty();
-  if (const auto *OMD = llvm::dyn_cast<ObjCMethodDecl>(D))
-    return OMD->isClassMethod();
-  return false;
-}
-
-bool isAbstract(const Decl *D) {
-  if (const auto *CMD = llvm::dyn_cast<CXXMethodDecl>(D))
-    return CMD->isPureVirtual();
-  if (const auto *CRD = llvm::dyn_cast<CXXRecordDecl>(D))
-    return CRD->hasDefinition() && CRD->isAbstract();
-  return false;
-}
-
-bool isVirtual(const Decl *D) {
-  if (const auto *CMD = llvm::dyn_cast<CXXMethodDecl>(D))
-    return CMD->isVirtual();
-  return false;
-}
-
 bool isDependent(const Decl *D) {
   if (isa<UnresolvedUsingValueDecl>(D))
     return true;

>From 5b77f732f6de70bc7b5eaee459ef600843cf5f63 Mon Sep 17 00:00:00 2001
From: chouzz <zhouhua258 at outlook.com>
Date: Mon, 28 Oct 2024 20:14:15 +0800
Subject: [PATCH 2/5] Fix access for class method

---
 clang-tools-extra/clangd/FindSymbols.cpp          | 6 ++++--
 clang-tools-extra/clangd/Protocol.cpp             | 2 ++
 clang-tools-extra/clangd/SemanticHighlighting.cpp | 1 +
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/clangd/FindSymbols.cpp b/clang-tools-extra/clangd/FindSymbols.cpp
index adb9b63fdca7e3..3a782506d3b54e 100644
--- a/clang-tools-extra/clangd/FindSymbols.cpp
+++ b/clang-tools-extra/clangd/FindSymbols.cpp
@@ -196,6 +196,9 @@ std::vector<SymbolTag> getSymbolTags(const NamedDecl &ND)
       Tags.push_back(SymbolTag::Constant);
   if (isStatic(&ND)) 
       Tags.push_back(SymbolTag::Static);
+  if (isVirtual(&ND))
+      Tags.push_back(SymbolTag::Virtual);
+  
   if (const FieldDecl *FD = dyn_cast<FieldDecl>(&ND)) {
     switch (FD->getAccess()) {
       case AS_public:
@@ -211,8 +214,7 @@ std::vector<SymbolTag> getSymbolTags(const NamedDecl &ND)
         break;
     }
   } 
-  if (isVirtual(&ND))
-      Tags.push_back(SymbolTag::Virtual);
+  
   return Tags;
 }
 
diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp
index 295ccd26a40454..8805c05ae4d13d 100644
--- a/clang-tools-extra/clangd/Protocol.cpp
+++ b/clang-tools-extra/clangd/Protocol.cpp
@@ -901,6 +901,8 @@ llvm::json::Value toJSON(const DocumentSymbol &S) {
     Result["children"] = S.children;
   if (S.deprecated)
     Result["deprecated"] = true;
+  if (!S.tags.empty())
+    Result["tags"] = S.tags;
   // FIXME: workaround for older gcc/clang
   return std::move(Result);
 }
diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index 035bd75c59bb59..10b96589c350c8 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "SemanticHighlighting.h"
+#include "AST.h"
 #include "Config.h"
 #include "FindTarget.h"
 #include "HeuristicResolver.h"

>From b5b3a7e3d583cedcc8cc21c8d2189288e9f2fd1e Mon Sep 17 00:00:00 2001
From: chouzz <zhouhua258 at outlook.com>
Date: Thu, 31 Oct 2024 19:47:47 +0800
Subject: [PATCH 3/5] Support Declaration and Definition tags

---
 clang-tools-extra/clangd/AST.cpp              | 17 +++++++
 clang-tools-extra/clangd/AST.h                |  2 +-
 clang-tools-extra/clangd/FindSymbols.cpp      | 46 ++++++++++---------
 .../clangd/SemanticHighlighting.cpp           | 17 -------
 4 files changed, 42 insertions(+), 40 deletions(-)

diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp
index 52578699b159b8..0f11945bc2d5be 100644
--- a/clang-tools-extra/clangd/AST.cpp
+++ b/clang-tools-extra/clangd/AST.cpp
@@ -232,6 +232,23 @@ bool isVirtual(const Decl *D) {
   return false;
 }
 
+bool isUniqueDefinition(const NamedDecl *Decl) {
+  if (auto *Func = dyn_cast<FunctionDecl>(Decl))
+    return Func->isThisDeclarationADefinition();
+  if (auto *Klass = dyn_cast<CXXRecordDecl>(Decl))
+    return Klass->isThisDeclarationADefinition();
+  if (auto *Iface = dyn_cast<ObjCInterfaceDecl>(Decl))
+    return Iface->isThisDeclarationADefinition();
+  if (auto *Proto = dyn_cast<ObjCProtocolDecl>(Decl))
+    return Proto->isThisDeclarationADefinition();
+  if (auto *Var = dyn_cast<VarDecl>(Decl))
+    return Var->isThisDeclarationADefinition();
+  return isa<TemplateTypeParmDecl>(Decl) ||
+         isa<NonTypeTemplateParmDecl>(Decl) ||
+         isa<TemplateTemplateParmDecl>(Decl) || isa<ObjCCategoryDecl>(Decl) ||
+         isa<ObjCImplDecl>(Decl);
+}
+
 SourceLocation nameLocation(const clang::Decl &D, const SourceManager &SM) {
   auto L = D.getLocation();
   // For `- (void)foo` we want `foo` not the `-`.
diff --git a/clang-tools-extra/clangd/AST.h b/clang-tools-extra/clangd/AST.h
index b7eb7ddedc1666..09bd979cb8649e 100644
--- a/clang-tools-extra/clangd/AST.h
+++ b/clang-tools-extra/clangd/AST.h
@@ -182,7 +182,7 @@ bool isConst(const Decl *D);
 bool isStatic(const Decl *D);
 bool isAbstract(const Decl *D);
 bool isVirtual(const Decl *D);
-
+bool isUniqueDefinition(const NamedDecl *Decl);
 /// Returns a nested name specifier loc of \p ND if it was present in the
 /// source, e.g.
 ///     void ns::something::foo() -> returns 'ns::something'
diff --git a/clang-tools-extra/clangd/FindSymbols.cpp b/clang-tools-extra/clangd/FindSymbols.cpp
index 3a782506d3b54e..0800eda47171e5 100644
--- a/clang-tools-extra/clangd/FindSymbols.cpp
+++ b/clang-tools-extra/clangd/FindSymbols.cpp
@@ -187,34 +187,36 @@ std::string getSymbolName(ASTContext &Ctx, const NamedDecl &ND) {
   return printName(Ctx, ND);
 }
 
-std::vector<SymbolTag> getSymbolTags(const NamedDecl &ND)
-{
+std::vector<SymbolTag> getSymbolTags(const NamedDecl &ND) {
   std::vector<SymbolTag> Tags;
-  if (ND.isDeprecated()) 
+  if (ND.isDeprecated())
     Tags.push_back(SymbolTag::Deprecated);
-  if (isConst(&ND)) 
-      Tags.push_back(SymbolTag::Constant);
-  if (isStatic(&ND)) 
-      Tags.push_back(SymbolTag::Static);
+  if (isConst(&ND))
+    Tags.push_back(SymbolTag::Constant);
+  if (isStatic(&ND))
+    Tags.push_back(SymbolTag::Static);
   if (isVirtual(&ND))
-      Tags.push_back(SymbolTag::Virtual);
-  
+    Tags.push_back(SymbolTag::Virtual);
+  if (!isa<UnresolvedUsingValueDecl>(ND))
+    Tags.push_back(SymbolTag::Declaration);
+  if (isUniqueDefinition(&ND))
+    Tags.push_back(SymbolTag::Definition);
   if (const FieldDecl *FD = dyn_cast<FieldDecl>(&ND)) {
     switch (FD->getAccess()) {
-      case AS_public:
-        Tags.push_back(SymbolTag::Public);
-        break;
-      case AS_protected:
-        Tags.push_back(SymbolTag::Protected);
-        break;
-      case AS_private:
-        Tags.push_back(SymbolTag::Private);
-        break;
-      default:
-        break;
+    case AS_public:
+      Tags.push_back(SymbolTag::Public);
+      break;
+    case AS_protected:
+      Tags.push_back(SymbolTag::Protected);
+      break;
+    case AS_private:
+      Tags.push_back(SymbolTag::Private);
+      break;
+    default:
+      break;
     }
-  } 
-  
+  }
+
   return Tags;
 }
 
diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index 10b96589c350c8..6597be81040b26 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -78,23 +78,6 @@ bool canHighlightName(DeclarationName Name) {
   llvm_unreachable("invalid name kind");
 }
 
-bool isUniqueDefinition(const NamedDecl *Decl) {
-  if (auto *Func = dyn_cast<FunctionDecl>(Decl))
-    return Func->isThisDeclarationADefinition();
-  if (auto *Klass = dyn_cast<CXXRecordDecl>(Decl))
-    return Klass->isThisDeclarationADefinition();
-  if (auto *Iface = dyn_cast<ObjCInterfaceDecl>(Decl))
-    return Iface->isThisDeclarationADefinition();
-  if (auto *Proto = dyn_cast<ObjCProtocolDecl>(Decl))
-    return Proto->isThisDeclarationADefinition();
-  if (auto *Var = dyn_cast<VarDecl>(Decl))
-    return Var->isThisDeclarationADefinition();
-  return isa<TemplateTypeParmDecl>(Decl) ||
-         isa<NonTypeTemplateParmDecl>(Decl) ||
-         isa<TemplateTemplateParmDecl>(Decl) || isa<ObjCCategoryDecl>(Decl) ||
-         isa<ObjCImplDecl>(Decl);
-}
-
 std::optional<HighlightingKind> kindForType(const Type *TP,
                                             const HeuristicResolver *Resolver);
 std::optional<HighlightingKind> kindForDecl(const NamedDecl *D,

>From 2d8224260143899f9af9a99465318da05d04722f Mon Sep 17 00:00:00 2001
From: chouzz <zhouhua258 at outlook.com>
Date: Mon, 18 Nov 2024 14:43:14 +0800
Subject: [PATCH 4/5] Remove constant tag

---
 clang-tools-extra/clangd/AST.cpp         |  4 +++
 clang-tools-extra/clangd/FindSymbols.cpp | 36 +++++++++++++-----------
 clang-tools-extra/clangd/Protocol.h      | 21 +++++++-------
 3 files changed, 33 insertions(+), 28 deletions(-)

diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp
index 0f11945bc2d5be..a234155a371913 100644
--- a/clang-tools-extra/clangd/AST.cpp
+++ b/clang-tools-extra/clangd/AST.cpp
@@ -203,6 +203,8 @@ bool isConst(const Decl *D) {
     if (CMD->isConst())
       return true;
   }
+  if (const auto *FD = llvm::dyn_cast<FunctionDecl>(D))
+    return isConst(FD->getReturnType());
   return false;
 }
 
@@ -215,6 +217,8 @@ bool isStatic(const Decl *D) {
     return OPD->isClassProperty();
   if (const auto *OMD = llvm::dyn_cast<ObjCMethodDecl>(D))
     return OMD->isClassMethod();
+  if (const auto *FD = llvm::dyn_cast<FunctionDecl>(D))
+    return FD->isStatic();
   return false;
 }
 
diff --git a/clang-tools-extra/clangd/FindSymbols.cpp b/clang-tools-extra/clangd/FindSymbols.cpp
index 0800eda47171e5..384e0db82d2284 100644
--- a/clang-tools-extra/clangd/FindSymbols.cpp
+++ b/clang-tools-extra/clangd/FindSymbols.cpp
@@ -192,29 +192,31 @@ std::vector<SymbolTag> getSymbolTags(const NamedDecl &ND) {
   if (ND.isDeprecated())
     Tags.push_back(SymbolTag::Deprecated);
   if (isConst(&ND))
-    Tags.push_back(SymbolTag::Constant);
+    Tags.push_back(SymbolTag::ReadOnly);
   if (isStatic(&ND))
     Tags.push_back(SymbolTag::Static);
   if (isVirtual(&ND))
     Tags.push_back(SymbolTag::Virtual);
-  if (!isa<UnresolvedUsingValueDecl>(ND))
-    Tags.push_back(SymbolTag::Declaration);
+  if (isAbstract(&ND))
+    Tags.push_back(SymbolTag::Abstract);
+
   if (isUniqueDefinition(&ND))
     Tags.push_back(SymbolTag::Definition);
-  if (const FieldDecl *FD = dyn_cast<FieldDecl>(&ND)) {
-    switch (FD->getAccess()) {
-    case AS_public:
-      Tags.push_back(SymbolTag::Public);
-      break;
-    case AS_protected:
-      Tags.push_back(SymbolTag::Protected);
-      break;
-    case AS_private:
-      Tags.push_back(SymbolTag::Private);
-      break;
-    default:
-      break;
-    }
+  else if (!isa<UnresolvedUsingValueDecl>(ND))
+    Tags.push_back(SymbolTag::Declaration);
+
+  switch (ND.getAccess()) {
+  case AS_public:
+    Tags.push_back(SymbolTag::Public);
+    break;
+  case AS_protected:
+    Tags.push_back(SymbolTag::Protected);
+    break;
+  case AS_private:
+    Tags.push_back(SymbolTag::Private);
+    break;
+  default:
+    break;
   }
 
   return Tags;
diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h
index 48d8c81d4ad0ce..fb43439695faca 100644
--- a/clang-tools-extra/clangd/Protocol.h
+++ b/clang-tools-extra/clangd/Protocol.h
@@ -1091,7 +1091,7 @@ struct CodeAction {
 llvm::json::Value toJSON(const CodeAction &);
 
 enum class SymbolTag { 
-  Deprecated = 1 ,
+  Deprecated = 1,
   Private = 2,
   Package = 3,
   Protected = 4,
@@ -1102,16 +1102,15 @@ enum class SymbolTag {
   Abstract = 9,
   Final = 10,
   Sealed = 11,
-  Constant = 12,
-  Transient = 13,
-  Volatile = 14,
-  Synchronized = 15,
-  Virtual = 16,
-  Nullable = 17,
-  NonNull = 18,
-  Declaration = 19,
-  Definition = 20,
-  ReadOnly = 21,
+  Transient = 12,
+  Volatile = 13,
+  Synchronized = 14,
+  Virtual = 15,
+  Nullable = 16,
+  NonNull = 17,
+  Declaration = 18,
+  Definition = 19,
+  ReadOnly = 20,
 };
 llvm::json::Value toJSON(SymbolTag);
 /// Represents programming constructs like variables, classes, interfaces etc.

>From 0f6d25b82fc6bbd191cebd61943defe5da2e3814 Mon Sep 17 00:00:00 2001
From: chouzz <zhouhua258 at outlook.com>
Date: Sat, 30 Nov 2024 11:10:32 +0800
Subject: [PATCH 5/5] Remove Constant tag

---
 clang-tools-extra/clangd/Protocol.h | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h
index fb43439695faca..d93ccf61ac0dcc 100644
--- a/clang-tools-extra/clangd/Protocol.h
+++ b/clang-tools-extra/clangd/Protocol.h
@@ -1102,15 +1102,16 @@ enum class SymbolTag {
   Abstract = 9,
   Final = 10,
   Sealed = 11,
-  Transient = 12,
-  Volatile = 13,
-  Synchronized = 14,
-  Virtual = 15,
-  Nullable = 16,
-  NonNull = 17,
-  Declaration = 18,
-  Definition = 19,
-  ReadOnly = 20,
+  Constant = 12,
+  Transient = 13,
+  Volatile = 14,
+  Synchronized = 15,
+  Virtual = 16,
+  Nullable = 17,
+  NonNull = 18,
+  Declaration = 19,
+  Definition = 20,
+  ReadOnly = 21,
 };
 llvm::json::Value toJSON(SymbolTag);
 /// Represents programming constructs like variables, classes, interfaces etc.



More information about the cfe-commits mailing list