forked from OSchip/llvm-project
ObjC kindof: set the type of a conditional expression when involving kindof.
When either LHS or RHS is a kindof type, we return a kindof type. rdar://problem/20513780 llvm-svn: 268781
This commit is contained in:
parent
f0b6b40fa4
commit
c46f7d1883
|
@ -7163,6 +7163,11 @@ QualType ASTContext::areCommonBaseCompatible(
|
||||||
if (!LDecl || !RDecl)
|
if (!LDecl || !RDecl)
|
||||||
return QualType();
|
return QualType();
|
||||||
|
|
||||||
|
// When either LHS or RHS is a kindof type, we should return a kindof type.
|
||||||
|
// For example, for common base of kindof(ASub1) and kindof(ASub2), we return
|
||||||
|
// kindof(A).
|
||||||
|
bool anyKindOf = LHS->isKindOfType() || RHS->isKindOfType();
|
||||||
|
|
||||||
// Follow the left-hand side up the class hierarchy until we either hit a
|
// Follow the left-hand side up the class hierarchy until we either hit a
|
||||||
// root or find the RHS. Record the ancestors in case we don't find it.
|
// root or find the RHS. Record the ancestors in case we don't find it.
|
||||||
llvm::SmallDenseMap<const ObjCInterfaceDecl *, const ObjCObjectType *, 4>
|
llvm::SmallDenseMap<const ObjCInterfaceDecl *, const ObjCObjectType *, 4>
|
||||||
|
@ -7197,10 +7202,12 @@ QualType ASTContext::areCommonBaseCompatible(
|
||||||
anyChanges = true;
|
anyChanges = true;
|
||||||
|
|
||||||
// If anything in the LHS will have changed, build a new result type.
|
// If anything in the LHS will have changed, build a new result type.
|
||||||
if (anyChanges) {
|
// If we need to return a kindof type but LHS is not a kindof type, we
|
||||||
|
// build a new result type.
|
||||||
|
if (anyChanges || LHS->isKindOfType() != anyKindOf) {
|
||||||
QualType Result = getObjCInterfaceType(LHS->getInterface());
|
QualType Result = getObjCInterfaceType(LHS->getInterface());
|
||||||
Result = getObjCObjectType(Result, LHSTypeArgs, Protocols,
|
Result = getObjCObjectType(Result, LHSTypeArgs, Protocols,
|
||||||
LHS->isKindOfType());
|
anyKindOf || LHS->isKindOfType());
|
||||||
return getObjCObjectPointerType(Result);
|
return getObjCObjectPointerType(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7245,10 +7252,12 @@ QualType ASTContext::areCommonBaseCompatible(
|
||||||
if (!Protocols.empty())
|
if (!Protocols.empty())
|
||||||
anyChanges = true;
|
anyChanges = true;
|
||||||
|
|
||||||
if (anyChanges) {
|
// If we need to return a kindof type but RHS is not a kindof type, we
|
||||||
|
// build a new result type.
|
||||||
|
if (anyChanges || RHS->isKindOfType() != anyKindOf) {
|
||||||
QualType Result = getObjCInterfaceType(RHS->getInterface());
|
QualType Result = getObjCInterfaceType(RHS->getInterface());
|
||||||
Result = getObjCObjectType(Result, RHSTypeArgs, Protocols,
|
Result = getObjCObjectType(Result, RHSTypeArgs, Protocols,
|
||||||
RHS->isKindOfType());
|
anyKindOf || RHS->isKindOfType());
|
||||||
return getObjCObjectPointerType(Result);
|
return getObjCObjectPointerType(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -187,6 +187,39 @@ void test_crosscast_conversions(void) {
|
||||||
NSString_obj = kindof_NSNumber_obj; // expected-warning{{from '__kindof NSNumber *'}}
|
NSString_obj = kindof_NSNumber_obj; // expected-warning{{from '__kindof NSNumber *'}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@interface NSCell : NSObject
|
||||||
|
@end
|
||||||
|
@interface NSCellSub : NSCell
|
||||||
|
@end
|
||||||
|
@interface NSCellSub2 : NSCell
|
||||||
|
@end
|
||||||
|
@interface NSCellSubSub : NSCellSub
|
||||||
|
@end
|
||||||
|
|
||||||
|
typedef signed char BOOL;
|
||||||
|
void test_conditional(BOOL flag) {
|
||||||
|
NSCellSubSub *result;
|
||||||
|
__kindof NSCellSub *kindof_Sub;
|
||||||
|
NSCell *cell;
|
||||||
|
NSCellSub *sub;
|
||||||
|
NSCellSub2 *sub2;
|
||||||
|
NSCellSubSub *subsub;
|
||||||
|
|
||||||
|
// LHS is kindof NSCellSub, RHS is NSCell --> kindof NSCell
|
||||||
|
// LHS is kindof NSCellSub, RHS is NSCellSub --> kindof NSCellSub
|
||||||
|
// LHS is kindof NSCellSub, RHS is NSCellSub2 --> kindof NSCell
|
||||||
|
// LHS is kindof NSCellSub, RHS is NSCellSubSub --> kindof NSCellSub
|
||||||
|
result = flag ? kindof_Sub : cell;
|
||||||
|
result = flag ? kindof_Sub : sub;
|
||||||
|
result = flag ? kindof_Sub : sub2;
|
||||||
|
result = flag ? kindof_Sub : subsub;
|
||||||
|
|
||||||
|
result = flag ? cell : kindof_Sub;
|
||||||
|
result = flag ? sub : kindof_Sub;
|
||||||
|
result = flag ? sub2 : kindof_Sub;
|
||||||
|
result = flag ? subsub : kindof_Sub;
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Blocks
|
// Blocks
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -277,7 +310,6 @@ void test(__kindof Bar *kBar) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure we don't emit warning about no method found.
|
// Make sure we don't emit warning about no method found.
|
||||||
typedef signed char BOOL;
|
|
||||||
@interface A : NSObject
|
@interface A : NSObject
|
||||||
@property (readonly, getter=isActive) BOOL active;
|
@property (readonly, getter=isActive) BOOL active;
|
||||||
@end
|
@end
|
||||||
|
|
Loading…
Reference in New Issue