From: Douglas Gregor Date: Mon, 23 Aug 2010 23:51:41 +0000 (+0000) Subject: When calling a function or messaging a method marked "sentinel", add X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=aaa107acc8f906203101af259e8d764b5027700a;p=clang When calling a function or messaging a method marked "sentinel", add the ", nil", ", NULL", or ", (void*)0" to the end of the code completion, since it always has to be there anyway. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111867 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index d886e64bb5..aec5568218 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -1666,6 +1666,20 @@ static void AddResultTypeChunk(ASTContext &Context, Result->AddResultTypeChunk(TypeStr); } +static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod, + CodeCompletionString *Result) { + if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr()) + if (Sentinel->getSentinel() == 0) { + if (Context.getLangOptions().ObjC1 && + Context.Idents.get("nil").hasMacroDefinition()) + Result->AddTextChunk(", nil"); + else if (Context.Idents.get("NULL").hasMacroDefinition()) + Result->AddTextChunk(", NULL"); + else + Result->AddTextChunk(", (void*)0"); + } +} + /// \brief Add function parameter chunks to the given code completion string. static void AddFunctionParameterChunks(ASTContext &Context, FunctionDecl *Function, @@ -1702,8 +1716,11 @@ static void AddFunctionParameterChunks(ASTContext &Context, if (const FunctionProtoType *Proto = Function->getType()->getAs()) - if (Proto->isVariadic()) + if (Proto->isVariadic()) { CCStr->AddPlaceholderChunk(", ..."); + + MaybeAddSentinel(Context, Function, CCStr); + } } /// \brief Add template parameter chunks to the given code completion string. @@ -2020,6 +2037,8 @@ CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S, Result->AddInformativeChunk(", ..."); else Result->AddPlaceholderChunk(", ..."); + + MaybeAddSentinel(S.Context, Method, Result); } return Result; diff --git a/test/Index/complete-exprs.c b/test/Index/complete-exprs.c index 1fbabab01b..a94b7f6f77 100644 --- a/test/Index/complete-exprs.c +++ b/test/Index/complete-exprs.c @@ -12,6 +12,12 @@ void f2() { f1(17); } const char *str = "Hello, \nWorld"; +void f3(const char*, ...) __attribute__((sentinel(0))); + +#define NULL __null +void f4(const char* str) { + f3(str, NULL); +} // RUN: c-index-test -code-completion-at=%s:7:9 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC1 %s // RUN: env CINDEXTEST_EDITING=1 c-index-test -code-completion-at=%s:7:9 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC1 %s // CHECK-CC1: NotImplemented:{TypedText __PRETTY_FUNCTION__} (60) @@ -49,3 +55,8 @@ const char *str = "Hello, \nWorld"; // RUN: c-index-test -code-completion-at=%s:13:28 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC5 %s // CHECK-CC5: NotImplemented:{TypedText void} (40) // CHECK-CC5: NotImplemented:{TypedText volatile} (40) + +// RUN: c-index-test -code-completion-at=%s:19:3 -Xclang -code-completion-patterns %s | FileCheck -check-prefix=CHECK-CC6 %s +// CHECK-CC6: FunctionDecl:{ResultType void}{TypedText f3}{LeftParen (}{Placeholder char const *}{Placeholder , ...}{Text , NULL}{RightParen )} (50) +// CHECK-CC6: NotImplemented:{TypedText void} (40) +// CHECK-CC6: NotImplemented:{TypedText volatile} (40) diff --git a/test/Index/complete-objc-message.m b/test/Index/complete-objc-message.m index 321d75f3fe..450ad0491b 100644 --- a/test/Index/complete-objc-message.m +++ b/test/Index/complete-objc-message.m @@ -1,6 +1,6 @@ // Note: the run lines follow their respective tests, since line/column // matter in this test. - +#define nil (void*)0 @protocol FooTestProtocol + protocolClassMethod; - protocolInstanceMethod : (int)value; @@ -96,9 +96,9 @@ void test_overload(Overload *ovl) { } @interface Ellipsis -- (int)Method:(int)i, ...; +- (int)Method:(int)i, ...; +- (int)SentinelMethod:(int)i, ... __attribute__((sentinel(0,1))); @end - void f(Ellipsis *e) { [e Method:1, 2, 3]; } @@ -171,6 +171,7 @@ void msg_id(id x) { // CHECK-CCA: {TypedText super} // RUN: c-index-test -code-completion-at=%s:103:6 %s | FileCheck -check-prefix=CHECK-CCB %s // CHECK-CCB: ObjCInstanceMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (int)i}{Placeholder , ...} +// CHECK-CCB: ObjCInstanceMethodDecl:{ResultType int}{TypedText SentinelMethod:}{Placeholder (int)i}{Placeholder , ...}{Text , nil} // RUN: c-index-test -code-completion-at=%s:116:14 %s | FileCheck -check-prefix=CHECK-CCC %s // CHECK-CCC: ObjCClassMethodDecl:{ResultType int}{TypedText Method} // CHECK-CCC: ObjCClassMethodDecl:{ResultType int}{TypedText Method:}{Placeholder (int)i}