Revert "[clang] NFC: Clear some uses of MemberPointerType::getClass" (#132281)
Reverts llvm/llvm-project#131965 Reverted due to issue reported here: https://github.com/llvm/llvm-project/pull/131965#issuecomment-2741619498
This commit is contained in:
parent
5151e6d7fe
commit
335a4614de
@ -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;
|
||||
|
||||
|
@ -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() &&
|
||||
|
@ -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
|
||||
|
@ -5769,11 +5769,10 @@ public:
|
||||
|
||||
/// 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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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(),
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 @@ public:
|
||||
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&
|
||||
|
@ -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)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user