-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[clang] NFC: Clear some uses of MemberPointerType::getClass #131965
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
Conversation
Originally split-off from #130537 |
@llvm/pr-subscribers-debuginfo @llvm/pr-subscribers-clang-codegen Author: Matheus Izvekov (mizvekov) ChangesThis 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. Patch is 28.41 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/131965.diff 19 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp
index 9d1d92b989bf1..a8a9e6bdcdff8 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp
@@ -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;
diff --git a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
index 0fea7946a59f9..b66cc8512fad6 100644
--- a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
+++ b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
@@ -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() &&
diff --git a/clang/include/clang/AST/CanonicalType.h b/clang/include/clang/AST/CanonicalType.h
index 6699284d215bd..50d1ba1b8f63f 100644
--- a/clang/include/clang/AST/CanonicalType.h
+++ b/clang/include/clang/AST/CanonicalType.h
@@ -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
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index fc3936d649320..846c5d09be2a3 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5754,10 +5754,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);
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index e76d93728e0db..ca3712ae51441 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 7803b1026aab9..5bcc4b86586aa 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -10545,8 +10545,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 fe34251688a98..15de407e122d8 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 72161c06a88d4..33e7008cc4776 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)
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 7c6dfc3e59d8c..2777c78d6459d 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 fa69caa41936c..98c93b5bb4883 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 c462b02676813..dcccbc0835d95 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 f71c18a8041b1..5d96959065dd9 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 dfbd444a850a5..11cf5758b6d3a 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 7e26a0da3d7d2..a5633f6349ffa 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 20533961a2217..3962464e22805 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -3000,48 +3000,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 34219e0235a74..fdfd3bab39db5 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -6476,7 +6476,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
@@ -6499,15 +6499,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_memp...
[truncated]
|
@llvm/pr-subscribers-clang-tidy Author: Matheus Izvekov (mizvekov) ChangesThis 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. Patch is 28.41 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/131965.diff 19 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp
index 9d1d92b989bf1..a8a9e6bdcdff8 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp
@@ -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;
diff --git a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
index 0fea7946a59f9..b66cc8512fad6 100644
--- a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
+++ b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
@@ -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() &&
diff --git a/clang/include/clang/AST/CanonicalType.h b/clang/include/clang/AST/CanonicalType.h
index 6699284d215bd..50d1ba1b8f63f 100644
--- a/clang/include/clang/AST/CanonicalType.h
+++ b/clang/include/clang/AST/CanonicalType.h
@@ -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
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index fc3936d649320..846c5d09be2a3 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5754,10 +5754,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);
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index e76d93728e0db..ca3712ae51441 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 7803b1026aab9..5bcc4b86586aa 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -10545,8 +10545,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 fe34251688a98..15de407e122d8 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 72161c06a88d4..33e7008cc4776 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)
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 7c6dfc3e59d8c..2777c78d6459d 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 fa69caa41936c..98c93b5bb4883 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 c462b02676813..dcccbc0835d95 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 f71c18a8041b1..5d96959065dd9 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 dfbd444a850a5..11cf5758b6d3a 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 7e26a0da3d7d2..a5633f6349ffa 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 20533961a2217..3962464e22805 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -3000,48 +3000,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 34219e0235a74..fdfd3bab39db5 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -6476,7 +6476,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
@@ -6499,15 +6499,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_memp...
[truncated]
|
@llvm/pr-subscribers-clang Author: Matheus Izvekov (mizvekov) ChangesThis 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. Patch is 28.41 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/131965.diff 19 Files Affected:
diff --git a/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp
index 9d1d92b989bf1..a8a9e6bdcdff8 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp
@@ -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;
diff --git a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
index 0fea7946a59f9..b66cc8512fad6 100644
--- a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
+++ b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
@@ -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() &&
diff --git a/clang/include/clang/AST/CanonicalType.h b/clang/include/clang/AST/CanonicalType.h
index 6699284d215bd..50d1ba1b8f63f 100644
--- a/clang/include/clang/AST/CanonicalType.h
+++ b/clang/include/clang/AST/CanonicalType.h
@@ -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
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index fc3936d649320..846c5d09be2a3 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5754,10 +5754,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);
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index e76d93728e0db..ca3712ae51441 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 7803b1026aab9..5bcc4b86586aa 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -10545,8 +10545,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 fe34251688a98..15de407e122d8 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 72161c06a88d4..33e7008cc4776 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)
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 7c6dfc3e59d8c..2777c78d6459d 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 fa69caa41936c..98c93b5bb4883 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 c462b02676813..dcccbc0835d95 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 f71c18a8041b1..5d96959065dd9 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 dfbd444a850a5..11cf5758b6d3a 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 7e26a0da3d7d2..a5633f6349ffa 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 20533961a2217..3962464e22805 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -3000,48 +3000,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 34219e0235a74..fdfd3bab39db5 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -6476,7 +6476,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
@@ -6499,15 +6499,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_memp...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just did a spot-check, but the uses I saw all seemed reasonable.
There ARE a few cases I saw where it did a cast
to RecordType
then a getDecl
, so this loses the assert, but I think that is still reasonable.
68bcd9f
to
7a80dab
Compare
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.
e44f256
to
ae35359
Compare
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/73/builds/14931 Here is the relevant piece of the build log for the reference
|
hi, this breaks which breaks stage 2 builds of clang on windows, e.g. https://lab.llvm.org/buildbot/#/builders/124/builds/513 |
seems like there are conflicts reverting this at head, could you take a look @mizvekov? |
… to member" (#132280) Reverts #132234 Needs to be reverted due to dependency. This blocks reverting another PR, see here: #131965 (comment)
…132281) Reverts #131965 Reverted due to issue reported here: #131965 (comment)
@aeubanks Done, reverted, needed to revert another PR first. |
…ing pointer to member" (#132280) Reverts llvm/llvm-project#132234 Needs to be reverted due to dependency. This blocks reverting another PR, see here: llvm/llvm-project#131965 (comment)
…:getClass" (#132281) Reverts llvm/llvm-project#131965 Reverted due to issue reported here: llvm/llvm-project#131965 (comment)
thanks! |
Original PR: #131965 Addresses #131965 (comment) * 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.
…132317) Relands Original PR: #131965 Addresses #131965 (comment) * 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.
…:getClass (#132317) Relands Original PR: llvm/llvm-project#131965 Addresses llvm/llvm-project#131965 (comment) * 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.
Fix crash when looking up associated namespaces for member pointers with an unknown class, due to dependency. It was a regression introduced in #131965 and reported here: #132317 (comment) No change notes since the regression was never released.
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.