Skip to content

fix: Properly implement Find implementations for classes #393

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 47 additions & 9 deletions indexer/Indexer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/MacroInfo.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"

#include "proto/fwd_decls.pb.h"
#include "scip/scip.pb.h"
Expand Down Expand Up @@ -662,7 +664,8 @@ void TuIndexer::saveNestedNameSpecifierLoc(
case Kind::Global:
case Kind::Super:
case Kind::TypeSpecWithTemplate:
// NOTE: Adding support for TypeSpecWithTemplate needs extra care
// FIXME(def: template-specialization-support)
// Adding support for TypeSpecWithTemplate needs extra care
// for (partial) template specializations. Example code:
//
// template <typename T0>
Expand Down Expand Up @@ -718,23 +721,58 @@ void TuIndexer::saveTagDecl(const clang::TagDecl &tagDecl) {
scip::SymbolInformation symbolInfo{};
this->getDocComment(tagDecl).addTo(symbolInfo);

llvm::SmallPtrSet<const clang::CXXRecordDecl *, 1> seen{};
llvm::SmallVector<const clang::CXXRecordDecl *, 1> stack{};
if (auto *cxxRecordDecl = llvm::dyn_cast<clang::CXXRecordDecl>(&tagDecl)) {
for (const clang::CXXBaseSpecifier &cxxBaseSpecifier :
cxxRecordDecl->bases()) {
if (auto *tagDecl = cxxBaseSpecifier.getType()->getAsTagDecl()) {
auto optRelatedSymbol = this->symbolFormatter.getTagSymbol(*tagDecl);
if (!optRelatedSymbol.has_value()) {
continue;
}
seen.insert(cxxRecordDecl);
stack.push_back(cxxRecordDecl);
}

while (!stack.empty()) {
auto *cxxRecordDecl = stack.back();
stack.pop_back();
if (!cxxRecordDecl) {
continue;
}
if (seen.find(cxxRecordDecl) == seen.end()) {
// See FIXME(ref: template-specialization-support) When we get the decl
// symbol here, we need to handle different kinds of templates
// differently. E.g. in the ImplicitInstantiation case, call
// getTemplateInstantiationPattern and use that rather than using the
// instantiated decl.
if (auto optRelatedSymbol =
this->symbolFormatter.getNamedDeclSymbol(*cxxRecordDecl)) {
scip::Relationship rel{};
auto symbol = optRelatedSymbol->value;
rel.set_symbol(symbol.data(), symbol.size());
rel.set_is_implementation(true);
*symbolInfo.add_relationships() = std::move(rel);
}
seen.insert(cxxRecordDecl);
}
}

for (const clang::CXXBaseSpecifier &cxxBaseSpecifier :
cxxRecordDecl->bases()) {
auto baseType = cxxBaseSpecifier.getType().getCanonicalType();
if (auto *baseRecordType = baseType->getAs<clang::RecordType>()) {
if (auto *baseCxxRecordDecl =
llvm::dyn_cast_or_null<clang::CXXRecordDecl>(
baseRecordType->getDecl())) {
stack.push_back(baseCxxRecordDecl);
}
} else if (auto *baseTemplateSpecType =
baseType->getAs<clang::TemplateSpecializationType>()) {
if (auto *templateDecl =
baseTemplateSpecType->getTemplateName().getAsTemplateDecl()) {
if (auto *baseCxxRecordDecl =
llvm::dyn_cast_or_null<clang::CXXRecordDecl>(
templateDecl->getTemplatedDecl())) {
stack.push_back(baseCxxRecordDecl);
}
}
}
}
}
this->saveDefinition(symbol, tagDecl.getLocation(), std::move(symbolInfo));
}

Expand Down
1 change: 0 additions & 1 deletion indexer/Indexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

#include "clang/AST/RawCommentList.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/SmallVector.h"

#include "indexer/ApproximateNameResolver.h"
#include "indexer/ClangAstMacros.h"
Expand Down
1 change: 1 addition & 0 deletions test/index/functions/methods.snapshot.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

struct S2 final: S1_0, S1_1 {
// ^^ definition [..] S2#
// relation implementation [..] S0#
// relation implementation [..] S1_0#
// relation implementation [..] S1_1#
// ^^^^ reference [..] S1_0#
Expand Down
1 change: 1 addition & 0 deletions test/index/functions/template_body.snapshot.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
// ^ definition local 5
struct ZZ : Z<T> {
// ^^ definition [..] ZZ#
// relation implementation [..] Z#
// ^ reference [..] Z#
// ^ reference local 5
void ff0() {
Expand Down
4 changes: 4 additions & 0 deletions test/index/functions/templates.snapshot.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
// ^ definition local 2
struct T1: T0<T> {
// ^^ definition [..] T1#
// relation implementation [..] T0#
// ^^ reference [..] T0#
// ^ reference local 2
void f1(T t) {
Expand Down Expand Up @@ -107,6 +108,7 @@
// ^ definition local 12
struct Q1: Q0<T> {
// ^^ definition [..] Q1#
// relation implementation [..] Q0#
// ^^ reference [..] Q0#
// ^ reference local 12
using Base1 = Q0<T>;
Expand All @@ -124,6 +126,8 @@
// ^ definition local 13
struct Q2: Q1<T> {
// ^^ definition [..] Q2#
// relation implementation [..] Q0#
// relation implementation [..] Q1#
// ^^ reference [..] Q1#
// ^ reference local 13
using Base2 = Q1<T>;
Expand Down
38 changes: 38 additions & 0 deletions test/index/types/inheritance.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
struct MonoBase {};

struct MonoDerived: MonoBase {};

struct MonoDerivedTwice: MonoDerived {};

template <typename T>
struct TemplatedBase {};

template <typename T>
struct TemplatedDerived: TemplatedBase<T> {};

struct DerivedFromInstantiation: TemplatedBase<int> {};

template <typename T>
struct SpecializedBase {};

template <>
struct SpecializedBase<int> {};

template <typename T>
struct SpecializedDerived: SpecializedBase<T> {};

struct DerivedFromSpecialization: SpecializedBase<int> {};

template <typename T>
struct CrtpBase { T *t; };

struct CrtpDerivedMono: CrtpBase<CrtpDerivedMono> {};

template <typename T>
struct CrtpDerivedTemplated: CrtpBase<CrtpDerivedTemplated<T>> {};

template <typename T>
struct DerivedFromTemplateParam: T {};

template <template <typename> typename H>
struct DerivedFromTemplateTemplateParam: H<int> {};
89 changes: 89 additions & 0 deletions test/index/types/inheritance.snapshot.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
struct MonoBase {};
//^^^^^^ definition [..] `<file>/inheritance.cc`/
// ^^^^^^^^ definition [..] MonoBase#

struct MonoDerived: MonoBase {};
// ^^^^^^^^^^^ definition [..] MonoDerived#
// relation implementation [..] MonoBase#
// ^^^^^^^^ reference [..] MonoBase#

struct MonoDerivedTwice: MonoDerived {};
// ^^^^^^^^^^^^^^^^ definition [..] MonoDerivedTwice#
// relation implementation [..] MonoBase#
// relation implementation [..] MonoDerived#
// ^^^^^^^^^^^ reference [..] MonoDerived#

template <typename T>
// ^ definition local 0
struct TemplatedBase {};
// ^^^^^^^^^^^^^ definition [..] TemplatedBase#

template <typename T>
// ^ definition local 1
struct TemplatedDerived: TemplatedBase<T> {};
// ^^^^^^^^^^^^^^^^ definition [..] TemplatedDerived#
// relation implementation [..] TemplatedBase#
// ^^^^^^^^^^^^^ reference [..] TemplatedBase#
// ^ reference local 1

struct DerivedFromInstantiation: TemplatedBase<int> {};
// ^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] DerivedFromInstantiation#
// relation implementation [..] TemplatedBase#
// ^^^^^^^^^^^^^ reference [..] TemplatedBase#

template <typename T>
// ^ definition local 2
struct SpecializedBase {};
// ^^^^^^^^^^^^^^^ definition [..] SpecializedBase#

template <>
struct SpecializedBase<int> {};
// ^^^^^^^^^^^^^^^ reference [..] SpecializedBase#
// ^^^^^^^^^^^^^^^ definition [..] SpecializedBase#

template <typename T>
// ^ definition local 3
struct SpecializedDerived: SpecializedBase<T> {};
// ^^^^^^^^^^^^^^^^^^ definition [..] SpecializedDerived#
// relation implementation [..] SpecializedBase#
// ^^^^^^^^^^^^^^^ reference [..] SpecializedBase#
// ^ reference local 3

struct DerivedFromSpecialization: SpecializedBase<int> {};
// ^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] DerivedFromSpecialization#
// relation implementation [..] SpecializedBase#
// ^^^^^^^^^^^^^^^ reference [..] SpecializedBase#

template <typename T>
// ^ definition local 4
struct CrtpBase { T *t; };
// ^^^^^^^^ definition [..] CrtpBase#
// ^ reference local 4
// ^ definition [..] CrtpBase#t.

struct CrtpDerivedMono: CrtpBase<CrtpDerivedMono> {};
// ^^^^^^^^^^^^^^^ definition [..] CrtpDerivedMono#
// relation implementation [..] CrtpBase#
// ^^^^^^^^ reference [..] CrtpBase#
// ^^^^^^^^^^^^^^^ reference [..] CrtpDerivedMono#

template <typename T>
// ^ definition local 5
struct CrtpDerivedTemplated: CrtpBase<CrtpDerivedTemplated<T>> {};
// ^^^^^^^^^^^^^^^^^^^^ definition [..] CrtpDerivedTemplated#
// relation implementation [..] CrtpBase#
// ^^^^^^^^ reference [..] CrtpBase#
// ^^^^^^^^^^^^^^^^^^^^ reference [..] CrtpDerivedTemplated#
// ^ reference local 5

template <typename T>
// ^ definition local 6
struct DerivedFromTemplateParam: T {};
// ^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] DerivedFromTemplateParam#
// ^ reference local 6

template <template <typename> typename H>
// ^ definition local 7
struct DerivedFromTemplateTemplateParam: H<int> {};
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] DerivedFromTemplateTemplateParam#
// ^ reference local 7
1 change: 1 addition & 0 deletions test/index/types/templates.snapshot.cc
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
// ^ definition local 23
struct M1: M0<T> {
// ^^ definition [..] M1#
// relation implementation [..] M0#
// ^^ reference [..] M0#
// ^ reference local 23
using B = M0<T>;
Expand Down
1 change: 1 addition & 0 deletions test/index/types/types.snapshot.cc
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@
// | No documentation available.
// relation implementation [..] Derived1#
// relation implementation [..] Derived2#
// relation implementation [..] DiamondBase#
// ^^^^^^^^ reference [..] Derived1#
// ^^^^^^^^ reference [..] Derived2#

Expand Down