-
Notifications
You must be signed in to change notification settings - Fork 12.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang] Compute accurate begin location for CallExpr with explicit object parameter #117841
base: main
Are you sure you want to change the base?
Conversation
…ject parameter The explicit object parameter is written before the callee expression, so the begin location should come from the explicit object parameter. Fixes llvm#116335
@llvm/pr-subscribers-clang Author: Nathan Ridge (HighCommander4) ChangesThe explicit object parameter is written before the callee expression, so the begin location should come from the explicit object parameter. Fixes #116335 Full diff: https://github.com/llvm/llvm-project/pull/117841.diff 3 Files Affected:
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index a4fb4d5a1f2ec4..8b10a2609c2ab0 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -1639,6 +1639,13 @@ SourceLocation CallExpr::getBeginLoc() const {
if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(this))
return OCE->getBeginLoc();
+ if (const CXXMethodDecl *Method =
+ dyn_cast_or_null<const CXXMethodDecl>(getCalleeDecl());
+ Method && Method->isExplicitObjectMemberFunction()) {
+ assert(getNumArgs() > 0 && getArg(0));
+ return getArg(0)->getBeginLoc();
+ }
+
SourceLocation begin = getCallee()->getBeginLoc();
if (begin.isInvalid() && getNumArgs() > 0 && getArg(0))
begin = getArg(0)->getBeginLoc();
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 4c9e37bd286dee..e4bf9aa521224b 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -15565,7 +15565,7 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
// Build the actual expression node.
ExprResult FnExpr =
CreateFunctionRefExpr(*this, Method, FoundDecl, MemExpr,
- HadMultipleCandidates, MemExpr->getBeginLoc());
+ HadMultipleCandidates, MemExpr->getExprLoc());
if (FnExpr.isInvalid())
return ExprError();
diff --git a/clang/test/AST/ast-dump-cxx2b-deducing-this.cpp b/clang/test/AST/ast-dump-cxx2b-deducing-this.cpp
index 04cff07376885a..1b385e0fc33319 100644
--- a/clang/test/AST/ast-dump-cxx2b-deducing-this.cpp
+++ b/clang/test/AST/ast-dump-cxx2b-deducing-this.cpp
@@ -9,7 +9,7 @@ int main() {
S s;
int x = s.f();
// CHECK: CallExpr 0x{{[^ ]*}} <col:11, col:15> 'int
- // CHECK-NEXT: |-ImplicitCastExpr 0x{{[^ ]*}} <col:11> 'int (*)(S &)' <FunctionToPointerDecay>
- // CHECK-NEXT: | `-DeclRefExpr 0x{{[^ ]*}} <col:11> 'int (S &)' lvalue CXXMethod 0x{{[^ ]*}} 'f' 'int (S &)'
+ // CHECK-NEXT: |-ImplicitCastExpr 0x{{[^ ]*}} <col:13> 'int (*)(S &)' <FunctionToPointerDecay>
+ // CHECK-NEXT: | `-DeclRefExpr 0x{{[^ ]*}} <col:13> 'int (S &)' lvalue CXXMethod 0x{{[^ ]*}} 'f' 'int (S &)'
}
}
|
@@ -1639,6 +1639,13 @@ SourceLocation CallExpr::getBeginLoc() const { | |||
if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(this)) | |||
return OCE->getBeginLoc(); | |||
|
|||
if (const CXXMethodDecl *Method = | |||
dyn_cast_or_null<const CXXMethodDecl>(getCalleeDecl()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dyn_cast_or_null<const CXXMethodDecl>(getCalleeDecl()); | |
dyn_cast_if_present<const CXXMethodDecl>(getCalleeDecl()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this also needs a selection tree test to demonstrate the original case works with the current approach.
Besides, If we can't highlight the loci differences (compared to the behavior before the last PR) using simple -ast-dump
flags, then perhaps we should reconsider the necessity of clang/test/AST/ast-dump-cxx2b-deducing-this.cpp - removing it might be a good option.
That said, I was still thinking if there's any possibility for us to find a better AST model for such use cases, rather than relying on special-casing it in CallExpr::getBeginLoc
A more general implementation of |
@@ -1639,6 +1639,13 @@ SourceLocation CallExpr::getBeginLoc() const { | |||
if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(this)) | |||
return OCE->getBeginLoc(); | |||
|
|||
if (const CXXMethodDecl *Method = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (const CXXMethodDecl *Method = | |
if (const auto *Method = |
The explicit object parameter is written before the callee expression, so the begin location should come from the explicit object parameter.
Fixes #116335