diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-09-18 23:21:38 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-09-18 23:21:38 +0000 |
commit | 63f07c55d58951574afe9bbb9f7cb3f92eecdd9b (patch) | |
tree | e637e94a7e083348edb2ad9ca4414c0b548183a8 /lib/Sema/CodeCompleteConsumer.cpp | |
parent | 56ff871ae74b1edccff44efe296f3167d694ce48 (diff) |
Make the construction of the code-completion string for a function
template smarter, by taking into account which function template
parameters are deducible from the call arguments. For example,
template<typename RandomAccessIterator>
void sort(RandomAccessIterator first, RandomAccessIterator last);
will have a code-completion string like
sort({RandomAccessIterator first}, {RandomAccessIterator last})
since the template argument for its template parameter is
deducible. On the other hand,
template<class X, class Y>
X* dyn_cast(Y *Val);
will have a code-completion string like
dyn_cast<{class X}>({Y *Val})
since the template type parameter X is not deducible from the function
call.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82306 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/CodeCompleteConsumer.cpp')
-rw-r--r-- | lib/Sema/CodeCompleteConsumer.cpp | 56 |
1 files changed, 48 insertions, 8 deletions
diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp index 2c682ebbfc..8c8d6a1831 100644 --- a/lib/Sema/CodeCompleteConsumer.cpp +++ b/lib/Sema/CodeCompleteConsumer.cpp @@ -765,14 +765,16 @@ static void AddFunctionParameterChunks(ASTContext &Context, /// \brief Add template parameter chunks to the given code completion string. static void AddTemplateParameterChunks(ASTContext &Context, TemplateDecl *Template, - CodeCompletionString *Result) { + CodeCompletionString *Result, + unsigned MaxParameters = 0) { CodeCompletionString *CCStr = Result; bool FirstParameter = true; TemplateParameterList *Params = Template->getTemplateParameters(); - for (TemplateParameterList::iterator P = Params->begin(), - PEnd = Params->end(); - P != PEnd; ++P) { + TemplateParameterList::iterator PEnd = Params->end(); + if (MaxParameters) + PEnd = Params->begin() + MaxParameters; + for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) { bool HasDefaultArg = false; std::string PlaceholderStr; if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) { @@ -850,13 +852,51 @@ CodeCompleteConsumer::CreateCodeCompletionString(Result R) { } if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) { - // FIXME: We treat these like functions for now, but it would be far - // better if we computed the template parameters that are non-deduced from - // a call, then printed only those template parameters in "<...>" before - // printing the function call arguments. CodeCompletionString *Result = new CodeCompletionString; FunctionDecl *Function = FunTmpl->getTemplatedDecl(); Result->AddTextChunk(Function->getNameAsString().c_str()); + + // Figure out which template parameters are deduced (or have default + // arguments). + llvm::SmallVector<bool, 16> Deduced; + getSema().MarkDeducedTemplateParameters(FunTmpl, Deduced); + unsigned LastDeducibleArgument; + for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0; + --LastDeducibleArgument) { + if (!Deduced[LastDeducibleArgument - 1]) { + // C++0x: Figure out if the template argument has a default. If so, + // the user doesn't need to type this argument. + // FIXME: We need to abstract template parameters better! + bool HasDefaultArg = false; + NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam( + LastDeducibleArgument - 1); + if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) + HasDefaultArg = TTP->hasDefaultArgument(); + else if (NonTypeTemplateParmDecl *NTTP + = dyn_cast<NonTypeTemplateParmDecl>(Param)) + HasDefaultArg = NTTP->hasDefaultArgument(); + else { + assert(isa<TemplateTemplateParmDecl>(Param)); + HasDefaultArg + = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument(); + } + + if (!HasDefaultArg) + break; + } + } + + if (LastDeducibleArgument) { + // Some of the function template arguments cannot be deduced from a + // function call, so we introduce an explicit template argument list + // containing all of the arguments up to the first deducible argument. + Result->AddTextChunk("<"); + AddTemplateParameterChunks(getSema().Context, FunTmpl, Result, + LastDeducibleArgument); + Result->AddTextChunk(">"); + } + + // Add the function parameters Result->AddTextChunk("("); AddFunctionParameterChunks(getSema().Context, Function, Result); Result->AddTextChunk(")"); |