From 8b2565fcd05b6c54f88e09a7f5b707a4e558cdcc Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 3 Oct 2018 00:27:45 -0700 Subject: [PATCH] For $ccls/member, use unadjusted RecordDecl (if there is forward declaration) and handle ClassTemplateSpecialization --- src/indexer.cc | 54 ++++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/src/indexer.cc b/src/indexer.cc index a817459a..5e9e4aa6 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -591,6 +591,30 @@ public: } } + void CollectRecordMembers(IndexType &type, const RecordDecl *RD) { + SmallVector, 2> Stack{{RD, 0}}; + llvm::DenseSet Seen; + Seen.insert(RD); + while (Stack.size()) { + int offset; + std::tie(RD, offset) = Stack.back(); + Stack.pop_back(); + if (!RD->isCompleteDefinition() || RD->isDependentType() || + RD->isInvalidDecl() || !ValidateRecord(RD)) + offset = -1; + for (FieldDecl *FD : RD->fields()) { + int offset1 = offset < 0 ? -1 : offset + Ctx->getFieldOffset(FD); + if (FD->getIdentifier()) + type.def.vars.emplace_back(GetUsr(FD), offset1); + else if (const auto *RT1 = FD->getType()->getAs()) { + if (const RecordDecl *RD1 = RT1->getDecl()) + if (Seen.insert(RD1).second) + Stack.push_back({RD1, offset1}); + } + } + } + } + public: IndexDataConsumer(IndexParam ¶m) : param(param) {} void initialize(ASTContext &Ctx) override { this->Ctx = param.Ctx = &Ctx; } @@ -914,35 +938,17 @@ public: type->def.short_name_size = name.size(); } } - if (is_def) { - SmallVector, 2> Stack{{RD, 0}}; - llvm::DenseSet Seen; - Seen.insert(RD); - while (Stack.size()) { - int offset; - std::tie(RD, offset) = Stack.back(); - Stack.pop_back(); - if (!RD->isCompleteDefinition() || RD->isDependentType() || - RD->isInvalidDecl() || !ValidateRecord(RD)) - offset = -1; - for (FieldDecl *FD : RD->fields()) { - int offset1 = offset < 0 ? -1 : offset + Ctx->getFieldOffset(FD); - if (FD->getIdentifier()) - type->def.vars.emplace_back(GetUsr(FD), offset1); - else if (const auto *RT1 = FD->getType()->getAs()) { - if (const RecordDecl *RD1 = RT1->getDecl()) - if (Seen.insert(RD1).second) - Stack.push_back({RD1, offset1}); - } - } - } - } + if (is_def) + if (auto *ORD = dyn_cast(OrigD)) + CollectRecordMembers(*type, ORD); } break; case Decl::ClassTemplateSpecialization: case Decl::ClassTemplatePartialSpecialization: type->def.kind = lsSymbolKind::Class; - if (is_def || is_decl) { + if (is_def) { + if (auto *ORD = dyn_cast(OrigD)) + CollectRecordMembers(*type, ORD); if (auto *RD = dyn_cast(D)) { Decl *D1 = nullptr; if (auto *SD = dyn_cast(RD))