aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Sema/CodeCompleteConsumer.h21
-rw-r--r--lib/Frontend/ASTUnit.cpp8
-rw-r--r--lib/Sema/CodeCompleteConsumer.cpp56
-rw-r--r--lib/Sema/SemaCodeComplete.cpp66
-rw-r--r--test/Index/complete-exprs.c7
-rw-r--r--test/Index/complete-preprocessor.m7
6 files changed, 93 insertions, 72 deletions
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
index 13d16e357d..d290d39a93 100644
--- a/include/clang/Sema/CodeCompleteConsumer.h
+++ b/include/clang/Sema/CodeCompleteConsumer.h
@@ -182,6 +182,9 @@ public:
CCC_MacroNameUse,
/// \brief Code completion occurred within a preprocessor expression.
CCC_PreprocessorExpression,
+ /// \brief Code completion occurred where a preprocessor directive is
+ /// expected.
+ CCC_PreprocessorDirective,
/// \brief Code completion occurred in a context where natural language is
/// expected, e.g., a comment or string literal.
///
@@ -580,6 +583,24 @@ private:
void computeCursorKindAndAvailability();
};
+bool operator<(const CodeCompletionResult &X, const CodeCompletionResult &Y);
+
+inline bool operator>(const CodeCompletionResult &X,
+ const CodeCompletionResult &Y) {
+ return Y < X;
+}
+
+inline bool operator<=(const CodeCompletionResult &X,
+ const CodeCompletionResult &Y) {
+ return !(Y < X);
+}
+
+inline bool operator>=(const CodeCompletionResult &X,
+ const CodeCompletionResult &Y) {
+ return !(X < Y);
+}
+
+
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
const CodeCompletionString &CCS);
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index 31e42a3c36..452803acd2 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -1552,8 +1552,10 @@ void CalculateHiddenNames(const CodeCompletionContext &Context,
case CodeCompletionContext::CCC_MacroName:
case CodeCompletionContext::CCC_MacroNameUse:
case CodeCompletionContext::CCC_PreprocessorExpression:
+ case CodeCompletionContext::CCC_PreprocessorDirective:
case CodeCompletionContext::CCC_NaturalLanguage:
- // If we're just looking for protocol or macro names, nothing can hide them.
+ // We're looking for nothing, or we're looking for names that cannot
+ // be hidden.
return;
}
@@ -1676,7 +1678,9 @@ 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 303647bbc1..4345123558 100644
--- a/lib/Sema/CodeCompleteConsumer.cpp
+++ b/lib/Sema/CodeCompleteConsumer.cpp
@@ -615,6 +615,62 @@ void CodeCompletionResult::computeCursorKindAndAvailability() {
}
}
+/// \brief 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
+/// saved into Saved and the returned StringRef will refer to it.
+static llvm::StringRef getOrderedName(const CodeCompletionResult &R,
+ std::string &Saved) {
+ switch (R.Kind) {
+ case CodeCompletionResult::RK_Keyword:
+ return R.Keyword;
+
+ case CodeCompletionResult::RK_Pattern:
+ return R.Pattern->getTypedText();
+
+ case CodeCompletionResult::RK_Macro:
+ return R.Macro->getName();
+
+ case CodeCompletionResult::RK_Declaration:
+ // Handle declarations below.
+ break;
+ }
+
+ DeclarationName Name = R.Declaration->getDeclName();
+
+ // If the name is a simple identifier (by far the common case), or a
+ // zero-argument selector, just return a reference to that identifier.
+ if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
+ return Id->getName();
+ if (Name.isObjCZeroArgSelector())
+ if (IdentifierInfo *Id
+ = Name.getObjCSelector().getIdentifierInfoForSlot(0))
+ return Id->getName();
+
+ Saved = Name.getAsString();
+ return Saved;
+}
+
+bool clang::operator<(const CodeCompletionResult &X,
+ const CodeCompletionResult &Y) {
+ std::string XSaved, YSaved;
+ llvm::StringRef XStr = getOrderedName(X, XSaved);
+ llvm::StringRef YStr = getOrderedName(Y, YSaved);
+ int cmp = XStr.compare_lower(YStr);
+ if (cmp)
+ return cmp < 0;
+
+ // Non-hidden names precede hidden names.
+ if (X.Hidden != Y.Hidden)
+ return !X.Hidden;
+
+ // Non-nested-name-specifiers precede nested-name-specifiers.
+ if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
+ return !X.StartsNestedNameSpecifier;
+
+ return false;
+}
+
void
CIndexCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
CodeCompletionContext Context,
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 6d91b465de..f8bb9b5a75 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -2231,67 +2231,6 @@ CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
return Result;
}
-namespace {
- struct SortCodeCompleteResult {
- typedef CodeCompletionResult Result;
-
- /// \brief 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
- /// saved into Saved and the returned StringRef will refer to it.
- static llvm::StringRef getOrderedName(const Result &R,
- std::string &Saved) {
- switch (R.Kind) {
- case Result::RK_Keyword:
- return R.Keyword;
-
- case Result::RK_Pattern:
- return R.Pattern->getTypedText();
-
- case Result::RK_Macro:
- return R.Macro->getName();
-
- case Result::RK_Declaration:
- // Handle declarations below.
- break;
- }
-
- DeclarationName Name = R.Declaration->getDeclName();
-
- // If the name is a simple identifier (by far the common case), or a
- // zero-argument selector, just return a reference to that identifier.
- if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
- return Id->getName();
- if (Name.isObjCZeroArgSelector())
- if (IdentifierInfo *Id
- = Name.getObjCSelector().getIdentifierInfoForSlot(0))
- return Id->getName();
-
- Saved = Name.getAsString();
- return Saved;
- }
-
- bool operator()(const Result &X, const Result &Y) const {
- std::string XSaved, YSaved;
- llvm::StringRef XStr = getOrderedName(X, XSaved);
- llvm::StringRef YStr = getOrderedName(Y, YSaved);
- int cmp = XStr.compare_lower(YStr);
- if (cmp)
- return cmp < 0;
-
- // Non-hidden names precede hidden names.
- if (X.Hidden != Y.Hidden)
- return !X.Hidden;
-
- // Non-nested-name-specifiers precede nested-name-specifiers.
- if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
- return !X.StartsNestedNameSpecifier;
-
- return false;
- }
- };
-}
-
unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName,
bool PreferredTypeIsPointer) {
unsigned Priority = CCP_Macro;
@@ -2338,7 +2277,7 @@ static void HandleCodeCompleteResults(Sema *S,
CodeCompletionContext Context,
CodeCompletionResult *Results,
unsigned NumResults) {
- std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
+ std::stable_sort(Results, Results + NumResults);
if (CodeCompleter)
CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
@@ -4804,9 +4743,8 @@ void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
// FIXME: we don't support #assert or #unassert, so don't suggest them.
Results.ExitScope();
- // FIXME: Create a new code-completion context for this?
HandleCodeCompleteResults(this, CodeCompleter,
- CodeCompletionContext::CCC_Other,
+ CodeCompletionContext::CCC_PreprocessorDirective,
Results.data(), Results.size());
}
diff --git a/test/Index/complete-exprs.c b/test/Index/complete-exprs.c
index aed825e045..35fe40405e 100644
--- a/test/Index/complete-exprs.c
+++ b/test/Index/complete-exprs.c
@@ -26,12 +26,7 @@ void f4(const char* str) {
// CHECK-CC1-NOT: NotImplemented:{TypedText float} (65)
// CHECK-CC1: ParmDecl:{ResultType int}{TypedText j} (2)
// CHECK-CC1: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )} (30)
-// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:7:9 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC1a %s
-// CHECK-CC1a: NotImplemented:{TypedText __PRETTY_FUNCTION__} (60)
-// CHECK-CC1a: ParmDecl:{ResultType int}{TypedText j} (2)
-// CHECK-CC1a: NotImplemented:{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )} (30)
-// CHECK-CC1a: FunctionDecl:{ResultType int}{TypedText f}{LeftParen (}{Placeholder int}{RightParen )} (12)
-// CHECK-CC1a: macro definition:{TypedText __VERSION__} (70)
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:7:9 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC1 %s
// RUN: c-index-test -code-completion-at=%s:7:14 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC3 %s
// RUN: env CINDEXTEST_EDITING=1 c-index-test -code-completion-at=%s:7:14 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC3 %s
// CHECK-CC3: macro definition:{TypedText __VERSION__} (70)
diff --git a/test/Index/complete-preprocessor.m b/test/Index/complete-preprocessor.m
index 6ca7214fa2..1873dad6f3 100644
--- a/test/Index/complete-preprocessor.m
+++ b/test/Index/complete-preprocessor.m
@@ -71,3 +71,10 @@ FOO(in,t) value;
// CHECK-CC5: NotImplemented:{TypedText inline} (30)
// CHECK-CC5: NotImplemented:{TypedText int} (65)
// CHECK-CC5: NotImplemented:{TypedText long} (65)
+
+// Same tests as above, but with completion caching.
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:4:2 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:5:2 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:9:8 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:11:5 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:14:5 %s | FileCheck -check-prefix=CHECK-CC5 %s