Basic representation of C++ class templates, from Andrew Sutton.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63750 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 114f4cb..e2601b6 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -1726,7 +1726,7 @@
 
         // If this identifier is followed by a '<', we may have a template-id.
         DeclTy *Template;
-        if (NextToken().is(tok::less) &&
+        if (getLang().CPlusPlus && NextToken().is(tok::less) &&
             (Template = Actions.isTemplateName(*Tok.getIdentifierInfo(), 
                                                CurScope))) {
           IdentifierInfo *II = Tok.getIdentifierInfo();
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 1fbe32a..b2b0d8f 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -345,8 +345,8 @@
     return;
   }
 
-  // Parse the tag portion of this.
-  DeclTy *TagDecl 
+  // Create the tag portion of the class, possibly resulting in a template.
+  DeclTy *TagOrTempDecl
     = Actions.ActOnTag(CurScope, TagType, TK, StartLoc, SS, Name, 
                        NameLoc, Attr,
                        Action::MultiTemplateParamsArg(
@@ -356,15 +356,15 @@
 
   // Parse the optional base clause (C++ only).
   if (getLang().CPlusPlus && Tok.is(tok::colon)) {
-    ParseBaseClause(TagDecl);
+    ParseBaseClause(TagOrTempDecl);
   }
 
   // If there is a body, parse it and inform the actions module.
   if (Tok.is(tok::l_brace))
     if (getLang().CPlusPlus)
-      ParseCXXMemberSpecification(StartLoc, TagType, TagDecl);
+      ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempDecl);
     else
-      ParseStructUnionBody(StartLoc, TagType, TagDecl);
+      ParseStructUnionBody(StartLoc, TagType, TagOrTempDecl);
   else if (TK == Action::TK_Definition) {
     // FIXME: Complain that we have a base-specifier list but no
     // definition.
@@ -372,7 +372,7 @@
   }
 
   const char *PrevSpec = 0;
-  if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec, TagDecl))
+  if (DS.SetTypeSpecType(TagType, StartLoc, PrevSpec, TagOrTempDecl))
     Diag(StartLoc, diag::err_invalid_decl_spec_combination) << PrevSpec;
 }
 
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index b9a5514..e95c106 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -39,7 +39,7 @@
   //
   // We parse multiple levels non-recursively so that we can build a
   // single data structure containing all of the template parameter
-  // lists, and easily differentiate between the case above and:
+  // lists easily differentiate between the case above and:
   //
   //   template<typename T>
   //   class A {
@@ -82,19 +82,16 @@
   } while (Tok.is(tok::kw_export) || Tok.is(tok::kw_template));
 
   // Parse the actual template declaration.
-  DeclTy *TemplateDecl = ParseDeclarationOrFunctionDefinition(&ParamLists);
-
-  return TemplateDecl;
+  return ParseDeclarationOrFunctionDefinition(&ParamLists);
 }
 
 /// ParseTemplateParameters - Parses a template-parameter-list enclosed in
-/// angle brackets. Depth is the depth of this
-/// template-parameter-list, which is the number of template headers
-/// directly enclosing this template header. TemplateParams is the
-/// current list of template parameters we're building. The template
-/// parameter we parse will be added to this list. LAngleLoc and
-/// RAngleLoc will receive the positions of the '<' and '>',
-/// respectively, that enclose this template parameter list.
+/// angle brackets. Depth is the depth of this template-parameter-list, which
+/// is the number of template headers directly enclosing this template header.
+/// TemplateParams is the current list of template parameters we're building.
+/// The template parameter we parse will be added to this list. LAngleLoc and
+/// RAngleLoc will receive the positions of the '<' and '>', respectively, 
+/// that enclose this template parameter list.
 bool Parser::ParseTemplateParameters(unsigned Depth,
                                      TemplateParameterList &TemplateParams,
                                      SourceLocation &LAngleLoc,
@@ -223,8 +220,8 @@
     return 0;
   }
   
-  DeclTy *TypeParam = Actions.ActOnTypeParameter(CurScope, TypenameKeyword, 
-						 KeyLoc, ParamName, NameLoc,
+  DeclTy *TypeParam = Actions.ActOnTypeParameter(CurScope, TypenameKeyword,
+                                                 KeyLoc, ParamName, NameLoc,
                                                  Depth, Position);
 
   // Grab a default type id (if given).
@@ -251,7 +248,7 @@
   SourceLocation TemplateLoc = ConsumeToken();
   TemplateParameterList TemplateParams; 
   SourceLocation LParenLoc, RParenLoc;
-  if(!ParseTemplateParameters(Depth+1, TemplateParams, LParenLoc,
+  if(!ParseTemplateParameters(Depth + 1, TemplateParams, LParenLoc,
                               RParenLoc)) {
     return 0;
   }
@@ -266,10 +263,11 @@
   SourceLocation ClassLoc = ConsumeToken();
 
   // Get the identifier, if given.
-  IdentifierInfo* ident = 0;
+  SourceLocation NameLoc;
+  IdentifierInfo* ParamName = 0;
   if(Tok.is(tok::identifier)) {
-    ident = Tok.getIdentifierInfo();
-    ConsumeToken();
+    ParamName = Tok.getIdentifierInfo();
+    NameLoc = ConsumeToken();
   } else if(Tok.is(tok::equal) || Tok.is(tok::comma) || Tok.is(tok::greater)) {
     // Unnamed template parameter. Don't have to do anything here, just
     // don't consume this token.
@@ -279,6 +277,8 @@
   }
 
   // Get the a default value, if given.
+  // FIXME: I think that the results of this block need to be passed to the
+  // act-on call, so we can assemble the parameter correctly.
   OwningExprResult DefaultExpr(Actions);
   if(Tok.is(tok::equal)) {
     ConsumeToken();
@@ -288,8 +288,9 @@
     }
   }
 
-  // FIXME: Add an action for template template parameters.
-  return 0;
+  return Actions.ActOnTemplateTemplateParameter(CurScope, TemplateLoc,
+                                                &TemplateParams, ParamName,
+                                                NameLoc, Depth, Position);
 }
 
 /// ParseNonTypeTemplateParameter - Handle the parsing of non-type
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index c5c7dd4..2f7e2ea 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -379,7 +379,6 @@
   case tok::kw_export:    // As in 'export template'
     // A function definition cannot start with a these keywords.
     return ParseDeclaration(Declarator::FileContext);
-       
   default:
     // We can't tell whether this is a function-definition or declaration yet.
     return ParseDeclarationOrFunctionDefinition();