https://github.com/mizvekov created https://github.com/llvm/llvm-project/pull/132281
Reverts llvm/llvm-project#131965 Reverted due to issue reported here: https://github.com/llvm/llvm-project/pull/131965#issuecomment-2741619498 >From 9d96ab9704ba87c81e71d7b26095b68b2ca8aa80 Mon Sep 17 00:00:00 2001 From: Matheus Izvekov <mizve...@gmail.com> Date: Thu, 20 Mar 2025 17:53:19 -0300 Subject: [PATCH] Revert "[clang] NFC: Clear some uses of MemberPointerType::getClass (#131965)" This reverts commit fd7be0d2e9e2cb7d43c9cb97edbb36da59a5b595. --- ...arePointerToMemberVirtualFunctionCheck.cpp | 5 +- .../clang-tidy/utils/ExceptionAnalyzer.cpp | 4 +- clang/include/clang/AST/CanonicalType.h | 2 - clang/include/clang/Sema/Sema.h | 7 ++- clang/lib/AST/ByteCode/Compiler.cpp | 10 ++-- clang/lib/AST/ExprConstant.cpp | 5 +- clang/lib/AST/MicrosoftMangle.cpp | 10 ++-- clang/lib/AST/Type.cpp | 20 ++++---- clang/lib/CodeGen/CGCXXABI.cpp | 5 +- clang/lib/CodeGen/CGClass.cpp | 7 +-- clang/lib/CodeGen/CGDebugInfo.cpp | 3 +- clang/lib/CodeGen/CGExprCXX.cpp | 8 ++-- clang/lib/CodeGen/CodeGenTypes.cpp | 2 +- clang/lib/CodeGen/ItaniumCXXABI.cpp | 11 ++--- clang/lib/Sema/SemaDeclCXX.cpp | 48 ++++++++++--------- clang/lib/Sema/SemaExprCXX.cpp | 32 ++++++------- clang/lib/Sema/SemaLookup.cpp | 7 ++- clang/lib/Sema/SemaOverload.cpp | 37 +++++++------- clang/lib/Sema/SemaStmt.cpp | 3 +- 19 files changed, 112 insertions(+), 114 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp index a8a9e6bdcdff8..9d1d92b989bf1 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp @@ -70,7 +70,10 @@ 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 CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl(); + const Type *T = MPT->getClass(); + if (T == nullptr) + return; + const CXXRecordDecl *RD = T->getAsCXXRecordDecl(); 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 b66cc8512fad6..0fea7946a59f9 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>()->getMostRecentCXXRecordDecl() == - P2->getAs<MemberPointerType>()->getMostRecentCXXRecordDecl(); + P1->getAs<MemberPointerType>()->getClass() == + P2->getAs<MemberPointerType>()->getClass(); if (P1->isConstantArrayType()) return P2->isConstantArrayType() && diff --git a/clang/include/clang/AST/CanonicalType.h b/clang/include/clang/AST/CanonicalType.h index 50d1ba1b8f63f..6699284d215bd 100644 --- a/clang/include/clang/AST/CanonicalType.h +++ b/clang/include/clang/AST/CanonicalType.h @@ -454,8 +454,6 @@ 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 9724f0def743a..0befe615c4ee1 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -5769,11 +5769,10 @@ 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 9dc02b25f8495..91640c4eb5cf9 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -238,9 +238,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) { const auto *FromMP = SubExpr->getType()->getAs<MemberPointerType>(); const auto *ToMP = CE->getType()->getAs<MemberPointerType>(); - unsigned DerivedOffset = - Ctx.collectBaseOffset(ToMP->getMostRecentCXXRecordDecl(), - FromMP->getMostRecentCXXRecordDecl()); + unsigned DerivedOffset = collectBaseOffset(QualType(ToMP->getClass(), 0), + QualType(FromMP->getClass(), 0)); if (!this->delegate(SubExpr)) return false; @@ -254,9 +253,8 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) { const auto *FromMP = SubExpr->getType()->getAs<MemberPointerType>(); const auto *ToMP = CE->getType()->getAs<MemberPointerType>(); - unsigned DerivedOffset = - Ctx.collectBaseOffset(FromMP->getMostRecentCXXRecordDecl(), - ToMP->getMostRecentCXXRecordDecl()); + unsigned DerivedOffset = collectBaseOffset(QualType(FromMP->getClass(), 0), + QualType(ToMP->getClass(), 0)); if (!this->delegate(SubExpr)) return false; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 92a28897cf3ee..0165a0a3b0df3 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -10551,9 +10551,8 @@ bool MemberPointerExprEvaluator::VisitCastExpr(const CastExpr *E) { if (!Result.castToDerived(Derived)) return Error(E); } - if (!Result.castToDerived(E->getType() - ->castAs<MemberPointerType>() - ->getMostRecentCXXRecordDecl())) + const Type *FinalTy = E->getType()->castAs<MemberPointerType>()->getClass(); + if (!Result.castToDerived(FinalTy->getAsCXXRecordDecl())) return Error(E); return true; } diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 15de407e122d8..fe34251688a98 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->getMostRecentCXXRecordDecl()); + mangleName(MPT->getClass()->getAsCXXRecordDecl()); } 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->getMostRecentCXXRecordDecl()); + mangleName(T->getClass()->castAs<RecordType>()->getDecl()); mangleFunctionType(FPT, nullptr, true); } else { mangleQualifiers(PointeeType.getQualifiers(), true); - mangleName(T->getMostRecentCXXRecordDecl()); + mangleName(T->getClass()->castAs<RecordType>()->getDecl()); 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->getMostRecentCXXRecordDecl()); + mangleName(T->getClass()->castAs<RecordType>()->getDecl()); mangleFunctionType(FPT, nullptr, true); } else { mangleQualifiers(PointeeType.getQualifiers(), true); - mangleName(T->getMostRecentCXXRecordDecl()); + mangleName(T->getClass()->castAs<RecordType>()->getDecl()); mangleAutoReturnType(PointeeType, QMM_Drop); } } diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 33e7008cc4776..72161c06a88d4 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2446,17 +2446,19 @@ 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. - // The inheritance attribute might only be present on the most recent - // CXXRecordDecl. - const CXXRecordDecl *RD = - cast<MemberPointerType>(CanonicalType)->getMostRecentCXXRecordDecl(); + auto *MPTy = cast<MemberPointerType>(CanonicalType); + const Type *ClassTy = MPTy->getClass(); // Member pointers with dependent class types don't get special treatment. - if (!RD) + if (ClassTy->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; @@ -4711,8 +4713,7 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) { return computeTypeLinkageInfo(cast<ReferenceType>(T)->getPointeeType()); case Type::MemberPointer: { const auto *MPT = cast<MemberPointerType>(T); - LinkageInfo LV = - getDeclLinkageAndVisibility(MPT->getMostRecentCXXRecordDecl()); + LinkageInfo LV = computeTypeLinkageInfo(MPT->getClass()); LV.merge(computeTypeLinkageInfo(MPT->getPointeeType())); return LV; } @@ -5178,10 +5179,7 @@ QualType::DestructionKind QualType::isDestructedTypeImpl(QualType type) { } CXXRecordDecl *MemberPointerType::getMostRecentCXXRecordDecl() const { - auto *RD = getClass()->getAsCXXRecordDecl(); - if (!RD) - return nullptr; - return RD->getMostRecentNonInjectedDecl(); + return getClass()->getAsCXXRecordDecl()->getMostRecentNonInjectedDecl(); } void clang::FixedPointValueToString(SmallVectorImpl<char> &Str, diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp index 2777c78d6459d..7c6dfc3e59d8c 100644 --- a/clang/lib/CodeGen/CGCXXABI.cpp +++ b/clang/lib/CodeGen/CGCXXABI.cpp @@ -50,7 +50,8 @@ CGCallee CGCXXABI::EmitLoadOfMemberFunctionPointer( llvm::Value *MemPtr, const MemberPointerType *MPT) { ErrorUnsupportedABI(CGF, "calls through member pointers"); - const auto *RD = MPT->getMostRecentCXXRecordDecl(); + const auto *RD = + cast<CXXRecordDecl>(MPT->getClass()->castAs<RecordType>()->getDecl()); ThisPtrForCall = CGF.getAsNaturalPointerTo(This, CGF.getContext().getRecordType(RD)); const FunctionProtoType *FPT = @@ -293,7 +294,7 @@ llvm::Constant *CGCXXABI::getMemberPointerAdjustment(const CastExpr *E) { derivedType = E->getType(); const CXXRecordDecl *derivedClass = - derivedType->castAs<MemberPointerType>()->getMostRecentCXXRecordDecl(); + derivedType->castAs<MemberPointerType>()->getClass()->getAsCXXRecordDecl(); return CGM.GetNonVirtualBaseClassOffset(derivedClass, E->path_begin(), diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 98c93b5bb4883..fa69caa41936c 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -161,9 +161,10 @@ CodeGenFunction::EmitCXXMemberDataPointerAddress(const Expr *E, Address base, QualType memberType = memberPtrType->getPointeeType(); CharUnits memberAlign = CGM.getNaturalTypeAlignment(memberType, BaseInfo, TBAAInfo); - memberAlign = CGM.getDynamicOffsetAlignment( - base.getAlignment(), memberPtrType->getMostRecentCXXRecordDecl(), - memberAlign); + memberAlign = + CGM.getDynamicOffsetAlignment(base.getAlignment(), + memberPtrType->getClass()->getAsCXXRecordDecl(), + memberAlign); return Address(ptr, ConvertTypeForMem(memberPtrType->getPointeeType()), memberAlign); } diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index dcccbc0835d95..c462b02676813 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -3490,8 +3490,7 @@ llvm::DIType *CGDebugInfo::CreateType(const MemberPointerType *Ty, } } - llvm::DIType *ClassType = getOrCreateType( - QualType(Ty->getMostRecentCXXRecordDecl()->getTypeForDecl(), 0), U); + llvm::DIType *ClassType = getOrCreateType(QualType(Ty->getClass(), 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 5d96959065dd9..f71c18a8041b1 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -453,7 +453,8 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, const auto *MPT = MemFnExpr->getType()->castAs<MemberPointerType>(); const auto *FPT = MPT->getPointeeType()->castAs<FunctionProtoType>(); - const auto *RD = MPT->getMostRecentCXXRecordDecl(); + const auto *RD = + cast<CXXRecordDecl>(MPT->getClass()->castAs<RecordType>()->getDecl()); // Emit the 'this' pointer. Address This = Address::invalid(); @@ -462,9 +463,8 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, else This = EmitLValue(BaseExpr, KnownNonNull).getAddress(); - EmitTypeCheck( - TCK_MemberCall, E->getExprLoc(), This.emitRawPointer(*this), - QualType(MPT->getMostRecentCXXRecordDecl()->getTypeForDecl(), 0)); + EmitTypeCheck(TCK_MemberCall, E->getExprLoc(), This.emitRawPointer(*this), + QualType(MPT->getClass(), 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 11cf5758b6d3a..dfbd444a850a5 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->getMostRecentCXXRecordDecl()->getTypeForDecl(); + auto *C = MPTy->getClass(); 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 a5633f6349ffa..7e26a0da3d7d2 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -628,7 +628,8 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer( const FunctionProtoType *FPT = MPT->getPointeeType()->castAs<FunctionProtoType>(); - auto *RD = MPT->getMostRecentCXXRecordDecl(); + auto *RD = + cast<CXXRecordDecl>(MPT->getClass()->castAs<RecordType>()->getDecl()); llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1); @@ -797,7 +798,7 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer( // Check the function pointer if CFI on member function pointers is enabled. if (ShouldEmitCFICheck) { - CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl(); + CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl(); if (RD->hasDefinition()) { CodeGenFunction::SanitizerScope SanScope(&CGF); @@ -3798,8 +3799,7 @@ static bool ContainsIncompleteClassType(QualType Ty) { if (const MemberPointerType *MemberPointerTy = dyn_cast<MemberPointerType>(Ty)) { // Check if the class type is incomplete. - const auto *ClassType = cast<RecordType>( - MemberPointerTy->getMostRecentCXXRecordDecl()->getTypeForDecl()); + const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass()); if (IsIncompleteClassType(ClassType)) return true; @@ -4538,8 +4538,7 @@ ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) { // attributes of the type pointed to. unsigned Flags = extractPBaseFlags(CGM.getContext(), PointeeTy); - const auto *ClassType = - cast<RecordType>(Ty->getMostRecentCXXRecordDecl()->getTypeForDecl()); + const RecordType *ClassType = cast<RecordType>(Ty->getClass()); if (IsIncompleteClassType(ClassType)) Flags |= PTI_ContainingClassIncomplete; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 7b2e0df8cb55d..a1551e8027cd3 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -3069,46 +3069,48 @@ void Sema::ActOnBaseSpecifiers(Decl *ClassDecl, AttachBaseSpecifiers(cast<CXXRecordDecl>(ClassDecl), Bases); } -bool Sema::IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived, - CXXRecordDecl *Base, CXXBasePaths &Paths) { +bool Sema::IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base) { if (!getLangOpts().CPlusPlus) return false; - if (!Base || !Derived) + CXXRecordDecl *DerivedRD = Derived->getAsCXXRecordDecl(); + if (!DerivedRD) + return false; + + CXXRecordDecl *BaseRD = Base->getAsCXXRecordDecl(); + if (!BaseRD) 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 (Base->isInvalidDecl() || Derived->isInvalidDecl()) + if (BaseRD->isInvalidDecl() || DerivedRD->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, Context.getTypeDeclType(Derived)) && - !Derived->isBeingDefined()) + if (!isCompleteType(Loc, Derived) && !DerivedRD->isBeingDefined()) return false; - return Derived->isDerivedFrom(Base, Paths); -} - -bool Sema::IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived, - CXXRecordDecl *Base) { - CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false, - /*DetectVirtual=*/false); - return IsDerivedFrom(Loc, Derived, Base, Paths); -} - -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); } bool Sema::IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base, CXXBasePaths &Paths) { - return IsDerivedFrom(Loc, Derived->getAsCXXRecordDecl(), - Base->getAsCXXRecordDecl(), Paths); + if (!getLangOpts().CPlusPlus) + return false; + + CXXRecordDecl *DerivedRD = Derived->getAsCXXRecordDecl(); + if (!DerivedRD) + return false; + + CXXRecordDecl *BaseRD = Base->getAsCXXRecordDecl(); + if (!BaseRD) + return false; + + if (!isCompleteType(Loc, Derived) && !DerivedRD->isBeingDefined()) + return false; + + return DerivedRD->isDerivedFrom(BaseRD, Paths); } static void BuildBasePathArray(const CXXBasePath &Path, diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 8f204b949cb2c..cbea98b8884e9 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(); } - CXXRecordDecl *RHSClass = MemPtr->getMostRecentCXXRecordDecl(); + QualType Class(MemPtr->getClass(), 0); // 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,16 +6552,15 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS, return QualType(); } } - CXXRecordDecl *LHSClass = LHSType->getAsCXXRecordDecl(); - if (!declaresSameEntity(LHSClass, RHSClass)) { + if (!Context.hasSameUnqualifiedType(Class, LHSType)) { // 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, LHSClass, RHSClass)) { + if (!IsDerivedFrom(Loc, LHSType, Class)) { Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling << (int)isIndirect << LHS.get()->getType(); return QualType(); @@ -6569,14 +6568,13 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS, CXXCastPath BasePath; if (CheckDerivedToBaseConversion( - LHSType, QualType(RHSClass->getTypeForDecl(), 0), Loc, + LHSType, Class, Loc, SourceRange(LHS.get()->getBeginLoc(), RHS.get()->getEndLoc()), &BasePath)) return QualType(); // Cast LHS to type of use. - QualType UseType = Context.getQualifiedType(RHSClass->getTypeForDecl(), - LHSType.getQualifiers()); + QualType UseType = Context.getQualifiedType(Class, LHSType.getQualifiers()); if (isIndirect) UseType = Context.getPointerType(UseType); ExprValueKind VK = isIndirect ? VK_PRValue : LHS.get()->getValueKind(); @@ -7533,20 +7531,18 @@ 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. - CXXRecordDecl *Cls = nullptr, - *Cls1 = MemPtr1->getMostRecentCXXRecordDecl(), - *Cls2 = MemPtr2->getMostRecentCXXRecordDecl(); - if (declaresSameEntity(Cls1, Cls2)) - Cls = Cls1; + const Type *Class = nullptr; + QualType Cls1(MemPtr1->getClass(), 0); + QualType Cls2(MemPtr2->getClass(), 0); + if (Context.hasSameType(Cls1, Cls2)) + Class = MemPtr1->getClass(); else if (Steps.empty()) - Cls = IsDerivedFrom(Loc, Cls1, Cls2) ? Cls1 - : IsDerivedFrom(Loc, Cls2, Cls1) ? Cls2 - : nullptr; - if (!Cls) + Class = IsDerivedFrom(Loc, Cls1, Cls2) ? MemPtr1->getClass() : + IsDerivedFrom(Loc, Cls2, Cls1) ? MemPtr2->getClass() : nullptr; + if (!Class) return QualType(); - Steps.emplace_back(Step::MemberPointer, - Context.getTypeDeclType(Cls).getTypePtr()); + Steps.emplace_back(Step::MemberPointer, Class); continue; } diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 59dc6df5fbe9f..aecf8ed1b4e4d 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -3210,8 +3210,11 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) { // X. case Type::MemberPointer: { const MemberPointerType *MemberPtr = cast<MemberPointerType>(T); - addAssociatedClassesAndNamespaces( - Result, MemberPtr->getMostRecentCXXRecordDecl()); + + // Queue up the class type into which this points. + Queue.push_back(MemberPtr->getClass()); + + // And directly continue with the pointee type. T = MemberPtr->getPointeeType().getTypePtr(); continue; } diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index f185bc3cb358a..d73a3b5cf99c4 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1897,8 +1897,7 @@ 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 (!declaresSameEntity(ToMPT->getMostRecentCXXRecordDecl(), - FromMPT->getMostRecentCXXRecordDecl())) + if (ToMPT->getClass() != FromMPT->getClass()) return false; CanTo = ToMPT->getPointeeType(); CanFrom = FromMPT->getPointeeType(); @@ -3291,8 +3290,7 @@ void Sema::HandleFunctionTypeMismatch(PartialDiagnostic &PDiag, if (FromType->isMemberPointerType() && ToType->isMemberPointerType()) { const auto *FromMember = FromType->castAs<MemberPointerType>(), *ToMember = ToType->castAs<MemberPointerType>(); - if (!declaresSameEntity(FromMember->getMostRecentCXXRecordDecl(), - ToMember->getMostRecentCXXRecordDecl())) { + if (!Context.hasSameType(FromMember->getClass(), ToMember->getClass())) { PDiag << ft_different_class << QualType(ToMember->getClass(), 0) << QualType(FromMember->getClass(), 0); return; @@ -4893,10 +4891,14 @@ CompareDerivedToBaseConversions(Sema &S, SourceLocation Loc, const auto *ToMemPointer1 = ToType1->castAs<MemberPointerType>(); const auto *FromMemPointer2 = FromType2->castAs<MemberPointerType>(); const auto *ToMemPointer2 = ToType2->castAs<MemberPointerType>(); - CXXRecordDecl *FromPointee1 = FromMemPointer1->getMostRecentCXXRecordDecl(); - CXXRecordDecl *ToPointee1 = ToMemPointer1->getMostRecentCXXRecordDecl(); - CXXRecordDecl *FromPointee2 = FromMemPointer2->getMostRecentCXXRecordDecl(); - CXXRecordDecl *ToPointee2 = ToMemPointer2->getMostRecentCXXRecordDecl(); + 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(); // conversion of A::* to B::* is better than conversion of A::* to C::*, if (FromPointee1 == FromPointee2 && ToPointee1 != ToPointee2) { if (S.IsDerivedFrom(Loc, ToPointee1, ToPointee2)) @@ -8870,18 +8872,20 @@ 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; - CXXRecordDecl *ClassDecl; + const RecordType *TyRec; if (const MemberPointerType *RHSMPType = - ArgExpr->getType()->getAs<MemberPointerType>()) - ClassDecl = RHSMPType->getMostRecentCXXRecordDecl(); + ArgExpr->getType()->getAs<MemberPointerType>()) + TyRec = RHSMPType->getClass()->getAs<RecordType>(); else - ClassDecl = ArgExpr->getType()->getAsCXXRecordDecl(); - if (!ClassDecl) { + TyRec = ArgExpr->getType()->getAs<RecordType>(); + if (!TyRec) { // 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; @@ -9874,10 +9878,9 @@ class BuiltinOperatorOverloadBuilder { continue; for (QualType MemPtrTy : CandidateTypes[1].member_pointer_types()) { const MemberPointerType *mptr = cast<MemberPointerType>(MemPtrTy); - CXXRecordDecl *D1 = C1->getAsCXXRecordDecl(), - *D2 = mptr->getMostRecentCXXRecordDecl(); - if (!declaresSameEntity(D1, D2) && - !S.IsDerivedFrom(CandidateSet.getLocation(), D1, D2)) + QualType C2 = QualType(mptr->getClass(), 0); + C2 = C2.getUnqualifiedType(); + if (C1 != C2 && !S.IsDerivedFrom(CandidateSet.getLocation(), C1, C2)) break; QualType ParamTypes[2] = {PtrTy, MemPtrTy}; // build CV12 T& diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index e1b9ccc693bd5..112eaf758cf36 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -799,8 +799,7 @@ 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 = - Context.getTypeDeclType(MPT->getMostRecentCXXRecordDecl()); + CalleeType.This = QualType(MPT->getClass(), 0); CalleeType.Func = MPT->getPointeeType()->castAs<FunctionProtoType>(); CalleeType.MemberType = FuncType::ft_pointer_to_member; } else if (isa<CXXPseudoDestructorExpr>(CalleeExpr)) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits