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/MinimalAction.cpp b/lib/Parse/MinimalAction.cpp
index 2d6c9a6..ce15cf9 100644
--- a/lib/Parse/MinimalAction.cpp
+++ b/lib/Parse/MinimalAction.cpp
@@ -95,14 +95,11 @@
   return false;
 }
 
-  /// isTemplateName - Determines whether the identifier II is a
-  /// template name in the current scope, and returns the template
-  /// declaration if II names a template. An optional CXXScope can be
-  /// passed to indicate the C++ scope in which the identifier will be
-  /// found. 
-Action::DeclTy *MinimalAction::isTemplateName(IdentifierInfo &II, Scope *S,
-                                              const CXXScopeSpec *SS ) {
-  return 0;
+Action::TemplateNameKind 
+MinimalAction::isTemplateName(IdentifierInfo &II, Scope *S,
+                              DeclTy *&TemplateDecl,
+                              const CXXScopeSpec *SS) {
+  return TNK_Non_template;
 }
 
 /// ActOnDeclarator - If this is a typedef declarator, we modify the
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 73a09ee..5d601bc 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -499,6 +499,7 @@
       Token Next = NextToken();
       TypeTy *TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(),
                                             Next.getLocation(), CurScope, &SS);
+
       if (TypeRep == 0)
         goto DoneWithDeclSpec;
 
@@ -553,9 +554,23 @@
       // It has to be available as a typedef too!
       TypeTy *TypeRep = Actions.getTypeName(*Tok.getIdentifierInfo(), 
                                             Tok.getLocation(), CurScope);
+
+      if (TypeRep == 0 && getLang().CPlusPlus && NextToken().is(tok::less)) {
+        // If we have a template name, annotate the token and try again.
+        DeclTy *Template = 0;
+        if (TemplateNameKind TNK =
+              Actions.isTemplateName(*Tok.getIdentifierInfo(), CurScope,
+                                     Template)) {
+          AnnotateTemplateIdToken(Template, TNK, 0);
+          continue;
+        }
+      }
+
       if (TypeRep == 0)
         goto DoneWithDeclSpec;
       
+
+
       // C++: If the identifier is actually the name of the class type
       // being defined and the next token is a '(', then this is a
       // constructor declaration. We're done with the decl-specifiers
@@ -1752,11 +1767,12 @@
 
         // If this identifier is followed by a '<', we may have a template-id.
         DeclTy *Template;
+        Action::TemplateNameKind TNK;
         if (getLang().CPlusPlus && NextToken().is(tok::less) &&
-            (Template = Actions.isTemplateName(*Tok.getIdentifierInfo(), 
-                                               CurScope))) {
+            (TNK = Actions.isTemplateName(*Tok.getIdentifierInfo(), 
+                                          CurScope, Template))) {
           IdentifierInfo *II = Tok.getIdentifierInfo();
-          AnnotateTemplateIdToken(Template, 0);
+          AnnotateTemplateIdToken(Template, TNK, 0);
           // FIXME: Set the declarator to a template-id. How? I don't
           // know... for now, just use the identifier.
           D.SetIdentifier(II, Tok.getLocation());
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 332ad77..0f04d13 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -55,8 +55,17 @@
 /// getBinOpPrecedence - Return the precedence of the specified binary operator
 /// token.  This returns:
 ///
-static prec::Level getBinOpPrecedence(tok::TokenKind Kind) {
+static prec::Level getBinOpPrecedence(tok::TokenKind Kind, 
+                                      bool GreaterThanIsOperator) {
   switch (Kind) {
+  case tok::greater:
+    // The '>' token can act as either an operator or as the ending
+    // token for a template argument list.  
+    // FIXME: '>>' is similar, for error recovery and C++0x.
+    if (GreaterThanIsOperator)
+      return prec::Relational;
+    return prec::Unknown;
+      
   default:                        return prec::Unknown;
   case tok::comma:                return prec::Comma;
   case tok::equal:
@@ -80,8 +89,7 @@
   case tok::equalequal:           return prec::Equality;
   case tok::lessequal:
   case tok::less:
-  case tok::greaterequal:
-  case tok::greater:              return prec::Relational;
+  case tok::greaterequal:         return prec::Relational;
   case tok::lessless:
   case tok::greatergreater:       return prec::Shift;
   case tok::plus:
@@ -266,7 +274,7 @@
 /// LHS and has a precedence of at least MinPrec.
 Parser::OwningExprResult
 Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, unsigned MinPrec) {
-  unsigned NextTokPrec = getBinOpPrecedence(Tok.getKind());
+  unsigned NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator);
   SourceLocation ColonLoc;
 
   while (1) {
@@ -316,7 +324,7 @@
     // Remember the precedence of this operator and get the precedence of the
     // operator immediately to the right of the RHS.
     unsigned ThisPrec = NextTokPrec;
-    NextTokPrec = getBinOpPrecedence(Tok.getKind());
+    NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator);
 
     // Assignment and conditional expressions are right-associative.
     bool isRightAssoc = ThisPrec == prec::Conditional ||
@@ -335,7 +343,7 @@
       if (RHS.isInvalid())
         return move(RHS);
 
-      NextTokPrec = getBinOpPrecedence(Tok.getKind());
+      NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator);
     }
     assert(NextTokPrec <= ThisPrec && "Recursion didn't work!");
 
@@ -1104,6 +1112,7 @@
 Parser::ParseParenExpression(ParenParseOption &ExprType,
                              TypeTy *&CastTy, SourceLocation &RParenLoc) {
   assert(Tok.is(tok::l_paren) && "Not a paren expr!");
+  MakeGreaterThanAnOperator G(GreaterThanIsOperator);
   SourceLocation OpenLoc = ConsumeParen();
   OwningExprResult Result(Actions, true);
   CastTy = 0;
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
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index f28767a..7b09d21 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -20,7 +20,8 @@
 using namespace clang;
 
 Parser::Parser(Preprocessor &pp, Action &actions)
-  : PP(pp), Actions(actions), Diags(PP.getDiagnostics()) {
+  : PP(pp), Actions(actions), Diags(PP.getDiagnostics()), 
+    GreaterThanIsOperator(true) {
   Tok.setKind(tok::eof);
   CurScope = 0;
   NumCachedScopes = 0;
@@ -785,10 +786,15 @@
     }
     
     // If this is a template-id, annotate the template-id token.
-    if (NextToken().is(tok::less))
-      if (DeclTy *Template =
-          Actions.isTemplateName(*Tok.getIdentifierInfo(), CurScope, &SS))
-        AnnotateTemplateIdToken(Template, &SS);
+    if (NextToken().is(tok::less)) {
+      DeclTy *Template;
+      if (TemplateNameKind TNK 
+            = Actions.isTemplateName(*Tok.getIdentifierInfo(),
+                                     CurScope, Template, &SS)) {
+        AnnotateTemplateIdToken(Template, TNK, &SS);
+        return true;
+      }
+    }
 
     // We either have an identifier that is not a type name or we have
     // just created a template-id that might be a type name. Both