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