-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[clang][Sema] Handle undeduced auto types in HeuristicResolver #124236
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-clang Author: Nathan Ridge (HighCommander4) ChangesFixes clangd/clangd#897 Full diff: https://github.com/llvm/llvm-project/pull/124236.diff 2 Files Affected:
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() {} };
|
zyn0217
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, though having to nest five levels of 'if's seems a bit awkward
I'll follow this up with a patch to implement the |
94c375f to
27d53f5
Compare
|
(Fixed brace style) |
Fixes clangd/clangd#897