aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-12-05 09:08:56 +0000
committerDouglas Gregor <dgregor@apple.com>2009-12-05 09:08:56 +0000
commit2b0cc12cf1f9fd05ceb2551686641837c7800528 (patch)
tree0b21244ffb9fb6499a736bfabad412051c1699b6
parent7c176fac847ea4dcdb344dc5b26f44bf1cd48e91 (diff)
Improve the performance of code completion by 2.2x when completing for ordinary names with Cocoa.h included, by drastically improving the performance of our results sorting.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90661 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaCodeComplete.cpp52
1 files changed, 46 insertions, 6 deletions
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index b386adb9df..567cd2091d 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -1064,11 +1064,52 @@ namespace {
typedef CodeCompleteConsumer::Result Result;
bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
- if (!X.getObjCSelector().isNull() && !Y.getObjCSelector().isNull()) {
- // Consider all selector kinds to be equivalent.
- } else if (X.getNameKind() != Y.getNameKind())
+ Selector XSel = X.getObjCSelector();
+ Selector YSel = Y.getObjCSelector();
+ if (!XSel.isNull() && !YSel.isNull()) {
+ // We are comparing two selectors.
+ unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
+ if (N == 0)
+ ++N;
+ for (unsigned I = 0; I != N; ++I) {
+ IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
+ IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
+ if (!XId || !YId)
+ return XId && !YId;
+
+ switch (XId->getName().compare_lower(YId->getName())) {
+ case -1: return true;
+ case 1: return false;
+ default: break;
+ }
+ }
+
+ return XSel.getNumArgs() < YSel.getNumArgs();
+ }
+
+ // For non-selectors, order by kind.
+ if (X.getNameKind() != Y.getNameKind())
return X.getNameKind() < Y.getNameKind();
+ // Order identifiers by comparison of their lowercased names.
+ if (IdentifierInfo *XId = X.getAsIdentifierInfo())
+ return XId->getName().compare_lower(
+ Y.getAsIdentifierInfo()->getName()) < 0;
+
+ // Order overloaded operators by the order in which they appear
+ // in our list of operators.
+ if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
+ return XOp < Y.getCXXOverloadedOperator();
+
+ // Order C++0x user-defined literal operators lexically by their
+ // lowercased suffixes.
+ if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
+ return XLit->getName().compare_lower(
+ Y.getCXXLiteralIdentifier()->getName()) < 0;
+
+ // The only stable ordering we have is to turn the name into a
+ // string and then compare the lower-case strings. This is
+ // inefficient, but thankfully does not happen too often.
return llvm::LowercaseString(X.getAsString())
< llvm::LowercaseString(Y.getAsString());
}
@@ -1088,7 +1129,7 @@ namespace {
: X.Pattern->getTypedText();
const char *YStr = (Y.Kind == Result::RK_Keyword)? Y.Keyword
: Y.Pattern->getTypedText();
- return strcmp(XStr, YStr) < 0;
+ return strcasecmp(XStr, YStr) < 0;
}
// Result kinds are ordered by decreasing importance.
@@ -1113,8 +1154,7 @@ namespace {
Y.Declaration->getDeclName());
case Result::RK_Macro:
- return llvm::LowercaseString(X.Macro->getName()) <
- llvm::LowercaseString(Y.Macro->getName());
+ return X.Macro->getName().compare_lower(Y.Macro->getName()) < 0;
case Result::RK_Keyword:
case Result::RK_Pattern: