================
@@ -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
----------------
HighCommander4 wrote:
This is a nice enhancement, but it doesn't involve resolving template
parameters, so the PR title "Improve heuristic resolution of template
parameters reached indirectly" isn't accurate with this in the PR. Could you
either split this out into a different PR, or make the title of this PR more
generic?
https://github.com/llvm/llvm-project/pull/223667
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits