Use explicitly-specified template argument lists to help naming

explicit template specializations, when available.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82824 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2009-09-25 23:53:26 +00:00
Родитель 7416524283
Коммит 0b60d9e009
6 изменённых файлов: 68 добавлений и 20 удалений

Просмотреть файл

@ -254,6 +254,12 @@ public:
} }
bool getSuppressAllDiagnostics() const { return SuppressAllDiagnostics; } bool getSuppressAllDiagnostics() const { return SuppressAllDiagnostics; }
/// \brief Pretend that the last diagnostic issued was ignored. This can
/// be used by clients who suppress diagnostics themselves.
void setLastDiagnosticIgnored() {
LastDiagLevel = Ignored;
}
/// setExtensionHandlingBehavior - This controls whether otherwise-unmapped /// setExtensionHandlingBehavior - This controls whether otherwise-unmapped
/// extension diagnostics are mapped onto ignore/warning/error. This /// extension diagnostics are mapped onto ignore/warning/error. This
/// corresponds to the GCC -pedantic and -pedantic-errors option. /// corresponds to the GCC -pedantic and -pedantic-errors option.

Просмотреть файл

@ -403,6 +403,7 @@ public:
// deduction, and that error is one of the SFINAE errors, // deduction, and that error is one of the SFINAE errors,
// suppress the diagnostic. // suppress the diagnostic.
++NumSFINAEErrors; ++NumSFINAEErrors;
Diags.setLastDiagnosticIgnored();
return SemaDiagnosticBuilder(*this); return SemaDiagnosticBuilder(*this);
} }
@ -2444,6 +2445,10 @@ public:
TemplateParameterList *TemplateParams, TemplateParameterList *TemplateParams,
AccessSpecifier AS); AccessSpecifier AS);
void translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn,
SourceLocation *TemplateArgLocs,
llvm::SmallVector<TemplateArgument, 16> &TemplateArgs);
QualType CheckTemplateIdType(TemplateName Template, QualType CheckTemplateIdType(TemplateName Template,
SourceLocation TemplateLoc, SourceLocation TemplateLoc,
SourceLocation LAngleLoc, SourceLocation LAngleLoc,

Просмотреть файл

@ -2693,15 +2693,49 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
isOutOfScopePreviousDeclaration(PrevDecl, DC, Context))) isOutOfScopePreviousDeclaration(PrevDecl, DC, Context)))
PrevDecl = 0; PrevDecl = 0;
// FIXME: If the declarator has a template argument list but // If the declarator is a template-id, translate the parser's template
// isFunctionTemplateSpecialization is false, this is a function template // argument list into our AST format.
// specialization but the user forgot the "template<>" header. Complain about bool HasExplicitTemplateArgs = false;
// the missing template<> header and set isFunctionTemplateSpecialization. llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
SourceLocation LAngleLoc, RAngleLoc;
if (D.getKind() == Declarator::DK_TemplateId) {
TemplateIdAnnotation *TemplateId = D.getTemplateId();
ASTTemplateArgsPtr TemplateArgsPtr(*this,
TemplateId->getTemplateArgs(),
TemplateId->getTemplateArgIsType(),
TemplateId->NumArgs);
translateTemplateArguments(TemplateArgsPtr,
TemplateId->getTemplateArgLocations(),
TemplateArgs);
TemplateArgsPtr.release();
HasExplicitTemplateArgs = true;
LAngleLoc = TemplateId->LAngleLoc;
RAngleLoc = TemplateId->RAngleLoc;
if (FunctionTemplate) {
// FIXME: Diagnostic function template with explicit template
// arguments.
HasExplicitTemplateArgs = false;
} else if (!isFunctionTemplateSpecialization &&
!D.getDeclSpec().isFriendSpecified()) {
// We have encountered something that the user meant to be a
// specialization (because it has explicitly-specified template
// arguments) but that was not introduced with a "template<>" (or had
// too few of them).
Diag(D.getIdentifierLoc(), diag::err_template_spec_needs_header)
<< SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)
<< CodeModificationHint::CreateInsertion(
D.getDeclSpec().getSourceRange().getBegin(),
"template<> ");
isFunctionTemplateSpecialization = true;
}
}
if (isFunctionTemplateSpecialization && if (isFunctionTemplateSpecialization &&
CheckFunctionTemplateSpecialization(NewFD, CheckFunctionTemplateSpecialization(NewFD, HasExplicitTemplateArgs,
/*FIXME:*/false, SourceLocation(), LAngleLoc, TemplateArgs.data(),
0, 0, SourceLocation(), TemplateArgs.size(), RAngleLoc,
PrevDecl)) PrevDecl))
NewFD->setInvalidDecl(); NewFD->setInvalidDecl();

Просмотреть файл

@ -1037,9 +1037,8 @@ Sema::MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc,
/// \brief Translates template arguments as provided by the parser /// \brief Translates template arguments as provided by the parser
/// into template arguments used by semantic analysis. /// into template arguments used by semantic analysis.
static void void Sema::translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn,
translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn, SourceLocation *TemplateArgLocs,
SourceLocation *TemplateArgLocs,
llvm::SmallVector<TemplateArgument, 16> &TemplateArgs) { llvm::SmallVector<TemplateArgument, 16> &TemplateArgs) {
TemplateArgs.reserve(TemplateArgsIn.size()); TemplateArgs.reserve(TemplateArgsIn.size());
@ -3409,7 +3408,8 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
return DeclPtrTy(); return DeclPtrTy();
} }
// Translate the parser's template argument list in our AST format. // If the declarator is a template-id, translate the parser's template
// argument list into our AST format.
bool HasExplicitTemplateArgs = false; bool HasExplicitTemplateArgs = false;
llvm::SmallVector<TemplateArgument, 16> TemplateArgs; llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
if (D.getKind() == Declarator::DK_TemplateId) { if (D.getKind() == Declarator::DK_TemplateId) {
@ -3423,8 +3423,7 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
TemplateArgs); TemplateArgs);
HasExplicitTemplateArgs = true; HasExplicitTemplateArgs = true;
} }
// C++ [temp.explicit]p1: // C++ [temp.explicit]p1:
// A [...] function [...] can be explicitly instantiated from its template. // A [...] function [...] can be explicitly instantiated from its template.
// A member function [...] of a class template can be explicitly // A member function [...] of a class template can be explicitly

Просмотреть файл

@ -1,6 +0,0 @@
// RN: clang-cc -fsyntax-only -verify %s
// RUN: false
// XFAIL
template<int N> void f(int (&array)[N]);
template<> void f<1>(int (&array)[1]) { }

Просмотреть файл

@ -12,6 +12,7 @@ void test_f0() {
// Function template specialization where there are no matches // Function template specialization where there are no matches
template<> void f0(char (&array)[1]); // expected-error{{no function template matches}} template<> void f0(char (&array)[1]); // expected-error{{no function template matches}}
template<> void f0<2>(int (&array)[2]) { }
// Function template specialization that requires partial ordering // Function template specialization that requires partial ordering
template<typename T, int N> void f1(T (&array)[N]); // expected-note{{matches}} template<typename T, int N> void f1(T (&array)[N]); // expected-note{{matches}}
@ -23,3 +24,12 @@ template<> void f1(int (&array)[1]);
// Function template specialization that results in an ambiguity // Function template specialization that results in an ambiguity
template<typename T> void f1(T (&array)[17]); // expected-note{{matches}} template<typename T> void f1(T (&array)[17]); // expected-note{{matches}}
template<> void f1(int (&array)[17]); // expected-error{{ambiguous}} template<> void f1(int (&array)[17]); // expected-error{{ambiguous}}
// Resolving that ambiguity with explicitly-specified template arguments.
template<int N> void f2(double (&array)[N]);
template<typename T> void f2(T (&array)[42]);
template<> void f2<double>(double (&array)[42]);
template<> void f2<42>(double (&array)[42]);
void f2<25>(double (&array)[25]); // expected-error{{specialization}}