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.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74021 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 426f56f..7153bad 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -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)) {
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index eabe10f..daf9500 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -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)
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 3f96948..fe13b56 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -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, 
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 51a75b3..10ab5c2 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -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);
 }
 
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index e98ebb1..26e5673 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -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,