Store the unresolved class type in MemberPointerType's Class field,

from Peter Collingbourne!

llvm-svn: 86030
This commit is contained in:
Douglas Gregor 2009-11-04 16:49:01 +00:00
parent b73beb36f5
commit 615ac67fb8
4 changed files with 37 additions and 9 deletions

View File

@ -1374,7 +1374,7 @@ QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) {
// If the pointee or class type isn't canonical, this won't be a canonical
// type either, so fill in the canonical type field.
QualType Canonical;
if (!T.isCanonical()) {
if (!T.isCanonical() || !Cls->isCanonicalUnqualified()) {
Canonical = getMemberPointerType(getCanonicalType(T),getCanonicalType(Cls));
// Get the new insert position for the node we care about.

View File

@ -291,7 +291,7 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E) {
const FunctionProtoType *FPT =
MPT->getPointeeType()->getAs<FunctionProtoType>();
const CXXRecordDecl *RD =
cast<CXXRecordDecl>(cast<RecordType>(MPT->getClass())->getDecl());
cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
const llvm::FunctionType *FTy =
CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(RD, FPT),

View File

@ -22,6 +22,7 @@
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Parse/DeclSpec.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/ErrorHandling.h"
using namespace clang;
/// \brief Perform adjustment on the parameter type of a function.
@ -1162,15 +1163,29 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
}
// The scope spec must refer to a class, or be dependent.
QualType ClsType;
if (isDependentScopeSpecifier(DeclType.Mem.Scope())) {
if (isDependentScopeSpecifier(DeclType.Mem.Scope())
|| dyn_cast_or_null<CXXRecordDecl>(
computeDeclContext(DeclType.Mem.Scope()))) {
NestedNameSpecifier *NNS
= (NestedNameSpecifier *)DeclType.Mem.Scope().getScopeRep();
assert(NNS->getAsType() && "Nested-name-specifier must name a type");
ClsType = QualType(NNS->getAsType(), 0);
} else if (CXXRecordDecl *RD
= dyn_cast_or_null<CXXRecordDecl>(
computeDeclContext(DeclType.Mem.Scope()))) {
ClsType = Context.getTagDeclType(RD);
NestedNameSpecifier *NNSPrefix = NNS->getPrefix();
switch (NNS->getKind()) {
case NestedNameSpecifier::Identifier:
ClsType = Context.getTypenameType(NNSPrefix, NNS->getAsIdentifier());
break;
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::Global:
llvm::llvm_unreachable("Nested-name-specifier must name a type");
break;
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate:
ClsType = QualType(NNS->getAsType(), 0);
if (NNSPrefix)
ClsType = Context.getQualifiedNameType(NNSPrefix, ClsType);
break;
}
} else {
Diag(DeclType.Mem.Scope().getBeginLoc(),
diag::err_illegal_decl_mempointer_in_nonclass)

View File

@ -32,6 +32,15 @@ public:
F Af;
};
template <typename T> struct TT {
int T::t::*pti;
};
struct I {
typedef I t;
int x;
};
void pr(const F& b) {
printf(" %d %f\n", b.iF, b.fF);
}
@ -69,9 +78,12 @@ void test_aggr_pdata_1(A* pa) {
int main()
{
A a1;
TT<I> tt;
I i;
int A::* pa = &A::Ai;
float A::* pf = &A::f;
double A::* pd = &A::d;
tt.pti = &I::x;
printf("%d %d %d\n", &A::Ai, &A::f, &A::d);
printf("%d\n", &A::B::iB);
printf("%d\n", &A::B1::iB1);
@ -81,6 +93,7 @@ int main()
printf("%d\n", &A::B::V::iV);
printf("%d\n", &A::B1::V::iV);
printf("%d, %f, %f \n", a1.*pa, a1.*pf, a1.*pd);
printf("%d\n", i.*tt.pti);
test_aggr_pdata(a1);
test_aggr_pdata_1(&a1);
}