https://github.com/zyn0217 updated 
https://github.com/llvm/llvm-project/pull/93404

>From 7639cb738dfb876c7abdf7337fad3aa80e912736 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7...@gmail.com>
Date: Sun, 26 May 2024 15:52:31 +0800
Subject: [PATCH 1/2] [clang][CodeComplete] Recurse into the subexpression of
 deref operator in getApproximateType

The issue with the previous implementation bc31be7 was that
getApproximateType could potentially return a null QualType for a
dereferencing operator, which is not what its caller wants.
---
 clang/lib/Sema/SemaCodeComplete.cpp         | 12 ++++++++++--
 clang/test/CodeCompletion/member-access.cpp | 16 ++++++++++++++++
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaCodeComplete.cpp 
b/clang/lib/Sema/SemaCodeComplete.cpp
index 328641ed94881..73ed99e099869 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -5680,8 +5680,16 @@ QualType getApproximateType(const Expr *E) {
     }
   }
   if (const auto *UO = llvm::dyn_cast<UnaryOperator>(E)) {
-    if (UO->getOpcode() == UnaryOperatorKind::UO_Deref)
-      return UO->getSubExpr()->getType()->getPointeeType();
+    if (UO->getOpcode() == UnaryOperatorKind::UO_Deref) {
+      // We recurse into the subexpression because it could be of dependent
+      // type.
+      QualType SubType = getApproximateType(UO->getSubExpr());
+      if (auto Pointee = SubType->getPointeeType(); !Pointee.isNull())
+        return Pointee;
+      // Our caller expects a non-null result, even though the SubType is
+      // supposed to have a pointee.
+      return SubType;
+    }
   }
   return Unresolved;
 }
diff --git a/clang/test/CodeCompletion/member-access.cpp 
b/clang/test/CodeCompletion/member-access.cpp
index 9f8c21c0bca6d..912f269db6c1a 100644
--- a/clang/test/CodeCompletion/member-access.cpp
+++ b/clang/test/CodeCompletion/member-access.cpp
@@ -367,4 +367,20 @@ class A {
 // CHECK-DEREF-THIS: [#void#]function()
   }
 };
+
+template <typename Element>
+struct RepeatedField {
+  void Add();
+};
+
+template <typename T>
+RepeatedField<T>* MutableRepeatedField() {}
+
+template <class T>
+void Foo() {
+  auto& C = *MutableRepeatedField<T>();
+  C.
+}
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:382:5 %s -o - | 
FileCheck -check-prefix=CHECK-DEREF-DEPENDENT %s
+// CHECK-DEREF-DEPENDENT: [#void#]Add()
 }

>From 079f9646121c5b906ad0625cc09e3e470c6a6990 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7...@gmail.com>
Date: Mon, 27 May 2024 14:41:00 +0800
Subject: [PATCH 2/2] Address feedback

---
 clang/lib/Sema/SemaCodeComplete.cpp | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Sema/SemaCodeComplete.cpp 
b/clang/lib/Sema/SemaCodeComplete.cpp
index 73ed99e099869..f831e1244970d 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -5683,12 +5683,11 @@ QualType getApproximateType(const Expr *E) {
     if (UO->getOpcode() == UnaryOperatorKind::UO_Deref) {
       // We recurse into the subexpression because it could be of dependent
       // type.
-      QualType SubType = getApproximateType(UO->getSubExpr());
-      if (auto Pointee = SubType->getPointeeType(); !Pointee.isNull())
+      if (auto Pointee = 
getApproximateType(UO->getSubExpr())->getPointeeType();
+          !Pointee.isNull())
         return Pointee;
       // Our caller expects a non-null result, even though the SubType is
-      // supposed to have a pointee.
-      return SubType;
+      // supposed to have a pointee. Fall through to Unresolved anyway.
     }
   }
   return Unresolved;

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to