llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: None (llvmbot) <details> <summary>Changes</summary> Backport 32c8754fbcb936ba6b5bc6cb6817cf3b6a4602f4 Requested by: @<!-- -->HighCommander4 --- Full diff: https://github.com/llvm/llvm-project/pull/127148.diff 2 Files Affected: - (modified) clang/lib/AST/Expr.cpp (+16-5) - (modified) clang/test/AST/ast-dump-cxx2b-deducing-this.cpp (+13) ``````````diff diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 06b0491442673..aa7e14329a21b 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1645,11 +1645,22 @@ SourceLocation CallExpr::getBeginLoc() const { if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(this)) return OCE->getBeginLoc(); - if (const auto *Method = - dyn_cast_if_present<const CXXMethodDecl>(getCalleeDecl()); - Method && Method->isExplicitObjectMemberFunction()) { - assert(getNumArgs() > 0 && getArg(0)); - return getArg(0)->getBeginLoc(); + // A non-dependent call to a member function with an explicit object parameter + // is modelled with the object expression being the first argument, e.g. in + // `o.f(x)`, the callee will be just `f`, and `o` will be the first argument. + // Since the first argument is written before the callee, the expression's + // begin location should come from the first argument. + // This does not apply to dependent calls, which are modelled with `o.f` + // being the callee. + if (!isTypeDependent()) { + if (const auto *Method = + dyn_cast_if_present<const CXXMethodDecl>(getCalleeDecl()); + Method && Method->isExplicitObjectMemberFunction()) { + bool HasFirstArg = getNumArgs() > 0 && getArg(0); + assert(HasFirstArg); + if (HasFirstArg) + return getArg(0)->getBeginLoc(); + } } SourceLocation begin = getCallee()->getBeginLoc(); diff --git a/clang/test/AST/ast-dump-cxx2b-deducing-this.cpp b/clang/test/AST/ast-dump-cxx2b-deducing-this.cpp index 854d12b4cdba6..abe9d6a5b5bc6 100644 --- a/clang/test/AST/ast-dump-cxx2b-deducing-this.cpp +++ b/clang/test/AST/ast-dump-cxx2b-deducing-this.cpp @@ -13,3 +13,16 @@ void main() { // CHECK-NEXT: | `-DeclRefExpr 0x{{[^ ]*}} <col:13> 'int (S &)' lvalue CXXMethod 0x{{[^ ]*}} 'f' 'int (S &)' } } + +namespace GH1269720 { +template <typename T> +struct S { + void f(this S&); + void g(S s) { + s.f(); + } + // CHECK: CallExpr 0x{{[^ ]*}} <line:22:5, col:9> '<dependent type>' + // CHECK-NEXT: `-MemberExpr 0x{{[^ ]*}} <col:5, col:7> '<bound member function type>' .f + // CHECK-NEXT: `-DeclRefExpr 0x{{[^ ]*}} <col:5> 'S<T>' lvalue ParmVar 0x{{[^ ]*}} 's' 'S<T>' +}; +} `````````` </details> https://github.com/llvm/llvm-project/pull/127148 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits