[cfe-commits] r74021 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Parse/Action.h include/clang/Parse/Parser.h lib/Parse/ParseDecl.cpp lib/Parse/ParseTemplate.cpp lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaTemplate.cpp test/SemaTemplate/template-decl-fail.cpp

Douglas Gregor dgregor at apple.com
Tue Jun 23 16:11:29 PDT 2009


Author: dgregor
Date: Tue Jun 23 18:11:28 2009
New Revision: 74021

URL: http://llvm.org/viewvc/llvm-project?rev=74021&view=rev
Log:
Start propagating template parameter lists to the right places to
handle function templates. There's no actual code for function
templates yet, but at least we complain about typedef templates.

Added:
    cfe/trunk/test/SemaTemplate/template-decl-fail.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseTemplate.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=74021&r1=74020&r2=74021&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jun 23 18:11:28 2009
@@ -651,6 +651,7 @@
 def err_template_outside_namespace_or_class_scope : Error<
   "templates can only be declared in namespace or class scope">;
 def err_template_linkage : Error<"templates must have C++ linkage">;
+def err_template_typedef : Error<"a typedef cannot be a template">;
 def err_template_unnamed_class : Error<
   "cannot declare a class template with no name">;
 def err_template_param_list_different_arity : Error<

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=74021&r1=74020&r2=74021&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Tue Jun 23 18:11:28 2009
@@ -1453,6 +1453,18 @@
     return DeclResult();
   }
 
+  /// \brief Invoked when a declarator that has one or more template parameter
+  /// lists has been parsed.
+  ///
+  /// This action is similar to ActOnDeclarator(), except that the declaration
+  /// being created somehow involves a template, e.g., it is a template 
+  /// declaration or specialization.
+  virtual DeclPtrTy ActOnTemplateDeclarator(Scope *S, 
+                              MultiTemplateParamsArg TemplateParameterLists,
+                                            Declarator &D) {
+    return DeclPtrTy();
+  }
+  
   /// \brief Process the explicit instantiation of a class template
   /// specialization.
   ///

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=74021&r1=74020&r2=74021&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Tue Jun 23 18:11:28 2009
@@ -909,7 +909,8 @@
   DeclGroupPtrTy ParseSimpleDeclaration(unsigned Context,
                                         SourceLocation &DeclEnd,
                                         bool RequireSemi = true);
-  DeclPtrTy ParseDeclarationAfterDeclarator(Declarator &D);
+  DeclPtrTy ParseDeclarationAfterDeclarator(Declarator &D,
+               const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
   DeclGroupPtrTy ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
   DeclPtrTy ParseFunctionStatementBody(DeclPtrTy Decl);
   DeclPtrTy ParseFunctionTryBlock(DeclPtrTy Decl);

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=74021&r1=74020&r2=74021&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue Jun 23 18:11:28 2009
@@ -371,7 +371,8 @@
 /// According to the standard grammar, =default and =delete are function
 /// definitions, but that definitely doesn't fit with the parser here.
 ///
-Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D) {
+Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D,
+                                     const ParsedTemplateInfo &TemplateInfo) {
   // If a simple-asm-expr is present, parse it.
   if (Tok.is(tok::kw_asm)) {
     SourceLocation Loc;
@@ -393,7 +394,13 @@
   }
   
   // Inform the current actions module that we just parsed this declarator.
-  DeclPtrTy ThisDecl = Actions.ActOnDeclarator(CurScope, D);
+  DeclPtrTy ThisDecl = TemplateInfo.TemplateParams? 
+      Actions.ActOnTemplateDeclarator(CurScope,
+                             Action::MultiTemplateParamsArg(Actions,
+                                          TemplateInfo.TemplateParams->data(),
+                                          TemplateInfo.TemplateParams->size()),
+                                    D)
+    : Actions.ActOnDeclarator(CurScope, D);
   
   // Parse declarator '=' initializer.
   if (Tok.is(tok::equal)) {

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=74021&r1=74020&r2=74021&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Tue Jun 23 18:11:28 2009
@@ -170,7 +170,8 @@
   // If we have a declaration or declarator list, handle it.
   if (isDeclarationAfterDeclarator()) {
     // Parse this declaration.
-    DeclPtrTy ThisDecl = ParseDeclarationAfterDeclarator(DeclaratorInfo);
+    DeclPtrTy ThisDecl = ParseDeclarationAfterDeclarator(DeclaratorInfo,
+                                                         TemplateInfo);
 
     if (Tok.is(tok::comma)) {
       Diag(Tok, diag::err_multiple_template_declarators)

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=74021&r1=74020&r2=74021&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Jun 23 18:11:28 2009
@@ -421,9 +421,12 @@
   virtual DeclSpec::TST isTagName(IdentifierInfo &II, Scope *S);
   
   virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D) {
-    return ActOnDeclarator(S, D, false);
+    return HandleDeclarator(S, D, MultiTemplateParamsArg(*this), false);
   }
-  DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D, bool IsFunctionDefinition);
+  
+  DeclPtrTy HandleDeclarator(Scope *S, Declarator &D, 
+                             MultiTemplateParamsArg TemplateParameterLists,
+                             bool IsFunctionDefinition);
   void RegisterLocallyScopedExternCDecl(NamedDecl *ND, NamedDecl *PrevDecl,
                                         Scope *S);
   void DiagnoseFunctionSpecifiers(Declarator& D);
@@ -437,6 +440,7 @@
                                 bool &Redeclaration);
   NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
                                      QualType R, NamedDecl* PrevDecl, 
+                                     MultiTemplateParamsArg TemplateParamLists,
                                      bool IsFunctionDefinition,
                                      bool &Redeclaration);
   void CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
@@ -2068,6 +2072,10 @@
                                    AttributeList *Attr,
                                  MultiTemplateParamsArg TemplateParameterLists);
 
+  virtual DeclPtrTy ActOnTemplateDeclarator(Scope *S, 
+                                  MultiTemplateParamsArg TemplateParameterLists,
+                                            Declarator &D);
+  
   virtual DeclResult
   ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
                              unsigned TagSpec, 

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=74021&r1=74020&r2=74021&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Jun 23 18:11:28 2009
@@ -1385,7 +1385,9 @@
 }
 
 Sema::DeclPtrTy 
-Sema::ActOnDeclarator(Scope *S, Declarator &D, bool IsFunctionDefinition) {
+Sema::HandleDeclarator(Scope *S, Declarator &D, 
+                       MultiTemplateParamsArg TemplateParamLists,
+                       bool IsFunctionDefinition) {
   DeclarationName Name = GetNameForDeclarator(D);
 
   // All of these full declarators require an identifier.  If it doesn't have
@@ -1500,9 +1502,15 @@
 
   bool Redeclaration = false;
   if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
+    if (TemplateParamLists.size()) {
+      Diag(D.getIdentifierLoc(), diag::err_template_typedef);
+      return DeclPtrTy();
+    }
+      
     New = ActOnTypedefDeclarator(S, D, DC, R, PrevDecl, Redeclaration);
   } else if (R->isFunctionType()) {
     New = ActOnFunctionDeclarator(S, D, DC, R, PrevDecl, 
+                                  move(TemplateParamLists),
                                   IsFunctionDefinition, Redeclaration);
   } else {
     New = ActOnVariableDeclarator(S, D, DC, R, PrevDecl, Redeclaration);
@@ -1987,6 +1995,7 @@
 NamedDecl* 
 Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
                               QualType R, NamedDecl* PrevDecl,
+                              MultiTemplateParamsArg TemplateParamLists,
                               bool IsFunctionDefinition, bool &Redeclaration) {
   assert(R.getTypePtr()->isFunctionType());
 
@@ -2044,6 +2053,11 @@
       << R->getAsFunctionType()->getResultType();
     D.setInvalidType();
   }
+
+  // Check that we can declare a template here.
+  if (TemplateParamLists.size() && 
+      CheckTemplateDeclScope(S, TemplateParamLists))
+    return 0;
   
   bool isVirtualOkay = false;
   FunctionDecl *NewFD;
@@ -2987,7 +3001,9 @@
   
   Scope *ParentScope = FnBodyScope->getParent();
 
-  DeclPtrTy DP = ActOnDeclarator(ParentScope, D, /*IsFunctionDefinition=*/true);
+  DeclPtrTy DP = HandleDeclarator(ParentScope, D, 
+                                  MultiTemplateParamsArg(*this),
+                                  /*IsFunctionDefinition=*/true);
   return ActOnStartOfFunctionDef(FnBodyScope, DP);
 }
 

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=74021&r1=74020&r2=74021&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Jun 23 18:11:28 2009
@@ -2499,6 +2499,13 @@
   return DeclPtrTy::make(Specialization);
 }
 
+Sema::DeclPtrTy 
+Sema::ActOnTemplateDeclarator(Scope *S, 
+                              MultiTemplateParamsArg TemplateParameterLists,
+                              Declarator &D) {
+  return HandleDeclarator(S, D, move(TemplateParameterLists), false);
+}
+
 // Explicit instantiation of a class template specialization
 Sema::DeclResult
 Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,

Added: cfe/trunk/test/SemaTemplate/template-decl-fail.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/template-decl-fail.cpp?rev=74021&view=auto

==============================================================================
--- cfe/trunk/test/SemaTemplate/template-decl-fail.cpp (added)
+++ cfe/trunk/test/SemaTemplate/template-decl-fail.cpp Tue Jun 23 18:11:28 2009
@@ -0,0 +1,3 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+template<typename T> typedef T X; // expected-error{{typedef cannot be a template}}





More information about the cfe-commits mailing list