From b3c71facc346f70fe4958f766ab55bd537229195 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Tue, 15 Oct 2013 00:00:28 +0000 Subject: [PATCH] ObjectiveC migrator: Support for more possibility of migration to NS_ENUM/NS_OPTIONS macros; when typedef'ed to NSInteger/NSUInteger preceeds well before of the enum declaration. // rdar://15201056 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@192645 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/ARCMigrate/ObjCMT.cpp | 112 ++++++++++++++++++++------- test/ARCMT/objcmt-ns-macros.m | 21 +++++ test/ARCMT/objcmt-ns-macros.m.result | 21 ++++- 3 files changed, 125 insertions(+), 29 deletions(-) diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp index 7b8aebbac5..3801ca5715 100644 --- a/lib/ARCMigrate/ObjCMT.cpp +++ b/lib/ARCMigrate/ObjCMT.cpp @@ -46,6 +46,7 @@ class ObjCMigrateASTConsumer : public ASTConsumer { void migrateObjCInterfaceDecl(ASTContext &Ctx, ObjCContainerDecl *D); void migrateProtocolConformance(ASTContext &Ctx, const ObjCImplementationDecl *ImpDecl); + void CacheObjCNSIntegerTypedefed(const TypedefDecl *TypedefDcl); bool migrateNSEnumDecl(ASTContext &Ctx, const EnumDecl *EnumDcl, const TypedefDecl *TypedefDcl); void migrateAllMethodInstaceType(ASTContext &Ctx, ObjCContainerDecl *CDecl); @@ -77,6 +78,8 @@ public: std::string MigrateDir; unsigned ASTMigrateActions; unsigned FileId; + const TypedefDecl *NSIntegerTypedefed; + const TypedefDecl *NSUIntegerTypedefed; OwningPtr NSAPIObj; OwningPtr Editor; FileRemapper &Remapper; @@ -96,7 +99,8 @@ public: bool isOutputFile = false) : MigrateDir(migrateDir), ASTMigrateActions(astMigrateActions), - FileId(0), Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP), + FileId(0), NSIntegerTypedefed(0), NSUIntegerTypedefed(0), + Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP), IsOutputFile(isOutputFile) { } protected: @@ -509,15 +513,34 @@ static bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl, ClassString += ')'; SourceRange R(EnumDcl->getLocStart(), EnumDcl->getLocStart()); commit.replace(R, ClassString); - SourceLocation EndOfTypedefLoc = TypedefDcl->getLocEnd(); - EndOfTypedefLoc = trans::findLocationAfterSemi(EndOfTypedefLoc, NS.getASTContext(), + SourceLocation EndOfEnumDclLoc = EnumDcl->getLocEnd(); + EndOfEnumDclLoc = trans::findSemiAfterLocation(EndOfEnumDclLoc, + NS.getASTContext(), /*IsDecl*/true); + if (!EndOfEnumDclLoc.isInvalid()) { + SourceRange EnumDclRange(EnumDcl->getLocStart(), EndOfEnumDclLoc); + commit.insertFromRange(TypedefDcl->getLocStart(), EnumDclRange); + } + else + return false; + + SourceLocation EndTypedefDclLoc = TypedefDcl->getLocEnd(); + EndTypedefDclLoc = trans::findSemiAfterLocation(EndTypedefDclLoc, + NS.getASTContext(), /*IsDecl*/true); + if (!EndTypedefDclLoc.isInvalid()) { + SourceRange TDRange(TypedefDcl->getLocStart(), EndTypedefDclLoc); + commit.remove(TDRange); + } + else + return false; + + EndOfEnumDclLoc = trans::findLocationAfterSemi(EnumDcl->getLocEnd(), NS.getASTContext(), /*IsDecl*/true); - SourceLocation BeginOfTypedefLoc = TypedefDcl->getLocStart(); - if (!EndOfTypedefLoc.isInvalid()) { - // FIXME. This assumes that typedef decl; is immediately preceeded by eoln. - // It is trying to remove the typedef decl. line entirely. - BeginOfTypedefLoc = BeginOfTypedefLoc.getLocWithOffset(-1); - commit.remove(SourceRange(BeginOfTypedefLoc, EndOfTypedefLoc)); + if (!EndOfEnumDclLoc.isInvalid()) { + SourceLocation BeginOfEnumDclLoc = EnumDcl->getLocStart(); + // FIXME. This assumes that enum decl; is immediately preceeded by eoln. + // It is trying to remove the enum decl. lines entirely. + BeginOfEnumDclLoc = BeginOfEnumDclLoc.getLocWithOffset(-1); + commit.remove(SourceRange(BeginOfEnumDclLoc, EndOfEnumDclLoc)); return true; } return false; @@ -638,12 +661,41 @@ void ObjCMigrateASTConsumer::migrateProtocolConformance(ASTContext &Ctx, Editor->commit(commit); } +void ObjCMigrateASTConsumer::CacheObjCNSIntegerTypedefed( + const TypedefDecl *TypedefDcl) { + + QualType qt = TypedefDcl->getTypeSourceInfo()->getType(); + if (NSAPIObj->isObjCNSIntegerType(qt)) + NSIntegerTypedefed = TypedefDcl; + else if (NSAPIObj->isObjCNSUIntegerType(qt)) + NSUIntegerTypedefed = TypedefDcl; +} + bool ObjCMigrateASTConsumer::migrateNSEnumDecl(ASTContext &Ctx, const EnumDecl *EnumDcl, const TypedefDecl *TypedefDcl) { if (!EnumDcl->isCompleteDefinition() || EnumDcl->getIdentifier() || - !TypedefDcl->getIdentifier() || - EnumDcl->isDeprecated() || TypedefDcl->isDeprecated()) + EnumDcl->isDeprecated()) + return false; + if (!TypedefDcl) { + if (NSIntegerTypedefed) { + TypedefDcl = NSIntegerTypedefed; + NSIntegerTypedefed = 0; + } + else if (NSUIntegerTypedefed) { + TypedefDcl = NSUIntegerTypedefed; + NSUIntegerTypedefed = 0; + } + else + return false; + unsigned FileIdOfTypedefDcl = + PP.getSourceManager().getFileID(TypedefDcl->getLocation()).getHashValue(); + unsigned FileIdOfEnumDcl = + PP.getSourceManager().getFileID(EnumDcl->getLocation()).getHashValue(); + if (FileIdOfTypedefDcl != FileIdOfEnumDcl) + return false; + } + if (TypedefDcl->isDeprecated()) return false; QualType qt = TypedefDcl->getTypeSourceInfo()->getType(); @@ -678,9 +730,10 @@ bool ObjCMigrateASTConsumer::migrateNSEnumDecl(ASTContext &Ctx, if (IsNSUIntegerType && !Ctx.Idents.get("NS_OPTIONS").hasMacroDefinition()) return false; edit::Commit commit(*Editor); - rewriteToNSEnumDecl(EnumDcl, TypedefDcl, *NSAPIObj, commit, IsNSIntegerType, NSOptions); + bool Res = rewriteToNSEnumDecl(EnumDcl, TypedefDcl, *NSAPIObj, + commit, IsNSIntegerType, NSOptions); Editor->commit(commit); - return true; + return Res; } static void ReplaceWithInstancetype(const ObjCMigrateASTConsumer &ASTC, @@ -1432,26 +1485,29 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { migrateProtocolConformance(Ctx, ImpDecl); } else if (const EnumDecl *ED = dyn_cast(*D)) { + if (!(ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros)) + continue; DeclContext::decl_iterator N = D; - ++N; - if (N != DEnd) - if (const TypedefDecl *TD = dyn_cast(*N)) { - if (ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros) { - if (migrateNSEnumDecl(Ctx, ED, TD)) - D++; - } - } + if (++N != DEnd) { + const TypedefDecl *TD = dyn_cast(*N); + if (migrateNSEnumDecl(Ctx, ED, TD) && TD) + D++; + } + else + migrateNSEnumDecl(Ctx, ED, /*TypedefDecl */0); } else if (const TypedefDecl *TD = dyn_cast(*D)) { - DeclContext::decl_iterator N = D; - ++N; - if (N != DEnd) - if (const EnumDecl *ED = dyn_cast(*N)) { - if (ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros) { - if (migrateNSEnumDecl(Ctx, ED, TD)) + if (ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros) { + DeclContext::decl_iterator N = D; + if (++N != DEnd) + if (const EnumDecl *ED = dyn_cast(*N)) { + if (migrateNSEnumDecl(Ctx, ED, TD)) { ++D; + continue; + } } - } + CacheObjCNSIntegerTypedefed(TD); + } } else if (const FunctionDecl *FD = dyn_cast(*D)) { if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) diff --git a/test/ARCMT/objcmt-ns-macros.m b/test/ARCMT/objcmt-ns-macros.m index b8715716d6..a2f0707ed7 100644 --- a/test/ARCMT/objcmt-ns-macros.m +++ b/test/ARCMT/objcmt-ns-macros.m @@ -216,6 +216,9 @@ enum { } NS_ENUM_AVAILABLE_MAC(10.9); typedef NSInteger NSModalResponse NS_AVAILABLE_MAC(10.9); +// rdar://15201056 +typedef NSUInteger FarAwayNSUInteger; + // rdar://15200915 typedef NSUInteger NSWorkspaceLaunchOptions; enum { @@ -246,8 +249,26 @@ enum { NSExclude10_4ElementsCreationOption = 1 << 2 }; +enum { + FarAway1 = 1 << 1, + FarAway2 = 1 << 2 +}; + enum { NSExcludeQuickDrawElementsIconOption = 1 << 1, NSExclude10_4ElementsIconOption = 1 << 2 }; typedef NSUInteger NSWorkspaceIconOptions; + +typedef NSInteger NSCollectionViewDropOperation; + +@interface INTF { + NSCollectionViewDropOperation I1; + NSCollectionViewDropOperation I2; +} +@end + +enum { + NotFarAway1 = 1 << 1, + NotFarAway2 = 1 << 2 +}; diff --git a/test/ARCMT/objcmt-ns-macros.m.result b/test/ARCMT/objcmt-ns-macros.m.result index 62f1cd7342..445b367a3f 100644 --- a/test/ARCMT/objcmt-ns-macros.m.result +++ b/test/ARCMT/objcmt-ns-macros.m.result @@ -121,6 +121,7 @@ typedef enum { #define NS_ENUM_AVAILABLE(X,Y) + typedef NS_OPTIONS(NSUInteger, NSFOptions) { NSFStrongMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (0UL << 0), NSFOpaqueMemory NS_ENUM_AVAILABLE(10_5, 6_0) = (2UL << 0), @@ -137,7 +138,6 @@ typedef NS_OPTIONS(NSUInteger, NSFOptions) { NSFCopyIn NS_ENUM_AVAILABLE(10_5, 6_0) = (1UL << 16), }; - typedef NS_ENUM(NSInteger, UIP) { UIP0One = 0, UIP0Two = 1, @@ -206,6 +206,12 @@ typedef NS_ENUM(NSInteger, NSModalResponse) { NSModalResponseContinue = (-1002), } NS_ENUM_AVAILABLE_MAC(10.9); +// rdar://15201056 +typedef NS_OPTIONS(NSUInteger, FarAwayNSUInteger) { + FarAway1 = 1 << 1, + FarAway2 = 1 << 2 +}; + // rdar://15200915 typedef NS_OPTIONS(NSUInteger, NSWorkspaceLaunchOptions) { NSWorkspaceLaunchAndPrint = 0x00000002, @@ -233,7 +239,20 @@ typedef NS_OPTIONS(NSUInteger, NSWorkspaceCreationOptions) { NSExclude10_4ElementsCreationOption = 1 << 2 }; + typedef NS_OPTIONS(NSUInteger, NSWorkspaceIconOptions) { NSExcludeQuickDrawElementsIconOption = 1 << 1, NSExclude10_4ElementsIconOption = 1 << 2 }; + +typedef NS_OPTIONS(NSUInteger, NSCollectionViewDropOperation) { + NotFarAway1 = 1 << 1, + NotFarAway2 = 1 << 2 +}; + +@interface INTF { + NSCollectionViewDropOperation I1; + NSCollectionViewDropOperation I2; +} +@end + -- 2.40.0