From: Douglas Gregor Date: Sat, 21 Jan 2012 00:43:38 +0000 (+0000) Subject: Fix the code completion string for variadic macros with more than one X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c8dc1352071575c36401158094a865ad682fb886;p=clang Fix the code completion string for variadic macros with more than one argument, which was broken and very ugly (and even had a test case to make *sure* it was broken and ugly). Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148606 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 3d1c3bca86..5a553513b4 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/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/test/Index/complete-macros.c b/test/Index/complete-macros.c index f1c1346a7d..df798a8477 100644 --- a/test/Index/complete-macros.c +++ b/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)