Preliminary AST representation and semantic analysis for
explicitly-specified template argument lists in member reference
expressions, e.g.,

  x->f<int>()



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80646 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index a8cdb67..63d2831 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1602,12 +1602,32 @@
                                                    SourceLocation LLoc,
                                                    ExprArg Idx,
                                                    SourceLocation RLoc);
+
+  OwningExprResult BuildMemberReferenceExpr(Scope *S, ExprArg Base,
+                                            SourceLocation OpLoc,
+                                            tok::TokenKind OpKind,
+                                            SourceLocation MemberLoc,
+                                            DeclarationName MemberName,
+                                            DeclPtrTy ImplDecl,
+                                            const CXXScopeSpec *SS = 0) {
+    // FIXME: Temporary helper while we migrate existing calls to 
+    // BuildMemberReferenceExpr to support explicitly-specified template
+    // arguments.
+    return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, MemberLoc,
+                                    MemberName, false, SourceLocation(), 0, 0,
+                                    SourceLocation(), ImplDecl, SS);
+  }
   
   OwningExprResult BuildMemberReferenceExpr(Scope *S, ExprArg Base,
                                             SourceLocation OpLoc,
                                             tok::TokenKind OpKind,
                                             SourceLocation MemberLoc,
                                             DeclarationName MemberName,
+                                            bool HasExplicitTemplateArgs,
+                                            SourceLocation LAngleLoc,
+                                const TemplateArgument *ExplicitTemplateArgs,
+                                            unsigned NumExplicitTemplateArgs,
+                                            SourceLocation RAngleLoc,
                                             DeclPtrTy ImplDecl,
                                             const CXXScopeSpec *SS = 0);
   
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index df94f20..d272be9 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -885,7 +885,10 @@
   if (SS && SS->isSet())
     return MemberExpr::Create(C, Base, isArrow, 
                               (NestedNameSpecifier *)SS->getScopeRep(),
-                              SS->getRange(), Member, Loc, Ty);
+                              SS->getRange(), Member, Loc, 
+                              // FIXME: Explicit template argument lists
+                              false, SourceLocation(), 0, 0, SourceLocation(),
+                              Ty);
   
   return new (C) MemberExpr(Base, isArrow, Member, Loc, Ty);
 }
@@ -1980,6 +1983,11 @@
 Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
                                tok::TokenKind OpKind, SourceLocation MemberLoc,
                                DeclarationName MemberName, 
+                               bool HasExplicitTemplateArgs,
+                               SourceLocation LAngleLoc,
+                               const TemplateArgument *ExplicitTemplateArgs,
+                               unsigned NumExplicitTemplateArgs,
+                               SourceLocation RAngleLoc,
                                DeclPtrTy ObjCImpDecl, const CXXScopeSpec *SS) {
   if (SS && SS->isInvalid())
     return ExprError();
@@ -2153,14 +2161,34 @@
     if (FunctionTemplateDecl *FunTmpl 
           = dyn_cast<FunctionTemplateDecl>(MemberDecl)) {
       MarkDeclarationReferenced(MemberLoc, MemberDecl);
+      
+      if (HasExplicitTemplateArgs)
+        return Owned(MemberExpr::Create(Context, BaseExpr, OpKind == tok::arrow, 
+                             (NestedNameSpecifier *)(SS? SS->getScopeRep() : 0), 
+                                       SS? SS->getRange() : SourceRange(),
+                                        FunTmpl, MemberLoc, true, 
+                                        LAngleLoc, ExplicitTemplateArgs, 
+                                        NumExplicitTemplateArgs, RAngleLoc, 
+                                        Context.OverloadTy));
+      
       return Owned(BuildMemberExpr(Context, BaseExpr, OpKind == tok::arrow, SS,
                                    FunTmpl, MemberLoc,
                                    Context.OverloadTy));
     }
     if (OverloadedFunctionDecl *Ovl
-          = dyn_cast<OverloadedFunctionDecl>(MemberDecl))
+          = dyn_cast<OverloadedFunctionDecl>(MemberDecl)) {
+      if (HasExplicitTemplateArgs)
+        return Owned(MemberExpr::Create(Context, BaseExpr, OpKind == tok::arrow, 
+                             (NestedNameSpecifier *)(SS? SS->getScopeRep() : 0), 
+                                        SS? SS->getRange() : SourceRange(),
+                                        Ovl, MemberLoc, true, 
+                                        LAngleLoc, ExplicitTemplateArgs, 
+                                        NumExplicitTemplateArgs, RAngleLoc, 
+                                        Context.OverloadTy));
+
       return Owned(BuildMemberExpr(Context, BaseExpr, OpKind == tok::arrow, SS,
                                    Ovl, MemberLoc, Context.OverloadTy));
+    }
     if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) {
       MarkDeclarationReferenced(MemberLoc, MemberDecl);
       return Owned(BuildMemberExpr(Context, BaseExpr, OpKind == tok::arrow, SS,
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index dc58ecc..3593826 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -1831,21 +1831,6 @@
                                   ConvName, DeclPtrTy(), SS);
 }
 
-Sema::OwningExprResult
-Sema::ActOnMemberTemplateIdReferenceExpr(Scope *S, ExprArg Base,
-                                         SourceLocation OpLoc,
-                                         tok::TokenKind OpKind,
-                                         const CXXScopeSpec &SS,
-                                         TemplateTy Template,
-                                         SourceLocation TemplateNameLoc,
-                                         SourceLocation LAngleLoc,
-                                         ASTTemplateArgsPtr TemplateArgs,
-                                         SourceLocation *TemplateArgLocs,
-                                         SourceLocation RAngleLoc) {
-  // FIXME: Implement!
-  return ExprError();
-}
-
 Sema::OwningExprResult Sema::ActOnFinishFullExpr(ExprArg Arg) {
   Expr *FullExpr = Arg.takeAs<Expr>();
   if (FullExpr)
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index f22c117..1427d48 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -4563,9 +4563,11 @@
         AddMethodCandidate(Method, ObjectArg, Args, NumArgs, CandidateSet, 
                            /*SuppressUserConversions=*/false);
       else
-        AddMethodTemplateCandidate(cast<FunctionTemplateDecl>(*Func), 
-                                   /*FIXME:*/false, /*FIXME:*/0, 
-                                   /*FIXME:*/0, ObjectArg, Args, NumArgs,
+        AddMethodTemplateCandidate(cast<FunctionTemplateDecl>(*Func),
+                                   MemExpr->hasExplicitTemplateArgumentList(),
+                                   MemExpr->getTemplateArgs(),
+                                   MemExpr->getNumTemplateArgs(),
+                                   ObjectArg, Args, NumArgs,
                                    CandidateSet,
                                    /*SuppressUsedConversions=*/false);
     }
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index fb25e99..3985c1c 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1084,6 +1084,41 @@
                              RAngleLoc);
 }
 
+Sema::OwningExprResult
+Sema::ActOnMemberTemplateIdReferenceExpr(Scope *S, ExprArg Base,
+                                         SourceLocation OpLoc,
+                                         tok::TokenKind OpKind,
+                                         const CXXScopeSpec &SS,
+                                         TemplateTy TemplateD,
+                                         SourceLocation TemplateNameLoc,
+                                         SourceLocation LAngleLoc,
+                                         ASTTemplateArgsPtr TemplateArgsIn,
+                                         SourceLocation *TemplateArgLocs,
+                                         SourceLocation RAngleLoc) {
+  TemplateName Template = TemplateD.getAsVal<TemplateName>();
+  
+  // FIXME: We're going to end up looking up the template based on its name,
+  // twice!
+  DeclarationName Name;
+  if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl())
+    Name = ActualTemplate->getDeclName();
+  else if (OverloadedFunctionDecl *Ovl = Template.getAsOverloadedFunctionDecl())
+    Name = Ovl->getDeclName();
+  else
+    assert(false && "Cannot support dependent template names yet");
+  
+  // Translate the parser's template argument list in our AST format.
+  llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
+  translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
+  TemplateArgsIn.release();
+  
+  // Do we have the save the actual template name? We might need it...
+  return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, TemplateNameLoc,
+                                  Name, true, LAngleLoc,
+                                  TemplateArgs.data(), TemplateArgs.size(),
+                                  RAngleLoc, DeclPtrTy(), &SS);  
+}
+
 /// \brief Form a dependent template name.
 ///
 /// This action forms a dependent template name given the template
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 3879b39..386a2c6 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -2964,7 +2964,7 @@
     Qualifier 
       = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
                                                   E->getQualifierRange());
-    if (Qualifier == 0);
+    if (Qualifier == 0)
       return SemaRef.ExprError();
   }