From 4f9ea543b705967ad7ef461af152f972fb8b4357 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Fri, 5 May 2023 15:23:41 +0800 Subject: [PATCH 1/5] test: Add more cases for dependent member expressions --- test/index/functions/template_body.cc | 19 ++++++++++++ .../index/functions/template_body.snapshot.cc | 30 +++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/test/index/functions/template_body.cc b/test/index/functions/template_body.cc index 9c05a39c..e304d008 100644 --- a/test/index/functions/template_body.cc +++ b/test/index/functions/template_body.cc @@ -18,3 +18,22 @@ void f() { // - Templated function-local classes // - Templates inside function-local classes } + +template +struct Z { + void f0() {} + + void f1() { + f0(); + } + + template + void g0() { + f0(); + } + + template + void g1() { + g0(); + } +}; diff --git a/test/index/functions/template_body.snapshot.cc b/test/index/functions/template_body.snapshot.cc index 41d24656..317de89d 100644 --- a/test/index/functions/template_body.snapshot.cc +++ b/test/index/functions/template_body.snapshot.cc @@ -31,3 +31,33 @@ // - Templated function-local classes // - Templates inside function-local classes } + + template +// ^ 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 +// ^ definition local 3 + void g0() { +// ^^ definition [..] Z#g0(49f6e7a06ebc5aa8). + f0(); +// ^^ reference [..] Z#f0(49f6e7a06ebc5aa8). + } + + template +// ^ definition local 4 + void g1() { +// ^^ definition [..] Z#g1(49f6e7a06ebc5aa8). + g0(); +// ^ reference local 4 + } + }; From 4d4dace51bc04a2feae46376dc234c55e5ba8b6c Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Fri, 5 May 2023 15:25:15 +0800 Subject: [PATCH 2/5] fix: Emit more refs for dependent member exprs --- indexer/ClangAstMacros.h | 1 + indexer/Indexer.cc | 14 ++++++++++++++ test/index/functions/template_body.snapshot.cc | 3 +++ 3 files changed, 18 insertions(+) diff --git a/indexer/ClangAstMacros.h b/indexer/ClangAstMacros.h index 26e3f321..b2aab9ca 100644 --- a/indexer/ClangAstMacros.h +++ b/indexer/ClangAstMacros.h @@ -25,6 +25,7 @@ #define FOR_EACH_EXPR_TO_BE_INDEXED(F) \ F(CXXConstruct) \ + F(CXXDependentScopeMember) \ F(DeclRef) \ F(Member) diff --git a/indexer/Indexer.cc b/indexer/Indexer.cc index 0ca63b34..55fc0516 100644 --- a/indexer/Indexer.cc +++ b/indexer/Indexer.cc @@ -788,6 +788,20 @@ void TuIndexer::saveCXXConstructExpr( } } +void TuIndexer::saveCXXDependentScopeMemberExpr(const clang::CXXDependentScopeMemberExpr &cxxDepScopeMemberExpr) { + auto baseType = cxxDepScopeMemberExpr.getBaseType(); + if (auto *tagType = baseType->getAs()) { + auto memberNameInfo = cxxDepScopeMemberExpr.getMemberNameInfo(); + auto lookupResult = tagType->getDecl()->lookup(memberNameInfo.getName()); + for (auto *namedDecl: lookupResult) { + auto optSymbol = this->symbolFormatter.getNamedDeclSymbol(*namedDecl); + if (optSymbol) { + this->saveReference(*optSymbol, memberNameInfo.getLoc()); + } + } + } +} + void TuIndexer::saveDeclRefExpr(const clang::DeclRefExpr &declRefExpr) { // In the presence of 'using', prefer going to the 'using' instead // of directly dereferencing. diff --git a/test/index/functions/template_body.snapshot.cc b/test/index/functions/template_body.snapshot.cc index 317de89d..ebc94f51 100644 --- a/test/index/functions/template_body.snapshot.cc +++ b/test/index/functions/template_body.snapshot.cc @@ -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 From b7d6854129c5c5ea87e986ac88dff636931846c9 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Fri, 5 May 2023 16:38:03 +0800 Subject: [PATCH 3/5] test: Add more tests for dependent members --- test/index/functions/template_body.cc | 13 ++++++++++++ .../index/functions/template_body.snapshot.cc | 21 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/test/index/functions/template_body.cc b/test/index/functions/template_body.cc index e304d008..1dd5826b 100644 --- a/test/index/functions/template_body.cc +++ b/test/index/functions/template_body.cc @@ -37,3 +37,16 @@ struct Z { g0(); } }; + +template +struct ZZ : Z { + void ff0() { + this->f0(); + } + + template + void gg0() { + this->f0(); + this->template g0(); + } +}; \ No newline at end of file diff --git a/test/index/functions/template_body.snapshot.cc b/test/index/functions/template_body.snapshot.cc index ebc94f51..160b104d 100644 --- a/test/index/functions/template_body.snapshot.cc +++ b/test/index/functions/template_body.snapshot.cc @@ -64,3 +64,24 @@ // ^ reference local 4 } }; + + template +// ^ definition local 5 + struct ZZ : Z { +// ^^ definition [..] ZZ# +// ^ reference [..] Z# +// ^ reference local 5 + void ff0() { +// ^^^ definition [..] ZZ#ff0(49f6e7a06ebc5aa8). + this->f0(); + } + + template +// ^ definition local 6 + void gg0() { +// ^^^ definition [..] ZZ#gg0(49f6e7a06ebc5aa8). + this->f0(); + this->template g0(); +// ^ reference local 6 + } + }; From 3ee03b921a055f405cf623d35461ff0e339365e7 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Fri, 5 May 2023 16:40:38 +0800 Subject: [PATCH 4/5] fix: Attempt name lookup for unresolved members --- indexer/ClangAstMacros.h | 3 +- indexer/Indexer.cc | 50 ++++++++++++++----- indexer/Indexer.h | 3 ++ .../index/functions/template_body.snapshot.cc | 1 + 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/indexer/ClangAstMacros.h b/indexer/ClangAstMacros.h index b2aab9ca..5b8f9181 100644 --- a/indexer/ClangAstMacros.h +++ b/indexer/ClangAstMacros.h @@ -27,7 +27,8 @@ F(CXXConstruct) \ F(CXXDependentScopeMember) \ F(DeclRef) \ - F(Member) + F(Member) \ + F(UnresolvedMember) #define FOR_EACH_TYPE_TO_BE_INDEXED(F) \ F(Enum) \ diff --git a/indexer/Indexer.cc b/indexer/Indexer.cc index 55fc0516..495610df 100644 --- a/indexer/Indexer.cc +++ b/indexer/Indexer.cc @@ -788,18 +788,11 @@ void TuIndexer::saveCXXConstructExpr( } } -void TuIndexer::saveCXXDependentScopeMemberExpr(const clang::CXXDependentScopeMemberExpr &cxxDepScopeMemberExpr) { - auto baseType = cxxDepScopeMemberExpr.getBaseType(); - if (auto *tagType = baseType->getAs()) { - auto memberNameInfo = cxxDepScopeMemberExpr.getMemberNameInfo(); - auto lookupResult = tagType->getDecl()->lookup(memberNameInfo.getName()); - for (auto *namedDecl: lookupResult) { - auto optSymbol = this->symbolFormatter.getNamedDeclSymbol(*namedDecl); - if (optSymbol) { - this->saveReference(*optSymbol, memberNameInfo.getLoc()); - } - } - } +void TuIndexer::saveCXXDependentScopeMemberExpr( + const clang::CXXDependentScopeMemberExpr &cxxDepScopeMemberExpr) { + this->trySaveMemberReferenceViaLookup( + cxxDepScopeMemberExpr.getBaseType(), + cxxDepScopeMemberExpr.getMemberNameInfo()); } void TuIndexer::saveDeclRefExpr(const clang::DeclRefExpr &declRefExpr) { @@ -840,6 +833,39 @@ 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(): 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}); diff --git a/indexer/Indexer.h b/indexer/Indexer.h index 1746ccc9..871932ad 100644 --- a/indexer/Indexer.h +++ b/indexer/Indexer.h @@ -35,6 +35,7 @@ FOR_EACH_TYPE_TO_BE_INDEXED(FORWARD_DECLARE) class ASTContext; class Decl; +class DeclarationNameInfo; class LangOptions; class MacroDefinition; class MacroInfo; @@ -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 &); diff --git a/test/index/functions/template_body.snapshot.cc b/test/index/functions/template_body.snapshot.cc index 160b104d..364ff0c5 100644 --- a/test/index/functions/template_body.snapshot.cc +++ b/test/index/functions/template_body.snapshot.cc @@ -61,6 +61,7 @@ void g1() { // ^^ definition [..] Z#g1(49f6e7a06ebc5aa8). g0(); +// ^^ reference [..] Z#g0(49f6e7a06ebc5aa8). // ^ reference local 4 } }; From c3740b0f2a9777ae1a80499c6c0d8f375da54644 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Fri, 5 May 2023 16:42:26 +0800 Subject: [PATCH 5/5] docs: Add issue URL --- indexer/Indexer.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indexer/Indexer.cc b/indexer/Indexer.cc index 495610df..e15e6f0b 100644 --- a/indexer/Indexer.cc +++ b/indexer/Indexer.cc @@ -855,7 +855,8 @@ void TuIndexer::trySaveMemberReferenceViaLookup( if (!recordDecl) { return; } - // FIXME(): We should try to use more standard code which takes + // 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) {