@@ -120,16 +120,6 @@ bool isAbstract(const Decl *D) {
120120}
121121
122122// Indicates whether declaration D is virtual in cases where D is a method.
123- // We want to treat a method as virtual if it is declared virtual, even if it
124- // is not implemented in this class, or if it overrides/implements a
125- // base-class method. This is because the "virtual" modifier is still relevant
126- // to the method's behavior and how it should be highlighted, even if it is
127- // not itself a virtual method in the strictest sense. For example, a method
128- // that overrides a virtual method from a base class is still considered
129- // virtual, even if it is not declared as such in the derived class.
130- // Similarly, a method that implements a pure virtual method from a base class
131- // is also considered virtual, even if it is not declared as such in the
132- // derived class.
133123bool isVirtual (const Decl *D) {
134124 if (const auto *CMD = llvm::dyn_cast<CXXMethodDecl>(D))
135125 return CMD ->isVirtual ();
@@ -206,20 +196,15 @@ bool isUniqueDefinition(const NamedDecl *Decl) {
206196// Filter symbol tags based on the presence of other tags and the kind of
207197// symbol. This is needed to avoid redundant tags, e.g. final implies override,
208198// override implies virtual, etc.
209- SymbolTags filterSymbolTags (const NamedDecl & ND , const SymbolTags ST ) {
199+ SymbolTags filterSymbolTags (const SymbolTags ST ) {
210200 SymbolTags Result = ST ;
211201
212- if (not isa<CXXMethodDecl>(ND ))
213- return Result;
214-
215202 if (ST & toSymbolTagBitmask (SymbolTag::Overrides)) {
216203 // Overrides means that ND overrides an existing implementation of a virtual
217204 // method in a base class. If a symbol is marked as Overrides, the tags
218205 // Virtual, Declaration and Definition should be removed, as the Overrides
219206 // tag implies that the symbol has/is virtual/declaration/definition.
220207 Result &= ~toSymbolTagBitmask (SymbolTag::Virtual);
221- Result &= ~toSymbolTagBitmask (SymbolTag::Declaration);
222- Result &= ~toSymbolTagBitmask (SymbolTag::Definition);
223208 }
224209 if (ST & toSymbolTagBitmask (SymbolTag::Implements)) {
225210 // Implements means that ND implements an existing pure virtual method in a
@@ -228,26 +213,14 @@ SymbolTags filterSymbolTags(const NamedDecl &ND, const SymbolTags ST) {
228213 // Implements tag implies that the symbol is virtual, is a declaration, is a
229214 // definition, and overrides a method.
230215 Result &= ~toSymbolTagBitmask (SymbolTag::Virtual);
231- Result &= ~toSymbolTagBitmask (SymbolTag::Declaration);
232- Result &= ~toSymbolTagBitmask (SymbolTag::Definition);
233216 Result &= ~toSymbolTagBitmask (SymbolTag::Overrides);
234217 }
235- if (ST & toSymbolTagBitmask (SymbolTag::Virtual)) {
236- // Virtual means that ND is a virtual method that does not override any
237- // method in a base class. If a symbol is marked as Virtual, the tags
238- // Declaration and Definition should be removed, as the Virtual tag implies
239- // that the symbol is a declaration/definition.
240- Result &= ~toSymbolTagBitmask (SymbolTag::Declaration);
241- Result &= ~toSymbolTagBitmask (SymbolTag::Definition);
242- }
243218 if (ST & toSymbolTagBitmask (SymbolTag::Abstract)) {
244219 // Abstract means that ND is a pure virtual method. If a symbol is marked as
245220 // Abstract, the tags Virtual, Declaration and Definition should be removed,
246221 // as the Abstract tag implies that the symbol is virtual and a
247222 // declaration/definition.
248223 Result &= ~toSymbolTagBitmask (SymbolTag::Virtual);
249- Result &= ~toSymbolTagBitmask (SymbolTag::Declaration);
250- Result &= ~toSymbolTagBitmask (SymbolTag::Definition);
251224 }
252225 if (ST & toSymbolTagBitmask (SymbolTag::Final)) {
253226 // Final means that ND is a method that cannot be overridden by any method
@@ -259,6 +232,24 @@ SymbolTags filterSymbolTags(const NamedDecl &ND, const SymbolTags ST) {
259232 }
260233 return Result;
261234}
235+
236+ bool isCXXClassMethod (const clang::clangd::Symbol &S) {
237+ using clang::index::SymbolKind;
238+ using clang::index::SymbolLanguage;
239+
240+ if (S.SymInfo .Lang != SymbolLanguage::CXX )
241+ return false ;
242+
243+ return llvm::is_contained ({SymbolKind::InstanceMethod,
244+ SymbolKind::StaticMethod, SymbolKind::Constructor,
245+ SymbolKind::Destructor,
246+ SymbolKind::ConversionFunction},
247+ S.SymInfo .Kind );
248+ }
249+
250+ template <typename E> constexpr E enumIncrement (E Value) {
251+ return static_cast <E>(static_cast <std::underlying_type_t <E>>(Value) + 1 );
252+ }
262253} // namespace
263254
264255SymbolTags toSymbolTagBitmask (const SymbolTag ST ) {
@@ -343,25 +334,31 @@ std::vector<SymbolTag> expandTagBitmask(const SymbolTags STGS) {
343334 return Tags;
344335}
345336
337+ std::vector<SymbolTag> getSymbolTags (const Symbol &S) {
338+ const SymbolTags Tags =
339+ isCXXClassMethod (S) ? filterSymbolTags (S.Tags ) : S.Tags ;
340+ return expandTagBitmask (Tags);
341+ }
342+
346343std::vector<SymbolTag> getSymbolTags (const NamedDecl &ND ) {
347- const auto symbolTags = computeSymbolTags (ND );
344+ const auto STGS = computeSymbolTags (ND );
345+ SymbolTags FilteredTags = STGS ;
348346 std::vector<SymbolTag> Tags;
349347
350- if (symbolTags == 0 )
348+ if (STGS == 0 )
351349 return Tags;
352350
353- // Apply specific filter to the symbol tags.
354- const auto filteredTags = filterSymbolTags (ND , symbolTags);
351+ // Apply specific filter to the symbol tags only on CXX class methods.
352+ if (isa<CXXMethodDecl>(ND ))
353+ FilteredTags = filterSymbolTags (STGS );
355354
356355 // Iterate through SymbolTag enum values and collect any that are present in
357356 // the bitmask. SymbolTag values are in the numeric range
358357 // [FirstTag .. LastTag].
359- constexpr unsigned MinTag = static_cast <unsigned >(SymbolTag::FirstTag);
360- constexpr unsigned MaxTag = static_cast <unsigned >(SymbolTag::LastTag);
361- for (unsigned I = MinTag; I <= MaxTag; ++I) {
362- auto ST = static_cast <SymbolTag>(I);
363- if (filteredTags & toSymbolTagBitmask (ST ))
364- Tags.push_back (ST );
358+ for (SymbolTag Tag = SymbolTag::FirstTag; Tag <= SymbolTag::LastTag;
359+ Tag = enumIncrement (Tag)) {
360+ if (FilteredTags & toSymbolTagBitmask (Tag))
361+ Tags.push_back (Tag);
365362 }
366363 return Tags;
367364}
@@ -497,7 +494,7 @@ getWorkspaceSymbols(llvm::StringRef Query, int Limit,
497494 Info.score = Relevance.NameMatch > std::numeric_limits<float >::epsilon ()
498495 ? Score / Relevance.NameMatch
499496 : QualScore;
500- Info.tags = expandTagBitmask (Sym. Tags );
497+ Info.tags = getSymbolTags (Sym);
501498 Top.push ({Score, std::move (Info)});
502499 });
503500 for (auto &R : std::move (Top).items ())
0 commit comments