[clang-tools-extra] Symbol tags in SymbolInformation, WorkspaceSymbol, CallHierarchyItem and TypeHierarchyItem (PR #170103)

Dimitri Ratz via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 14 04:02:38 PDT 2026


================
@@ -153,6 +202,63 @@ bool isUniqueDefinition(const NamedDecl *Decl) {
          isa<TemplateTemplateParmDecl>(Decl) || isa<ObjCCategoryDecl>(Decl) ||
          isa<ObjCImplDecl>(Decl);
 }
+
+// Filter symbol tags based on the presence of other tags and the kind of
+// symbol. This is needed to avoid redundant tags, e.g. final implies override,
+// override implies virtual, etc.
+SymbolTags filterSymbolTags(const NamedDecl &ND, const SymbolTags ST) {
+  SymbolTags Result = ST;
+
+  if (not isa<CXXMethodDecl>(ND))
+    return Result;
+
+  if (ST & toSymbolTagBitmask(SymbolTag::Overrides)) {
+    // Overrides means that ND overrides an existing implementation of a virtual
+    // method in a base class. If a symbol is marked as Overrides, the tags
+    // Virtual, Declaration and Definition should be removed, as the Overrides
+    // tag implies that the symbol has/is virtual/declaration/definition.
+    Result &= ~toSymbolTagBitmask(SymbolTag::Virtual);
+    Result &= ~toSymbolTagBitmask(SymbolTag::Declaration);
+    Result &= ~toSymbolTagBitmask(SymbolTag::Definition);
+  }
+  if (ST & toSymbolTagBitmask(SymbolTag::Implements)) {
+    // Implements means that ND implements an existing pure virtual method in a
+    // base class. If a symbol is marked as Implements, the tags Virtual,
+    // Declaration, Definition and Overrides should be removed, as the
+    // Implements tag implies that the symbol is virtual, is a declaration, is a
+    // definition, and overrides a method.
+    Result &= ~toSymbolTagBitmask(SymbolTag::Virtual);
+    Result &= ~toSymbolTagBitmask(SymbolTag::Declaration);
+    Result &= ~toSymbolTagBitmask(SymbolTag::Definition);
+    Result &= ~toSymbolTagBitmask(SymbolTag::Overrides);
+  }
+  if (ST & toSymbolTagBitmask(SymbolTag::Virtual)) {
+    // Virtual means that ND is a virtual method that does not override any
+    // method in a base class. If a symbol is marked as Virtual, the tags
+    // Declaration and Definition should be removed, as the Virtual tag implies
+    // that the symbol is a declaration/definition.
+    Result &= ~toSymbolTagBitmask(SymbolTag::Declaration);
+    Result &= ~toSymbolTagBitmask(SymbolTag::Definition);
+  }
+  if (ST & toSymbolTagBitmask(SymbolTag::Abstract)) {
+    // Abstract means that ND is a pure virtual method. If a symbol is marked as
+    // Abstract, the tags Virtual, Declaration and Definition should be removed,
+    // as the Abstract tag implies that the symbol is virtual and a
+    // declaration/definition.
+    Result &= ~toSymbolTagBitmask(SymbolTag::Virtual);
+    Result &= ~toSymbolTagBitmask(SymbolTag::Declaration);
+    Result &= ~toSymbolTagBitmask(SymbolTag::Definition);
+  }
+  if (ST & toSymbolTagBitmask(SymbolTag::Final)) {
----------------
ratzdi wrote:

Clarification is needed.

https://github.com/llvm/llvm-project/pull/170103


More information about the cfe-commits mailing list