summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/CodeCompleteConsumer.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-09-18 23:21:38 +0000
committerDouglas Gregor <dgregor@apple.com>2009-09-18 23:21:38 +0000
commitce23bae4f82a4d2999f8bd502d8277fc3d0db8da (patch)
treec2744e50f692f18fdbb14f1794207aa6eab0f4e3 /clang/lib/Sema/CodeCompleteConsumer.cpp
parent3f6ca389270770fd7d4beeaa3df27fb6b21c0ef4 (diff)
downloadbcm5719-llvm-ce23bae4f82a4d2999f8bd502d8277fc3d0db8da.tar.gz
bcm5719-llvm-ce23bae4f82a4d2999f8bd502d8277fc3d0db8da.zip
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. llvm-svn: 82306
Diffstat (limited to 'clang/lib/Sema/CodeCompleteConsumer.cpp')
-rw-r--r--clang/lib/Sema/CodeCompleteConsumer.cpp56
1 files changed, 48 insertions, 8 deletions
diff --git a/clang/lib/Sema/CodeCompleteConsumer.cpp b/clang/lib/Sema/CodeCompleteConsumer.cpp
index 2c682ebbfc4..8c8d6a18318 100644
--- a/clang/lib/Sema/CodeCompleteConsumer.cpp
+++ b/clang/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(")");
OpenPOWER on IntegriCloud