diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 3d1c3bca866ab4c8e1b79ce80d5635c7d14db44d..5a553513b41cc63933afca9c89304f094b3ab89a 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -2455,45 +2455,34 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx, // Format a function-like macro with placeholders for the arguments. Result.AddChunk(Chunk(CodeCompletionString::CK_LeftParen)); - bool CombineVariadicArgument = false; MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end(); - if (MI->isVariadic() && AEnd - A > 1) { - AEnd -= 2; - CombineVariadicArgument = true; + + // C99 variadic macros add __VA_ARGS__ at the end. Skip it. + if (MI->isC99Varargs()) { + --AEnd; + + if (A == AEnd) { + Result.AddPlaceholderChunk("..."); + } } + for (MacroInfo::arg_iterator A = MI->arg_begin(); A != AEnd; ++A) { if (A != MI->arg_begin()) Result.AddChunk(Chunk(CodeCompletionString::CK_Comma)); - - if (!MI->isVariadic() || A + 1 != AEnd) { - // Non-variadic argument. - Result.AddPlaceholderChunk( - Result.getAllocator().CopyString((*A)->getName())); - continue; - } - - // Variadic argument; cope with the difference between GNU and C99 - // variadic macros, providing a single placeholder for the rest of the - // arguments. - if ((*A)->isStr("__VA_ARGS__")) - Result.AddPlaceholderChunk("..."); - else { - std::string Arg = (*A)->getName(); - Arg += "..."; + + if (MI->isVariadic() && (A+1) == AEnd) { + llvm::SmallString<32> Arg = (*A)->getName(); + if (MI->isC99Varargs()) + Arg += ", ..."; + else + Arg += "..."; Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg)); + break; } - } - - if (CombineVariadicArgument) { - // Handle the next-to-last argument, combining it with the variadic - // argument. - std::string LastArg = (*A)->getName(); - ++A; - if ((*A)->isStr("__VA_ARGS__")) - LastArg += ", ..."; - else - LastArg += ", " + (*A)->getName().str() + "..."; - Result.AddPlaceholderChunk(Result.getAllocator().CopyString(LastArg)); + + // Non-variadic macros are simple. + Result.AddPlaceholderChunk( + Result.getAllocator().CopyString((*A)->getName())); } Result.AddChunk(Chunk(CodeCompletionString::CK_RightParen)); return Result.TakeString(); diff --git a/clang/test/Index/complete-macros.c b/clang/test/Index/complete-macros.c index f1c1346a7db82531ddeddf81c47444eb89a5c3e8..df798a8477f6e7169d406b674c3dea0cb3ee20c9 100644 --- a/clang/test/Index/complete-macros.c +++ b/clang/test/Index/complete-macros.c @@ -19,6 +19,7 @@ void f2() { #define variadic2(args...) #define variadic3(args, ...) #define variadic4(first, second, args, ...) +#define variadic5(first, second, args ...) void test_variadic() { @@ -34,8 +35,9 @@ void test_variadic() { // RUN: c-index-test -code-completion-at=%s:15:5 %s | FileCheck -check-prefix=CHECK-CC3 %s // RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:15:5 %s | FileCheck -check-prefix=CHECK-CC3 %s // CHECK-CC3: macro definition:{TypedText nil} (65) -// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:24:2 %s | FileCheck -check-prefix=CHECK-VARIADIC %s +// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:25:2 %s | FileCheck -check-prefix=CHECK-VARIADIC %s // CHECK-VARIADIC: macro definition:{TypedText variadic1}{LeftParen (}{Placeholder ...}{RightParen )} (70) // CHECK-VARIADIC: macro definition:{TypedText variadic2}{LeftParen (}{Placeholder args...}{RightParen )} (70) // CHECK-VARIADIC: macro definition:{TypedText variadic3}{LeftParen (}{Placeholder args, ...}{RightParen )} (70) -// CHECK-VARIADIC: macro definition:{TypedText variadic4}{LeftParen (}{Placeholder first}{Comma , }{Placeholder second...}{Placeholder first, second...}{RightParen )} (70) +// CHECK-VARIADIC: macro definition:{TypedText variadic4}{LeftParen (}{Placeholder first}{Comma , }{Placeholder second}{Comma , }{Placeholder args, ...}{RightParen )} (70) +// CHECK-VARIADIC: macro definition:{TypedText variadic5}{LeftParen (}{Placeholder first}{Comma , }{Placeholder second}{Comma , }{Placeholder args...}{RightParen )} (70)