r186856 - Objective-C migration: Use NS_OPTIONS when enumerators
Fariborz Jahanian
fjahanian at apple.com
Mon Jul 22 11:53:46 PDT 2013
Author: fjahanian
Date: Mon Jul 22 13:53:45 2013
New Revision: 186856
URL: http://llvm.org/viewvc/llvm-project?rev=186856&view=rev
Log:
Objective-C migration: Use NS_OPTIONS when enumerators
have shift/bitwise operators or are power of 2.
Modified:
cfe/trunk/lib/ARCMigrate/ObjCMT.cpp
cfe/trunk/test/ARCMT/objcmt-ns-macros.m
cfe/trunk/test/ARCMT/objcmt-ns-macros.m.result
Modified: cfe/trunk/lib/ARCMigrate/ObjCMT.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/ObjCMT.cpp?rev=186856&r1=186855&r2=186856&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/ObjCMT.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/ObjCMT.cpp Mon Jul 22 13:53:45 2013
@@ -399,10 +399,12 @@ static bool rewriteToNSEnumDecl(const En
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 En
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::migrateNSEn
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.
Modified: cfe/trunk/test/ARCMT/objcmt-ns-macros.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/objcmt-ns-macros.m?rev=186856&r1=186855&r2=186856&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/objcmt-ns-macros.m (original)
+++ cfe/trunk/test/ARCMT/objcmt-ns-macros.m Mon Jul 22 13:53:45 2013
@@ -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
Modified: cfe/trunk/test/ARCMT/objcmt-ns-macros.m.result
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/objcmt-ns-macros.m.result?rev=186856&r1=186855&r2=186856&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/objcmt-ns-macros.m.result (original)
+++ cfe/trunk/test/ARCMT/objcmt-ns-macros.m.result Mon Jul 22 13:53:45 2013
@@ -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, UIViewAnimati
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
More information about the cfe-commits
mailing list