diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 29 |
3 files changed, 24 insertions, 9 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index aef3d29894..d1b7a364d8 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -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. diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index 3e854ca279..d8b532e697 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -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), diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 0003b1b0c4..1a8111c551 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -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) |