[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