[clang] [clang][HeuristicResolver] Resolve more dependent member accesses (PR #223667)
Christian Kandeler via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 24 06:25:28 PDT 2026
================
@@ -580,6 +580,136 @@ TEST(HeuristicResolver, MemberExpr_DefaultTemplateArgument_Recursive) {
cxxMethodDecl(hasName("foo")).bind("output"));
}
+TEST(HeuristicResolver, MemberExpr_DefaultTemplateArgument_MemberTypedef) {
+ std::string Code = R"cpp(
+ struct Default {
+ void foo();
+ };
+ template <typename T, typename A = Default>
+ struct S {
+ typedef A type;
+ };
+ template <typename T>
+ void bar() {
+ typename S<T>::type t;
+ t.foo();
+ }
+ )cpp";
+ // Test resolution of "foo" in "t.foo()", where the type of "t" resolves
+ // to the template parameter "A" via the member typedef "type".
+ expectResolution(
+ Code, &HeuristicResolver::resolveMemberExpr,
+ cxxDependentScopeMemberExpr(hasMemberName("foo")).bind("input"),
+ cxxMethodDecl(hasName("foo")).bind("output"));
+}
+
+TEST(HeuristicResolver, MemberExpr_DefaultTemplateArgument_ReturnType) {
+ std::string Code = R"cpp(
+ struct Default {
+ void foo();
+ };
+ template <typename T, typename A = Default>
+ struct S {
+ typedef A type;
+ type get();
+ };
+ template <typename T>
+ void bar(S<T> s) {
+ s.get().foo();
+ }
+ )cpp";
+ // Test resolution of "foo" in "s.get().foo()", where the return type of
+ // "get()" resolves to the template parameter "A" via the member typedef
+ // "type".
+ expectResolution(
+ Code, &HeuristicResolver::resolveMemberExpr,
+ cxxDependentScopeMemberExpr(hasMemberName("foo")).bind("input"),
+ cxxMethodDecl(hasName("foo")).bind("output"));
+}
+
+TEST(HeuristicResolver, MemberExpr_MemberTypedefWithoutDefaultArgument) {
+ std::string Code = R"cpp(
+ template <typename T>
+ struct S {
+ typedef T type;
+ };
+ template <typename T>
+ void bar() {
+ typename S<T>::type t;
+ t.foo();
+ }
+ )cpp";
+ // Test that "foo" in "t.foo()" does not resolve: "S<T>::type" names S's own
+ // parameter T, which has no default argument to fall back on, and nothing
+ // else says what T will be. This is the member-typedef analogue of
+ // `std::vector<T>::value_type`.
+ expectResolution(
+ Code, &HeuristicResolver::resolveMemberExpr,
+ cxxDependentScopeMemberExpr(hasMemberName("foo")).bind("input"));
+}
+
+TEST(HeuristicResolver, MemberExpr_CallOfUsingDeclFromDependentBase) {
+ std::string Code = R"cpp(
+ struct Result {
+ void foo();
+ };
+ template <typename T>
+ struct Base {
+ Result get();
+ };
+ template <typename T>
+ struct Derived : Base<T> {
+ typedef Base<T> _Base;
+ using _Base::get;
+ };
+ template <typename T>
+ void bar(Derived<T> d) {
+ d.get().foo();
+ }
+ )cpp";
+ // Test resolution of "foo" in "d.get().foo()", where "get" is found as a
----------------
ckandeler wrote:
Re-titled.
https://github.com/llvm/llvm-project/pull/223667
More information about the cfe-commits
mailing list