if (!LDecl || !RDecl)
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
// root or find the RHS. Record the ancestors in case we don't find it.
llvm::SmallDenseMap<const ObjCInterfaceDecl *, const ObjCObjectType *, 4>
anyChanges = true;
// 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());
Result = getObjCObjectType(Result, LHSTypeArgs, Protocols,
- LHS->isKindOfType());
+ anyKindOf || LHS->isKindOfType());
return getObjCObjectPointerType(Result);
}
if (!Protocols.empty())
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());
Result = getObjCObjectType(Result, RHSTypeArgs, Protocols,
- RHS->isKindOfType());
+ anyKindOf || RHS->isKindOfType());
return getObjCObjectPointerType(Result);
}
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
// ---------------------------------------------------------------------------
}
// Make sure we don't emit warning about no method found.
-typedef signed char BOOL;
@interface A : NSObject
@property (readonly, getter=isActive) BOOL active;
@end