diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-04-27 16:10:10 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-04-27 16:10:10 +0000 |
commit | 66c45154186b7786d5dca645d548d73c47cf5d87 (patch) | |
tree | b7675b47a2d5a31d680172f31334169745501647 | |
parent | 1744a3504af13343f4bc0e566f6d7349fc6e3f04 (diff) |
When instantiating UnresolvedLookupExpr and UnresolvedMemberExpr
expressions, be sure to set the naming class of the LookupResult
structure. Fixes PR6947.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102434 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/TreeTransform.h | 40 | ||||
-rw-r--r-- | test/SemaTemplate/instantiate-method.cpp | 25 |
2 files changed, 65 insertions, 0 deletions
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index f80747b69f..2f36807659 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -5336,6 +5336,20 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr( SS.setScopeRep(Qualifier); SS.setRange(Old->getQualifierRange()); + + // If this nested-name-specifier refers to a class type, that is the + // naming class. + if (const Type *NamedType = Qualifier->getAsType()) + if (const RecordType *NamedRecord = NamedType->getAs<RecordType>()) + R.setNamingClass(cast<CXXRecordDecl>(NamedRecord->getDecl())); + } else if (Old->getNamingClass()) { + CXXRecordDecl *NamingClass + = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl( + Old->getNameLoc(), + Old->getNamingClass())); + if (!NamingClass) + return SemaRef.ExprError(); + R.setNamingClass(NamingClass); } // If we have no template arguments, it's a normal declaration name. @@ -5721,6 +5735,7 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) BaseType = getDerived().TransformType(Old->getBaseType()); } + CXXRecordDecl *NamingClass = 0; NestedNameSpecifier *Qualifier = 0; if (Old->getQualifier()) { Qualifier @@ -5728,6 +5743,12 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) Old->getQualifierRange()); if (Qualifier == 0) return SemaRef.ExprError(); + + // If this nested-name-specifier refers to a class type, that is the + // naming class. + if (const Type *NamedType = Qualifier->getAsType()) + if (const RecordType *NamedRecord = NamedType->getAs<RecordType>()) + NamingClass = cast<CXXRecordDecl>(NamedRecord->getDecl()); } LookupResult R(SemaRef, Old->getMemberName(), Old->getMemberLoc(), @@ -5762,6 +5783,25 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) R.resolveKind(); + // Determine the naming class, if we haven't already. + if (!NamingClass) { + QualType T = BaseType; + if (const PointerType *PointerTy = T->getAs<PointerType>()) + T = PointerTy->getPointeeType(); + if (const RecordType *NamedRecord = T->getAs<RecordType>()) + NamingClass = cast<CXXRecordDecl>(NamedRecord->getDecl()); + } + + if (!NamingClass && Old->getNamingClass()) { + NamingClass = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl( + Old->getMemberLoc(), + Old->getNamingClass())); + if (!NamingClass) + return SemaRef.ExprError(); + } + if (NamingClass) + R.setNamingClass(NamingClass); + TemplateArgumentListInfo TransArgs; if (Old->hasExplicitTemplateArgs()) { TransArgs.setLAngleLoc(Old->getLAngleLoc()); diff --git a/test/SemaTemplate/instantiate-method.cpp b/test/SemaTemplate/instantiate-method.cpp index 3ef07d356d..c0325cfa6c 100644 --- a/test/SemaTemplate/instantiate-method.cpp +++ b/test/SemaTemplate/instantiate-method.cpp @@ -127,3 +127,28 @@ namespace test1 { }; template class B<int>; } + +namespace PR6947 { + template< class T > + struct X { + int f0( ) + { + typedef void ( X::*impl_fun_ptr )( ); + impl_fun_ptr pImpl = &X::template + f0_impl1<int>; + } + private: + int f1() { + } + template< class Processor> + void f0_impl1( ) + { + } + }; + + char g0() { + X<int> pc; + pc.f0(); + } + +} |