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/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;