summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/CodeCompleteConsumer.cpp61
-rw-r--r--clang/lib/Sema/SemaCodeComplete.cpp40
2 files changed, 94 insertions, 7 deletions
diff --git a/clang/lib/Sema/CodeCompleteConsumer.cpp b/clang/lib/Sema/CodeCompleteConsumer.cpp
index 88ac4e49cf9..a9d83010576 100644
--- a/clang/lib/Sema/CodeCompleteConsumer.cpp
+++ b/clang/lib/Sema/CodeCompleteConsumer.cpp
@@ -117,6 +117,33 @@ CodeCompletionString::Chunk::CreateCurrentParameter(
return Chunk(CK_CurrentParameter, CurrentParameter);
}
+CodeCompletionString::Chunk CodeCompletionString::Chunk::Clone() const {
+ switch (Kind) {
+ case CK_TypedText:
+ case CK_Text:
+ case CK_Placeholder:
+ case CK_Informative:
+ case CK_CurrentParameter:
+ case CK_LeftParen:
+ case CK_RightParen:
+ case CK_LeftBracket:
+ case CK_RightBracket:
+ case CK_LeftBrace:
+ case CK_RightBrace:
+ case CK_LeftAngle:
+ case CK_RightAngle:
+ case CK_Comma:
+ return Chunk(Kind, Text);
+
+ case CK_Optional: {
+ std::auto_ptr<CodeCompletionString> Opt(Optional->Clone());
+ return CreateOptional(Opt);
+ }
+ }
+
+ // Silence GCC warning.
+ return Chunk();
+}
void
CodeCompletionString::Chunk::Destroy() {
@@ -168,6 +195,20 @@ std::string CodeCompletionString::getAsString() const {
return Result;
}
+const char *CodeCompletionString::getTypedText() const {
+ for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
+ if (C->Kind == CK_TypedText)
+ return C->Text;
+
+ return 0;
+}
+
+CodeCompletionString *CodeCompletionString::Clone() const {
+ CodeCompletionString *Result = new CodeCompletionString;
+ for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
+ Result->AddChunk(C->Clone());
+ return Result;
+}
namespace {
// Escape a string for XML-like formatting.
@@ -473,6 +514,13 @@ CodeCompletionString *CodeCompletionString::Deserialize(llvm::StringRef &Str) {
return Result;
}
+void CodeCompleteConsumer::Result::Destroy() {
+ if (Kind == RK_Pattern) {
+ delete Pattern;
+ Pattern = 0;
+ }
+}
+
//===----------------------------------------------------------------------===//
// Code completion overload candidate implementation
//===----------------------------------------------------------------------===//
@@ -545,6 +593,12 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
OS << '\n';
break;
}
+
+ case Result::RK_Pattern: {
+ OS << "Pattern : " << Results[I].Rank << " : "
+ << Results[I].Pattern->getAsString() << '\n';
+ break;
+ }
}
}
@@ -627,6 +681,13 @@ CIndexCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
OS << '\n';
break;
}
+
+ case Result::RK_Pattern: {
+ OS << "Pattern:";
+ Results[I].Pattern->Serialize(OS);
+ OS << '\n';
+ break;
+ }
}
}
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index 22d2884ede1..f3f7d3f4055 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -1066,6 +1066,17 @@ namespace {
else if (X.Rank > Y.Rank)
return false;
+ // We use a special ordering for keywords and patterns, based on the
+ // typed text.
+ if ((X.Kind == Result::RK_Keyword || X.Kind == Result::RK_Pattern) &&
+ (Y.Kind == Result::RK_Keyword || Y.Kind == Result::RK_Pattern)) {
+ const char *XStr = (X.Kind == Result::RK_Keyword)? X.Keyword
+ : X.Pattern->getTypedText();
+ const char *YStr = (Y.Kind == Result::RK_Keyword)? Y.Keyword
+ : Y.Pattern->getTypedText();
+ return strcmp(XStr, YStr) < 0;
+ }
+
// Result kinds are ordered by decreasing importance.
if (X.Kind < Y.Kind)
return true;
@@ -1087,12 +1098,14 @@ namespace {
return isEarlierDeclarationName(X.Declaration->getDeclName(),
Y.Declaration->getDeclName());
- case Result::RK_Keyword:
- return strcmp(X.Keyword, Y.Keyword) < 0;
-
case Result::RK_Macro:
return llvm::LowercaseString(X.Macro->getName()) <
llvm::LowercaseString(Y.Macro->getName());
+
+ case Result::RK_Keyword:
+ case Result::RK_Pattern:
+ llvm::llvm_unreachable("Result kinds handled above");
+ break;
}
// Silence GCC warning.
@@ -1120,6 +1133,9 @@ static void HandleCodeCompleteResults(Sema *S,
if (CodeCompleter)
CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
+
+ for (unsigned I = 0; I != NumResults; ++I)
+ Results[I].Destroy();
}
void Sema::CodeCompleteOrdinaryName(Scope *S) {
@@ -1635,10 +1651,20 @@ void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Results.MaybeAddResult(CodeCompleteConsumer::Result("copy", 0));
if (!(Attributes & ObjCDeclSpec::DQ_PR_nonatomic))
Results.MaybeAddResult(CodeCompleteConsumer::Result("nonatomic", 0));
- if (!(Attributes & ObjCDeclSpec::DQ_PR_setter))
- Results.MaybeAddResult(CodeCompleteConsumer::Result("setter", 0));
- if (!(Attributes & ObjCDeclSpec::DQ_PR_getter))
- Results.MaybeAddResult(CodeCompleteConsumer::Result("getter", 0));
+ if (!(Attributes & ObjCDeclSpec::DQ_PR_setter)) {
+ CodeCompletionString *Setter = new CodeCompletionString;
+ Setter->AddTypedTextChunk("setter");
+ Setter->AddTextChunk(" = ");
+ Setter->AddPlaceholderChunk("method");
+ Results.MaybeAddResult(CodeCompleteConsumer::Result(Setter, 0));
+ }
+ if (!(Attributes & ObjCDeclSpec::DQ_PR_getter)) {
+ CodeCompletionString *Getter = new CodeCompletionString;
+ Getter->AddTypedTextChunk("getter");
+ Getter->AddTextChunk(" = ");
+ Getter->AddPlaceholderChunk("method");
+ Results.MaybeAddResult(CodeCompleteConsumer::Result(Getter, 0));
+ }
Results.ExitScope();
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
}
OpenPOWER on IntegriCloud