When instantiating a MemberExpr, be sure to instantiate the
explicitly-specified template arguments, too!


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86066 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 5713da9..51393a3 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -941,7 +941,13 @@
                                      NestedNameSpecifier *Qualifier,
                                      SourceRange QualifierRange,
                                      SourceLocation MemberLoc,
-                                     NamedDecl *Member) {
+                                     NamedDecl *Member,
+                                     bool HasExplicitTemplateArgs,
+                                     SourceLocation LAngleLoc,
+                              const TemplateArgumentLoc *ExplicitTemplateArgs,
+                                     unsigned NumExplicitTemplateArgs,
+                                     SourceLocation RAngleLoc,
+                                     NamedDecl *FirstQualifierInScope) {
     if (!Member->getDeclName()) {
       // We have a reference to an unnamed field.
       assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
@@ -963,8 +969,14 @@
                                               isArrow? tok::arrow : tok::period,
                                               MemberLoc,
                                               Member->getDeclName(),
+                                              HasExplicitTemplateArgs,
+                                              LAngleLoc,
+                                              ExplicitTemplateArgs,
+                                              NumExplicitTemplateArgs,
+                                              RAngleLoc,
                                      /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
-                                              &SS);
+                                              &SS,
+                                              FirstQualifierInScope);
   }
 
   /// \brief Build a new binary operator expression.
@@ -3656,9 +3668,20 @@
   if (!getDerived().AlwaysRebuild() &&
       Base.get() == E->getBase() &&
       Qualifier == E->getQualifier() &&
-      Member == E->getMemberDecl())
+      Member == E->getMemberDecl() &&
+      !E->hasExplicitTemplateArgumentList())
     return SemaRef.Owned(E->Retain());
 
+  llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs;
+  if (E->hasExplicitTemplateArgumentList()) {
+    TransArgs.resize(E->getNumTemplateArgs());
+    for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
+      if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
+                                                 TransArgs[I]))
+        return SemaRef.ExprError();
+    }
+  }
+  
   // FIXME: Bogus source location for the operator
   SourceLocation FakeOperatorLoc
     = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
@@ -3668,7 +3691,13 @@
                                         Qualifier,
                                         E->getQualifierRange(),
                                         E->getMemberLoc(),
-                                        Member);
+                                        Member,
+                                        E->hasExplicitTemplateArgumentList(),
+                                        E->getLAngleLoc(),
+                                        TransArgs.data(),
+                                        TransArgs.size(),
+                                        E->getRAngleLoc(),
+                                        0);
 }
 
 template<typename Derived>
diff --git a/test/SemaTemplate/template-id-expr.cpp b/test/SemaTemplate/template-id-expr.cpp
index a0cbe44..dd8694a 100644
--- a/test/SemaTemplate/template-id-expr.cpp
+++ b/test/SemaTemplate/template-id-expr.cpp
@@ -1,5 +1,4 @@
 // RUN: clang-cc -fsyntax-only -verify %s
-
 // PR5336
 template<typename FromCl>
 struct isa_impl_cl {
@@ -12,3 +11,19 @@
 
 class Value;
 void f0(const Value &Val) { isa<Value>(Val); }
+
+// Implicit template-ids.
+template<typename T>
+struct X0 {
+  template<typename U>
+  void f1();
+  
+  template<typename U>
+  void f2(U) {
+    f1<U>();
+  }
+};
+
+void test_X0_int(X0<int> xi, float f) {
+  xi.f2(f);
+}