diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-11-12 17:40:13 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-11-12 17:40:13 +0000 |
commit | 231edff7907cf151f1d046f287d3ee4ad90037cc (patch) | |
tree | 3e3254a2a414b0969e22c1e9c602ac1687d70d62 /lib | |
parent | 2811ccf48d6d898c42cc4cfad37abedb36236d20 (diff) |
When instantiating a reference to a non-type template parameter of pointer to
member type (e.g., T Class::*Member), build a pointer-to-member
constant expression. Previously, we we just building a simple
declaration reference expression, which meant that the expression was
not treated as a pointer to member.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@87000 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index b303dce06f..721bfb9004 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -700,7 +700,6 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E, NamedDecl *D = E->getDecl(); if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) { if (NTTP->getDepth() < TemplateArgs.getNumLevels()) { - // If the corresponding template argument is NULL or non-existent, it's // because we are performing instantiation from explicitly-specified // template arguments in a function template, but there were some @@ -725,7 +724,38 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E, if (!VD) return SemaRef.ExprError(); - return SemaRef.BuildDeclRefExpr(VD, VD->getType(), E->getLocation(), + if (VD->getDeclContext()->isRecord()) { + // If the value is a class member, we might have a pointer-to-member. + // Determine whether the non-type template template parameter is of + // pointer-to-member type. If so, we need to build an appropriate + // expression for a pointer-to-member, since a "normal" DeclRefExpr + // would refer to the member itself. + if (NTTP->getType()->isMemberPointerType()) { + QualType ClassType + = SemaRef.Context.getTypeDeclType( + cast<RecordDecl>(VD->getDeclContext())); + NestedNameSpecifier *Qualifier + = NestedNameSpecifier::Create(SemaRef.Context, 0, false, + ClassType.getTypePtr()); + CXXScopeSpec SS; + SS.setScopeRep(Qualifier); + OwningExprResult RefExpr + = SemaRef.BuildDeclRefExpr(VD, + VD->getType().getNonReferenceType(), + E->getLocation(), + /*FIXME:*/false, /*FIXME:*/false, + &SS); + if (RefExpr.isInvalid()) + return SemaRef.ExprError(); + + return SemaRef.CreateBuiltinUnaryOp(E->getLocation(), + UnaryOperator::AddrOf, + move(RefExpr)); + } + } + + return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), + E->getLocation(), /*FIXME:*/false, /*FIXME:*/false); } |