Objective-C migration: Use NS_OPTIONS when enumerators

have shift/bitwise operators or are power of 2.

llvm-svn: 186856
This commit is contained in:
Fariborz Jahanian 2013-07-22 18:53:45 +00:00
parent 44ff81d4e3
commit d0f6f79f4e
3 changed files with 104 additions and 25 deletions

View 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.

View 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

View 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