From 8a4386b3634065b96d08f94736bc1f953e385f50 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 4 Nov 2009 23:20:05 +0000 Subject: [PATCH] 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 --- lib/Sema/TreeTransform.h | 37 +++++++++++++++++++++++--- test/SemaTemplate/template-id-expr.cpp | 17 +++++++++++- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 5713da9fa5..51393a37c0 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -941,7 +941,13 @@ public: 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 @@ public: 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 @@ TreeTransform::TransformMemberExpr(MemberExpr *E, 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 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 @@ TreeTransform::TransformMemberExpr(MemberExpr *E, Qualifier, E->getQualifierRange(), E->getMemberLoc(), - Member); + Member, + E->hasExplicitTemplateArgumentList(), + E->getLAngleLoc(), + TransArgs.data(), + TransArgs.size(), + E->getRAngleLoc(), + 0); } template diff --git a/test/SemaTemplate/template-id-expr.cpp b/test/SemaTemplate/template-id-expr.cpp index a0cbe44084..dd8694afa7 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 struct isa_impl_cl { @@ -12,3 +11,19 @@ void isa(const Y &Val) { return isa_impl_cl::template isa(Val); } class Value; void f0(const Value &Val) { isa(Val); } + +// Implicit template-ids. +template +struct X0 { + template + void f1(); + + template + void f2(U) { + f1(); + } +}; + +void test_X0_int(X0 xi, float f) { + xi.f2(f); +} -- 2.40.0