From: Eric Liu Date: Fri, 6 Jul 2018 09:43:57 +0000 (+0000) Subject: [SemaCodeComplete] Expose a method to create CodeCompletionString for macros. X-Git-Tag: llvmorg-7.0.0-rc1~2083 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=00f43c959d420a6c64ac14288dde630bb3b1f3bd;p=platform%2Fupstream%2Fllvm.git [SemaCodeComplete] Expose a method to create CodeCompletionString for macros. Summary: The method only takes PPreprocessor and don't require structures that might not be available (e.g. Sema and ASTContext) when CodeCompletionString needs to be generated for macros. Reviewers: sammccall Reviewed By: sammccall Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D48973 llvm-svn: 336427 --- diff --git a/clang/include/clang/Sema/CodeCompleteConsumer.h b/clang/include/clang/Sema/CodeCompleteConsumer.h index d3f6b65..8022fa7 100644 --- a/clang/include/clang/Sema/CodeCompleteConsumer.h +++ b/clang/include/clang/Sema/CodeCompleteConsumer.h @@ -918,6 +918,13 @@ public: CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo, bool IncludeBriefComments); + /// Creates a new code-completion string for the macro result. Similar to the + /// above overloads, except this only requires preprocessor information. + /// The result kind must be `RK_Macro`. + CodeCompletionString * + CreateCodeCompletionStringForMacro(Preprocessor &PP, + CodeCompletionAllocator &Allocator, + CodeCompletionTUInfo &CCTUInfo); /// Retrieve the name that should be used to order a result. /// diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index a2252f2..9beefc0 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -2745,6 +2745,52 @@ CodeCompletionString *CodeCompletionResult::CreateCodeCompletionString(Sema &S, CCTUInfo, IncludeBriefComments); } +CodeCompletionString *CodeCompletionResult::CreateCodeCompletionStringForMacro( + Preprocessor &PP, CodeCompletionAllocator &Allocator, + CodeCompletionTUInfo &CCTUInfo) { + assert(Kind == RK_Macro); + CodeCompletionBuilder Result(Allocator, CCTUInfo, Priority, Availability); + const MacroInfo *MI = PP.getMacroInfo(Macro); + Result.AddTypedTextChunk(Result.getAllocator().CopyString(Macro->getName())); + + if (!MI || !MI->isFunctionLike()) + return Result.TakeString(); + + // Format a function-like macro with placeholders for the arguments. + Result.AddChunk(CodeCompletionString::CK_LeftParen); + MacroInfo::param_iterator A = MI->param_begin(), AEnd = MI->param_end(); + + // C99 variadic macros add __VA_ARGS__ at the end. Skip it. + if (MI->isC99Varargs()) { + --AEnd; + + if (A == AEnd) { + Result.AddPlaceholderChunk("..."); + } + } + + for (MacroInfo::param_iterator A = MI->param_begin(); A != AEnd; ++A) { + if (A != MI->param_begin()) + Result.AddChunk(CodeCompletionString::CK_Comma); + + if (MI->isVariadic() && (A + 1) == AEnd) { + SmallString<32> Arg = (*A)->getName(); + if (MI->isC99Varargs()) + Arg += ", ..."; + else + Arg += "..."; + Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg)); + break; + } + + // Non-variadic macros are simple. + Result.AddPlaceholderChunk( + Result.getAllocator().CopyString((*A)->getName())); + } + Result.AddChunk(CodeCompletionString::CK_RightParen); + return Result.TakeString(); +} + /// If possible, create a new code completion string for the given /// result. /// @@ -2758,6 +2804,9 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx, CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo, bool IncludeBriefComments) { + if (Kind == RK_Macro) + return CreateCodeCompletionStringForMacro(PP, Allocator, CCTUInfo); + CodeCompletionBuilder Result(Allocator, CCTUInfo, Priority, Availability); PrintingPolicy Policy = getCompletionPrintingPolicy(Ctx, PP); @@ -2782,50 +2831,6 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx, Result.AddTypedTextChunk(Keyword); return Result.TakeString(); } - - if (Kind == RK_Macro) { - const MacroInfo *MI = PP.getMacroInfo(Macro); - Result.AddTypedTextChunk( - Result.getAllocator().CopyString(Macro->getName())); - - if (!MI || !MI->isFunctionLike()) - return Result.TakeString(); - - // Format a function-like macro with placeholders for the arguments. - Result.AddChunk(CodeCompletionString::CK_LeftParen); - MacroInfo::param_iterator A = MI->param_begin(), AEnd = MI->param_end(); - - // C99 variadic macros add __VA_ARGS__ at the end. Skip it. - if (MI->isC99Varargs()) { - --AEnd; - - if (A == AEnd) { - Result.AddPlaceholderChunk("..."); - } - } - - for (MacroInfo::param_iterator A = MI->param_begin(); A != AEnd; ++A) { - if (A != MI->param_begin()) - Result.AddChunk(CodeCompletionString::CK_Comma); - - if (MI->isVariadic() && (A+1) == AEnd) { - SmallString<32> Arg = (*A)->getName(); - if (MI->isC99Varargs()) - Arg += ", ..."; - else - Arg += "..."; - Result.AddPlaceholderChunk(Result.getAllocator().CopyString(Arg)); - break; - } - - // Non-variadic macros are simple. - Result.AddPlaceholderChunk( - Result.getAllocator().CopyString((*A)->getName())); - } - Result.AddChunk(CodeCompletionString::CK_RightParen); - return Result.TakeString(); - } - assert(Kind == RK_Declaration && "Missed a result kind?"); const NamedDecl *ND = Declaration; Result.addParentContext(ND->getDeclContext());