diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-01-21 00:43:38 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-01-21 00:43:38 +0000 |
commit | c8dc1352071575c36401158094a865ad682fb886 (patch) | |
tree | 005ff18447164b8c6889cfeba1fff77198920761 /lib/Sema/SemaCodeComplete.cpp | |
parent | e424844985873dc7cd7b6c8e47d670c0ce34cfdf (diff) |
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 <rdar://problem/10609117>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148606 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaCodeComplete.cpp')
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 53 |
1 files changed, 21 insertions, 32 deletions
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(); |