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);
+}