зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
7416524283
Коммит
0b60d9e009
|
@ -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}}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче