aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Frontend/ASTUnit.cpp4
-rw-r--r--lib/Sema/CodeCompleteConsumer.cpp9
-rw-r--r--lib/Sema/SemaCodeComplete.cpp2
-rw-r--r--test/Index/code-completion.cpp2
-rw-r--r--test/Index/complete-method-decls.m4
-rw-r--r--test/Index/complete-objc-message.m31
-rw-r--r--tools/c-index-test/c-index-test.c86
-rw-r--r--tools/libclang/CIndexCodeCompletion.cpp2
8 files changed, 116 insertions, 24 deletions
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index 452803acd2..874fd012b3 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -1678,9 +1678,7 @@ void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,
Next.ProcessCodeCompleteResults(S, Context, Results, NumResults);
return;
}
-
- // Sort the completion results before passing them on to the actual consumer.
- std::stable_sort(AllResults.begin(), AllResults.end());
+
Next.ProcessCodeCompleteResults(S, Context, AllResults.data(),
AllResults.size());
diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp
index 4345123558..c4e7bb4269 100644
--- a/lib/Sema/CodeCompleteConsumer.cpp
+++ b/lib/Sema/CodeCompleteConsumer.cpp
@@ -443,6 +443,8 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
CodeCompletionContext Context,
CodeCompletionResult *Results,
unsigned NumResults) {
+ std::stable_sort(Results, Results + NumResults);
+
// Print the results.
for (unsigned I = 0; I != NumResults; ++I) {
OS << "COMPLETION: ";
@@ -660,6 +662,11 @@ bool clang::operator<(const CodeCompletionResult &X,
if (cmp)
return cmp < 0;
+ // If case-insensitive comparison fails, try case-sensitive comparison.
+ cmp = XStr.compare(YStr);
+ if (cmp)
+ return cmp < 0;
+
// Non-hidden names precede hidden names.
if (X.Hidden != Y.Hidden)
return !X.Hidden;
@@ -695,7 +702,7 @@ CIndexCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef,
unsigned NumCandidates) {
for (unsigned I = 0; I != NumCandidates; ++I) {
WriteUnsigned(OS, CXCursor_NotImplemented);
- WriteUnsigned(OS, /*Priority=*/0);
+ WriteUnsigned(OS, /*Priority=*/I);
WriteUnsigned(OS, /*Availability=*/CXAvailability_Available);
CodeCompletionString *CCS
= Candidates[I].CreateSignatureString(CurrentArg, SemaRef);
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index fed6536570..d61ddcdf75 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -2277,8 +2277,6 @@ static void HandleCodeCompleteResults(Sema *S,
CodeCompletionContext Context,
CodeCompletionResult *Results,
unsigned NumResults) {
- std::stable_sort(Results, Results + NumResults);
-
if (CodeCompleter)
CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
diff --git a/test/Index/code-completion.cpp b/test/Index/code-completion.cpp
index 354e746166..8efac1fea1 100644
--- a/test/Index/code-completion.cpp
+++ b/test/Index/code-completion.cpp
@@ -60,8 +60,8 @@ Z::operator int() const {
// RUN: c-index-test -code-completion-at=%s:37:10 %s | FileCheck -check-prefix=CHECK-EXPR %s
// CHECK-EXPR: NotImplemented:{TypedText int} (65)
// CHECK-EXPR: NotImplemented:{TypedText long} (65)
-// CHECK-EXPR: FieldDecl:{ResultType double}{TypedText member} (10)
// CHECK-EXPR: FieldDecl:{ResultType int}{Text X::}{TypedText member} (5)
+// CHECK-EXPR: FieldDecl:{ResultType double}{TypedText member} (10)
// CHECK-EXPR: FieldDecl:{ResultType float}{Text Y::}{TypedText member} (11)
// CHECK-EXPR: FunctionDecl:{ResultType void}{TypedText memfunc}{LeftParen (}{Optional {Placeholder int i}}{RightParen )} (22)
// CHECK-EXPR: NotImplemented:{TypedText N}{Text ::} (75)
diff --git a/test/Index/complete-method-decls.m b/test/Index/complete-method-decls.m
index 1324ae4a69..0c9a55a2b3 100644
--- a/test/Index/complete-method-decls.m
+++ b/test/Index/complete-method-decls.m
@@ -113,13 +113,13 @@
// CHECK-CCC: ObjCInstanceMethodDecl:{TypedText first}{Colon :}{LeftParen (}{Text int}{RightParen )}{Text x}{HorizontalSpace }{Text second2}{Colon :}{LeftParen (}{Text float}{RightParen )}{Text y}{HorizontalSpace }{Text third}{Colon :}{LeftParen (}{Text double}{RightParen )}{Text z} (30)
// RUN: c-index-test -code-completion-at=%s:56:21 %s | FileCheck -check-prefix=CHECK-CCD %s
// FIXME: These results could be more precise.
-// CHECK-CCD: ObjCInstanceMethodDecl:{ResultType id}{Informative first:}{TypedText second2:}{Text (float)y2}{HorizontalSpace }{Text third:}{Text (double)z} (20)
// CHECK-CCD: ObjCInstanceMethodDecl:{ResultType int}{Informative first:}{TypedText second2:}{Text (float)y}{HorizontalSpace }{Text third:}{Text (double)z} (5)
+// CHECK-CCD: ObjCInstanceMethodDecl:{ResultType id}{Informative first:}{TypedText second2:}{Text (float)y2}{HorizontalSpace }{Text third:}{Text (double)z} (20)
// CHECK-CCD: ObjCInstanceMethodDecl:{ResultType void *}{Informative first:}{TypedText second3:}{Text (float)y3}{HorizontalSpace }{Text third:}{Text (double)z} (20)
// CHECK-CCD: ObjCInstanceMethodDecl:{ResultType int}{Informative first:}{TypedText second:}{Text (float)y}{HorizontalSpace }{Text third:}{Text (double)z} (5)
// RUN: c-index-test -code-completion-at=%s:56:38 %s | FileCheck -check-prefix=CHECK-CCE %s
-// CHECK-CCE: ObjCInstanceMethodDecl:{ResultType id}{Informative first:}{Informative second2:}{TypedText third:}{Text (double)z} (20)
// CHECK-CCE: ObjCInstanceMethodDecl:{ResultType int}{Informative first:}{Informative second2:}{TypedText third:}{Text (double)z} (5)
+// CHECK-CCE: ObjCInstanceMethodDecl:{ResultType id}{Informative first:}{Informative second2:}{TypedText third:}{Text (double)z} (20)
// RUN: c-index-test -code-completion-at=%s:60:4 %s | FileCheck -check-prefix=CHECK-CCF %s
// CHECK-CCF: ObjCInterfaceDecl:{TypedText A} (65)
// CHECK-CCF: ObjCInterfaceDecl:{TypedText B} (65)
diff --git a/test/Index/complete-objc-message.m b/test/Index/complete-objc-message.m
index 54f62a045d..1f96bb61e3 100644
--- a/test/Index/complete-objc-message.m
+++ b/test/Index/complete-objc-message.m
@@ -209,20 +209,23 @@ void test_ranking(B *b) {
// CHECK-CCF: {ResultType Class}{TypedText self}
// CHECK-CCF: {TypedText super}
// RUN: c-index-test -code-completion-at=%s:120:6 %s | FileCheck -check-prefix=CHECK-CCG %s
-// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType id}{TypedText categoryInstanceMethod}
-// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType id}{TypedText instanceMethod1}
-// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method}
-// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (int)i}
-// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace }{Text Arg2:}{Placeholder (int)i2}
-// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace }{Text OtherArg:}{Placeholder (id)obj}
-// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace }{Text SomeArg:}{Placeholder (int)i1}{HorizontalSpace }{Text OtherArg:}{Placeholder (id)obj}
-// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyInstMethod:}{Placeholder (id)x}{HorizontalSpace }{Text second:}{Placeholder (id)y}
-// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyPrivateInstMethod}
-// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText MySubInstMethod}
-// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText MySubInstMethod:}{Placeholder (id)obj}
-// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText OtherMethod:}{Placeholder (float)f}{HorizontalSpace }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace }{Text Arg2:}{Placeholder (int)i2}
-// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType id}{TypedText protocolInstanceMethod:}{Placeholder (int)value}
-// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText secondProtocolInstanceMethod}
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType id}{TypedText categoryInstanceMethod} (20)
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType id}{TypedText instanceMethod1} (20)
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method} (20)
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (int)i} (20)
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace }{Text Arg2:}{Placeholder (int)i2} (20)
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace }{Text OtherArg:}{Placeholder (id)obj} (20)
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (float)f}{HorizontalSpace }{Text SomeArg:}{Placeholder (int)i1}{HorizontalSpace }{Text OtherArg:}{Placeholder (id)obj} (20)
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyInstMethod:}{Placeholder (id)x}{HorizontalSpace }{Text second:}{Placeholder (id)y} (20)
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyPrivateInstMethod} (20)
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText MySubInstMethod} (20)
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText MySubInstMethod:}{Placeholder (id)obj} (20)
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText OtherMethod:}{Placeholder (float)f}{HorizontalSpace }{Text Arg1:}{Placeholder (int)i1}{HorizontalSpace }{Text Arg2:}{Placeholder (int)i2} (20)
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType id}{TypedText protocolInstanceMethod:}{Placeholder (int)value} (20)
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText secondProtocolInstanceMethod} (20)
+// CHECK-CCG: ObjCInstanceMethodDecl:{ResultType int}{TypedText SentinelMethod:}{Placeholder (int)i}{Placeholder , ...}{Text , nil} (20)
+
+
// RUN: c-index-test -code-completion-at=%s:121:14 %s | FileCheck -check-prefix=CHECK-CCG %s
// RUN: c-index-test -code-completion-at=%s:122:7 %s | FileCheck -check-prefix=CHECK-CCH %s
// CHECK-CCH: ObjCClassMethodDecl:{ResultType id}{TypedText categoryClassMethod}
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 330fa545f9..c13ae91cb6 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -1,6 +1,7 @@
/* c-index-test.c */
#include "clang-c/Index.h"
+#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -895,6 +896,84 @@ void print_completion_result(CXCompletionResult *completion_result,
fprintf(file, "\n");
}
+int my_stricmp(const char *s1, const char *s2) {
+ while (*s1 && *s2) {
+ int c1 = tolower(*s1), c2 = tolower(*s2);
+ if (c1 < c2)
+ return -1;
+ else if (c1 > c2)
+ return 1;
+
+ ++s1;
+ ++s2;
+ }
+
+ if (*s1)
+ return 1;
+ else if (*s2)
+ return -1;
+ return 0;
+}
+
+int compare_completion_string(const void *xv, const void *yv) {
+ CXCompletionString x = ((CXCompletionResult *)xv)->CompletionString;
+ CXCompletionString y = ((CXCompletionResult *)yv)->CompletionString;
+ CXString xText, yText;
+ int I, N;
+ int result;
+ int FoundXText = 0, FoundYText = 0;
+
+ /* Find the typed text in x. */
+ for (I = 0, N = clang_getNumCompletionChunks(x); I != N; ++I) {
+ if (clang_getCompletionChunkKind(x, I) == CXCompletionChunk_TypedText) {
+ xText = clang_getCompletionChunkText(x, I);
+ FoundXText = 1;
+ break;
+ }
+ }
+
+ /* Find the typed text in x. */
+ for (I = 0, N = clang_getNumCompletionChunks(y); I != N; ++I) {
+ if (clang_getCompletionChunkKind(y, I) == CXCompletionChunk_TypedText) {
+ yText = clang_getCompletionChunkText(y, I);
+ FoundYText = 1;
+ break;
+ }
+ }
+
+ if (!FoundXText || !FoundYText) {
+ /* At least one of the results is missing a TypedText chunk. */
+ if (FoundXText)
+ clang_disposeString(xText);
+ if (FoundYText)
+ clang_disposeString(xText);
+
+ if (FoundXText || FoundYText)
+ return FoundXText? -1 : 1;
+ } else {
+ /* First, try case-insensitive comparisons. */
+ result = my_stricmp(clang_getCString(xText), clang_getCString(yText));
+
+ /* If that fails, try case-sensitive comparison. */
+ if (!result)
+ result = strcmp(clang_getCString(xText), clang_getCString(yText));
+
+ clang_disposeString(xText);
+ clang_disposeString(yText);
+ if (result)
+ return result;
+ }
+
+ /* The completion strings appear to be the same; try to order based on
+ priority. */
+ if (clang_getCompletionPriority(x) < clang_getCompletionPriority(y))
+ return -1;
+ else if (clang_getCompletionPriority(x) > clang_getCompletionPriority(y))
+ return 1;
+
+ return 0;
+}
+
int perform_code_completion(int argc, const char **argv, int timing_only) {
const char *input = argv[1];
char *filename = 0;
@@ -950,9 +1029,14 @@ int perform_code_completion(int argc, const char **argv, int timing_only) {
if (results) {
unsigned i, n = results->NumResults;
- if (!timing_only)
+ if (!timing_only) {
+ /* Sort the code-completion results based on the typed text. */
+ mergesort(results->Results, results->NumResults,
+ sizeof(CXCompletionResult), &compare_completion_string);
+
for (i = 0; i != n; ++i)
print_completion_result(results->Results + i, stdout);
+ }
n = clang_codeCompleteGetNumDiagnostics(results);
for (i = 0; i != n; ++i) {
CXDiagnostic diag = clang_codeCompleteGetDiagnostic(results, i);
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
index 026d0be4ba..7cf8f9f779 100644
--- a/tools/libclang/CIndexCodeCompletion.cpp
+++ b/tools/libclang/CIndexCodeCompletion.cpp
@@ -582,6 +582,8 @@ namespace {
AllocatedResults.Results[I].CompletionString = StoredCompletion;
}
}
+
+ // FIXME: Add ProcessOverloadCandidates?
};
}