diff --git a/index_tests/constructors/destructor.cc b/index_tests/constructors/destructor.cc index 3bb394d2..97207f37 100644 --- a/index_tests/constructors/destructor.cc +++ b/index_tests/constructors/destructor.cc @@ -56,7 +56,7 @@ OUTPUT: "kind": 6, "storage": 0, "declarations": [], - "spell": "4:3-4:4|15041163540773201510|2|1026|-1", + "spell": "4:3-4:7|15041163540773201510|2|1026|-1", "extent": "4:3-4:12|15041163540773201510|2|0|-1", "bases": [], "derived": [], diff --git a/index_tests/inheritance/multiple_base_functions.cc b/index_tests/inheritance/multiple_base_functions.cc index 11719475..76cd27ee 100644 --- a/index_tests/inheritance/multiple_base_functions.cc +++ b/index_tests/inheritance/multiple_base_functions.cc @@ -21,7 +21,7 @@ OUTPUT: "kind": 6, "storage": 0, "declarations": [], - "spell": "5:11-5:12|15826803741381445676|2|1090|-1", + "spell": "5:11-5:17|15826803741381445676|2|1090|-1", "extent": "5:3-5:23|15826803741381445676|2|0|-1", "bases": [], "derived": [], @@ -36,7 +36,7 @@ OUTPUT: "kind": 6, "storage": 0, "declarations": [], - "spell": "8:3-8:4|10963370434658308541|2|5186|-1", + "spell": "8:3-8:11|10963370434658308541|2|5186|-1", "extent": "8:3-8:26|10963370434658308541|2|0|-1", "bases": [], "derived": [], @@ -51,7 +51,7 @@ OUTPUT: "kind": 6, "storage": 0, "declarations": [], - "spell": "2:11-2:12|11628904180681204356|2|1090|-1", + "spell": "2:11-2:17|11628904180681204356|2|1090|-1", "extent": "2:3-2:23|11628904180681204356|2|0|-1", "bases": [], "derived": [], diff --git a/src/indexer.cc b/src/indexer.cc index 55586691..3d9e2d67 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -675,6 +675,21 @@ public: IndexParam::DeclInfo *info; Usr usr = GetUsr(D, &info); + if (is_def) + switch (OrigD->getKind()) { + case Decl::CXXConversion: // *operator* int => *operator int* + case Decl::CXXDestructor: // *~*A => *~A* + if (Loc.isFileID()) { + SourceRange R = + cast(OrigD)->getNameInfo().getSourceRange(); + if (R.getEnd().isFileID()) + loc = FromTokenRange(SM, Lang, R); + } + break; + default: + break; + } + auto do_def_decl = [&](auto *entity) { if (is_def) { entity->def.spell = GetUse(db, lid, loc, SemDC, role); @@ -704,8 +719,10 @@ public: return true; case SymbolKind::Func: func = &db->ToFunc(usr); - // Span one more column to the left/right if D is CXXConstructor. - if (!is_def && !is_decl && D->getKind() == Decl::CXXConstructor) + // Mark as Role::Implicit to span one more column to the left/right. + if (!is_def && !is_decl && + (D->getKind() == Decl::CXXConstructor || + D->getKind() == Decl::CXXConversion)) role = Role(role | Role::Implicit); do_def_decl(func); if (Spell != Loc) @@ -728,7 +745,7 @@ public: do_def_decl(type); if (Spell != Loc) AddMacroUse(db, SM, usr, SymbolKind::Type, Spell); - if (type->def.detailed_name[0] == '\0') + if (type->def.detailed_name[0] == '\0' && info->short_name.size()) SetName(OrigD, info->short_name, info->qualified, type->def); if (is_def || is_decl) { const Decl *DC = cast(SemDC); @@ -885,6 +902,25 @@ public: // spec has no Union, use Class type->def.kind = RD->getTagKind() == TTK_Struct ? lsSymbolKind::Struct : lsSymbolKind::Class; + if (type->def.detailed_name[0] == '\0' && info->short_name.empty()) { + if (TypedefNameDecl *TD = RD->getTypedefNameForAnonDecl()) { + StringRef Name = TD->getName(); + StringRef Tag; + switch (RD->getTagKind()) { + case TTK_Struct: Tag = "struct "; break; + case TTK_Interface: Tag = "__interface "; break; + case TTK_Union: Tag = "union "; break; + case TTK_Class: Tag = "class "; break; + case TTK_Enum: Tag = "enum "; break; + } + std::string name = ("anon " + Tag + Name).str(); + type->def.detailed_name = Intern(name); + type->def.short_name_size = name.size(); + } else { + // e.g. "struct {}" + SetName(OrigD, "", "", type->def); + } + } if (is_def) { SmallVector, 2> Stack{{RD, 0}}; llvm::DenseSet Seen;