aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorMatheus Izvekov <mizvekov@gmail.com>2025-03-21 10:54:24 -0300
committerGitHub <noreply@github.com>2025-03-21 10:54:24 -0300
commit141656644959ea43b61868ef16e3d2782d40ea51 (patch)
treed6be138e2335bdf573b8872b2d46b4629bb30905 /clang/lib
parentac9049df7e62e2ca4dc5d103593b51639b5715e3 (diff)
downloadllvm-141656644959ea43b61868ef16e3d2782d40ea51.zip
llvm-141656644959ea43b61868ef16e3d2782d40ea51.tar.gz
llvm-141656644959ea43b61868ef16e3d2782d40ea51.tar.bz2
Reland: [clang] NFC: Clear some uses of MemberPointerType::getClass (#132317)
Relands Original PR: https://github.com/llvm/llvm-project/pull/131965 Addresses https://github.com/llvm/llvm-project/pull/131965#issuecomment-2741619498 * Fixes isIncompleteType for injected classes This clears up some uses of getClass on MemberPointerType when equivalent uses of getMostRecentCXXRecordDecl would be just as simple or simpler. This is split-off from a larger patch which removes getClass, in order to facilitate review.
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ByteCode/Compiler.cpp10
-rw-r--r--clang/lib/AST/ExprConstant.cpp5
-rw-r--r--clang/lib/AST/MicrosoftMangle.cpp10
-rw-r--r--clang/lib/AST/Type.cpp20
-rw-r--r--clang/lib/CodeGen/CGCXXABI.cpp5
-rw-r--r--clang/lib/CodeGen/CGClass.cpp7
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp3
-rw-r--r--clang/lib/CodeGen/CGExprCXX.cpp8
-rw-r--r--clang/lib/CodeGen/CodeGenTypes.cpp2
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp11
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp48
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp32
-rw-r--r--clang/lib/Sema/SemaLookup.cpp7
-rw-r--r--clang/lib/Sema/SemaOverload.cpp37
-rw-r--r--clang/lib/Sema/SemaStmt.cpp3
15 files changed, 105 insertions, 103 deletions
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 91640c4..9dc02b2 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -238,8 +238,9 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
const auto *FromMP = SubExpr->getType()->getAs<MemberPointerType>();
const auto *ToMP = CE->getType()->getAs<MemberPointerType>();
- unsigned DerivedOffset = collectBaseOffset(QualType(ToMP->getClass(), 0),
- QualType(FromMP->getClass(), 0));
+ unsigned DerivedOffset =
+ Ctx.collectBaseOffset(ToMP->getMostRecentCXXRecordDecl(),
+ FromMP->getMostRecentCXXRecordDecl());
if (!this->delegate(SubExpr))
return false;
@@ -253,8 +254,9 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
const auto *FromMP = SubExpr->getType()->getAs<MemberPointerType>();
const auto *ToMP = CE->getType()->getAs<MemberPointerType>();
- unsigned DerivedOffset = collectBaseOffset(QualType(FromMP->getClass(), 0),
- QualType(ToMP->getClass(), 0));
+ unsigned DerivedOffset =
+ Ctx.collectBaseOffset(FromMP->getMostRecentCXXRecordDecl(),
+ ToMP->getMostRecentCXXRecordDecl());
if (!this->delegate(SubExpr))
return false;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 1f97c3c..8b40cdf 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -10556,8 +10556,9 @@ bool MemberPointerExprEvaluator::VisitCastExpr(const CastExpr *E) {
if (!Result.castToDerived(Derived))
return Error(E);
}
- const Type *FinalTy = E->getType()->castAs<MemberPointerType>()->getClass();
- if (!Result.castToDerived(FinalTy->getAsCXXRecordDecl()))
+ if (!Result.castToDerived(E->getType()
+ ->castAs<MemberPointerType>()
+ ->getMostRecentCXXRecordDecl()))
return Error(E);
return true;
}
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index fe34251..15de407 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -695,7 +695,7 @@ void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {
mangleQualifiers(MPT->getPointeeType().getQualifiers(), true);
// Member pointers are suffixed with a back reference to the member
// pointer's class name.
- mangleName(MPT->getClass()->getAsCXXRecordDecl());
+ mangleName(MPT->getMostRecentCXXRecordDecl());
} else
mangleQualifiers(Ty->getPointeeType().getQualifiers(), false);
} else if (const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
@@ -3331,11 +3331,11 @@ void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T,
manglePointerExtQualifiers(Quals, PointeeType);
if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
Out << '8';
- mangleName(T->getClass()->castAs<RecordType>()->getDecl());
+ mangleName(T->getMostRecentCXXRecordDecl());
mangleFunctionType(FPT, nullptr, true);
} else {
mangleQualifiers(PointeeType.getQualifiers(), true);
- mangleName(T->getClass()->castAs<RecordType>()->getDecl());
+ mangleName(T->getMostRecentCXXRecordDecl());
mangleType(PointeeType, Range, QMM_Drop);
}
}
@@ -4309,11 +4309,11 @@ void MicrosoftCXXNameMangler::mangleAutoReturnType(const MemberPointerType *T,
manglePointerExtQualifiers(Quals, PointeeType);
if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
Out << '8';
- mangleName(T->getClass()->castAs<RecordType>()->getDecl());
+ mangleName(T->getMostRecentCXXRecordDecl());
mangleFunctionType(FPT, nullptr, true);
} else {
mangleQualifiers(PointeeType.getQualifiers(), true);
- mangleName(T->getClass()->castAs<RecordType>()->getDecl());
+ mangleName(T->getMostRecentCXXRecordDecl());
mangleAutoReturnType(PointeeType, QMM_Drop);
}
}
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 72161c0..9c5fd22 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2446,19 +2446,17 @@ bool Type::isIncompleteType(NamedDecl **Def) const {
// Member pointers in the MS ABI have special behavior in
// RequireCompleteType: they attach a MSInheritanceAttr to the CXXRecordDecl
// to indicate which inheritance model to use.
- auto *MPTy = cast<MemberPointerType>(CanonicalType);
- const Type *ClassTy = MPTy->getClass();
+ // The inheritance attribute might only be present on the most recent
+ // CXXRecordDecl.
+ const CXXRecordDecl *RD =
+ cast<MemberPointerType>(CanonicalType)->getMostRecentCXXRecordDecl();
// Member pointers with dependent class types don't get special treatment.
- if (ClassTy->isDependentType())
+ if (!RD || RD->isDependentType())
return false;
- const CXXRecordDecl *RD = ClassTy->getAsCXXRecordDecl();
ASTContext &Context = RD->getASTContext();
// Member pointers not in the MS ABI don't get special treatment.
if (!Context.getTargetInfo().getCXXABI().isMicrosoft())
return false;
- // The inheritance attribute might only be present on the most recent
- // CXXRecordDecl, use that one.
- RD = RD->getMostRecentNonInjectedDecl();
// Nothing interesting to do if the inheritance attribute is already set.
if (RD->hasAttr<MSInheritanceAttr>())
return false;
@@ -4713,7 +4711,8 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {
return computeTypeLinkageInfo(cast<ReferenceType>(T)->getPointeeType());
case Type::MemberPointer: {
const auto *MPT = cast<MemberPointerType>(T);
- LinkageInfo LV = computeTypeLinkageInfo(MPT->getClass());
+ LinkageInfo LV =
+ getDeclLinkageAndVisibility(MPT->getMostRecentCXXRecordDecl());
LV.merge(computeTypeLinkageInfo(MPT->getPointeeType()));
return LV;
}
@@ -5179,7 +5178,10 @@ QualType::DestructionKind QualType::isDestructedTypeImpl(QualType type) {
}
CXXRecordDecl *MemberPointerType::getMostRecentCXXRecordDecl() const {
- return getClass()->getAsCXXRecordDecl()->getMostRecentNonInjectedDecl();
+ auto *RD = getClass()->getAsCXXRecordDecl();
+ if (!RD)
+ return nullptr;
+ return RD->getMostRecentNonInjectedDecl();
}
void clang::FixedPointValueToString(SmallVectorImpl<char> &Str,
diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp
index 7c6dfc3..2777c78d 100644
--- a/clang/lib/CodeGen/CGCXXABI.cpp
+++ b/clang/lib/CodeGen/CGCXXABI.cpp
@@ -50,8 +50,7 @@ CGCallee CGCXXABI::EmitLoadOfMemberFunctionPointer(
llvm::Value *MemPtr, const MemberPointerType *MPT) {
ErrorUnsupportedABI(CGF, "calls through member pointers");
- const auto *RD =
- cast<CXXRecordDecl>(MPT->getClass()->castAs<RecordType>()->getDecl());
+ const auto *RD = MPT->getMostRecentCXXRecordDecl();
ThisPtrForCall =
CGF.getAsNaturalPointerTo(This, CGF.getContext().getRecordType(RD));
const FunctionProtoType *FPT =
@@ -294,7 +293,7 @@ llvm::Constant *CGCXXABI::getMemberPointerAdjustment(const CastExpr *E) {
derivedType = E->getType();
const CXXRecordDecl *derivedClass =
- derivedType->castAs<MemberPointerType>()->getClass()->getAsCXXRecordDecl();
+ derivedType->castAs<MemberPointerType>()->getMostRecentCXXRecordDecl();
return CGM.GetNonVirtualBaseClassOffset(derivedClass,
E->path_begin(),
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index fa69caa4..98c93b5 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -161,10 +161,9 @@ CodeGenFunction::EmitCXXMemberDataPointerAddress(const Expr *E, Address base,
QualType memberType = memberPtrType->getPointeeType();
CharUnits memberAlign =
CGM.getNaturalTypeAlignment(memberType, BaseInfo, TBAAInfo);
- memberAlign =
- CGM.getDynamicOffsetAlignment(base.getAlignment(),
- memberPtrType->getClass()->getAsCXXRecordDecl(),
- memberAlign);
+ memberAlign = CGM.getDynamicOffsetAlignment(
+ base.getAlignment(), memberPtrType->getMostRecentCXXRecordDecl(),
+ memberAlign);
return Address(ptr, ConvertTypeForMem(memberPtrType->getPointeeType()),
memberAlign);
}
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index c462b02..dcccbc0 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -3490,7 +3490,8 @@ llvm::DIType *CGDebugInfo::CreateType(const MemberPointerType *Ty,
}
}
- llvm::DIType *ClassType = getOrCreateType(QualType(Ty->getClass(), 0), U);
+ llvm::DIType *ClassType = getOrCreateType(
+ QualType(Ty->getMostRecentCXXRecordDecl()->getTypeForDecl(), 0), U);
if (Ty->isMemberDataPointerType())
return DBuilder.createMemberPointerType(
getOrCreateType(Ty->getPointeeType(), U), ClassType, Size, /*Align=*/0,
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index f71c18a..5d96959 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -453,8 +453,7 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
const auto *MPT = MemFnExpr->getType()->castAs<MemberPointerType>();
const auto *FPT = MPT->getPointeeType()->castAs<FunctionProtoType>();
- const auto *RD =
- cast<CXXRecordDecl>(MPT->getClass()->castAs<RecordType>()->getDecl());
+ const auto *RD = MPT->getMostRecentCXXRecordDecl();
// Emit the 'this' pointer.
Address This = Address::invalid();
@@ -463,8 +462,9 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
else
This = EmitLValue(BaseExpr, KnownNonNull).getAddress();
- EmitTypeCheck(TCK_MemberCall, E->getExprLoc(), This.emitRawPointer(*this),
- QualType(MPT->getClass(), 0));
+ EmitTypeCheck(
+ TCK_MemberCall, E->getExprLoc(), This.emitRawPointer(*this),
+ QualType(MPT->getMostRecentCXXRecordDecl()->getTypeForDecl(), 0));
// Get the member function pointer.
llvm::Value *MemFnPtr = EmitScalarExpr(MemFnExpr);
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index dfbd444..11cf575 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -728,7 +728,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
case Type::MemberPointer: {
auto *MPTy = cast<MemberPointerType>(Ty);
if (!getCXXABI().isMemberPointerConvertible(MPTy)) {
- auto *C = MPTy->getClass();
+ auto *C = MPTy->getMostRecentCXXRecordDecl()->getTypeForDecl();
auto Insertion = RecordsWithOpaqueMemberPointers.insert({C, nullptr});
if (Insertion.second)
Insertion.first->second = llvm::StructType::create(getLLVMContext());
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 7e26a0d..a5633f6 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -628,8 +628,7 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
const FunctionProtoType *FPT =
MPT->getPointeeType()->castAs<FunctionProtoType>();
- auto *RD =
- cast<CXXRecordDecl>(MPT->getClass()->castAs<RecordType>()->getDecl());
+ auto *RD = MPT->getMostRecentCXXRecordDecl();
llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
@@ -798,7 +797,7 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
// Check the function pointer if CFI on member function pointers is enabled.
if (ShouldEmitCFICheck) {
- CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
+ CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
if (RD->hasDefinition()) {
CodeGenFunction::SanitizerScope SanScope(&CGF);
@@ -3799,7 +3798,8 @@ static bool ContainsIncompleteClassType(QualType Ty) {
if (const MemberPointerType *MemberPointerTy =
dyn_cast<MemberPointerType>(Ty)) {
// Check if the class type is incomplete.
- const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
+ const auto *ClassType = cast<RecordType>(
+ MemberPointerTy->getMostRecentCXXRecordDecl()->getTypeForDecl());
if (IsIncompleteClassType(ClassType))
return true;
@@ -4538,7 +4538,8 @@ ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
// attributes of the type pointed to.
unsigned Flags = extractPBaseFlags(CGM.getContext(), PointeeTy);
- const RecordType *ClassType = cast<RecordType>(Ty->getClass());
+ const auto *ClassType =
+ cast<RecordType>(Ty->getMostRecentCXXRecordDecl()->getTypeForDecl());
if (IsIncompleteClassType(ClassType))
Flags |= PTI_ContainingClassIncomplete;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 8ea24de..478e92f 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -3069,48 +3069,46 @@ void Sema::ActOnBaseSpecifiers(Decl *ClassDecl,
AttachBaseSpecifiers(cast<CXXRecordDecl>(ClassDecl), Bases);
}
-bool Sema::IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base) {
+bool Sema::IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived,
+ CXXRecordDecl *Base, CXXBasePaths &Paths) {
if (!getLangOpts().CPlusPlus)
return false;
- CXXRecordDecl *DerivedRD = Derived->getAsCXXRecordDecl();
- if (!DerivedRD)
- return false;
-
- CXXRecordDecl *BaseRD = Base->getAsCXXRecordDecl();
- if (!BaseRD)
+ if (!Base || !Derived)
return false;
// If either the base or the derived type is invalid, don't try to
// check whether one is derived from the other.
- if (BaseRD->isInvalidDecl() || DerivedRD->isInvalidDecl())
+ if (Base->isInvalidDecl() || Derived->isInvalidDecl())
return false;
// FIXME: In a modules build, do we need the entire path to be visible for us
// to be able to use the inheritance relationship?
- if (!isCompleteType(Loc, Derived) && !DerivedRD->isBeingDefined())
+ if (!isCompleteType(Loc, Context.getTypeDeclType(Derived)) &&
+ !Derived->isBeingDefined())
return false;
- return DerivedRD->isDerivedFrom(BaseRD);
+ return Derived->isDerivedFrom(Base, Paths);
}
-bool Sema::IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base,
- CXXBasePaths &Paths) {
- if (!getLangOpts().CPlusPlus)
- return false;
-
- CXXRecordDecl *DerivedRD = Derived->getAsCXXRecordDecl();
- if (!DerivedRD)
- return false;
-
- CXXRecordDecl *BaseRD = Base->getAsCXXRecordDecl();
- if (!BaseRD)
- return false;
+bool Sema::IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived,
+ CXXRecordDecl *Base) {
+ CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false,
+ /*DetectVirtual=*/false);
+ return IsDerivedFrom(Loc, Derived, Base, Paths);
+}
- if (!isCompleteType(Loc, Derived) && !DerivedRD->isBeingDefined())
- return false;
+bool Sema::IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base) {
+ CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false,
+ /*DetectVirtual=*/false);
+ return IsDerivedFrom(Loc, Derived->getAsCXXRecordDecl(),
+ Base->getAsCXXRecordDecl(), Paths);
+}
- return DerivedRD->isDerivedFrom(BaseRD, Paths);
+bool Sema::IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base,
+ CXXBasePaths &Paths) {
+ return IsDerivedFrom(Loc, Derived->getAsCXXRecordDecl(),
+ Base->getAsCXXRecordDecl(), Paths);
}
static void BuildBasePathArray(const CXXBasePath &Path,
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index cbea98b..8f204b9 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -6529,7 +6529,7 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS,
return QualType();
}
- QualType Class(MemPtr->getClass(), 0);
+ CXXRecordDecl *RHSClass = MemPtr->getMostRecentCXXRecordDecl();
// Note: C++ [expr.mptr.oper]p2-3 says that the class type into which the
// member pointer points must be completely-defined. However, there is no
@@ -6552,15 +6552,16 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS,
return QualType();
}
}
+ CXXRecordDecl *LHSClass = LHSType->getAsCXXRecordDecl();
- if (!Context.hasSameUnqualifiedType(Class, LHSType)) {
+ if (!declaresSameEntity(LHSClass, RHSClass)) {
// If we want to check the hierarchy, we need a complete type.
if (RequireCompleteType(Loc, LHSType, diag::err_bad_memptr_lhs,
OpSpelling, (int)isIndirect)) {
return QualType();
}
- if (!IsDerivedFrom(Loc, LHSType, Class)) {
+ if (!IsDerivedFrom(Loc, LHSClass, RHSClass)) {
Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling
<< (int)isIndirect << LHS.get()->getType();
return QualType();
@@ -6568,13 +6569,14 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS,
CXXCastPath BasePath;
if (CheckDerivedToBaseConversion(
- LHSType, Class, Loc,
+ LHSType, QualType(RHSClass->getTypeForDecl(), 0), Loc,
SourceRange(LHS.get()->getBeginLoc(), RHS.get()->getEndLoc()),
&BasePath))
return QualType();
// Cast LHS to type of use.
- QualType UseType = Context.getQualifiedType(Class, LHSType.getQualifiers());
+ QualType UseType = Context.getQualifiedType(RHSClass->getTypeForDecl(),
+ LHSType.getQualifiers());
if (isIndirect)
UseType = Context.getPointerType(UseType);
ExprValueKind VK = isIndirect ? VK_PRValue : LHS.get()->getValueKind();
@@ -7531,18 +7533,20 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
// (Note that the only kinds of reference-relatedness in scope here are
// "same type or derived from".) At any other level, the class must
// exactly match.
- const Type *Class = nullptr;
- QualType Cls1(MemPtr1->getClass(), 0);
- QualType Cls2(MemPtr2->getClass(), 0);
- if (Context.hasSameType(Cls1, Cls2))
- Class = MemPtr1->getClass();
+ CXXRecordDecl *Cls = nullptr,
+ *Cls1 = MemPtr1->getMostRecentCXXRecordDecl(),
+ *Cls2 = MemPtr2->getMostRecentCXXRecordDecl();
+ if (declaresSameEntity(Cls1, Cls2))
+ Cls = Cls1;
else if (Steps.empty())
- Class = IsDerivedFrom(Loc, Cls1, Cls2) ? MemPtr1->getClass() :
- IsDerivedFrom(Loc, Cls2, Cls1) ? MemPtr2->getClass() : nullptr;
- if (!Class)
+ Cls = IsDerivedFrom(Loc, Cls1, Cls2) ? Cls1
+ : IsDerivedFrom(Loc, Cls2, Cls1) ? Cls2
+ : nullptr;
+ if (!Cls)
return QualType();
- Steps.emplace_back(Step::MemberPointer, Class);
+ Steps.emplace_back(Step::MemberPointer,
+ Context.getTypeDeclType(Cls).getTypePtr());
continue;
}
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index aecf8ed..59dc6df 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -3210,11 +3210,8 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) {
// X.
case Type::MemberPointer: {
const MemberPointerType *MemberPtr = cast<MemberPointerType>(T);
-
- // Queue up the class type into which this points.
- Queue.push_back(MemberPtr->getClass());
-
- // And directly continue with the pointee type.
+ addAssociatedClassesAndNamespaces(
+ Result, MemberPtr->getMostRecentCXXRecordDecl());
T = MemberPtr->getPointeeType().getTypePtr();
continue;
}
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index d73a3b5..f185bc3 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -1897,7 +1897,8 @@ bool Sema::IsFunctionConversion(QualType FromType, QualType ToType,
auto ToMPT = CanTo.castAs<MemberPointerType>();
auto FromMPT = CanFrom.castAs<MemberPointerType>();
// A function pointer conversion cannot change the class of the function.
- if (ToMPT->getClass() != FromMPT->getClass())
+ if (!declaresSameEntity(ToMPT->getMostRecentCXXRecordDecl(),
+ FromMPT->getMostRecentCXXRecordDecl()))
return false;
CanTo = ToMPT->getPointeeType();
CanFrom = FromMPT->getPointeeType();
@@ -3290,7 +3291,8 @@ void Sema::HandleFunctionTypeMismatch(PartialDiagnostic &PDiag,
if (FromType->isMemberPointerType() && ToType->isMemberPointerType()) {
const auto *FromMember = FromType->castAs<MemberPointerType>(),
*ToMember = ToType->castAs<MemberPointerType>();
- if (!Context.hasSameType(FromMember->getClass(), ToMember->getClass())) {
+ if (!declaresSameEntity(FromMember->getMostRecentCXXRecordDecl(),
+ ToMember->getMostRecentCXXRecordDecl())) {
PDiag << ft_different_class << QualType(ToMember->getClass(), 0)
<< QualType(FromMember->getClass(), 0);
return;
@@ -4891,14 +4893,10 @@ CompareDerivedToBaseConversions(Sema &S, SourceLocation Loc,
const auto *ToMemPointer1 = ToType1->castAs<MemberPointerType>();
const auto *FromMemPointer2 = FromType2->castAs<MemberPointerType>();
const auto *ToMemPointer2 = ToType2->castAs<MemberPointerType>();
- const Type *FromPointeeType1 = FromMemPointer1->getClass();
- const Type *ToPointeeType1 = ToMemPointer1->getClass();
- const Type *FromPointeeType2 = FromMemPointer2->getClass();
- const Type *ToPointeeType2 = ToMemPointer2->getClass();
- QualType FromPointee1 = QualType(FromPointeeType1, 0).getUnqualifiedType();
- QualType ToPointee1 = QualType(ToPointeeType1, 0).getUnqualifiedType();
- QualType FromPointee2 = QualType(FromPointeeType2, 0).getUnqualifiedType();
- QualType ToPointee2 = QualType(ToPointeeType2, 0).getUnqualifiedType();
+ CXXRecordDecl *FromPointee1 = FromMemPointer1->getMostRecentCXXRecordDecl();
+ CXXRecordDecl *ToPointee1 = ToMemPointer1->getMostRecentCXXRecordDecl();
+ CXXRecordDecl *FromPointee2 = FromMemPointer2->getMostRecentCXXRecordDecl();
+ CXXRecordDecl *ToPointee2 = ToMemPointer2->getMostRecentCXXRecordDecl();
// conversion of A::* to B::* is better than conversion of A::* to C::*,
if (FromPointee1 == FromPointee2 && ToPointee1 != ToPointee2) {
if (S.IsDerivedFrom(Loc, ToPointee1, ToPointee2))
@@ -8872,20 +8870,18 @@ static void AddBuiltinAssignmentOperatorCandidates(Sema &S,
/// if any, found in visible type conversion functions found in ArgExpr's type.
static Qualifiers CollectVRQualifiers(ASTContext &Context, Expr* ArgExpr) {
Qualifiers VRQuals;
- const RecordType *TyRec;
+ CXXRecordDecl *ClassDecl;
if (const MemberPointerType *RHSMPType =
- ArgExpr->getType()->getAs<MemberPointerType>())
- TyRec = RHSMPType->getClass()->getAs<RecordType>();
+ ArgExpr->getType()->getAs<MemberPointerType>())
+ ClassDecl = RHSMPType->getMostRecentCXXRecordDecl();
else
- TyRec = ArgExpr->getType()->getAs<RecordType>();
- if (!TyRec) {
+ ClassDecl = ArgExpr->getType()->getAsCXXRecordDecl();
+ if (!ClassDecl) {
// Just to be safe, assume the worst case.
VRQuals.addVolatile();
VRQuals.addRestrict();
return VRQuals;
}
-
- CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(TyRec->getDecl());
if (!ClassDecl->hasDefinition())
return VRQuals;
@@ -9878,9 +9874,10 @@ public:
continue;
for (QualType MemPtrTy : CandidateTypes[1].member_pointer_types()) {
const MemberPointerType *mptr = cast<MemberPointerType>(MemPtrTy);
- QualType C2 = QualType(mptr->getClass(), 0);
- C2 = C2.getUnqualifiedType();
- if (C1 != C2 && !S.IsDerivedFrom(CandidateSet.getLocation(), C1, C2))
+ CXXRecordDecl *D1 = C1->getAsCXXRecordDecl(),
+ *D2 = mptr->getMostRecentCXXRecordDecl();
+ if (!declaresSameEntity(D1, D2) &&
+ !S.IsDerivedFrom(CandidateSet.getLocation(), D1, D2))
break;
QualType ParamTypes[2] = {PtrTy, MemPtrTy};
// build CV12 T&
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 112eaf7..e1b9ccc 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -799,7 +799,8 @@ bool Sema::checkMustTailAttr(const Stmt *St, const Attr &MTA) {
// Call is: obj->*method_ptr or obj.*method_ptr
const auto *MPT =
CalleeBinOp->getRHS()->getType()->castAs<MemberPointerType>();
- CalleeType.This = QualType(MPT->getClass(), 0);
+ CalleeType.This =
+ Context.getTypeDeclType(MPT->getMostRecentCXXRecordDecl());
CalleeType.Func = MPT->getPointeeType()->castAs<FunctionProtoType>();
CalleeType.MemberType = FuncType::ft_pointer_to_member;
} else if (isa<CXXPseudoDestructorExpr>(CalleeExpr)) {