diff --git a/clang/lib/ARCMigrate/ObjCMT.cpp b/clang/lib/ARCMigrate/ObjCMT.cpp index ca86d12466f0..05a81393eabf 100644 --- a/clang/lib/ARCMigrate/ObjCMT.cpp +++ b/clang/lib/ARCMigrate/ObjCMT.cpp @@ -493,6 +493,7 @@ static bool rewriteToNSMacroDecl(const EnumDecl *EnumDcl, static bool UseNSOptionsMacro(ASTContext &Ctx, const EnumDecl *EnumDcl) { bool PowerOfTwo = true; + uint64_t MaxPowerOfTwoVal = 0; for (EnumDecl::enumerator_iterator EI = EnumDcl->enumerator_begin(), EE = EnumDcl->enumerator_end(); EI != EE; ++EI) { EnumConstantDecl *Enumerator = (*EI); @@ -507,10 +508,14 @@ static bool UseNSOptionsMacro(ASTContext &Ctx, return true; uint64_t EnumVal = Enumerator->getInitVal().getZExtValue(); - if (PowerOfTwo && EnumVal && !llvm::isPowerOf2_64(EnumVal)) - PowerOfTwo = false; + if (PowerOfTwo && EnumVal) { + if (!llvm::isPowerOf2_64(EnumVal)) + PowerOfTwo = false; + else if (EnumVal > MaxPowerOfTwoVal) + MaxPowerOfTwoVal = EnumVal; + } } - return PowerOfTwo; + return PowerOfTwo ? ((MaxPowerOfTwoVal > 2) ? true : false) : false; } void ObjCMigrateASTConsumer::migrateProtocolConformance(ASTContext &Ctx, diff --git a/clang/test/ARCMT/objcmt-ns-macros.m b/clang/test/ARCMT/objcmt-ns-macros.m index 2ca85699fb9d..26d5c33a55ab 100644 --- a/clang/test/ARCMT/objcmt-ns-macros.m +++ b/clang/test/ARCMT/objcmt-ns-macros.m @@ -64,3 +64,9 @@ enum { UNTwo }; +// Should use NS_ENUM even though it is all power of 2. +enum { + UIKOne = 0x1, + UIKTwo = 0x2, +}; +typedef NSInteger UIK; diff --git a/clang/test/ARCMT/objcmt-ns-macros.m.result b/clang/test/ARCMT/objcmt-ns-macros.m.result index efd4fe8cecab..b163cfbee1a2 100644 --- a/clang/test/ARCMT/objcmt-ns-macros.m.result +++ b/clang/test/ARCMT/objcmt-ns-macros.m.result @@ -64,3 +64,9 @@ enum { UNTwo }; +// Should use NS_ENUM even though it is all power of 2. +typedef NS_ENUM(NSInteger, UIK) { + UIKOne = 0x1, + UIKTwo = 0x2, +}; +