llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Nathan Ridge (HighCommander4) <details> <summary>Changes</summary> Fixes https://github.com/clangd/clangd/issues/897 --- Full diff: https://github.com/llvm/llvm-project/pull/124236.diff 2 Files Affected: - (modified) clang/lib/Sema/HeuristicResolver.cpp (+17-1) - (modified) clang/unittests/Sema/HeuristicResolverTest.cpp (+40) ``````````diff diff --git a/clang/lib/Sema/HeuristicResolver.cpp b/clang/lib/Sema/HeuristicResolver.cpp index 2a726fe51d355e..92045eb33a4816 100644 --- a/clang/lib/Sema/HeuristicResolver.cpp +++ b/clang/lib/Sema/HeuristicResolver.cpp @@ -227,6 +227,7 @@ std::vector<const NamedDecl *> HeuristicResolverImpl::resolveMemberExpr( } // Try resolving the member inside the expression's base type. + Expr *Base = ME->isImplicitAccess() ? nullptr : ME->getBase(); QualType BaseType = ME->getBaseType(); if (ME->isArrow()) { BaseType = getPointeeType(BaseType); @@ -237,11 +238,26 @@ std::vector<const NamedDecl *> HeuristicResolverImpl::resolveMemberExpr( // If BaseType is the type of a dependent expression, it's just // represented as BuiltinType::Dependent which gives us no information. We // can get further by analyzing the dependent expression. - Expr *Base = ME->isImplicitAccess() ? nullptr : ME->getBase(); if (Base && BT->getKind() == BuiltinType::Dependent) { BaseType = resolveExprToType(Base); } } + if (const auto *AT = BaseType->getContainedAutoType()) { + // If BaseType contains a dependent `auto` type, deduction will not have + // been performed on it yet. In simple cases (e.g. `auto` variable with + // initializer), get the approximate type that would result from deduction. + // FIXME: A more accurate implementation would propagate things like the + // `const` in `const auto`. + if (AT->isUndeducedAutoType()) { + if (const auto *DRE = dyn_cast<DeclRefExpr>(Base)) { + if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) { + if (VD->hasInit()) { + BaseType = resolveExprToType(VD->getInit()); + } + } + } + } + } return resolveDependentMember(BaseType, ME->getMember(), NoFilter); } diff --git a/clang/unittests/Sema/HeuristicResolverTest.cpp b/clang/unittests/Sema/HeuristicResolverTest.cpp index 2cd5486b3227f0..2b775b11719ea7 100644 --- a/clang/unittests/Sema/HeuristicResolverTest.cpp +++ b/clang/unittests/Sema/HeuristicResolverTest.cpp @@ -155,6 +155,46 @@ TEST(HeuristicResolver, MemberExpr_SmartPointer_Qualified) { cxxMethodDecl(hasName("find"), isConst()).bind("output")); } +TEST(HeuristicResolver, MemberExpr_AutoTypeDeduction1) { + std::string Code = R"cpp( + template <typename T> + struct A { + int waldo; + }; + template <typename T> + void foo(A<T> a) { + auto copy = a; + copy.waldo; + } + )cpp"; + expectResolution( + Code, &HeuristicResolver::resolveMemberExpr, + cxxDependentScopeMemberExpr(hasMemberName("waldo")).bind("input"), + fieldDecl(hasName("waldo")).bind("output")); +} + +TEST(HeuristicResolver, MemberExpr_AutoTypeDeduction2) { + std::string Code = R"cpp( + struct B { + int waldo; + }; + + template <typename T> + struct A { + B b; + }; + template <typename T> + void foo(A<T> a) { + auto b = a.b; + b.waldo; + } + )cpp"; + expectResolution( + Code, &HeuristicResolver::resolveMemberExpr, + cxxDependentScopeMemberExpr(hasMemberName("waldo")).bind("input"), + fieldDecl(hasName("waldo")).bind("output")); +} + TEST(HeuristicResolver, MemberExpr_Chained) { std::string Code = R"cpp( struct A { void foo() {} }; `````````` </details> https://github.com/llvm/llvm-project/pull/124236 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits