Add parsing for references to member function templates with explicit
template argument lists, e.g., x.f<int>().

Semantic analysis will be a separate commit.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80624 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index d00d6d2..36b6dd4 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -941,7 +941,7 @@
                                                  ObjCImpDecl, &SS);
         ConsumeToken();
       } else if (getLang().CPlusPlus && Tok.is(tok::tilde)) {
-        // We have a C++ pseudo-destructor.
+        // We have a C++ pseudo-destructor or a destructor call, e.g., t.~T()
         
         // Consume the tilde.
         ConsumeToken();
@@ -961,6 +961,8 @@
                                                      &SS);
         ConsumeToken();
       } else if (getLang().CPlusPlus && Tok.is(tok::kw_operator)) {
+        // We have a reference to a member operator, e.g., t.operator int or
+        // t.operator+.
         if (OverloadedOperatorKind Op = TryParseOperatorFunctionId()) {
           if (!LHS.isInvalid())
             LHS = Actions.ActOnOverloadedOperatorReferenceExpr(CurScope,
@@ -983,6 +985,27 @@
           // Don't emit a diagnostic; ParseConversionFunctionId does it for us
           return ExprError();
         }
+      } else if (getLang().CPlusPlus && Tok.is(tok::annot_template_id)) {
+        // We have a reference to a member template along with explicitly-
+        // specified template arguments, e.g., t.f<int>.
+        TemplateIdAnnotation *TemplateId 
+          = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
+        if (!LHS.isInvalid()) {
+          ASTTemplateArgsPtr TemplateArgsPtr(Actions, 
+                                             TemplateId->getTemplateArgs(),
+                                             TemplateId->getTemplateArgIsType(),
+                                             TemplateId->NumArgs);
+          
+          LHS = Actions.ActOnMemberTemplateIdReferenceExpr(CurScope, move(LHS),
+                                                           OpLoc, OpKind, SS,
+                                        TemplateTy::make(TemplateId->Template),
+                                                   TemplateId->TemplateNameLoc,
+                                                         TemplateId->LAngleLoc,
+                                                           TemplateArgsPtr,
+                                         TemplateId->getTemplateArgLocations(),
+                                                         TemplateId->RAngleLoc);
+        }
+        ConsumeToken();
       } else {
         if (getLang().CPlusPlus)
           Actions.ActOnCXXExitMemberScope(CurScope, MemberSS);