yvvan updated this revision to Diff 166110.
yvvan added a comment.

Test is added


https://reviews.llvm.org/D52261

Files:
  lib/Sema/SemaCodeComplete.cpp
  test/CodeCompletion/member-access.c

Index: test/CodeCompletion/member-access.c
===================================================================
--- test/CodeCompletion/member-access.c
+++ test/CodeCompletion/member-access.c
@@ -10,3 +10,22 @@
   // CHECK-CC1: x
   // CHECK-CC1: y
   // CHECK-CC1: z
+}
+
+struct Point2 {
+  float x;
+};
+
+void test2(struct Point2 p) {
+  p->
+}
+
+void test3(struct Point2 *p) {
+  p.
+}
+
+// RUN: %clang_cc1 -fsyntax-only -code-completion-with-fixits -code-completion-at=%s:20:6 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: x (requires fix-it: {20:4-20:6} to ".")
+
+// RUN: %clang_cc1 -fsyntax-only -code-completion-with-fixits -code-completion-at=%s:24:5 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: x (requires fix-it: {24:4-24:5} to "->")
Index: lib/Sema/SemaCodeComplete.cpp
===================================================================
--- lib/Sema/SemaCodeComplete.cpp
+++ lib/Sema/SemaCodeComplete.cpp
@@ -4037,39 +4037,33 @@
   QualType ConvertedBaseType = ConvertedBase.get()->getType();
 
   enum CodeCompletionContext::Kind contextKind;
+  QualType TypeWithoutPointer = ConvertedBaseType;
 
   if (IsArrow) {
-    if (const PointerType *Ptr = ConvertedBaseType->getAs<PointerType>())
-      ConvertedBaseType = Ptr->getPointeeType();
+    if (const PointerType *Ptr = TypeWithoutPointer->getAs<PointerType>())
+      TypeWithoutPointer = Ptr->getPointeeType();
   }
 
   if (IsArrow) {
     contextKind = CodeCompletionContext::CCC_ArrowMemberAccess;
   } else {
-    if (ConvertedBaseType->isObjCObjectPointerType() ||
-        ConvertedBaseType->isObjCObjectOrInterfaceType()) {
+    if (TypeWithoutPointer->isObjCObjectPointerType() ||
+        TypeWithoutPointer->isObjCObjectOrInterfaceType()) {
       contextKind = CodeCompletionContext::CCC_ObjCPropertyAccess;
     } else {
       contextKind = CodeCompletionContext::CCC_DotMemberAccess;
     }
   }
 
-  CodeCompletionContext CCContext(contextKind, ConvertedBaseType);
+  CodeCompletionContext CCContext(contextKind, TypeWithoutPointer);
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
                         CodeCompleter->getCodeCompletionTUInfo(), CCContext,
                         &ResultBuilder::IsMember);
 
-  auto DoCompletion = [&](Expr *Base, bool IsArrow, Optional<FixItHint> AccessOpFixIt) -> bool {
-    if (!Base)
+  auto DoCompletion = [&](QualType BaseType, bool IsArrow,
+                          Optional<FixItHint> AccessOpFixIt) -> bool {
+    if (BaseType.isNull())
       return false;
-
-    ExprResult ConvertedBase = PerformMemberExprBaseConversion(Base, IsArrow);
-    if (ConvertedBase.isInvalid())
-      return false;
-    Base = ConvertedBase.get();
-
-    QualType BaseType = Base->getType();
-
     if (IsArrow) {
       if (const PointerType *Ptr = BaseType->getAs<PointerType>())
         BaseType = Ptr->getPointeeType();
@@ -4140,13 +4134,28 @@
 
   Results.EnterNewScope();
 
-  bool CompletionSucceded = DoCompletion(Base, IsArrow, None);
+  bool CompletionSucceded = DoCompletion(ConvertedBaseType, IsArrow, None);
   if (CodeCompleter->includeFixIts()) {
-    const CharSourceRange OpRange =
-        CharSourceRange::getTokenRange(OpLoc, OpLoc);
-    CompletionSucceded |= DoCompletion(
-        OtherOpBase, !IsArrow,
-        FixItHint::CreateReplacement(OpRange, IsArrow ? "." : "->"));
+    QualType ConvertedOtherBaseType;
+    if (!OtherOpBase) {
+      const Type *BaseTypePtr = ConvertedBaseType.getTypePtrOrNull();
+      // Proceed if the initial type is pointer but IsArrow is false or the
+      // other way around.
+      if (BaseTypePtr && IsArrow != BaseTypePtr->isPointerType())
+        ConvertedOtherBaseType = ConvertedBaseType;
+    } else {
+      ExprResult ConvertedOtherBase =
+          PerformMemberExprBaseConversion(OtherOpBase, !IsArrow);
+      if (!ConvertedOtherBase.isInvalid())
+        ConvertedOtherBaseType = ConvertedOtherBase.get()->getType();
+    }
+    if (!ConvertedOtherBaseType.isNull()) {
+      const CharSourceRange OpRange =
+          CharSourceRange::getTokenRange(OpLoc, OpLoc);
+      CompletionSucceded |= DoCompletion(
+          ConvertedOtherBaseType, !IsArrow,
+          FixItHint::CreateReplacement(OpRange, IsArrow ? "." : "->"));
+    }
   }
 
   Results.ExitScope();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to