@@ -1054,6 +1054,9 @@ class QualType {
1054
1054
const DeclContext *dc,
1055
1055
ObjCSubstitutionContext context) const ;
1056
1056
1057
+ // / Strip Objective-C "__kindof" types from the given type.
1058
+ QualType stripObjCKindOfType (const ASTContext &ctx) const ;
1059
+
1057
1060
private:
1058
1061
// These methods are implemented in a separate translation unit;
1059
1062
// "static"-ize them to avoid creating temporary QualTypes in the
@@ -1353,9 +1356,12 @@ class Type : public ExtQualsTypeCommonBase {
1353
1356
1354
1357
// / NumProtocols - The number of protocols stored directly on this
1355
1358
// / object type.
1356
- unsigned NumProtocols : 7 ;
1359
+ unsigned NumProtocols : 6 ;
1360
+
1361
+ // / Whether this is a "kindof" type.
1362
+ unsigned IsKindOf : 1 ;
1357
1363
};
1358
- static_assert (NumTypeBits + 7 + 7 <= 32 , " Does not fit in an unsigned" );
1364
+ static_assert (NumTypeBits + 7 + 6 + 1 <= 32 , " Does not fit in an unsigned" );
1359
1365
1360
1366
class ReferenceTypeBitfields {
1361
1367
friend class ReferenceType ;
@@ -1649,7 +1655,27 @@ class Type : public ExtQualsTypeCommonBase {
1649
1655
bool isObjCQualifiedClassType () const ; // Class<foo>
1650
1656
bool isObjCObjectOrInterfaceType () const ;
1651
1657
bool isObjCIdType () const ; // id
1658
+
1659
+ // / Whether the type is Objective-C 'id' or a __kindof type of an
1660
+ // / object type, e.g., __kindof NSView * or __kindof id
1661
+ // / <NSCopying>.
1662
+ // /
1663
+ // / \param bound Will be set to the bound on non-id subtype types,
1664
+ // / which will be (possibly specialized) Objective-C class type, or
1665
+ // / null for 'id.
1666
+ bool isObjCIdOrObjectKindOfType (const ASTContext &ctx,
1667
+ const ObjCObjectType *&bound) const ;
1668
+
1652
1669
bool isObjCClassType () const ; // Class
1670
+
1671
+ // / Whether the type is Objective-C 'Class' or a __kindof type of an
1672
+ // / Class type, e.g., __kindof Class <NSCopying>.
1673
+ // /
1674
+ // / Unlike \c isObjCIdOrObjectKindOfType, there is no relevant bound
1675
+ // / here because Objective-C's type system cannot express "a class
1676
+ // / object for a subclass of NSFoo".
1677
+ bool isObjCClassOrClassKindOfType () const ;
1678
+
1653
1679
bool isBlockCompatibleObjCPointerType (ASTContext &ctx) const ;
1654
1680
bool isObjCSelType () const ; // Class
1655
1681
bool isObjCBuiltinType () const ; // 'id' or 'Class'
@@ -3581,6 +3607,7 @@ class AttributedType : public Type, public llvm::FoldingSetNode {
3581
3607
attr_nonnull,
3582
3608
attr_nullable,
3583
3609
attr_null_unspecified,
3610
+ attr_objc_kindof,
3584
3611
};
3585
3612
3586
3613
private:
@@ -4514,14 +4541,16 @@ class ObjCObjectType : public Type {
4514
4541
protected:
4515
4542
ObjCObjectType (QualType Canonical, QualType Base,
4516
4543
ArrayRef<QualType> typeArgs,
4517
- ArrayRef<ObjCProtocolDecl *> protocols);
4544
+ ArrayRef<ObjCProtocolDecl *> protocols,
4545
+ bool isKindOf);
4518
4546
4519
4547
enum Nonce_ObjCInterface { Nonce_ObjCInterface };
4520
4548
ObjCObjectType (enum Nonce_ObjCInterface)
4521
4549
: Type(ObjCInterface, QualType(), false , false , false , false ),
4522
4550
BaseType (QualType(this_(), 0)) {
4523
4551
ObjCObjectTypeBits.NumProtocols = 0 ;
4524
4552
ObjCObjectTypeBits.NumTypeArgs = 0 ;
4553
+ ObjCObjectTypeBits.IsKindOf = 0 ;
4525
4554
}
4526
4555
4527
4556
void computeSuperClassTypeSlow () const ;
@@ -4603,6 +4632,17 @@ class ObjCObjectType : public Type {
4603
4632
return qual_begin ()[I];
4604
4633
}
4605
4634
4635
+ // / Retrieve all of the protocol qualifiers.
4636
+ ArrayRef<ObjCProtocolDecl *> getProtocols () const {
4637
+ return ArrayRef<ObjCProtocolDecl *>(qual_begin (), getNumProtocols ());
4638
+ }
4639
+
4640
+ // / Whether this is a "__kindof" type as written.
4641
+ bool isKindOfTypeAsWritten () const { return ObjCObjectTypeBits.IsKindOf ; }
4642
+
4643
+ // / Whether this ia a "__kindof" type (semantically).
4644
+ bool isKindOfType () const ;
4645
+
4606
4646
// / Retrieve the type of the superclass of this object type.
4607
4647
// /
4608
4648
// / This operation substitutes any type arguments into the
@@ -4617,6 +4657,10 @@ class ObjCObjectType : public Type {
4617
4657
return QualType (CachedSuperClassType.getPointer (), 0 );
4618
4658
}
4619
4659
4660
+ // / Strip off the Objective-C "kindof" type and (with it) any
4661
+ // / protocol qualifiers.
4662
+ QualType stripObjCKindOfTypeAndQuals (const ASTContext &ctx) const ;
4663
+
4620
4664
bool isSugared () const { return false ; }
4621
4665
QualType desugar () const { return QualType (this , 0 ); }
4622
4666
@@ -4638,15 +4682,17 @@ class ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode {
4638
4682
4639
4683
ObjCObjectTypeImpl (QualType Canonical, QualType Base,
4640
4684
ArrayRef<QualType> typeArgs,
4641
- ArrayRef<ObjCProtocolDecl *> protocols)
4642
- : ObjCObjectType(Canonical, Base, typeArgs, protocols) {}
4685
+ ArrayRef<ObjCProtocolDecl *> protocols,
4686
+ bool isKindOf)
4687
+ : ObjCObjectType(Canonical, Base, typeArgs, protocols, isKindOf) {}
4643
4688
4644
4689
public:
4645
4690
void Profile (llvm::FoldingSetNodeID &ID);
4646
4691
static void Profile (llvm::FoldingSetNodeID &ID,
4647
4692
QualType Base,
4648
4693
ArrayRef<QualType> typeArgs,
4649
- ArrayRef<ObjCProtocolDecl *> protocols);
4694
+ ArrayRef<ObjCProtocolDecl *> protocols,
4695
+ bool isKindOf);
4650
4696
};
4651
4697
4652
4698
inline QualType *ObjCObjectType::getTypeArgStorage () {
@@ -4798,6 +4844,12 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
4798
4844
return getObjectType ()->isObjCUnqualifiedClass ();
4799
4845
}
4800
4846
4847
+ // / isObjCIdOrClassType - True if this is equivalent to the 'id' or
4848
+ // / 'Class' type,
4849
+ bool isObjCIdOrClassType () const {
4850
+ return getObjectType ()->isObjCUnqualifiedIdOrClass ();
4851
+ }
4852
+
4801
4853
// / isObjCQualifiedIdType - True if this is equivalent to 'id<P>' for some
4802
4854
// / non-empty set of protocols.
4803
4855
bool isObjCQualifiedIdType () const {
@@ -4810,6 +4862,9 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
4810
4862
return getObjectType ()->isObjCQualifiedClass ();
4811
4863
}
4812
4864
4865
+ // / Whether this is a "__kindof" type.
4866
+ bool isKindOfType () const { return getObjectType ()->isKindOfType (); }
4867
+
4813
4868
// / Whether this type is specialized, meaning that it has type arguments.
4814
4869
bool isSpecialized () const { return getObjectType ()->isSpecialized (); }
4815
4870
@@ -4873,6 +4928,11 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
4873
4928
// / null type if there is no superclass.
4874
4929
QualType getSuperClassType () const ;
4875
4930
4931
+ // / Strip off the Objective-C "kindof" type and (with it) any
4932
+ // / protocol qualifiers.
4933
+ const ObjCObjectPointerType *stripObjCKindOfTypeAndQuals (
4934
+ const ASTContext &ctx) const ;
4935
+
4876
4936
void Profile (llvm::FoldingSetNodeID &ID) {
4877
4937
Profile (ID, getPointeeType ());
4878
4938
}
0 commit comments