kadircet updated this revision to Diff 167071.
kadircet added a comment.

- Change order of fucntions for better diff.
- Add tests.


Repository:
  rC Clang

https://reviews.llvm.org/D52225

Files:
  include/clang/Sema/CodeCompleteConsumer.h
  lib/Sema/SemaCodeComplete.cpp
  test/CodeCompletion/overrides.cpp

Index: test/CodeCompletion/overrides.cpp
===================================================================
--- /dev/null
+++ test/CodeCompletion/overrides.cpp
@@ -0,0 +1,30 @@
+class A {
+ public:
+  virtual void vfunc(bool param);
+  virtual void vfunc(bool param, int p);
+  void func(bool param);
+};
+class B : public A {
+virtual int ttt(bool param) const;
+void vfunc(bool param, int p) override;
+};
+class C : public B {
+ public:
+  void vfunc(bool param) override;
+  void
+};
+
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:14:3 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:14:5 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:14:8 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC1: COMPLETION: Pattern : int ttt(bool param) const override
+// CHECK-CC2-NOT: COMPLETION: Pattern : int ttt(bool param) const override
+// CHECK-CC3-NOT: COMPLETION: Pattern : int ttt(bool param) const override
+//
+// CHECK-CC1: COMPLETION: Pattern : void vfunc(bool param, int p) override
+// CHECK-CC2: COMPLETION: Pattern : void vfunc(bool param, int p) override
+// CHECK-CC3-NOT: COMPLETION: Pattern : void vfunc(bool param, int p) override
+//
+// CHECK-CC1-NOT: COMPLETION: Pattern : void vfunc(bool param) override
+// CHECK-CC2-NOT: COMPLETION: Pattern : void vfunc(bool param) override
+// CHECK-CC3-NOT: COMPLETION: Pattern : void vfunc(bool param) override
Index: lib/Sema/SemaCodeComplete.cpp
===================================================================
--- lib/Sema/SemaCodeComplete.cpp
+++ lib/Sema/SemaCodeComplete.cpp
@@ -1598,6 +1598,66 @@
   Results.AddResult(CodeCompletionResult(Builder.TakeString()));
 }
 
+static void AddOverrideResults(ResultBuilder &Results,
+                               const CodeCompletionContext &CCContext,
+                               CodeCompletionBuilder &Builder, Sema &S) {
+  const auto *CR = llvm::dyn_cast<CXXRecordDecl>(S.CurContext);
+  // If not inside a class/struct/union return empty.
+  if (!CR)
+    return;
+  // First store overrides within current class.
+  // These are stored by name to make querying fast in the later step.
+  llvm::StringMap<std::vector<FunctionDecl *>> Overrides;
+  for (auto *Method : CR->methods()) {
+    if (!Method->isVirtual() || !Method->getIdentifier())
+      continue;
+    Overrides[Method->getName()].push_back(Method);
+  }
+
+  for (const auto &Base : CR->bases()) {
+    const auto *BR = Base.getType().getTypePtr()->getAsCXXRecordDecl();
+    if (!BR)
+      continue;
+    for (auto *Method : BR->methods()) {
+      if (!Method->isVirtual() || !Method->getIdentifier())
+        continue;
+      const auto it = Overrides.find(Method->getName());
+      bool IsOverriden = false;
+      if (it != Overrides.end()) {
+        for (auto *MD : it->second) {
+          // If the method in current body is not an overload of this virtual
+          // function, then it overrides this one.
+          if (!S.IsOverload(MD, Method, false)) {
+            IsOverriden = true;
+            break;
+          }
+        }
+      }
+      if (!IsOverriden) {
+        std::string OverrideSignature;
+        llvm::raw_string_ostream OS(OverrideSignature);
+        CodeCompletionResult CCR(Method, 0);
+        PrintingPolicy Policy =
+            getCompletionPrintingPolicy(S.getASTContext(), S.getPreprocessor());
+        CCR.createCodeCompletionStringForDecl(
+            S.getPreprocessor(), S.getASTContext(), Builder,
+            false, CCContext, Policy);
+        for(const auto& C : *Builder.TakeString()) {
+          if (C.Kind == CodeCompletionString::CK_Optional)
+            continue;
+          OS << C.Text;
+          if (C.Kind == CodeCompletionString::CK_ResultType)
+            OS << ' ';
+        }
+        OS << " override";
+        Builder.AddTypedTextChunk(Builder.getAllocator().CopyString(OS.str()));
+        Results.AddResult(CodeCompletionResult(Builder.TakeString(), Method,
+                                               CCP_CodePattern));
+      }
+    }
+  }
+}
+
 /// Add language constructs that show up for "ordinary" names.
 static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
                                    Scope *S,
@@ -1706,6 +1766,9 @@
         if (IsNotInheritanceScope && Results.includeCodePatterns())
           Builder.AddChunk(CodeCompletionString::CK_Colon);
         Results.AddResult(Result(Builder.TakeString()));
+
+        AddOverrideResults(Results, CodeCompletionContext::CCC_ClassStructUnion,
+                           Builder, SemaRef);
       }
     }
     LLVM_FALLTHROUGH;
@@ -2834,7 +2897,16 @@
     return Result.TakeString();
   }
   assert(Kind == RK_Declaration && "Missed a result kind?");
-  const NamedDecl *ND = Declaration;
+  createCodeCompletionStringForDecl(PP, Ctx, Result, IncludeBriefComments,
+                                    CCContext, Policy);
+  return Result.TakeString();
+}
+
+void CodeCompletionResult::createCodeCompletionStringForDecl(
+    Preprocessor &PP, ASTContext &Ctx,
+    CodeCompletionBuilder &Result, bool IncludeBriefComments,
+    const CodeCompletionContext &CCContext, PrintingPolicy &Policy) {
+  const NamedDecl* ND = Declaration;
   Result.addParentContext(ND->getDeclContext());
 
   if (IncludeBriefComments) {
@@ -2848,7 +2920,7 @@
     Result.AddTypedTextChunk(
                       Result.getAllocator().CopyString(ND->getNameAsString()));
     Result.AddTextChunk("::");
-    return Result.TakeString();
+    return;
   }
 
   for (const auto *I : ND->specific_attrs<AnnotateAttr>())
@@ -2864,7 +2936,7 @@
     AddFunctionParameterChunks(PP, Policy, Function, Result);
     Result.AddChunk(CodeCompletionString::CK_RightParen);
     AddFunctionTypeQualsToCompletionString(Result, Function);
-    return Result.TakeString();
+    return;
   }
 
   if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
@@ -2918,7 +2990,7 @@
     AddFunctionParameterChunks(PP, Policy, Function, Result);
     Result.AddChunk(CodeCompletionString::CK_RightParen);
     AddFunctionTypeQualsToCompletionString(Result, Function);
-    return Result.TakeString();
+    return;
   }
 
   if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
@@ -2929,15 +3001,14 @@
     Result.AddChunk(CodeCompletionString::CK_LeftAngle);
     AddTemplateParameterChunks(Ctx, Policy, Template, Result);
     Result.AddChunk(CodeCompletionString::CK_RightAngle);
-    return Result.TakeString();
+    return;
   }
-
   if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
     Selector Sel = Method->getSelector();
     if (Sel.isUnarySelector()) {
       Result.AddTypedTextChunk(Result.getAllocator().CopyString(
                                   Sel.getNameForSlot(0)));
-      return Result.TakeString();
+      return;
     }
 
     std::string SelName = Sel.getNameForSlot(0).str();
@@ -3019,16 +3090,15 @@
       MaybeAddSentinel(PP, Method, Result);
     }
 
-    return Result.TakeString();
+    return;
   }
 
   if (Qualifier)
     AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
                                    Ctx, Policy);
 
   Result.AddTypedTextChunk(
                        Result.getAllocator().CopyString(ND->getNameAsString()));
-  return Result.TakeString();
 }
 
 const RawComment *clang::getCompletionComment(const ASTContext &Ctx,
Index: include/clang/Sema/CodeCompleteConsumer.h
===================================================================
--- include/clang/Sema/CodeCompleteConsumer.h
+++ include/clang/Sema/CodeCompleteConsumer.h
@@ -946,6 +946,12 @@
                                      CodeCompletionAllocator &Allocator,
                                      CodeCompletionTUInfo &CCTUInfo);
 
+  void createCodeCompletionStringForDecl(Preprocessor &PP, ASTContext &Ctx,
+                                         CodeCompletionBuilder &Result,
+                                         bool IncludeBriefComments,
+                                         const CodeCompletionContext &CCContext,
+                                         PrintingPolicy &Policy);
+
   /// Retrieve the name that should be used to order a result.
   ///
   /// If the name needs to be constructed as a string, that string will be
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to