Skip to content

Commit 9ccde12

Browse files
[clang] Compute accurate begin location for CallExpr with explicit object parameter (llvm#117841)
The explicit object parameter is written before the callee expression, so the begin location should come from the explicit object parameter. Fixes llvm#116335
1 parent 2b855dd commit 9ccde12

File tree

4 files changed

+21
-3
lines changed

4 files changed

+21
-3
lines changed

clang-tools-extra/clangd/unittests/XRefsTests.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,6 +1019,15 @@ TEST(LocateSymbol, All) {
10191019
void *Value;
10201020
void *getPointer() const { return Info::get^Pointer(Value); }
10211021
};
1022+
)cpp",
1023+
R"cpp(// Deducing this
1024+
struct S {
1025+
int bar(this S&);
1026+
};
1027+
void foo() {
1028+
S [[waldo]];
1029+
int x = wa^ldo.bar();
1030+
}
10221031
)cpp"};
10231032
for (const char *Test : Tests) {
10241033
Annotations T(Test);
@@ -1035,6 +1044,7 @@ TEST(LocateSymbol, All) {
10351044
TU.Code = std::string(T.code());
10361045

10371046
TU.ExtraArgs.push_back("-xobjective-c++");
1047+
TU.ExtraArgs.push_back("-std=c++23");
10381048

10391049
auto AST = TU.build();
10401050
auto Results = locateSymbolAt(AST, T.point());

clang/lib/AST/Expr.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1639,11 +1639,19 @@ SourceLocation CallExpr::getBeginLoc() const {
16391639
if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(this))
16401640
return OCE->getBeginLoc();
16411641

1642+
if (const auto *Method =
1643+
dyn_cast_if_present<const CXXMethodDecl>(getCalleeDecl());
1644+
Method && Method->isExplicitObjectMemberFunction()) {
1645+
assert(getNumArgs() > 0 && getArg(0));
1646+
return getArg(0)->getBeginLoc();
1647+
}
1648+
16421649
SourceLocation begin = getCallee()->getBeginLoc();
16431650
if (begin.isInvalid() && getNumArgs() > 0 && getArg(0))
16441651
begin = getArg(0)->getBeginLoc();
16451652
return begin;
16461653
}
1654+
16471655
SourceLocation CallExpr::getEndLoc() const {
16481656
if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(this))
16491657
return OCE->getEndLoc();

clang/lib/Sema/SemaOverload.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15575,7 +15575,7 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
1557515575
// Build the actual expression node.
1557615576
ExprResult FnExpr =
1557715577
CreateFunctionRefExpr(*this, Method, FoundDecl, MemExpr,
15578-
HadMultipleCandidates, MemExpr->getBeginLoc());
15578+
HadMultipleCandidates, MemExpr->getExprLoc());
1557915579
if (FnExpr.isInvalid())
1558015580
return ExprError();
1558115581

clang/test/AST/ast-dump-cxx2b-deducing-this.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ int main() {
99
S s;
1010
int x = s.f();
1111
// CHECK: CallExpr 0x{{[^ ]*}} <col:11, col:15> 'int
12-
// CHECK-NEXT: |-ImplicitCastExpr 0x{{[^ ]*}} <col:11> 'int (*)(S &)' <FunctionToPointerDecay>
13-
// CHECK-NEXT: | `-DeclRefExpr 0x{{[^ ]*}} <col:11> 'int (S &)' lvalue CXXMethod 0x{{[^ ]*}} 'f' 'int (S &)'
12+
// CHECK-NEXT: |-ImplicitCastExpr 0x{{[^ ]*}} <col:13> 'int (*)(S &)' <FunctionToPointerDecay>
13+
// CHECK-NEXT: | `-DeclRefExpr 0x{{[^ ]*}} <col:13> 'int (S &)' lvalue CXXMethod 0x{{[^ ]*}} 'f' 'int (S &)'
1414
}
1515
}

0 commit comments

Comments
 (0)