}
/// \brief Add type specifiers for the current language as keyword results.
-static void AddTypeSpecifierResults(const LangOptions &LangOpts, unsigned Rank,
+static void AddTypeSpecifierResults(const LangOptions &LangOpts, unsigned Rank,
ResultBuilder &Results) {
typedef CodeCompleteConsumer::Result Result;
Results.MaybeAddResult(Result("short", Rank));
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
}
+static void AddObjCExpressionResults(unsigned Rank, ResultBuilder &Results) {
+ typedef CodeCompleteConsumer::Result Result;
+ CodeCompletionString *Pattern = 0;
+
+ // @encode ( type-name )
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("encode");
+ Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+ Pattern->AddPlaceholderChunk("type-name");
+ Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+ Results.MaybeAddResult(Result(Pattern, Rank));
+
+ // @protocol ( protocol-name )
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("protocol");
+ Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+ Pattern->AddPlaceholderChunk("protocol-name");
+ Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+ Results.MaybeAddResult(Result(Pattern, Rank));
+
+ // @selector ( selector )
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("selector");
+ Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+ Pattern->AddPlaceholderChunk("selector");
+ Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+ Results.MaybeAddResult(Result(Pattern, Rank));
+}
+
+void Sema::CodeCompleteObjCAtStatement(Scope *S) {
+ typedef CodeCompleteConsumer::Result Result;
+ ResultBuilder Results(*this);
+ Results.EnterNewScope();
+
+ CodeCompletionString *Pattern = 0;
+
+ // @try { statements } @catch ( declaration ) { statements } @finally
+ // { statements }
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("try");
+ Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+ Pattern->AddPlaceholderChunk("statements");
+ Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+ Pattern->AddTextChunk("@catch");
+ Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+ Pattern->AddPlaceholderChunk("parameter");
+ Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+ Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+ Pattern->AddPlaceholderChunk("statements");
+ Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+ Pattern->AddTextChunk("@finally");
+ Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+ Pattern->AddPlaceholderChunk("statements");
+ Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+ Results.MaybeAddResult(Result(Pattern, 0));
+
+ // @throw
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("throw");
+ Pattern->AddTextChunk(" ");
+ Pattern->AddPlaceholderChunk("expression");
+ Pattern->AddTextChunk(";");
+ Results.MaybeAddResult(Result(Pattern, 0)); // FIXME: add ';' chunk
+
+ // @synchronized ( expression ) { statements }
+ Pattern = new CodeCompletionString;
+ Pattern->AddTypedTextChunk("synchronized");
+ Pattern->AddTextChunk(" ");
+ Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+ Pattern->AddPlaceholderChunk("expression");
+ Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+ Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
+ Pattern->AddPlaceholderChunk("statements");
+ Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
+ Results.MaybeAddResult(Result(Pattern, 0)); // FIXME: add ';' chunk
+
+ AddObjCExpressionResults(0, Results);
+ Results.ExitScope();
+ HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCAtExpression(Scope *S) {
+ ResultBuilder Results(*this);
+ Results.EnterNewScope();
+ AddObjCExpressionResults(0, Results);
+ Results.ExitScope();
+ HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+}
+
/// \brief Determine whether the addition of the given flag to an Objective-C
/// property's attributes will cause a conflict.
static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
--- /dev/null
+/* The run lines are below, because this test is line- and
+ column-number sensitive. */
+@interface MyClass { }
+- (int)myMethod:(int)arg;
+@end
+
+@implementation MyClass
+- (int)myMethod:(int)arg {
+ @synchronized (@encode(MyClass)) { }
+}
+@end
+// RUN: c-index-test -code-completion-at=%s:9:4 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: {TypedText encode}{LeftParen (}{Placeholder type-name}{RightParen )}
+// CHECK-CC1: {TypedText protocol}{LeftParen (}{Placeholder protocol-name}{RightParen )}
+// CHECK-CC1: {TypedText selector}{LeftParen (}{Placeholder selector}{RightParen )}
+// CHECK-CC1: {TypedText synchronized}{Text }{LeftParen (}{Placeholder expression}{RightParen )}{LeftBrace {}{Placeholder statements}{RightBrace }}
+// CHECK-CC1: {TypedText throw}{Text }{Placeholder expression}{Text ;}
+// CHECK-CC1: {TypedText try}{LeftBrace {}{Placeholder statements}{RightBrace }}{Text @catch}{LeftParen (}{Placeholder parameter}{RightParen )}{LeftBrace {}{Placeholder statements}{RightBrace }}{Text @finally}{LeftBrace {}{Placeholder statements}{RightBrace }}
+// RUN: c-index-test -code-completion-at=%s:9:19 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: {TypedText encode}{LeftParen (}{Placeholder type-name}{RightParen )}
+// CHECK-CC2: {TypedText protocol}{LeftParen (}{Placeholder protocol-name}{RightParen )}
+// CHECK-CC2: {TypedText selector}{LeftParen (}{Placeholder selector}{RightParen )}
+