Start processing template-ids as types when the template-name refers
to a class template. For example, the template-id 'vector<int>' now
has a nice, sugary type in the type system. What we can do now:

  - Parse template-ids like 'vector<int>' (where 'vector' names a
    class template) and form proper types for them in the type system.
  - Parse icky template-ids like 'A<5>' and 'A<(5 > 0)>' properly,
    using (sadly) a bool in the parser to tell it whether '>' should
    be treated as an operator or not.

This is a baby-step, with major problems and limitations:
  - There are currently two ways that we handle template arguments
  (whether they are types or expressions). These will be merged, and,
  most likely, TemplateArg will disappear.
  - We don't have any notion of the declaration of class template
  specializations or of template instantiations, so all template-ids
  are fancy names for 'int' :)



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64153 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index 8836106..2e2cf53 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -15,6 +15,7 @@
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Parse/DeclSpec.h"
 #include "clang/Parse/Scope.h"
+#include "AstGuard.h"
 
 using namespace clang;
 
@@ -354,7 +355,8 @@
 /// AnnotateTemplateIdToken - The current token is an identifier that
 /// refers to the template declaration Template, and is followed by a
 /// '<'. Turn this template-id into a template-id annotation token.
-void Parser::AnnotateTemplateIdToken(DeclTy *Template, const CXXScopeSpec *SS) {
+void Parser::AnnotateTemplateIdToken(DeclTy *Template, TemplateNameKind TNK,
+                                     const CXXScopeSpec *SS) {
   assert(getLang().CPlusPlus && "Can only annotate template-ids in C++");
   assert(Template && Tok.is(tok::identifier) && NextToken().is(tok::less) &&
          "Parser isn't at the beginning of a template-id");
@@ -366,13 +368,16 @@
   SourceLocation LAngleLoc = ConsumeToken();
 
   // Parse the optional template-argument-list.
-  TemplateArgList TemplateArgs;
-  if (Tok.isNot(tok::greater) && ParseTemplateArgumentList(TemplateArgs)) {
-    // Try to find the closing '>'.
-    SkipUntil(tok::greater, true, true);
-
-    // FIXME: What's our recovery strategy for failed template-argument-lists?
-    return;
+  ASTVector<&ActionBase::DeleteTemplateArg, 8> TemplateArgs(Actions);
+  {
+    MakeGreaterThanTemplateArgumentListTerminator G(GreaterThanIsOperator);
+    if (Tok.isNot(tok::greater) && ParseTemplateArgumentList(TemplateArgs)) {
+      // Try to find the closing '>'.
+      SkipUntil(tok::greater, true, true);
+      
+      // FIXME: What's our recovery strategy for failed template-argument-lists?
+      return;
+    }
   }
 
   if (Tok.isNot(tok::greater))
@@ -382,24 +387,41 @@
   // token, because we'll be replacing it with the template-id.
   SourceLocation RAngleLoc = Tok.getLocation();
   
-  Tok.setKind(tok::annot_template_id);
+  // Build the annotation token.
+  if (TNK == Action::TNK_Function_template) {
+    // This is a function template. We'll be building a template-id
+    // annotation token.
+    TemplateArgs.take(); // Annotation token takes ownership
+    Tok.setKind(tok::annot_template_id);    
+    TemplateIdAnnotation *TemplateId 
+      = (TemplateIdAnnotation *)malloc(sizeof(TemplateIdAnnotation) + 
+                                  sizeof(TemplateArgTy*) * TemplateArgs.size());
+    TemplateId->TemplateNameLoc = TemplateNameLoc;
+    TemplateId->Template = Template;
+    TemplateId->LAngleLoc = LAngleLoc;
+    TemplateId->NumArgs = TemplateArgs.size();
+    TemplateArgTy **Args = (TemplateArgTy**)(TemplateId + 1);
+    for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); Arg != ArgEnd; ++Arg)
+      Args[Arg] = TemplateArgs[Arg];
+    Tok.setAnnotationValue(TemplateId);
+  } else {
+    // This is a type template, e.g., a class template, template
+    // template parameter, or template alias. We'll be building a
+    // "typename" annotation token.
+    TypeTy *Ty 
+      = Actions.ActOnClassTemplateSpecialization(Template,LAngleLoc,
+                                                 move_arg(TemplateArgs),
+                                                 RAngleLoc, SS);
+    Tok.setKind(tok::annot_typename);
+    Tok.setAnnotationValue(Ty);
+  }
+
+  // Common fields for the annotation token
   Tok.setAnnotationEndLoc(RAngleLoc);
   Tok.setLocation(TemplateNameLoc);
   if (SS && SS->isNotEmpty())
     Tok.setLocation(SS->getBeginLoc());
 
-  TemplateIdAnnotation *TemplateId 
-    = (TemplateIdAnnotation *)malloc(sizeof(TemplateIdAnnotation) + 
-                                  sizeof(TemplateArgTy*) * TemplateArgs.size());
-  TemplateId->TemplateNameLoc = TemplateNameLoc;
-  TemplateId->Template = Template;
-  TemplateId->LAngleLoc = LAngleLoc;
-  TemplateId->NumArgs = TemplateArgs.size();
-  TemplateArgTy **Args = (TemplateArgTy**)(TemplateId + 1);
-  for (unsigned Arg = 0, ArgEnd = TemplateArgs.size(); Arg != ArgEnd; ++Arg)
-    Args[Arg] = TemplateArgs[Arg];
-  Tok.setAnnotationValue(TemplateId);
-
   // In case the tokens were cached, have Preprocessor replace them with the
   // annotation token.
   PP.AnnotateCachedTokens(Tok);
@@ -412,8 +434,22 @@
 ///         type-id
 ///         id-expression
 Parser::OwningTemplateArgResult Parser::ParseTemplateArgument() {
-  // FIXME: Implement this!
-  return TemplateArgError();
+  // C++ [temp.arg]p2:
+  //   In a template-argument, an ambiguity between a type-id and an
+  //   expression is resolved to a type-id, regardless of the form of
+  //   the corresponding template-parameter.
+  //
+  // Therefore, we initially try to parse a type-id.
+  if (isTypeIdInParens()) {
+    TypeTy *TypeArg = ParseTypeName();
+    return Actions.ActOnTypeTemplateArgument(TypeArg);
+  }
+
+  OwningExprResult ExprArg = ParseExpression();
+  if (ExprArg.isInvalid())
+    return TemplateArgError();
+
+  return Actions.ActOnExprTemplateArgument(move(ExprArg));
 }
 
 /// ParseTemplateArgumentList - Parse a C++ template-argument-list