[cfe-commits] r82306 - in /cfe/trunk: lib/Sema/CodeCompleteConsumer.cpp lib/Sema/Sema.h lib/Sema/SemaTemplateDeduction.cpp test/CodeCompletion/function-templates.cpp
Douglas Gregor
dgregor at apple.com
Fri Sep 18 16:21:38 PDT 2009
Author: dgregor
Date: Fri Sep 18 18:21:38 2009
New Revision: 82306
URL: http://llvm.org/viewvc/llvm-project?rev=82306&view=rev
Log:
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.
Added:
cfe/trunk/test/CodeCompletion/function-templates.cpp (with props)
Modified:
cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
Modified: cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp?rev=82306&r1=82305&r2=82306&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp (original)
+++ cfe/trunk/lib/Sema/CodeCompleteConsumer.cpp Fri Sep 18 18:21:38 2009
@@ -765,14 +765,16 @@
/// \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 @@
}
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(")");
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=82306&r1=82305&r2=82306&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Sep 18 18:21:38 2009
@@ -2750,8 +2750,10 @@
void MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs,
bool OnlyDeduced,
- llvm::SmallVectorImpl<bool> &Deduced);
-
+ llvm::SmallVectorImpl<bool> &Used);
+ void MarkDeducedTemplateParameters(FunctionTemplateDecl *FunctionTemplate,
+ llvm::SmallVectorImpl<bool> &Deduced);
+
//===--------------------------------------------------------------------===//
// C++ Template Instantiation
//
Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=82306&r1=82305&r2=82306&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Fri Sep 18 18:21:38 2009
@@ -2199,3 +2199,18 @@
for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
::MarkUsedTemplateParameters(*this, TemplateArgs[I], OnlyDeduced, Used);
}
+
+/// \brief Marks all of the template parameters that will be deduced by a
+/// call to the given function template.
+void Sema::MarkDeducedTemplateParameters(FunctionTemplateDecl *FunctionTemplate,
+ llvm::SmallVectorImpl<bool> &Deduced) {
+ TemplateParameterList *TemplateParams
+ = FunctionTemplate->getTemplateParameters();
+ Deduced.clear();
+ Deduced.resize(TemplateParams->size());
+
+ FunctionDecl *Function = FunctionTemplate->getTemplatedDecl();
+ for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I)
+ ::MarkUsedTemplateParameters(*this, Function->getParamDecl(I)->getType(),
+ true, Deduced);
+}
Added: cfe/trunk/test/CodeCompletion/function-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeCompletion/function-templates.cpp?rev=82306&view=auto
==============================================================================
--- cfe/trunk/test/CodeCompletion/function-templates.cpp (added)
+++ cfe/trunk/test/CodeCompletion/function-templates.cpp Fri Sep 18 18:21:38 2009
@@ -0,0 +1,16 @@
+// RUN: clang-cc -fsyntax-only -code-completion-dump=1 %s -o - | FileCheck -check-prefix=CC1 %s &&
+// RUN: true
+
+namespace std {
+ template<typename RandomAccessIterator>
+ void sort(RandomAccessIterator first, RandomAccessIterator last);
+
+ template<class X, class Y>
+ X* dyn_cast(Y *Val);
+}
+
+void f() {
+ // CHECK-CC1: dyn_cast<<#class X#>>(<#Y *Val#>)
+ // CHECK-CC1: sort(<#RandomAccessIterator first#>, <#RandomAccessIterator last#>)
+ std::
+
Propchange: cfe/trunk/test/CodeCompletion/function-templates.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/CodeCompletion/function-templates.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/CodeCompletion/function-templates.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the cfe-commits
mailing list