summaryrefslogtreecommitdiffstats
path: root/clang
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
commit249d6826cd0db3014e52eaeff0991aa91ba81ed8 (patch)
tree4198f2095b71f007781dc8b7e9476046c7b290ee /clang
parent2da786f7942502b44b428835b79cd2e3fb64e14a (diff)
downloadbcm5719-llvm-249d6826cd0db3014e52eaeff0991aa91ba81ed8.tar.gz
bcm5719-llvm-249d6826cd0db3014e52eaeff0991aa91ba81ed8.zip
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.
llvm-svn: 90661
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaCodeComplete.cpp52
1 files changed, 46 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index b386adb9df5..567cd2091db 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/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:
OpenPOWER on IntegriCloud