Skip to content

Commit

Permalink
[clangd] Do not ignore qualifier in heuristic resolution of dependent…
Browse files Browse the repository at this point in the history
… MemberExpr

Fixes #64841

Differential Revision: https://reviews.llvm.org/D158873
  • Loading branch information
HighCommander4 committed Aug 25, 2023
1 parent 6bdf485 commit f0f53cb
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 5 deletions.
13 changes: 9 additions & 4 deletions clang-tools-extra/clangd/HeuristicResolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ const Type *HeuristicResolver::getPointeeType(const Type *T) const {

std::vector<const NamedDecl *> HeuristicResolver::resolveMemberExpr(
const CXXDependentScopeMemberExpr *ME) const {
// If the expression has a qualifier, first try resolving the member
// inside the qualifier's type.
// If the expression has a qualifier, try resolving the member inside the
// qualifier's type.
// Note that we cannot use a NonStaticFilter in either case, for a couple
// of reasons:
// 1. It's valid to access a static member using instance member syntax,
Expand All @@ -137,10 +137,15 @@ std::vector<const NamedDecl *> HeuristicResolver::resolveMemberExpr(
if (!Decls.empty())
return Decls;
}

// Do not proceed to try resolving the member in the expression's base type
// without regard to the qualifier, as that could produce incorrect results.
// For example, `void foo() { this->Base::foo(); }` shouldn't resolve to
// foo() itself!
return {};
}

// If that didn't yield any results, try resolving the member inside
// the expression's base type.
// Try resolving the member inside the expression's base type.
const Type *BaseType = ME->getBaseType().getTypePtrOrNull();
if (ME->isArrow()) {
BaseType = getPointeeType(BaseType);
Expand Down
12 changes: 11 additions & 1 deletion clang-tools-extra/clangd/unittests/XRefsTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1009,7 +1009,17 @@ TEST(LocateSymbol, All) {
void play(Dog *dog) {
[dog ho^wl];
}
)objc"};
)objc",
R"cpp(
struct PointerIntPairInfo {
static void *getPointer(void *Value);
};
template <typename Info = PointerIntPairInfo> struct PointerIntPair {
void *Value;
void *getPointer() const { return Info::get^Pointer(Value); }
};
)cpp"};
for (const char *Test : Tests) {
Annotations T(Test);
std::optional<Range> WantDecl;
Expand Down

0 comments on commit f0f53cb

Please sign in to comment.