Skip to content

Reland: [clang] NFC: Clear some uses of MemberPointerType::getClass #132317

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,7 @@ void ComparePointerToMemberVirtualFunctionCheck::check(
// compare with variable which type is pointer to member function.
llvm::SmallVector<SourceLocation, 12U> SameSignatureVirtualMethods{};
const auto *MPT = cast<MemberPointerType>(DRE->getType().getCanonicalType());
const Type *T = MPT->getClass();
if (T == nullptr)
return;
const CXXRecordDecl *RD = T->getAsCXXRecordDecl();
const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
if (RD == nullptr)
return;

Expand Down
4 changes: 2 additions & 2 deletions clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,8 @@ bool isQualificationConvertiblePointer(QualType From, QualType To,

if (P1->isMemberPointerType())
return P2->isMemberPointerType() &&
P1->getAs<MemberPointerType>()->getClass() ==
P2->getAs<MemberPointerType>()->getClass();
P1->getAs<MemberPointerType>()->getMostRecentCXXRecordDecl() ==
P2->getAs<MemberPointerType>()->getMostRecentCXXRecordDecl();

if (P1->isConstantArrayType())
return P2->isConstantArrayType() &&
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/AST/CanonicalType.h
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,8 @@ struct CanProxyAdaptor<MemberPointerType>
: public CanProxyBase<MemberPointerType> {
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const Type *, getClass)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const CXXRecordDecl *,
getMostRecentCXXRecordDecl)
};

// CanProxyAdaptors for arrays are intentionally unimplemented because
Expand Down
7 changes: 4 additions & 3 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -5769,10 +5769,11 @@ class Sema final : public SemaBase {

/// Determine whether the type \p Derived is a C++ class that is
/// derived from the type \p Base.
bool IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived,
CXXRecordDecl *Base, CXXBasePaths &Paths);
bool IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived,
CXXRecordDecl *Base);
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base);

/// Determine whether the type \p Derived is a C++ class that is
/// derived from the type \p Base.
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base,
CXXBasePaths &Paths);

Expand Down
10 changes: 6 additions & 4 deletions clang/lib/AST/ByteCode/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10551,8 +10551,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;
}
Expand Down
10 changes: 5 additions & 5 deletions clang/lib/AST/MicrosoftMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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);
}
}
Expand Down
20 changes: 11 additions & 9 deletions clang/lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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,
Expand Down
5 changes: 2 additions & 3 deletions clang/lib/CodeGen/CGCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down Expand Up @@ -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(),
Expand Down
7 changes: 3 additions & 4 deletions clang/lib/CodeGen/CGClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/CodeGen/CGDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/CodeGen/CGExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CodeGenTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
11 changes: 6 additions & 5 deletions clang/lib/CodeGen/ItaniumCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down
48 changes: 23 additions & 25 deletions clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading