diff --git a/index_tests/multi_file/impl.cc b/index_tests/multi_file/impl.cc index 1ef51a20..dc754b8c 100644 --- a/index_tests/multi_file/impl.cc +++ b/index_tests/multi_file/impl.cc @@ -215,8 +215,8 @@ OUTPUT: impl.cc "callees": ["4:3-4:7|11650481237659640387|3|16420"] }, { "usr": 11650481237659640387, - "detailed_name": "template<> void Foo1()", - "qual_name_offset": 16, + "detailed_name": "void Foo1()", + "qual_name_offset": 5, "short_name": "Foo1", "kind": 12, "storage": 0, diff --git a/index_tests/multi_file/static.cc b/index_tests/multi_file/static.cc index 7f8d6c72..50096fb2 100644 --- a/index_tests/multi_file/static.cc +++ b/index_tests/multi_file/static.cc @@ -50,8 +50,8 @@ OUTPUT: static.cc "skipped_ranges": [], "usr2func": [{ "usr": 14576076421851654759, - "detailed_name": "void Buffer::CreateSharedBuffer()", - "qual_name_offset": 5, + "detailed_name": "static void Buffer::CreateSharedBuffer()", + "qual_name_offset": 12, "short_name": "CreateSharedBuffer", "kind": 254, "storage": 0, diff --git a/index_tests/outline/static_function_in_type.cc b/index_tests/outline/static_function_in_type.cc index 7bf971e6..c29aae07 100644 --- a/index_tests/outline/static_function_in_type.cc +++ b/index_tests/outline/static_function_in_type.cc @@ -84,8 +84,8 @@ OUTPUT: static_function_in_type.cc "skipped_ranges": [], "usr2func": [{ "usr": 17019747379608639279, - "detailed_name": "void Foo::Register(ns::Manager *m)", - "qual_name_offset": 5, + "detailed_name": "static void ns::Foo::Register(ns::Manager *)", + "qual_name_offset": 12, "short_name": "Register", "kind": 254, "storage": 0, diff --git a/index_tests/templates/func_specialized_template_param.cc b/index_tests/templates/func_specialized_template_param.cc index 32222811..af88d365 100644 --- a/index_tests/templates/func_specialized_template_param.cc +++ b/index_tests/templates/func_specialized_template_param.cc @@ -29,21 +29,6 @@ OUTPUT: "callees": [] }], "usr2type": [{ - "usr": 2100211316767379401, - "detailed_name": "template<> class Template", - "qual_name_offset": 17, - "short_name": "Template", - "kind": 5, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["5:12-5:20|15041163540773201510|2|4|-1", "8:15-8:23|0|1|4|-1"] - }, { "usr": 15041163540773201510, "detailed_name": "struct Foo {}", "qual_name_offset": 7, @@ -76,7 +61,7 @@ OUTPUT: "funcs": [], "vars": [], "instances": [], - "uses": [] + "uses": ["5:12-5:20|15041163540773201510|2|4|-1", "8:15-8:23|0|1|4|-1"] }], "usr2var": [] } diff --git a/index_tests/templates/specialized_func_definition.cc b/index_tests/templates/specialized_func_definition.cc index 17dfb783..1397ba80 100644 --- a/index_tests/templates/specialized_func_definition.cc +++ b/index_tests/templates/specialized_func_definition.cc @@ -24,8 +24,8 @@ OUTPUT: "skipped_ranges": [], "usr2func": [{ "usr": 6995843774014807426, - "detailed_name": "template <> void Template::Foo()", - "qual_name_offset": 31, + "detailed_name": "void Template::Foo()", + "qual_name_offset": 5, "short_name": "Foo", "kind": 6, "storage": 0, diff --git a/index_tests/usage/type_usage_as_template_parameter_complex.cc b/index_tests/usage/type_usage_as_template_parameter_complex.cc index a49ccb84..3ed6d40d 100644 --- a/index_tests/usage/type_usage_as_template_parameter_complex.cc +++ b/index_tests/usage/type_usage_as_template_parameter_complex.cc @@ -159,21 +159,6 @@ OUTPUT: "vars": [], "instances": [], "uses": ["15:30-15:32|0|1|4|-1", "33:23-33:25|0|1|4|-1", "33:63-33:65|0|1|4|-1", "54:25-54:27|18320186404467436976|3|4|-1", "65:14-65:16|15041163540773201510|2|4|-1", "79:12-79:14|0|1|4|-1"] - }, { - "usr": 7147635971744144194, - "detailed_name": "template<> class unique_ptr", - "qual_name_offset": 17, - "short_name": "unique_ptr", - "kind": 5, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["15:19-15:29|0|1|4|-1", "33:12-33:22|0|1|4|-1", "33:52-33:62|0|1|4|-1", "54:14-54:24|18320186404467436976|3|4|-1", "65:3-65:13|15041163540773201510|2|4|-1", "79:1-79:11|0|1|4|-1"] }, { "usr": 12728490517004312484, "detailed_name": "struct S2", @@ -203,7 +188,7 @@ OUTPUT: "funcs": [], "vars": [], "instances": [2933643612409209903, 500112618220246], - "uses": [] + "uses": ["15:8-15:18|0|1|4|-1", "15:19-15:29|0|1|4|-1", "33:1-33:11|0|1|4|-1", "33:12-33:22|0|1|4|-1", "33:52-33:62|0|1|4|-1", "54:3-54:13|18320186404467436976|3|4|-1", "54:14-54:24|18320186404467436976|3|4|-1", "65:3-65:13|15041163540773201510|2|4|-1", "79:1-79:11|0|1|4|-1"] }, { "usr": 15041163540773201510, "detailed_name": "class Foo {}", @@ -221,21 +206,6 @@ OUTPUT: "vars": [], "instances": [], "uses": ["79:21-79:24|0|1|4|-1"] - }, { - "usr": 18153735331422331128, - "detailed_name": "template<> class unique_ptr, S2>", - "qual_name_offset": 17, - "short_name": "unique_ptr", - "kind": 5, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["15:8-15:18|0|1|4|-1", "33:1-33:11|0|1|4|-1", "54:3-54:13|18320186404467436976|3|4|-1"] }], "usr2var": [{ "usr": 500112618220246, diff --git a/index_tests/usage/type_usage_typedef_and_using_template.cc b/index_tests/usage/type_usage_typedef_and_using_template.cc index e7043557..3c742067 100644 --- a/index_tests/usage/type_usage_typedef_and_using_template.cc +++ b/index_tests/usage/type_usage_typedef_and_using_template.cc @@ -19,7 +19,7 @@ OUTPUT: "declarations": [], "spell": "4:7-4:11|0|1|2|-1", "extent": "4:1-4:22|0|1|0|-1", - "alias_of": 5123806965838456033, + "alias_of": 10528472276654770367, "bases": [], "derived": [], "types": [], @@ -27,27 +27,12 @@ OUTPUT: "vars": [], "instances": [], "uses": ["5:13-5:17|0|1|4|-1"] - }, { - "usr": 5123806965838456033, - "detailed_name": "template<> struct Foo", - "qual_name_offset": 18, - "short_name": "Foo", - "kind": 5, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["4:14-4:17|0|1|4|-1"] }, { "usr": 10528472276654770367, "detailed_name": "struct Foo", "qual_name_offset": 7, "short_name": "Foo", - "kind": 23, + "kind": 5, "declarations": ["2:8-2:11|2:1-2:11|0|1|1|-1"], "alias_of": 0, "bases": [], @@ -56,22 +41,7 @@ OUTPUT: "funcs": [], "vars": [], "instances": [], - "uses": [] - }, { - "usr": 14491685842684954828, - "detailed_name": "template<> struct Foo>", - "qual_name_offset": 18, - "short_name": "Foo", - "kind": 5, - "declarations": [], - "alias_of": 0, - "bases": [], - "derived": [], - "types": [], - "funcs": [], - "vars": [], - "instances": [], - "uses": ["5:9-5:12|0|1|4|-1"] + "uses": ["4:14-4:17|0|1|4|-1", "5:9-5:12|0|1|4|-1"] }, { "usr": 15933698173231330933, "detailed_name": "typedef Foo Foo2", @@ -81,7 +51,7 @@ OUTPUT: "declarations": [], "spell": "5:19-5:23|0|1|2|-1", "extent": "5:1-5:23|0|1|0|-1", - "alias_of": 14491685842684954828, + "alias_of": 10528472276654770367, "bases": [], "derived": [], "types": [], diff --git a/src/indexer.cc b/src/indexer.cc index 6383c375..14c1905a 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -296,6 +296,35 @@ try_again: return D; } +const Decl *GetAdjustedDecl(const Decl *D) { + while (D) { + if (auto *R = dyn_cast(D)) { + if (auto *S = dyn_cast(R)) { + if (!S->getTypeAsWritten()) { + llvm::PointerUnion + Result = S->getSpecializedTemplateOrPartial(); + if (Result.is()) + D = Result.get(); + else + D = Result.get(); + continue; + } + } else if (auto *D1 = R->getInstantiatedFromMemberClass()) { + D = D1; + continue; + } + } else if (auto *ED = dyn_cast(D)) { + if (auto *D1 = ED->getInstantiatedFromMemberEnum()) { + D = D1; + continue; + } + } + break; + } + return D; +} + bool ValidateRecord(const RecordDecl *RD) { for (const auto *I : RD->fields()) { QualType FQT = I->getType(); @@ -636,11 +665,12 @@ public: return true; } + // spell, extent, comments use OrigD while most others use adjusted |D|. const Decl *OrigD = ASTNode.OrigD; const DeclContext *SemDC = OrigD->getDeclContext(); const DeclContext *LexDC = ASTNode.ContainerDC; Role role = static_cast(Roles); - db->language = LanguageId((int)db->language | (int)GetDeclLanguage(OrigD)); + db->language = LanguageId((int)db->language | (int)GetDeclLanguage(D)); bool is_decl = Roles & uint32_t(index::SymbolRole::Declaration); bool is_def = Roles & uint32_t(index::SymbolRole::Definition); @@ -650,11 +680,9 @@ public: IndexType *type = nullptr; IndexVar *var = nullptr; SymbolKind kind = GetSymbolKind(D); - IndexParam::DeclInfo *info; - Usr usr = GetUsr(D, &info); if (is_def) - switch (OrigD->getKind()) { + switch (D->getKind()) { case Decl::CXXConversion: // *operator* int => *operator int* case Decl::CXXDestructor: // *~*A => *~A* case Decl::CXXMethod: // *operator*= => *operator=* @@ -669,6 +697,15 @@ public: default: break; } + else { + // e.g. typedef Foo gg; => Foo has an unadjusted `D` + const Decl *D1 = GetAdjustedDecl(D); + if (D1 && D1 != D) + D = D1; + } + + IndexParam::DeclInfo *info; + Usr usr = GetUsr(D, &info); auto do_def_decl = [&](auto *entity) { if (is_def) { @@ -708,7 +745,7 @@ public: if (Spell != Loc) AddMacroUse(db, SM, usr, SymbolKind::Func, Spell); if (func->def.detailed_name[0] == '\0') - SetName(OrigD, info->short_name, info->qualified, func->def); + SetName(D, info->short_name, info->qualified, func->def); if (is_def || is_decl) { const Decl *DC = cast(SemDC); if (GetSymbolKind(DC) == SymbolKind::Type) @@ -726,7 +763,7 @@ public: if (Spell != Loc) AddMacroUse(db, SM, usr, SymbolKind::Type, Spell); if (type->def.detailed_name[0] == '\0' && info->short_name.size()) - SetName(OrigD, info->short_name, info->qualified, type->def); + SetName(D, info->short_name, info->qualified, type->def); if (is_def || is_decl) { const Decl *DC = cast(SemDC); if (GetSymbolKind(DC) == SymbolKind::Type) @@ -739,7 +776,7 @@ public: if (Spell != Loc) AddMacroUse(db, SM, usr, SymbolKind::Var, Spell); if (var->def.detailed_name[0] == '\0') - SetVarName(OrigD, info->short_name, info->qualified, var->def); + SetVarName(D, info->short_name, info->qualified, var->def); QualType T; if (auto *VD = dyn_cast(D)) T = VD->getType(); @@ -756,63 +793,44 @@ public: Usr usr1 = static_cast(BT->getKind()); var->def.type = usr1; db->ToType(usr1).instances.push_back(usr); - } else { - for (const Decl *D1 = GetTypeDecl(T); D1; ) { - if (auto *R1 = dyn_cast(D1)) { - if (auto *S1 = dyn_cast(D1)) { - if (!S1->getTypeAsWritten()) { - llvm::PointerUnion - Result = S1->getSpecializedTemplateOrPartial(); - if (Result.is()) - D1 = Result.get(); - else - D1 = Result.get(); - continue; - } - } else if (auto *D2 = R1->getInstantiatedFromMemberClass()) { - D1 = D2; - continue; - } - } else if (auto *TP1 = dyn_cast(D1)) { - // e.g. TemplateTypeParmDecl is not handled by - // handleDeclOccurence. - SourceRange R1 = D1->getSourceRange(); - if (SM.getFileID(R1.getBegin()) == LocFID) { - IndexParam::DeclInfo *info1; - Usr usr1 = GetUsr(D1, &info1); - IndexType &type1 = db->ToType(usr1); - SourceLocation L1 = D1->getLocation(); - type1.def.spell = - GetUse(db, lid, FromTokenRange(SM, Lang, {L1, L1}), SemDC, - Role::Definition); - type1.def.extent = GetUse(db, lid, FromTokenRange(SM, Lang, R1), - LexDC, Role::None); - type1.def.detailed_name = Intern(info1->short_name); - type1.def.short_name_size = int16_t(info1->short_name.size()); - type1.def.kind = lsSymbolKind::TypeParameter; - var->def.type = usr1; - type1.instances.push_back(usr); - break; - } + } else if (const Decl *D1 = GetAdjustedDecl(GetTypeDecl(T))) { + if (isa(D1)) { + // e.g. TemplateTypeParmDecl is not handled by + // handleDeclOccurence. + SourceRange R1 = D1->getSourceRange(); + if (SM.getFileID(R1.getBegin()) == LocFID) { + IndexParam::DeclInfo *info1; + Usr usr1 = GetUsr(D1, &info1); + IndexType &type1 = db->ToType(usr1); + SourceLocation L1 = D1->getLocation(); + type1.def.spell = + GetUse(db, lid, FromTokenRange(SM, Lang, {L1, L1}), SemDC, + Role::Definition); + type1.def.extent = GetUse(db, lid, FromTokenRange(SM, Lang, R1), + LexDC, Role::None); + type1.def.detailed_name = Intern(info1->short_name); + type1.def.short_name_size = int16_t(info1->short_name.size()); + type1.def.kind = lsSymbolKind::TypeParameter; + var->def.type = usr1; + type1.instances.push_back(usr); + break; } - - IndexParam::DeclInfo *info1; - Usr usr1 = GetUsr(D1, &info1); - var->def.type = usr1; - db->ToType(usr1).instances.push_back(usr); - break; } + + IndexParam::DeclInfo *info1; + Usr usr1 = GetUsr(D1, &info1); + var->def.type = usr1; + db->ToType(usr1).instances.push_back(usr); } } } else if (!var->def.spell && var->declarations.empty()) { // e.g. lambda parameter - SourceLocation L = OrigD->getLocation(); + SourceLocation L = D->getLocation(); if (SM.getFileID(L) == LocFID) { var->def.spell = GetUse(db, lid, FromTokenRange(SM, Lang, {L, L}), SemDC, Role::Definition); var->def.extent = - GetUse(db, lid, FromTokenRange(SM, Lang, OrigD->getSourceRange()), + GetUse(db, lid, FromTokenRange(SM, Lang, D->getSourceRange()), LexDC, Role::None); } } @@ -822,8 +840,8 @@ public: switch (D->getKind()) { case Decl::Namespace: type->def.kind = lsSymbolKind::Namespace; - if (OrigD->isFirstDecl()) { - auto *ND = cast(OrigD); + if (D->isFirstDecl()) { + auto *ND = cast(D); auto *ND1 = cast(ND->getParent()); if (isa(ND1)) { Usr usr1 = GetUsr(ND1); @@ -874,29 +892,19 @@ public: break; case Decl::CXXRecord: if (is_def) { - auto *RD = dyn_cast(OrigD); - if (RD && RD->hasDefinition()) { - for (const CXXBaseSpecifier &Base : RD->bases()) { - QualType T = Base.getType(); - const NamedDecl *BaseD = nullptr; - if (auto *TDT = T->getAs()) { - BaseD = TDT->getDecl(); - } else if (auto *TST = T->getAs()) { - BaseD = TST->getTemplateName().getAsTemplateDecl(); - } else if (auto *RT = T->getAs()) { - BaseD = RT->getDecl(); - } - if (BaseD) { + auto *RD = dyn_cast(D); + if (RD && RD->hasDefinition()) + for (const CXXBaseSpecifier &Base : RD->bases()) + if (const Decl *BaseD = + GetAdjustedDecl(GetTypeDecl(Base.getType()))) { Usr usr1 = GetUsr(BaseD); type->def.bases.push_back(usr1); db->ToType(usr1).derived.push_back(usr); } - } - } } [[fallthrough]]; case Decl::Record: - if (auto *RD = dyn_cast(OrigD)) { + if (auto *RD = dyn_cast(D)) { // spec has no Union, use Class type->def.kind = RD->getTagKind() == TTK_Struct ? lsSymbolKind::Struct : lsSymbolKind::Class; @@ -979,7 +987,7 @@ public: if (auto *TD = dyn_cast(D)) { bool specialization = false; QualType T = TD->getUnderlyingType(); - if (const Decl *D1 = GetTypeDecl(T, &specialization)) { + if (const Decl *D1 = GetAdjustedDecl(GetTypeDecl(T, &specialization))) { Usr usr1 = GetUsr(D1); IndexType &type1 = db->ToType(usr1); type->def.alias_of = usr1;