зеркало из https://github.com/microsoft/clang-1.git
Several cleanups:
- rename isObjCIdType/isObjCClassType -> isObjCIdStructType/isObjCClassStructType. The previous name didn't do what you would expect. - add back isObjCIdType/isObjCClassType to do what you would expect. Not currently used, however many of the isObjCIdStructType/isObjCClassStructType clients could be converted over time. - move static Sema function areComparableObjCInterfaces to ASTContext (renamed to areComparableObjCPointerTypes, since it now operates on pointer types). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64385 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
17f194f439
Коммит
389bf46ae4
|
@ -541,11 +541,17 @@ public:
|
|||
bool typesAreBlockCompatible(QualType lhs, QualType rhs);
|
||||
|
||||
bool isObjCIdType(QualType T) const {
|
||||
return T == ObjCIdType;
|
||||
}
|
||||
bool isObjCIdStructType(QualType T) const {
|
||||
if (!IdStructType) // ObjC isn't enabled
|
||||
return false;
|
||||
return T->getAsStructureType() == IdStructType;
|
||||
}
|
||||
bool isObjCClassType(QualType T) const {
|
||||
return T == ObjCClassType;
|
||||
}
|
||||
bool isObjCClassStructType(QualType T) const {
|
||||
if (!ClassStructType) // ObjC isn't enabled
|
||||
return false;
|
||||
return T->getAsStructureType() == ClassStructType;
|
||||
|
@ -558,6 +564,7 @@ public:
|
|||
// Check the safety of assignment from LHS to RHS
|
||||
bool canAssignObjCInterfaces(const ObjCInterfaceType *LHS,
|
||||
const ObjCInterfaceType *RHS);
|
||||
bool areComparableObjCPointerTypes(QualType LHS, QualType RHS);
|
||||
|
||||
// Functions for calculating composite types
|
||||
QualType mergeTypes(QualType, QualType);
|
||||
|
|
|
@ -2046,7 +2046,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
|
|||
S.replace(S.end()-2, S.end(), replace);
|
||||
}
|
||||
}
|
||||
if (isObjCIdType(PointeeTy)) {
|
||||
if (isObjCIdStructType(PointeeTy)) {
|
||||
S += '@';
|
||||
return;
|
||||
}
|
||||
|
@ -2076,7 +2076,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
|
|||
S += '"';
|
||||
}
|
||||
return;
|
||||
} else if (isObjCClassType(PointeeTy)) {
|
||||
} else if (isObjCClassStructType(PointeeTy)) {
|
||||
S += '#';
|
||||
return;
|
||||
} else if (isObjCSelType(PointeeTy)) {
|
||||
|
@ -2411,6 +2411,29 @@ bool ASTContext::canAssignObjCInterfaces(const ObjCInterfaceType *LHS,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ASTContext::areComparableObjCPointerTypes(QualType LHS, QualType RHS) {
|
||||
// get the "pointed to" types
|
||||
const PointerType *LHSPT = LHS->getAsPointerType();
|
||||
const PointerType *RHSPT = RHS->getAsPointerType();
|
||||
|
||||
if (!LHSPT || !RHSPT)
|
||||
return false;
|
||||
|
||||
QualType lhptee = LHSPT->getPointeeType();
|
||||
QualType rhptee = RHSPT->getPointeeType();
|
||||
const ObjCInterfaceType* LHSIface = lhptee->getAsObjCInterfaceType();
|
||||
const ObjCInterfaceType* RHSIface = rhptee->getAsObjCInterfaceType();
|
||||
// ID acts sort of like void* for ObjC interfaces
|
||||
if (LHSIface && isObjCIdStructType(rhptee))
|
||||
return true;
|
||||
if (RHSIface && isObjCIdStructType(lhptee))
|
||||
return true;
|
||||
if (!LHSIface || !RHSIface)
|
||||
return false;
|
||||
return canAssignObjCInterfaces(LHSIface, RHSIface) ||
|
||||
canAssignObjCInterfaces(RHSIface, LHSIface);
|
||||
}
|
||||
|
||||
/// typesAreCompatible - C99 6.7.3p9: For two qualified types to be compatible,
|
||||
/// both shall have the identically qualified version of a compatible type.
|
||||
/// C99 6.2.7p1: Two types have compatible types if their types are the
|
||||
|
@ -2552,7 +2575,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
|
|||
if (LHS->isObjCQualifiedIdType()) {
|
||||
if (const PointerType *PT = RHS->getAsPointerType()) {
|
||||
QualType pType = PT->getPointeeType();
|
||||
if (isObjCIdType(pType))
|
||||
if (isObjCIdStructType(pType))
|
||||
return LHS;
|
||||
// FIXME: need to use ObjCQualifiedIdTypesAreCompatible(LHS, RHS, true).
|
||||
// Unfortunately, this API is part of Sema (which we don't have access
|
||||
|
@ -2565,7 +2588,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
|
|||
if (RHS->isObjCQualifiedIdType()) {
|
||||
if (const PointerType *PT = LHS->getAsPointerType()) {
|
||||
QualType pType = PT->getPointeeType();
|
||||
if (isObjCIdType(pType))
|
||||
if (isObjCIdStructType(pType))
|
||||
return RHS;
|
||||
// FIXME: need to use ObjCQualifiedIdTypesAreCompatible(LHS, RHS, true).
|
||||
// Unfortunately, this API is part of Sema (which we don't have access
|
||||
|
@ -2662,8 +2685,8 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
|
|||
return mergeFunctionTypes(LHS, RHS);
|
||||
case Type::Tagged:
|
||||
// FIXME: Why are these compatible?
|
||||
if (isObjCIdType(LHS) && isObjCClassType(RHS)) return LHS;
|
||||
if (isObjCClassType(LHS) && isObjCIdType(RHS)) return LHS;
|
||||
if (isObjCIdStructType(LHS) && isObjCClassStructType(RHS)) return LHS;
|
||||
if (isObjCClassStructType(LHS) && isObjCIdStructType(RHS)) return LHS;
|
||||
return QualType();
|
||||
case Type::Builtin:
|
||||
// Only exactly equal builtin types are compatible, which is tested above.
|
||||
|
|
|
@ -1449,7 +1449,7 @@ static QualType GetReturnType(Expr* RetE, ASTContext& Ctx) {
|
|||
|
||||
ObjCMessageExpr* ME = dyn_cast<ObjCMessageExpr>(RetE);
|
||||
|
||||
if (!ME || !Ctx.isObjCIdType(PT->getPointeeType()))
|
||||
if (!ME || !Ctx.isObjCIdStructType(PT->getPointeeType()))
|
||||
return RetTy;
|
||||
|
||||
ObjCInterfaceDecl* D = ME->getClassInfo().first;
|
||||
|
|
|
@ -1970,7 +1970,7 @@ void CGObjCMac::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
|
|||
// catch(id e) always matches.
|
||||
// FIXME: For the time being we also match id<X>; this should
|
||||
// be rejected by Sema instead.
|
||||
if ((PT && CGF.getContext().isObjCIdType(PT->getPointeeType())) ||
|
||||
if ((PT && CGF.getContext().isObjCIdStructType(PT->getPointeeType())) ||
|
||||
VD->getType()->isObjCQualifiedIdType())
|
||||
AllMatched = true;
|
||||
}
|
||||
|
|
|
@ -2256,9 +2256,9 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
|
|||
} else if (LHSIface && RHSIface &&
|
||||
Context.canAssignObjCInterfaces(RHSIface, LHSIface)) {
|
||||
compositeType = rexT;
|
||||
} else if (Context.isObjCIdType(lhptee) ||
|
||||
Context.isObjCIdType(rhptee)) {
|
||||
// FIXME: This code looks wrong, because isObjCIdType checks
|
||||
} else if (Context.isObjCIdStructType(lhptee) ||
|
||||
Context.isObjCIdStructType(rhptee)) {
|
||||
// FIXME: This code looks wrong, because isObjCIdStructType checks
|
||||
// the struct but getObjCIdType returns the pointer to
|
||||
// struct. This is horrible and should be fixed.
|
||||
compositeType = Context.getObjCIdType();
|
||||
|
@ -2412,9 +2412,9 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
|
|||
return ConvTy;
|
||||
|
||||
// ID acts sort of like void* for ObjC interfaces
|
||||
if (LHSIface && Context.isObjCIdType(rhptee))
|
||||
if (LHSIface && Context.isObjCIdStructType(rhptee))
|
||||
return ConvTy;
|
||||
if (RHSIface && Context.isObjCIdType(lhptee))
|
||||
if (RHSIface && Context.isObjCIdStructType(lhptee))
|
||||
return ConvTy;
|
||||
|
||||
// C99 6.5.16.1p1 (constraint 3): both operands are pointers to qualified or
|
||||
|
@ -2903,21 +2903,6 @@ QualType Sema::CheckShiftOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
|
|||
return lex->getType();
|
||||
}
|
||||
|
||||
static bool areComparableObjCInterfaces(QualType LHS, QualType RHS,
|
||||
ASTContext& Context) {
|
||||
const ObjCInterfaceType* LHSIface = LHS->getAsObjCInterfaceType();
|
||||
const ObjCInterfaceType* RHSIface = RHS->getAsObjCInterfaceType();
|
||||
// ID acts sort of like void* for ObjC interfaces
|
||||
if (LHSIface && Context.isObjCIdType(RHS))
|
||||
return true;
|
||||
if (RHSIface && Context.isObjCIdType(LHS))
|
||||
return true;
|
||||
if (!LHSIface || !RHSIface)
|
||||
return false;
|
||||
return Context.canAssignObjCInterfaces(LHSIface, RHSIface) ||
|
||||
Context.canAssignObjCInterfaces(RHSIface, LHSIface);
|
||||
}
|
||||
|
||||
// C99 6.5.8
|
||||
QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
|
||||
bool isRelational) {
|
||||
|
@ -2977,7 +2962,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
|
|||
!LCanPointeeTy->isVoidType() && !RCanPointeeTy->isVoidType() &&
|
||||
!Context.typesAreCompatible(LCanPointeeTy.getUnqualifiedType(),
|
||||
RCanPointeeTy.getUnqualifiedType()) &&
|
||||
!areComparableObjCInterfaces(LCanPointeeTy, RCanPointeeTy, Context)) {
|
||||
!Context.areComparableObjCPointerTypes(lType, rType)) {
|
||||
Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
|
||||
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
|
||||
}
|
||||
|
|
|
@ -485,11 +485,11 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
|
|||
// Allow id<P..> and an 'id' or void* type in all cases.
|
||||
if (const PointerType *PT = lhs->getAsPointerType()) {
|
||||
QualType PointeeTy = PT->getPointeeType();
|
||||
if (Context.isObjCIdType(PointeeTy) || PointeeTy->isVoidType())
|
||||
if (Context.isObjCIdStructType(PointeeTy) || PointeeTy->isVoidType())
|
||||
return true;
|
||||
} else if (const PointerType *PT = rhs->getAsPointerType()) {
|
||||
QualType PointeeTy = PT->getPointeeType();
|
||||
if (Context.isObjCIdType(PointeeTy) || PointeeTy->isVoidType())
|
||||
if (Context.isObjCIdStructType(PointeeTy) || PointeeTy->isVoidType())
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1019,8 +1019,8 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
|
|||
|
||||
// Objective C++: We're able to convert between "id" and a pointer
|
||||
// to any interface (in both directions).
|
||||
if ((FromIface && Context.isObjCIdType(ToPointeeType))
|
||||
|| (ToIface && Context.isObjCIdType(FromPointeeType))) {
|
||||
if ((FromIface && Context.isObjCIdStructType(ToPointeeType))
|
||||
|| (ToIface && Context.isObjCIdStructType(FromPointeeType))) {
|
||||
ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
|
||||
ToPointeeType,
|
||||
ToType, Context);
|
||||
|
@ -1029,10 +1029,10 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
|
|||
|
||||
// Objective C++: Allow conversions between the Objective-C "id" and
|
||||
// "Class", in either direction.
|
||||
if ((Context.isObjCIdType(FromPointeeType) &&
|
||||
Context.isObjCClassType(ToPointeeType)) ||
|
||||
(Context.isObjCClassType(FromPointeeType) &&
|
||||
Context.isObjCIdType(ToPointeeType))) {
|
||||
if ((Context.isObjCIdStructType(FromPointeeType) &&
|
||||
Context.isObjCClassStructType(ToPointeeType)) ||
|
||||
(Context.isObjCClassStructType(FromPointeeType) &&
|
||||
Context.isObjCIdStructType(ToPointeeType))) {
|
||||
ConvertedType = ToType;
|
||||
return true;
|
||||
}
|
||||
|
@ -1131,10 +1131,10 @@ bool Sema::CheckPointerConversion(Expr *From, QualType ToType) {
|
|||
// Objective-C++ conversions are always okay.
|
||||
// FIXME: We should have a different class of conversions for
|
||||
// the Objective-C++ implicit conversions.
|
||||
if (Context.isObjCIdType(FromPointeeType) ||
|
||||
Context.isObjCIdType(ToPointeeType) ||
|
||||
Context.isObjCClassType(FromPointeeType) ||
|
||||
Context.isObjCClassType(ToPointeeType))
|
||||
if (Context.isObjCIdStructType(FromPointeeType) ||
|
||||
Context.isObjCIdStructType(ToPointeeType) ||
|
||||
Context.isObjCClassStructType(FromPointeeType) ||
|
||||
Context.isObjCClassStructType(ToPointeeType))
|
||||
return false;
|
||||
|
||||
if (FromPointeeType->isRecordType() &&
|
||||
|
|
Загрузка…
Ссылка в новой задаче