]> granicus.if.org Git - clang/commitdiff
Objective-C migration: Use NS_OPTIONS when enumerators
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 22 Jul 2013 18:53:45 +0000 (18:53 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 22 Jul 2013 18:53:45 +0000 (18:53 +0000)
have shift/bitwise operators or are power of 2.

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

lib/ARCMigrate/ObjCMT.cpp
test/ARCMT/objcmt-ns-macros.m
test/ARCMT/objcmt-ns-macros.m.result

index e4ec0c83c500df8b5adb7d19728d4df73364e706..1bc0b8c891c70f7aff2216b6d77ed25346d454b4 100644 (file)
@@ -399,10 +399,12 @@ static bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl,
   return false;
 }
 
-static bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl,
+static bool rewriteToNSMacroDecl(const EnumDecl *EnumDcl,
                                 const TypedefDecl *TypedefDcl,
-                                const NSAPI &NS, edit::Commit &commit) {
-  std::string ClassString = "NS_ENUM(NSInteger, ";
+                                const NSAPI &NS, edit::Commit &commit,
+                                 bool IsNSIntegerType) {
+  std::string ClassString =
+    IsNSIntegerType ? "NS_ENUM(NSInteger, " : "NS_OPTIONS(NSUInteger, ";
   ClassString += TypedefDcl->getIdentifier()->getName();
   ClassString += ')';
   SourceRange R(EnumDcl->getLocStart(), EnumDcl->getLocStart());
@@ -412,6 +414,29 @@ static bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl,
   return true;
 }
 
+static bool UseNSOptionsMacro(ASTContext &Ctx,
+                              const EnumDecl *EnumDcl) {
+  bool PowerOfTwo = true;
+  for (EnumDecl::enumerator_iterator EI = EnumDcl->enumerator_begin(),
+       EE = EnumDcl->enumerator_end(); EI != EE; ++EI) {
+    EnumConstantDecl *Enumerator = (*EI);
+    const Expr *InitExpr = Enumerator->getInitExpr();
+    if (!InitExpr) {
+      PowerOfTwo = false;
+      continue;
+    }
+    InitExpr = InitExpr->IgnoreImpCasts();
+    if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(InitExpr))
+      if (BO->isShiftOp() || BO->isBitwiseOp())
+        return true;
+    
+    uint64_t EnumVal = Enumerator->getInitVal().getZExtValue();
+    if (PowerOfTwo && EnumVal && !llvm::isPowerOf2_64(EnumVal))
+      PowerOfTwo = false;
+  }
+  return PowerOfTwo;
+}
+
 void ObjCMigrateASTConsumer::migrateProtocolConformance(ASTContext &Ctx,   
                                             const ObjCImplementationDecl *ImpDecl) {
   const ObjCInterfaceDecl *IDecl = ImpDecl->getClassInterface();
@@ -479,23 +504,29 @@ void ObjCMigrateASTConsumer::migrateNSEnumDecl(ASTContext &Ctx,
   QualType qt = TypedefDcl->getTypeSourceInfo()->getType();
   bool IsNSIntegerType = NSAPIObj->isObjCNSIntegerType(qt);
   bool IsNSUIntegerType = !IsNSIntegerType && NSAPIObj->isObjCNSUIntegerType(qt);
+  
   if (!IsNSIntegerType && !IsNSUIntegerType) {
     // Also check for typedef enum {...} TD;
     if (const EnumType *EnumTy = qt->getAs<EnumType>()) {
       if (EnumTy->getDecl() == EnumDcl) {
-        // NS_ENUM must be available.
-        if (!Ctx.Idents.get("NS_ENUM").hasMacroDefinition())
+        bool NSOptions = UseNSOptionsMacro(Ctx, EnumDcl);
+        if (NSOptions) {
+          if (!Ctx.Idents.get("NS_OPTIONS").hasMacroDefinition())
+            return;
+        }
+        else if (!Ctx.Idents.get("NS_ENUM").hasMacroDefinition())
           return;
         edit::Commit commit(*Editor);
-        rewriteToNSEnumDecl(EnumDcl, TypedefDcl, *NSAPIObj, commit);
+        rewriteToNSMacroDecl(EnumDcl, TypedefDcl, *NSAPIObj, commit, !NSOptions);
         Editor->commit(commit);
-        return;
       }
-      else
-        return;
     }
-    else
-      return;
+    return;
+  }
+  if (IsNSIntegerType && UseNSOptionsMacro(Ctx, EnumDcl)) {
+    // We may still use NS_OPTIONS based on what we find in the enumertor list.
+    IsNSIntegerType = false;
+    IsNSUIntegerType = true;
   }
   
   // NS_ENUM must be available.
index 42d7d2cd8f69895f770b7333dcd054760c54e94e..2ca85699fb9d180d7a5c67b80dfc7d57299c4c3f 100644 (file)
@@ -17,14 +17,13 @@ typedef NSInteger wibble;
 
 enum {
     UIViewAutoresizingNone                 = 0,
-    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
-    UIViewAutoresizingFlexibleWidth        = 1 << 1,
-    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
-    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
-    UIViewAutoresizingFlexibleHeight       = 1 << 4,
-    UIViewAutoresizingFlexibleBottomMargin = 1 << 5
+    UIViewAutoresizingFlexibleLeftMargin,
+    UIViewAutoresizingFlexibleWidth,
+    UIViewAutoresizingFlexibleRightMargin,
+    UIViewAutoresizingFlexibleTopMargin,
+    UIViewAutoresizingFlexibleHeight,
+    UIViewAutoresizingFlexibleBottomMargin
 };
-
 typedef NSUInteger UITableViewCellStyle;
 
 typedef enum {
@@ -35,6 +34,31 @@ typedef enum {
     UIViewAnimationTransitionCurlDown,
 } UIViewAnimationTransition;
 
+typedef enum {
+    UIViewOne   = 0,
+    UIViewTwo   = 1 << 0,
+    UIViewThree = 1 << 1,
+    UIViewFour  = 1 << 2,
+    UIViewFive  = 1 << 3,
+    UIViewSix   = 1 << 4,
+    UIViewSeven = 1 << 5
+} UITableView;
+
+enum {
+  UIOne = 0,
+  UITwo = 0x1,
+  UIthree = 0x8,
+  UIFour = 0x100
+};
+typedef NSInteger UI;
+
+typedef enum {
+  UIP2One = 0,
+  UIP2Two = 0x1,
+  UIP2three = 0x8,
+  UIP2Four = 0x100
+} UIPOWER2;
+
 enum {
   UNOne,
   UNTwo
index ee9b60596ffe3293f5399b58631b325166ad99f4..efd4fe8cecabffd29abc43018c0c58ff9fe430c6 100644 (file)
@@ -17,16 +17,15 @@ typedef NS_ENUM(NSInteger, wibble) {
 
 typedef NS_OPTIONS(NSUInteger, UITableViewCellStyle) {
     UIViewAutoresizingNone                 = 0,
-    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
-    UIViewAutoresizingFlexibleWidth        = 1 << 1,
-    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
-    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
-    UIViewAutoresizingFlexibleHeight       = 1 << 4,
-    UIViewAutoresizingFlexibleBottomMargin = 1 << 5
+    UIViewAutoresizingFlexibleLeftMargin,
+    UIViewAutoresizingFlexibleWidth,
+    UIViewAutoresizingFlexibleRightMargin,
+    UIViewAutoresizingFlexibleTopMargin,
+    UIViewAutoresizingFlexibleHeight,
+    UIViewAutoresizingFlexibleBottomMargin
 };
 
 
-
 typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {
     UIViewAnimationTransitionNone,
     UIViewAnimationTransitionFlipFromLeft,
@@ -35,6 +34,31 @@ typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {
     UIViewAnimationTransitionCurlDown,
 } ;
 
+typedef NS_OPTIONS(NSUInteger, UITableView) {
+    UIViewOne   = 0,
+    UIViewTwo   = 1 << 0,
+    UIViewThree = 1 << 1,
+    UIViewFour  = 1 << 2,
+    UIViewFive  = 1 << 3,
+    UIViewSix   = 1 << 4,
+    UIViewSeven = 1 << 5
+} ;
+
+typedef NS_OPTIONS(NSUInteger, UI) {
+  UIOne = 0,
+  UITwo = 0x1,
+  UIthree = 0x8,
+  UIFour = 0x100
+};
+
+
+typedef NS_OPTIONS(NSUInteger, UIPOWER2) {
+  UIP2One = 0,
+  UIP2Two = 0x1,
+  UIP2three = 0x8,
+  UIP2Four = 0x100
+} ;
+
 enum {
   UNOne,
   UNTwo