diff --git a/index_tests/types/anonymous_struct.cc b/index_tests/types/anonymous_struct.cc index ef381013..8a75ecf9 100644 --- a/index_tests/types/anonymous_struct.cc +++ b/index_tests/types/anonymous_struct.cc @@ -65,11 +65,17 @@ OUTPUT: "types": [1428566502523368801], "funcs": [], "vars": [{ - "L": 12549098950381705776, - "R": 0 - }, { "L": 1963212417280098348, "R": 0 + }, { + "L": 3348817847649945564, + "R": 0 + }, { + "L": 4821094820988543895, + "R": 32 + }, { + "L": 15292551660437765731, + "R": 64 }], "instances": [], "uses": [] 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 5e958e45..c9328477 100644 --- a/index_tests/usage/type_usage_typedef_and_using_template.cc +++ b/index_tests/usage/type_usage_typedef_and_using_template.cc @@ -81,7 +81,7 @@ OUTPUT: "declarations": [], "spell": "5:19-5:23|0|1|2", "extent": "5:1-5:23|0|1|0", - "alias_of": 0, + "alias_of": 14491685842684954828, "bases": [], "derived": [], "types": [], diff --git a/src/indexer.cc b/src/indexer.cc index a8fbd32c..958f77c4 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -207,7 +207,7 @@ QualType GetBaseType(QualType T, bool deduce_auto) { return BaseType; } -const Decl* GetTypeDecl(QualType T) { +const Decl *GetTypeDecl(QualType T, bool *specialization = nullptr) { Decl *D = nullptr; T = GetBaseType(T.getUnqualifiedType(), true); const Type* TP = T.getTypePtrOrNull(); @@ -233,6 +233,8 @@ try_again: D = cast(TP)->getDecl(); break; case Type::TemplateSpecialization: + if (specialization) + *specialization = true; if (const RecordType *Record = TP->getAs()) D = Record->getDecl(); else @@ -492,15 +494,14 @@ public: if (L.isMacroID() || !SM.isBeforeInTranslationUnit(L, R.getBegin())) return; StringRef Buf = GetSourceInRange(SM, Lang, R); - Twine Static("static "); - Twine T = Buf.count('\n') <= kInitializerMaxLines - 1 - ? def.detailed_name + (Buf.size() && Buf[0] == ':' - ? Twine(" ", Buf) - : Twine(" = ", Buf)) - : def.detailed_name; + Twine Init = Buf.count('\n') <= kInitializerMaxLines - 1 + ? Buf.size() && Buf[0] == ':' ? Twine(" ", Buf) + : Twine(" = ", Buf) + : Twine(); + Twine T = def.detailed_name + Init; def.hover = def.storage == SC_Static && strncmp(def.detailed_name, "static ", 7) - ? Intern((Static + T).str()) + ? Intern(("static " + T).str()) : Intern(T.str()); } } @@ -811,11 +812,21 @@ public: type->def.kind = RD->getTagKind() == TTK_Struct ? lsSymbolKind::Struct : lsSymbolKind::Class; if (is_def) { - bool can_get_offset = - RD->isCompleteDefinition() && !RD->isDependentType(); - for (FieldDecl *FD : RD->fields()) - type->def.vars.emplace_back( - GetUsr(FD), can_get_offset ? Ctx->getFieldOffset(FD) : -1); + SmallVector, 2> Stack{{RD, 0}}; + while (Stack.size()) { + int offset; + std::tie(RD, offset) = Stack.back(); + Stack.pop_back(); + if (!RD->isCompleteDefinition() || RD->isDependentType()) + offset = -1; + for (FieldDecl *FD : RD->fields()) { + int offset1 = offset >= 0 ? offset + Ctx->getFieldOffset(FD) : -1; + if (FD->getIdentifier()) + type->def.vars.emplace_back(GetUsr(FD), offset1); + else if (const auto *RT1 = FD->getType()->getAs()) + Stack.push_back({RT1->getDecl(), offset1}); + } + } } } break; @@ -851,11 +862,19 @@ public: case Decl::UnresolvedUsingTypename: type->def.kind = lsSymbolKind::TypeAlias; if (auto *TD = dyn_cast(D)) { + bool specialization = false; QualType T = TD->getUnderlyingType(); - if (const Decl* D1 = GetTypeDecl(T)) { + if (const Decl *D1 = GetTypeDecl(T, &specialization)) { Usr usr1 = GetUsr(D1); - if (db->usr2type.count(usr1)) - type->def.alias_of = usr1; + IndexType &type1 = db->ToType(usr1); + type->def.alias_of = usr1; + // Not visited template struct B {typedef A t;}; + if (specialization) { + const TypeSourceInfo *TSI = TD->getTypeSourceInfo(); + SourceLocation L1 = TSI->getTypeLoc().getBeginLoc(); + Range loc1 = FromTokenRange(SM, Lang, {L1, L1}); + type1.uses.push_back(GetUse(db, loc1, LexDC, Role::Reference)); + } } } break;