Skip to content

Commit 3e5e55f

Browse files
[clang] Compute accurate begin location for CallExpr with explicit object parameter
The explicit object parameter is written before the callee expression, so the begin location should come from the explicit object parameter.
1 parent 9fde1a4 commit 3e5e55f

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
@@ -15565,7 +15565,7 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
1556515565
// Build the actual expression node.
1556615566
ExprResult FnExpr =
1556715567
CreateFunctionRefExpr(*this, Method, FoundDecl, MemExpr,
15568-
HadMultipleCandidates, MemExpr->getBeginLoc());
15568+
HadMultipleCandidates, MemExpr->getExprLoc());
1556915569
if (FnExpr.isInvalid())
1557015570
return ExprError();
1557115571

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)