Skip to content
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
4 changes: 3 additions & 1 deletion indexer/ClangAstMacros.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@

#define FOR_EACH_EXPR_TO_BE_INDEXED(F) \
F(CXXConstruct) \
F(CXXDependentScopeMember) \
F(DeclRef) \
F(Member)
F(Member) \
F(UnresolvedMember)

#define FOR_EACH_TYPE_TO_BE_INDEXED(F) \
F(Enum) \
Expand Down
41 changes: 41 additions & 0 deletions indexer/Indexer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,13 @@ void TuIndexer::saveCXXConstructExpr(
}
}

void TuIndexer::saveCXXDependentScopeMemberExpr(
const clang::CXXDependentScopeMemberExpr &cxxDepScopeMemberExpr) {
this->trySaveMemberReferenceViaLookup(
cxxDepScopeMemberExpr.getBaseType(),
cxxDepScopeMemberExpr.getMemberNameInfo());
}

void TuIndexer::saveDeclRefExpr(const clang::DeclRefExpr &declRefExpr) {
// In the presence of 'using', prefer going to the 'using' instead
// of directly dereferencing.
Expand Down Expand Up @@ -826,6 +833,40 @@ void TuIndexer::saveMemberExpr(const clang::MemberExpr &memberExpr) {
this->saveReference(optSymbol.value(), memberExpr.getMemberLoc());
}

void TuIndexer::saveUnresolvedMemberExpr(
const clang::UnresolvedMemberExpr &unresolvedMemberExpr) {
this->trySaveMemberReferenceViaLookup(
unresolvedMemberExpr.getBaseType(),
unresolvedMemberExpr.getMemberNameInfo());
}

void TuIndexer::trySaveMemberReferenceViaLookup(
const clang::QualType &baseType,
const clang::DeclarationNameInfo &memberNameInfo) {
if (baseType.isNull()) {
return;
}
clang::QualType actualBaseType = baseType.getCanonicalType();
// C++23's 'deducing this' feature allows the base type to be a reference
if (baseType->isPointerType() || baseType->isReferenceType()) {
actualBaseType = baseType->getPointeeType();
}
auto *recordDecl = actualBaseType->getAsCXXRecordDecl();
if (!recordDecl) {
return;
}
// FIXME(issue: https://github.com/sourcegraph/scip-clang/issues/296):
// We should try to use more standard code which takes
// inheritance into account.
auto lookupResult = recordDecl->lookup(memberNameInfo.getName());
for (auto *namedDecl : lookupResult) {
auto optSymbol = this->symbolFormatter.getNamedDeclSymbol(*namedDecl);
if (optSymbol) {
this->saveReference(*optSymbol, memberNameInfo.getLoc());
}
}
}

void TuIndexer::emitDocumentOccurrencesAndSymbols(
bool deterministic, clang::FileID fileId, scip::Document &scipDocument) {
auto it = this->documentMap.find({fileId});
Expand Down
3 changes: 3 additions & 0 deletions indexer/Indexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ FOR_EACH_TYPE_TO_BE_INDEXED(FORWARD_DECLARE)

class ASTContext;
class Decl;
class DeclarationNameInfo;
class LangOptions;
class MacroDefinition;
class MacroInfo;
Expand Down Expand Up @@ -269,6 +270,8 @@ class TuIndexer final {
FOR_EACH_EXPR_TO_BE_INDEXED(SAVE_EXPR)
#undef SAVE_EXPR
void saveNestedNameSpecifierLoc(const clang::NestedNameSpecifierLoc &);
void trySaveMemberReferenceViaLookup(const clang::QualType &,
const clang::DeclarationNameInfo &);

#define SAVE_TYPE_LOC(TypeName) \
void save##TypeName##TypeLoc(const clang::TypeName##TypeLoc &);
Expand Down
32 changes: 32 additions & 0 deletions test/index/functions/template_body.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,35 @@ void f() {
// - Templated function-local classes
// - Templates inside function-local classes
}

template <typename T>
struct Z {
void f0() {}

void f1() {
f0();
}

template <typename U>
void g0() {
f0();
}

template <typename U>
void g1() {
g0<U>();
}
};

template <typename T>
struct ZZ : Z<T> {
void ff0() {
this->f0();
}

template <typename U>
void gg0() {
this->f0();
this->template g0<U>();
}
};
55 changes: 55 additions & 0 deletions test/index/functions/template_body.snapshot.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@

(void)C().plain_field;
// ^ reference [..] f(49f6e7a06ebc5aa8).C#
// ^^^^^^^^^^^ reference [..] f(49f6e7a06ebc5aa8).C#plain_field.
(void)C().dependent_field;
// ^ reference [..] f(49f6e7a06ebc5aa8).C#
// ^^^^^^^^^^^^^^^ reference [..] f(49f6e7a06ebc5aa8).C#dependent_field.
C().g();
// ^ reference [..] f(49f6e7a06ebc5aa8).C#
// ^ reference [..] f(49f6e7a06ebc5aa8).C#g(49f6e7a06ebc5aa8).

int x = 0;
// ^ definition local 1
Expand All @@ -31,3 +34,55 @@
// - Templated function-local classes
// - Templates inside function-local classes
}

template <typename T>
// ^ definition local 2
struct Z {
// ^ definition [..] Z#
void f0() {}
// ^^ definition [..] Z#f0(49f6e7a06ebc5aa8).

void f1() {
// ^^ definition [..] Z#f1(49f6e7a06ebc5aa8).
f0();
// ^^ reference [..] Z#f0(49f6e7a06ebc5aa8).
}

template <typename U>
// ^ definition local 3
void g0() {
// ^^ definition [..] Z#g0(49f6e7a06ebc5aa8).
f0();
// ^^ reference [..] Z#f0(49f6e7a06ebc5aa8).
}

template <typename U>
// ^ definition local 4
void g1() {
// ^^ definition [..] Z#g1(49f6e7a06ebc5aa8).
g0<U>();
// ^^ reference [..] Z#g0(49f6e7a06ebc5aa8).
// ^ reference local 4
}
};

template <typename T>
// ^ definition local 5
struct ZZ : Z<T> {
// ^^ definition [..] ZZ#
// ^ reference [..] Z#
// ^ reference local 5
void ff0() {
// ^^^ definition [..] ZZ#ff0(49f6e7a06ebc5aa8).
this->f0();
}

template <typename U>
// ^ definition local 6
void gg0() {
// ^^^ definition [..] ZZ#gg0(49f6e7a06ebc5aa8).
this->f0();
this->template g0<U>();
// ^ reference local 6
}
};