[cfe-commits] r82824 - in /cfe/trunk: include/clang/Basic/Diagnostic.h lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaTemplate.cpp test/SemaCXX/template-specialization.cpp test/SemaTemplate/function-template-specialization.cpp
Douglas Gregor
dgregor at apple.com
Fri Sep 25 16:53:26 PDT 2009
Author: dgregor
Date: Fri Sep 25 18:53:26 2009
New Revision: 82824
URL: http://llvm.org/viewvc/llvm-project?rev=82824&view=rev
Log:
Use explicitly-specified template argument lists to help naming
explicit template specializations, when available.
Removed:
cfe/trunk/test/SemaCXX/template-specialization.cpp
Modified:
cfe/trunk/include/clang/Basic/Diagnostic.h
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/SemaTemplate/function-template-specialization.cpp
Modified: cfe/trunk/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Diagnostic.h?rev=82824&r1=82823&r2=82824&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Diagnostic.h (original)
+++ cfe/trunk/include/clang/Basic/Diagnostic.h Fri Sep 25 18:53:26 2009
@@ -254,6 +254,12 @@
}
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
/// extension diagnostics are mapped onto ignore/warning/error. This
/// corresponds to the GCC -pedantic and -pedantic-errors option.
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=82824&r1=82823&r2=82824&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Sep 25 18:53:26 2009
@@ -403,6 +403,7 @@
// deduction, and that error is one of the SFINAE errors,
// suppress the diagnostic.
++NumSFINAEErrors;
+ Diags.setLastDiagnosticIgnored();
return SemaDiagnosticBuilder(*this);
}
@@ -2444,6 +2445,10 @@
TemplateParameterList *TemplateParams,
AccessSpecifier AS);
+ void translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn,
+ SourceLocation *TemplateArgLocs,
+ llvm::SmallVector<TemplateArgument, 16> &TemplateArgs);
+
QualType CheckTemplateIdType(TemplateName Template,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=82824&r1=82823&r2=82824&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Sep 25 18:53:26 2009
@@ -2693,15 +2693,49 @@
isOutOfScopePreviousDeclaration(PrevDecl, DC, Context)))
PrevDecl = 0;
- // FIXME: If the declarator has a template argument list but
- // isFunctionTemplateSpecialization is false, this is a function template
- // specialization but the user forgot the "template<>" header. Complain about
- // the missing template<> header and set isFunctionTemplateSpecialization.
-
+ // If the declarator is a template-id, translate the parser's template
+ // argument list into our AST format.
+ bool HasExplicitTemplateArgs = false;
+ 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 &&
- CheckFunctionTemplateSpecialization(NewFD,
- /*FIXME:*/false, SourceLocation(),
- 0, 0, SourceLocation(),
+ CheckFunctionTemplateSpecialization(NewFD, HasExplicitTemplateArgs,
+ LAngleLoc, TemplateArgs.data(),
+ TemplateArgs.size(), RAngleLoc,
PrevDecl))
NewFD->setInvalidDecl();
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=82824&r1=82823&r2=82824&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri Sep 25 18:53:26 2009
@@ -1037,9 +1037,8 @@
/// \brief Translates template arguments as provided by the parser
/// into template arguments used by semantic analysis.
-static void
-translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn,
- SourceLocation *TemplateArgLocs,
+void Sema::translateTemplateArguments(ASTTemplateArgsPtr &TemplateArgsIn,
+ SourceLocation *TemplateArgLocs,
llvm::SmallVector<TemplateArgument, 16> &TemplateArgs) {
TemplateArgs.reserve(TemplateArgsIn.size());
@@ -3409,7 +3408,8 @@
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;
llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
if (D.getKind() == Declarator::DK_TemplateId) {
@@ -3423,8 +3423,7 @@
TemplateArgs);
HasExplicitTemplateArgs = true;
}
-
-
+
// C++ [temp.explicit]p1:
// A [...] function [...] can be explicitly instantiated from its template.
// A member function [...] of a class template can be explicitly
Removed: cfe/trunk/test/SemaCXX/template-specialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/template-specialization.cpp?rev=82823&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/template-specialization.cpp (original)
+++ cfe/trunk/test/SemaCXX/template-specialization.cpp (removed)
@@ -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]) { }
Modified: cfe/trunk/test/SemaTemplate/function-template-specialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/function-template-specialization.cpp?rev=82824&r1=82823&r2=82824&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/function-template-specialization.cpp (original)
+++ cfe/trunk/test/SemaTemplate/function-template-specialization.cpp Fri Sep 25 18:53:26 2009
@@ -12,6 +12,7 @@
// Function template specialization where there are no 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
template<typename T, int N> void f1(T (&array)[N]); // expected-note{{matches}}
@@ -23,3 +24,12 @@
// Function template specialization that results in an ambiguity
template<typename T> void f1(T (&array)[17]); // expected-note{{matches}}
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}}
More information about the cfe-commits
mailing list