jordan_rose created this revision.
jordan_rose added reviewers: jfb, doug.gregor, dexonsmith.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Someone actually had an Objective-C object pointer type with more than 64 
protocols, probably collected through typedefs. Raise the ceiling by one order 
of magnitude...even though this is just kicking the can down the road, and we 
need a proper diagnostic for this.


Repository:
  rC Clang

https://reviews.llvm.org/D63943

Files:
  include/clang/AST/Type.h
  lib/AST/Type.cpp

Index: lib/AST/Type.cpp
===================================================================
--- lib/AST/Type.cpp
+++ lib/AST/Type.cpp
@@ -621,7 +621,7 @@
            Base->isVariablyModifiedType(),
            Base->containsUnexpandedParameterPack()),
       BaseType(Base) {
-  ObjCObjectTypeBits.IsKindOf = isKindOf;
+  CachedSuperClassAndIsKindOf.setInt(isKindOf);
 
   ObjCObjectTypeBits.NumTypeArgs = typeArgs.size();
   assert(getTypeArgsAsWritten().size() == typeArgs.size() &&
@@ -1454,20 +1454,20 @@
   // superclass type.
   ObjCInterfaceDecl *classDecl = getInterface();
   if (!classDecl) {
-    CachedSuperClassType.setInt(true);
+    CachedSuperClassAndIsKindOf.setPointer({nullptr, true});
     return;
   }
 
   // Extract the superclass type.
   const ObjCObjectType *superClassObjTy = classDecl->getSuperClassType();
   if (!superClassObjTy) {
-    CachedSuperClassType.setInt(true);
+    CachedSuperClassAndIsKindOf.setPointer({nullptr, true});
     return;
   }
 
   ObjCInterfaceDecl *superClassDecl = superClassObjTy->getInterface();
   if (!superClassDecl) {
-    CachedSuperClassType.setInt(true);
+    CachedSuperClassAndIsKindOf.setPointer({nullptr, true});
     return;
   }
 
@@ -1476,14 +1476,14 @@
   QualType superClassType(superClassObjTy, 0);
   ObjCTypeParamList *superClassTypeParams = superClassDecl->getTypeParamList();
   if (!superClassTypeParams) {
-    CachedSuperClassType.setPointerAndInt(
-      superClassType->castAs<ObjCObjectType>(), true);
+    CachedSuperClassAndIsKindOf.setPointer({
+      superClassType->castAs<ObjCObjectType>(), true});
     return;
   }
 
   // If the superclass reference is unspecialized, return it.
   if (superClassObjTy->isUnspecialized()) {
-    CachedSuperClassType.setPointerAndInt(superClassObjTy, true);
+    CachedSuperClassAndIsKindOf.setPointer({superClassObjTy, true});
     return;
   }
 
@@ -1491,8 +1491,8 @@
   // parameters in the superclass reference to substitute.
   ObjCTypeParamList *typeParams = classDecl->getTypeParamList();
   if (!typeParams) {
-    CachedSuperClassType.setPointerAndInt(
-      superClassType->castAs<ObjCObjectType>(), true);
+    CachedSuperClassAndIsKindOf.setPointer({
+      superClassType->castAs<ObjCObjectType>(), true});
     return;
   }
 
@@ -1502,20 +1502,19 @@
     QualType unspecializedSuper
       = classDecl->getASTContext().getObjCInterfaceType(
           superClassObjTy->getInterface());
-    CachedSuperClassType.setPointerAndInt(
-      unspecializedSuper->castAs<ObjCObjectType>(),
-      true);
+    CachedSuperClassAndIsKindOf.setPointer({
+      unspecializedSuper->castAs<ObjCObjectType>(), true});
     return;
   }
 
   // Substitute the provided type arguments into the superclass type.
   ArrayRef<QualType> typeArgs = getTypeArgs();
   assert(typeArgs.size() == typeParams->size());
-  CachedSuperClassType.setPointerAndInt(
+  CachedSuperClassAndIsKindOf.setPointer({
     superClassType.substObjCTypeArgs(classDecl->getASTContext(), typeArgs,
                                      ObjCSubstitutionContext::Superclass)
       ->castAs<ObjCObjectType>(),
-    true);
+    true});
 }
 
 const ObjCInterfaceType *ObjCObjectPointerType::getInterfaceType() const {
Index: include/clang/AST/Type.h
===================================================================
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1556,10 +1556,7 @@
     unsigned NumTypeArgs : 7;
 
     /// The number of protocols stored directly on this object type.
-    unsigned NumProtocols : 6;
-
-    /// Whether this is a "kindof" type.
-    unsigned IsKindOf : 1;
+    unsigned NumProtocols : 7;
   };
 
   class ReferenceTypeBitfields {
@@ -5560,9 +5557,12 @@
   /// Either a BuiltinType or an InterfaceType or sugar for either.
   QualType BaseType;
 
-  /// Cached superclass type.
-  mutable llvm::PointerIntPair<const ObjCObjectType *, 1, bool>
-    CachedSuperClassType;
+  using CachedSuperClassStorage =
+      llvm::PointerIntPair<const ObjCObjectType *, 1, bool>;
+
+  /// Cached superclass type plus whether this type was written with '__kindof'.
+  mutable llvm::PointerIntPair<CachedSuperClassStorage, 1, bool>
+      CachedSuperClassAndIsKindOf;
 
   QualType *getTypeArgStorage();
   const QualType *getTypeArgStorage() const {
@@ -5592,7 +5592,6 @@
           BaseType(QualType(this_(), 0)) {
     ObjCObjectTypeBits.NumProtocols = 0;
     ObjCObjectTypeBits.NumTypeArgs = 0;
-    ObjCObjectTypeBits.IsKindOf = 0;
   }
 
   void computeSuperClassTypeSlow() const;
@@ -5658,7 +5657,9 @@
   }
 
   /// Whether this is a "__kindof" type as written.
-  bool isKindOfTypeAsWritten() const { return ObjCObjectTypeBits.IsKindOf; }
+  bool isKindOfTypeAsWritten() const {
+    return CachedSuperClassAndIsKindOf.getInt();
+  }
 
   /// Whether this ia a "__kindof" type (semantically).
   bool isKindOfType() const;
@@ -5670,11 +5671,12 @@
   /// specialization of the superclass type. Produces a null type if
   /// there is no superclass.
   QualType getSuperClassType() const {
-    if (!CachedSuperClassType.getInt())
+    if (!CachedSuperClassAndIsKindOf.getPointer().getInt())
       computeSuperClassTypeSlow();
 
-    assert(CachedSuperClassType.getInt() && "Superclass not set?");
-    return QualType(CachedSuperClassType.getPointer(), 0);
+    assert(CachedSuperClassAndIsKindOf.getPointer().getInt() &&
+           "Superclass not set?");
+    return QualType(CachedSuperClassAndIsKindOf.getPointer().getPointer(), 0);
   }
 
   /// Strip off the Objective-C "kindof" type and (with it) any
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to