]> granicus.if.org Git - clang/commitdiff
Make getObjCEncodingForTypeImpl() take a bitmask instead of 8 bools
authorNico Weber <nicolasweber@gmx.de>
Tue, 14 May 2019 12:32:37 +0000 (12:32 +0000)
committerNico Weber <nicolasweber@gmx.de>
Tue, 14 May 2019 12:32:37 +0000 (12:32 +0000)
Slightly easier to read, uses slightly less stack space, and makes it
impossible to mix up the order of all those bools.

No behavior change.

Differential Revision: https://reviews.llvm.org/D61788

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@360668 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ASTContext.h
lib/AST/ASTContext.cpp

index aebcd604fa5653e21ab51428ad74a8ec63a63e38..1a15e824bd305ea766a57c8e1ff7d7e702b8312c 100644 (file)
@@ -2864,18 +2864,53 @@ public:
 private:
   void InitBuiltinType(CanQualType &R, BuiltinType::Kind K);
 
+  class ObjCEncOptions {
+    unsigned Bits;
+
+    ObjCEncOptions(unsigned Bits) : Bits(Bits) {}
+
+  public:
+    ObjCEncOptions() : Bits(0) {}
+    ObjCEncOptions(const ObjCEncOptions &RHS) : Bits(RHS.Bits) {}
+
+#define OPT_LIST(V)                                                            \
+  V(ExpandPointedToStructures, 0)                                              \
+  V(ExpandStructures, 1)                                                       \
+  V(IsOutermostType, 2)                                                        \
+  V(EncodingProperty, 3)                                                       \
+  V(IsStructField, 4)                                                          \
+  V(EncodeBlockParameters, 5)                                                  \
+  V(EncodeClassNames, 6)                                                       \
+  V(EncodePointerToObjCTypedef, 7)
+
+#define V(N,I) ObjCEncOptions& set##N() { Bits |= 1 << I; return *this; }
+OPT_LIST(V)
+#undef V
+
+#define V(N,I) bool N() const { return Bits & 1 << I; }
+OPT_LIST(V)
+#undef V
+
+#undef OPT_LIST
+
+    LLVM_NODISCARD ObjCEncOptions keepingOnly(ObjCEncOptions Mask) const {
+      return Bits & Mask.Bits;
+    }
+
+    LLVM_NODISCARD ObjCEncOptions forComponentType() const {
+      ObjCEncOptions Mask = ObjCEncOptions()
+                                .setIsOutermostType()
+                                .setIsStructField()
+                                .setEncodePointerToObjCTypedef();
+      return Bits & ~Mask.Bits;
+    }
+  };
+
   // Return the Objective-C type encoding for a given type.
   void getObjCEncodingForTypeImpl(QualType t, std::string &S,
-                                  bool ExpandPointedToStructures,
-                                  bool ExpandStructures,
+                                  ObjCEncOptions Options,
                                   const FieldDecl *Field,
-                                  bool OutermostType = false,
-                                  bool EncodingProperty = false,
-                                  bool StructField = false,
-                                  bool EncodeBlockParameters = false,
-                                  bool EncodeClassNames = false,
-                                  bool EncodePointerToObjCTypedef = false,
-                                  QualType *NotEncodedT=nullptr) const;
+                                  QualType *NotEncodedT = nullptr) const;
 
   // Adds the encoding of the structure's members.
   void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S,
index 814f914ec7107f9d1467f1eb8a74b914f01b6839..072cfad5ba2873f4e02da0593537a79b03eabbc3 100644 (file)
@@ -6311,13 +6311,13 @@ void ASTContext::getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,
   // Encode type qualifer, 'in', 'inout', etc. for the parameter.
   getObjCEncodingForTypeQualifier(QT, S);
   // Encode parameter type.
-  getObjCEncodingForTypeImpl(T, S, /*ExpandPointedToStructures=*/true,
-                             /*ExpandStructures=*/true, /*Field=*/nullptr,
-                             /*OutermostType=*/true,
-                             /*EncodingProperty=*/false,
-                             /*StructField=*/false,
-                             /*EncodeBlockParameters=*/Extended,
-                             /*EncodeClassNames=*/Extended);
+  ObjCEncOptions Options = ObjCEncOptions()
+                               .setExpandPointedToStructures()
+                               .setExpandStructures()
+                               .setIsOutermostType();
+  if (Extended)
+    Options.setEncodeBlockParameters().setEncodeClassNames();
+  getObjCEncodingForTypeImpl(T, S, Options, /*Field=*/nullptr);
 }
 
 /// getObjCEncodingForMethodDecl - Return the encoded type for this method
@@ -6509,13 +6509,12 @@ void ASTContext::getObjCEncodingForType(QualType T, std::string& S,
   // directly pointed to, and expanding embedded structures. Note that
   // these rules are sufficient to prevent recursive encoding of the
   // same type.
-  getObjCEncodingForTypeImpl(T, S, /*ExpandPointedToStructures=*/true,
-                             /*ExpandStructures=*/true, Field,
-                             /*OutermostType=*/true, /*EncodingProperty=*/false,
-                             /*StructField=*/false,
-                             /*EncodeBlockParameters=*/false,
-                             /*EncodeClassNames=*/false,
-                             /*EncodePointerToObjCTypedef=*/false, NotEncodedT);
+  getObjCEncodingForTypeImpl(T, S,
+                             ObjCEncOptions()
+                                 .setExpandPointedToStructures()
+                                 .setExpandStructures()
+                                 .setIsOutermostType(),
+                             Field, NotEncodedT);
 }
 
 void ASTContext::getObjCEncodingForPropertyType(QualType T,
@@ -6523,9 +6522,13 @@ void ASTContext::getObjCEncodingForPropertyType(QualType T,
   // Encode result type.
   // GCC has some special rules regarding encoding of properties which
   // closely resembles encoding of ivars.
-  getObjCEncodingForTypeImpl(
-      T, S, /*ExpandPointedToStructures=*/true, /*ExpandStructures=*/true,
-      /*Field=*/nullptr, /*OutermostType=*/true, /*EncodingProperty=*/true);
+  getObjCEncodingForTypeImpl(T, S,
+                             ObjCEncOptions()
+                                 .setExpandPointedToStructures()
+                                 .setExpandStructures()
+                                 .setIsOutermostType()
+                                 .setEncodingProperty(),
+                             /*Field=*/nullptr);
 }
 
 static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
@@ -6672,16 +6675,9 @@ static void EncodeBitField(const ASTContext *Ctx, std::string& S,
 }
 
 // FIXME: Use SmallString for accumulating string.
-void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
-                                            bool ExpandPointedToStructures,
-                                            bool ExpandStructures,
+void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S,
+                                            const ObjCEncOptions Options,
                                             const FieldDecl *FD,
-                                            bool OutermostType,
-                                            bool EncodingProperty,
-                                            bool StructField,
-                                            bool EncodeBlockParameters,
-                                            bool EncodeClassNames,
-                                            bool EncodePointerToObjCTypedef,
                                             QualType *NotEncodedT) const {
   CanQualType CT = getCanonicalType(T);
   switch (CT->getTypeClass()) {
@@ -6698,18 +6694,16 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
   case Type::Complex: {
     const auto *CT = T->castAs<ComplexType>();
     S += 'j';
-    getObjCEncodingForTypeImpl(CT->getElementType(), S,
-                               /*ExpandPointedToStructures=*/false,
-                               /*ExpandStructures=*/false, /*Field=*/nullptr);
+    getObjCEncodingForTypeImpl(CT->getElementType(), S, ObjCEncOptions(),
+                               /*Field=*/nullptr);
     return;
   }
 
   case Type::Atomic: {
     const auto *AT = T->castAs<AtomicType>();
     S += 'A';
-    getObjCEncodingForTypeImpl(AT->getValueType(), S,
-                               /*ExpandPointedToStructures=*/false,
-                               /*ExpandStructures=*/false, /*Field=*/nullptr);
+    getObjCEncodingForTypeImpl(AT->getValueType(), S, ObjCEncOptions(),
+                               /*Field=*/nullptr);
     return;
   }
 
@@ -6735,11 +6729,11 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
     // the pointer itself gets ignored, _unless_ we are looking at a typedef!
     // Also, do not emit the 'r' for anything but the outermost type!
     if (isa<TypedefType>(T.getTypePtr())) {
-      if (OutermostType && T.isConstQualified()) {
+      if (Options.IsOutermostType() && T.isConstQualified()) {
         isReadOnly = true;
         S += 'r';
       }
-    } else if (OutermostType) {
+    } else if (Options.IsOutermostType()) {
       QualType P = PointeeTy;
       while (P->getAs<PointerType>())
         P = P->getAs<PointerType>()->getPointeeType();
@@ -6779,13 +6773,11 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
     S += '^';
     getLegacyIntegralTypeEncoding(PointeeTy);
 
-    getObjCEncodingForTypeImpl(
-        PointeeTy, S, /*ExpandPointedToStructures=*/false,
-        /*ExpandStructures=*/ExpandPointedToStructures, /*Field=*/nullptr,
-        /*OutermostType=*/false, /*EncodingProperty=*/false,
-        /*StructField=*/false, /*EncodeBlockParameters=*/false,
-        /*EncodeClassNames=*/false, /*EncodePointerToObjCTypedef=*/false,
-        NotEncodedT);
+    ObjCEncOptions NewOptions;
+    if (Options.ExpandPointedToStructures())
+      NewOptions.setExpandStructures();
+    getObjCEncodingForTypeImpl(PointeeTy, S, NewOptions,
+                               /*Field=*/nullptr, NotEncodedT);
     return;
   }
 
@@ -6794,13 +6786,13 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
   case Type::VariableArray: {
     const auto *AT = cast<ArrayType>(CT);
 
-    if (isa<IncompleteArrayType>(AT) && !StructField) {
+    if (isa<IncompleteArrayType>(AT) && !Options.IsStructField()) {
       // Incomplete arrays are encoded as a pointer to the array element.
       S += '^';
 
-      getObjCEncodingForTypeImpl(AT->getElementType(), S,
-                                 /*ExpandPointedToStructures=*/false,
-                                 ExpandStructures, FD);
+      getObjCEncodingForTypeImpl(
+          AT->getElementType(), S,
+          Options.keepingOnly(ObjCEncOptions().setExpandStructures()), FD);
     } else {
       S += '[';
 
@@ -6815,11 +6807,8 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
 
       getObjCEncodingForTypeImpl(
           AT->getElementType(), S,
-          /*ExpandPointedToStructures=*/false, ExpandStructures, FD,
-          /*OutermostType=*/false,
-          /*EncodingProperty=*/false, /*StructField=*/false,
-          /*EncodeBlockParameters=*/false, /*EncodeClassNames=*/false,
-          /*EncodePointerToObjCTypedef=*/false, NotEncodedT);
+          Options.keepingOnly(ObjCEncOptions().setExpandStructures()), FD,
+          NotEncodedT);
       S += ']';
     }
     return;
@@ -6845,7 +6834,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
     } else {
       S += '?';
     }
-    if (ExpandStructures) {
+    if (Options.ExpandStructures()) {
       S += '=';
       if (!RDecl->isUnion()) {
         getObjCEncodingForStructureImpl(RDecl, S, FD, true, NotEncodedT);
@@ -6860,18 +6849,15 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
           // Special case bit-fields.
           if (Field->isBitField()) {
             getObjCEncodingForTypeImpl(Field->getType(), S,
-                                       /*ExpandPointedToStructures=*/false,
-                                       /*ExpandStructures=*/true, Field);
+                                       ObjCEncOptions().setExpandStructures(),
+                                       Field);
           } else {
             QualType qt = Field->getType();
             getLegacyIntegralTypeEncoding(qt);
             getObjCEncodingForTypeImpl(
-                qt, S, /*ExpandPointedToStructures=*/false,
-                /*ExpandStructures=*/true, FD, /*OutermostType=*/false,
-                /*EncodingProperty=*/false,
-                /*StructField=*/true, /*EncodeBlockParameters=*/false,
-                /*EncodeClassNames=*/false,
-                /*EncodePointerToObjCTypedef=*/false, NotEncodedT);
+                qt, S,
+                ObjCEncOptions().setExpandStructures().setIsStructField(), FD,
+                NotEncodedT);
           }
         }
       }
@@ -6883,26 +6869,20 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
   case Type::BlockPointer: {
     const auto *BT = T->castAs<BlockPointerType>();
     S += "@?"; // Unlike a pointer-to-function, which is "^?".
-    if (EncodeBlockParameters) {
+    if (Options.EncodeBlockParameters()) {
       const auto *FT = BT->getPointeeType()->castAs<FunctionType>();
 
       S += '<';
       // Block return type
-      getObjCEncodingForTypeImpl(
-          FT->getReturnType(), S, ExpandPointedToStructures, ExpandStructures,
-          FD, /*OutermostType=*/false, EncodingProperty,
-          /*StructField=*/false, EncodeBlockParameters, EncodeClassNames,
-          /*EncodePointerToObjCTypedef=*/false, NotEncodedT);
+      getObjCEncodingForTypeImpl(FT->getReturnType(), S,
+                                 Options.forComponentType(), FD, NotEncodedT);
       // Block self
       S += "@?";
       // Block parameters
       if (const auto *FPT = dyn_cast<FunctionProtoType>(FT)) {
         for (const auto &I : FPT->param_types())
-          getObjCEncodingForTypeImpl(
-              I, S, ExpandPointedToStructures, ExpandStructures, FD,
-              /*OutermostType=*/false, EncodingProperty,
-              /*StructField=*/false, EncodeBlockParameters, EncodeClassNames,
-              /*EncodePointerToObjCTypedef=*/false, NotEncodedT);
+          getObjCEncodingForTypeImpl(I, S, Options.forComponentType(), FD,
+                                     NotEncodedT);
       }
       S += '>';
     }
@@ -6930,7 +6910,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
     ObjCInterfaceDecl *OI = T->castAs<ObjCObjectType>()->getInterface();
     S += '{';
     S += OI->getObjCRuntimeNameAsString();
-    if (ExpandStructures) {
+    if (Options.ExpandStructures()) {
       S += '=';
       SmallVector<const ObjCIvarDecl*, 32> Ivars;
       DeepCollectObjCIvars(OI, true, Ivars);
@@ -6938,17 +6918,15 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
         const FieldDecl *Field = Ivars[i];
         if (Field->isBitField())
           getObjCEncodingForTypeImpl(Field->getType(), S,
-                                     /*ExpandPointedToStructures=*/false,
-                                     /*ExpandStructures=*/true, Field);
-        else
-          getObjCEncodingForTypeImpl(
-              Field->getType(), S,
-              /*ExpandPointedToStructures=*/false,
-              /*ExpandStructures=*/true, FD, /*OutermostType=*/false,
-              /*EncodingProperty=*/false,
-              /*StructField=*/false, /*EncodeBlockParameters=*/false,
-              /*EncodeClassNames=*/false, EncodePointerToObjCTypedef,
-              NotEncodedT);
+                                     ObjCEncOptions().setExpandStructures(),
+                                     Field);
+        else {
+          ObjCEncOptions NewOptions = ObjCEncOptions().setExpandStructures();
+          if (Options.EncodePointerToObjCTypedef())
+            NewOptions.setEncodePointerToObjCTypedef();
+          getObjCEncodingForTypeImpl(Field->getType(), S, NewOptions, FD,
+                                     NotEncodedT);
+        }
       }
     }
     S += '}';
@@ -6971,10 +6949,13 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
     }
 
     if (OPT->isObjCQualifiedIdType()) {
-      getObjCEncodingForTypeImpl(getObjCIdType(), S,
-                                 ExpandPointedToStructures,
-                                 ExpandStructures, FD);
-      if (FD || EncodingProperty || EncodeClassNames) {
+      getObjCEncodingForTypeImpl(
+          getObjCIdType(), S,
+          Options.keepingOnly(ObjCEncOptions()
+                                  .setExpandPointedToStructures()
+                                  .setExpandStructures()),
+          FD);
+      if (FD || Options.EncodingProperty() || Options.EncodeClassNames()) {
         // Note that we do extended encoding of protocol qualifer list
         // Only when doing ivar or property encoding.
         S += '"';
@@ -6989,9 +6970,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
     }
 
     QualType PointeeTy = OPT->getPointeeType();
-    if (!EncodingProperty &&
+    if (!Options.EncodingProperty() &&
         isa<TypedefType>(PointeeTy.getTypePtr()) &&
-        !EncodePointerToObjCTypedef) {
+        !Options.EncodePointerToObjCTypedef()) {
       // Another historical/compatibility reason.
       // We encode the underlying type which comes out as
       // {...};
@@ -7010,21 +6991,17 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
           }
         }
       }
-      getObjCEncodingForTypeImpl(
-          PointeeTy, S,
-          /*ExpandPointedToStructures=*/false,
-          /*ExpandStructures=*/ExpandPointedToStructures,
-          /*Field=*/nullptr,
-          /*OutermostType=*/false, /*EncodingProperty=*/false,
-          /*StructField=*/false, /*EncodeBlockParameters=*/false,
-          /*EncodeClassNames=*/false,
-          /*EncodePointerToObjCTypedef=*/true);
+      ObjCEncOptions NewOptions =
+          ObjCEncOptions().setEncodePointerToObjCTypedef();
+      if (Options.ExpandPointedToStructures())
+        NewOptions.setExpandStructures();
+      getObjCEncodingForTypeImpl(PointeeTy, S, NewOptions, /*Field=*/nullptr);
       return;
     }
 
     S += '@';
     if (OPT->getInterfaceDecl() &&
-        (FD || EncodingProperty || EncodeClassNames)) {
+        (FD || Options.EncodingProperty() || Options.EncodeClassNames())) {
       S += '"';
       S += OPT->getInterfaceDecl()->getObjCRuntimeNameAsString();
       for (const auto *I : OPT->quals()) {
@@ -7038,7 +7015,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
   }
 
   // gcc just blithely ignores member pointers.
-  // FIXME: we shoul do better than that.  'M' is available.
+  // FIXME: we should do better than that.  'M' is available.
   case Type::MemberPointer:
   // This matches gcc's encoding, even though technically it is insufficient.
   //FIXME. We should do a better job than gcc.
@@ -7201,13 +7178,8 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
         QualType qt = field->getType();
         getLegacyIntegralTypeEncoding(qt);
         getObjCEncodingForTypeImpl(
-            qt, S, /*ExpandPointedToStructures=*/false,
-            /*ExpandStructures=*/true, FD,
-            /*OutermostType=*/false,
-            /*EncodingProperty=*/false,
-            /*StructField=*/true, /*EncodeBlockParameters=*/false,
-            /*EncodeClassNames=*/false, /*EncodePointerToObjCTypedef=*/false,
-            NotEncodedT);
+            qt, S, ObjCEncOptions().setExpandStructures().setIsStructField(),
+            FD, NotEncodedT);
 #ifndef NDEBUG
         CurOffs += getTypeSize(field->getType());
 #endif