aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-04-27 16:10:10 +0000
committerDouglas Gregor <dgregor@apple.com>2010-04-27 16:10:10 +0000
commit66c45154186b7786d5dca645d548d73c47cf5d87 (patch)
treeb7675b47a2d5a31d680172f31334169745501647
parent1744a3504af13343f4bc0e566f6d7349fc6e3f04 (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.h40
-rw-r--r--test/SemaTemplate/instantiate-method.cpp25
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();
+ }
+
+}