diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -3774,6 +3774,8 @@ return MemberNameInfo.getEndLoc(); } + SourceLocation getExprLoc() const LLVM_READONLY { return getMemberLoc(); } + static bool classof(const Stmt *T) { return T->getStmtClass() == CXXDependentScopeMemberExprClass; } diff --git a/clang/unittests/AST/SourceLocationTest.cpp b/clang/unittests/AST/SourceLocationTest.cpp --- a/clang/unittests/AST/SourceLocationTest.cpp +++ b/clang/unittests/AST/SourceLocationTest.cpp @@ -634,6 +634,36 @@ friendDecl())); } +TEST(CXXDependentScopeMemberExpr, ExprLocation) { + + llvm::Annotations Example(R"cpp( +template +struct MyContainer +{ + template + void pushBack(); +}; + +template +void testCall() +{ + MyContainer mc; + mc.template $member_name^pushBack(); +} + )cpp"); + + auto AST = tooling::buildASTFromCodeWithArgs( + Example.code(), {"-fno-delayed-template-parsing"}); + SourceManager &SM = AST->getSourceManager(); + auto &Ctx = AST->getASTContext(); + + auto *M = selectFirst( + "mem", match(cxxDependentScopeMemberExpr().bind("mem"), Ctx)); + ASSERT_TRUE(M != nullptr); + + ASSERT_EQ(SM.getFileOffset(M->getExprLoc()), Example.point("member_name")); +} + TEST(FriendDecl, FriendTemplateClassRange) { RangeVerifier Verifier; Verifier.expectRange(2, 1, 3, 14);