hokein created this revision. hokein added a reviewer: sammccall. Herald added subscribers: usaxena95, kadircet, arphaman, jkorous, ilya-biryukov. Herald added a project: clang.
Previously, the range for "->" CXXOperatorCallExpr is the range of the class object (not including the operator!), e.g. "[[vector_ptr]]->size()". This patch includes the range of the operator, which fixes the issue where clangd doesn't go to the overloaded operator "->" definition. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D76128 Files: clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp clang-tools-extra/clangd/unittests/SelectionTests.cpp clang-tools-extra/clangd/unittests/XRefsTests.cpp clang/lib/AST/ExprCXX.cpp Index: clang/lib/AST/ExprCXX.cpp =================================================================== --- clang/lib/AST/ExprCXX.cpp +++ clang/lib/AST/ExprCXX.cpp @@ -637,7 +637,7 @@ // Postfix operator return SourceRange(getArg(0)->getBeginLoc(), getOperatorLoc()); } else if (Kind == OO_Arrow) { - return getArg(0)->getSourceRange(); + return SourceRange(getArg(0)->getBeginLoc(), getOperatorLoc()); } else if (Kind == OO_Call) { return SourceRange(getArg(0)->getBeginLoc(), getRParenLoc()); } else if (Kind == OO_Subscript) { Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -451,6 +451,14 @@ } )cpp", + R"cpp( + struct S1 { void f(); }; + struct S2 { S1 * $decl[[operator]]->(); }; + void test(S2 s2) { + s2-^>f(); + } + )cpp", + R"cpp(// Declaration of explicit template specialization template <typename T> struct $decl[[Foo]] {}; Index: clang-tools-extra/clangd/unittests/SelectionTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/SelectionTests.cpp +++ clang-tools-extra/clangd/unittests/SelectionTests.cpp @@ -380,6 +380,14 @@ {"struct foo { [[^~foo()]]; };", "CXXDestructorDecl"}, // FIXME: The following to should be class itself instead. {"struct foo { [[fo^o(){}]] };", "CXXConstructorDecl"}, + + {R"cpp( + struct S1 { void f(); }; + struct S2 { S1 * operator->(); }; + void test(S2 s2) { + s2[[-^>]]f(); + } + )cpp", "DeclRefExpr"} // DeclRefExpr to the "operator->" method. }; for (const Case &C : Cases) { Annotations Test(C.Code); Index: clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp +++ clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp @@ -649,9 +649,14 @@ const ForStmt *Loop, const Expr *ContainerExpr) { StringRef ContainerString; - if (isa<CXXThisExpr>(ContainerExpr->IgnoreParenImpCasts())) { + ContainerExpr = ContainerExpr->IgnoreParenImpCasts(); + if (isa<CXXThisExpr>(ContainerExpr)) { ContainerString = "this"; } else { + // For CXXOperatorCallExpr (e.g. vector_ptr->size()), its first argument is + // the class object (vector_ptr) we are targeting. + if (const auto* E = dyn_cast<CXXOperatorCallExpr>(ContainerExpr)) + ContainerExpr = E->getArg(0); ContainerString = getStringFromRange(Context->getSourceManager(), Context->getLangOpts(), ContainerExpr->getSourceRange());
Index: clang/lib/AST/ExprCXX.cpp =================================================================== --- clang/lib/AST/ExprCXX.cpp +++ clang/lib/AST/ExprCXX.cpp @@ -637,7 +637,7 @@ // Postfix operator return SourceRange(getArg(0)->getBeginLoc(), getOperatorLoc()); } else if (Kind == OO_Arrow) { - return getArg(0)->getSourceRange(); + return SourceRange(getArg(0)->getBeginLoc(), getOperatorLoc()); } else if (Kind == OO_Call) { return SourceRange(getArg(0)->getBeginLoc(), getRParenLoc()); } else if (Kind == OO_Subscript) { Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -451,6 +451,14 @@ } )cpp", + R"cpp( + struct S1 { void f(); }; + struct S2 { S1 * $decl[[operator]]->(); }; + void test(S2 s2) { + s2-^>f(); + } + )cpp", + R"cpp(// Declaration of explicit template specialization template <typename T> struct $decl[[Foo]] {}; Index: clang-tools-extra/clangd/unittests/SelectionTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/SelectionTests.cpp +++ clang-tools-extra/clangd/unittests/SelectionTests.cpp @@ -380,6 +380,14 @@ {"struct foo { [[^~foo()]]; };", "CXXDestructorDecl"}, // FIXME: The following to should be class itself instead. {"struct foo { [[fo^o(){}]] };", "CXXConstructorDecl"}, + + {R"cpp( + struct S1 { void f(); }; + struct S2 { S1 * operator->(); }; + void test(S2 s2) { + s2[[-^>]]f(); + } + )cpp", "DeclRefExpr"} // DeclRefExpr to the "operator->" method. }; for (const Case &C : Cases) { Annotations Test(C.Code); Index: clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp +++ clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp @@ -649,9 +649,14 @@ const ForStmt *Loop, const Expr *ContainerExpr) { StringRef ContainerString; - if (isa<CXXThisExpr>(ContainerExpr->IgnoreParenImpCasts())) { + ContainerExpr = ContainerExpr->IgnoreParenImpCasts(); + if (isa<CXXThisExpr>(ContainerExpr)) { ContainerString = "this"; } else { + // For CXXOperatorCallExpr (e.g. vector_ptr->size()), its first argument is + // the class object (vector_ptr) we are targeting. + if (const auto* E = dyn_cast<CXXOperatorCallExpr>(ContainerExpr)) + ContainerExpr = E->getArg(0); ContainerString = getStringFromRange(Context->getSourceManager(), Context->getLangOpts(), ContainerExpr->getSourceRange());
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits