From: Fariborz Jahanian Date: Fri, 11 Oct 2013 17:35:22 +0000 (+0000) Subject: ObjectiveC migrator: fixes a bug when in NS_ENUM/NS_OPTIONS X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1f9a09d4e50c3e8e622292350823eef776b93e3d;p=clang ObjectiveC migrator: fixes a bug when in NS_ENUM/NS_OPTIONS migration, the typedef has annotations. // rdar://15200602 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@192468 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp index ad00d545b2..cd4b284e7d 100644 --- a/lib/ARCMigrate/ObjCMT.cpp +++ b/lib/ARCMigrate/ObjCMT.cpp @@ -510,7 +510,8 @@ static bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl, SourceRange R(EnumDcl->getLocStart(), EnumDcl->getLocStart()); commit.replace(R, ClassString); SourceLocation EndOfTypedefLoc = TypedefDcl->getLocEnd(); - EndOfTypedefLoc = trans::findLocationAfterSemi(EndOfTypedefLoc, NS.getASTContext()); + EndOfTypedefLoc = trans::findLocationAfterSemi(EndOfTypedefLoc, NS.getASTContext(), + /*IsDecl*/true); SourceLocation BeginOfTypedefLoc = TypedefDcl->getLocStart(); if (!EndOfTypedefLoc.isInvalid()) { // FIXME. This assumes that typedef decl; is immediately preceeded by eoln. diff --git a/lib/ARCMigrate/Transforms.cpp b/lib/ARCMigrate/Transforms.cpp index 38f30a56f4..679b924ba0 100644 --- a/lib/ARCMigrate/Transforms.cpp +++ b/lib/ARCMigrate/Transforms.cpp @@ -122,8 +122,8 @@ bool trans::isPlusOne(const Expr *E) { /// If no semicolon is found or the location is inside a macro, the returned /// source location will be invalid. SourceLocation trans::findLocationAfterSemi(SourceLocation loc, - ASTContext &Ctx) { - SourceLocation SemiLoc = findSemiAfterLocation(loc, Ctx); + ASTContext &Ctx, bool IsDecl) { + SourceLocation SemiLoc = findSemiAfterLocation(loc, Ctx, IsDecl); if (SemiLoc.isInvalid()) return SourceLocation(); return SemiLoc.getLocWithOffset(1); @@ -134,7 +134,8 @@ SourceLocation trans::findLocationAfterSemi(SourceLocation loc, /// If no semicolon is found or the location is inside a macro, the returned /// source location will be invalid. SourceLocation trans::findSemiAfterLocation(SourceLocation loc, - ASTContext &Ctx) { + ASTContext &Ctx, + bool IsDecl) { SourceManager &SM = Ctx.getSourceManager(); if (loc.isMacroID()) { if (!Lexer::isAtEndOfMacroExpansion(loc, SM, Ctx.getLangOpts(), &loc)) @@ -159,8 +160,13 @@ SourceLocation trans::findSemiAfterLocation(SourceLocation loc, file.begin(), tokenBegin, file.end()); Token tok; lexer.LexFromRawLexer(tok); - if (tok.isNot(tok::semi)) - return SourceLocation(); + if (tok.isNot(tok::semi)) { + if (!IsDecl) + return SourceLocation(); + // Declaration may be followed with other tokens; such as an __attribute, + // before ending with a semicolon. + return findSemiAfterLocation(tok.getLocation(), Ctx, /*IsDecl*/true); + } return tok.getLocation(); } diff --git a/lib/ARCMigrate/Transforms.h b/lib/ARCMigrate/Transforms.h index e20fe5927f..eab5e85d56 100644 --- a/lib/ARCMigrate/Transforms.h +++ b/lib/ARCMigrate/Transforms.h @@ -167,13 +167,15 @@ bool isPlusOne(const Expr *E); /// immediately after the semicolon following the statement. /// If no semicolon is found or the location is inside a macro, the returned /// source location will be invalid. -SourceLocation findLocationAfterSemi(SourceLocation loc, ASTContext &Ctx); +SourceLocation findLocationAfterSemi(SourceLocation loc, ASTContext &Ctx, + bool IsDecl = false); /// \brief 'Loc' is the end of a statement range. This returns the location /// of the semicolon following the statement. /// If no semicolon is found or the location is inside a macro, the returned /// source location will be invalid. -SourceLocation findSemiAfterLocation(SourceLocation loc, ASTContext &Ctx); +SourceLocation findSemiAfterLocation(SourceLocation loc, ASTContext &Ctx, + bool IsDecl = false); bool hasSideEffects(Expr *E, ASTContext &Ctx); bool isGlobalVar(Expr *E); diff --git a/test/ARCMT/objcmt-ns-macros.m b/test/ARCMT/objcmt-ns-macros.m index 4ae42c496e..b83857de7d 100644 --- a/test/ARCMT/objcmt-ns-macros.m +++ b/test/ARCMT/objcmt-ns-macros.m @@ -204,3 +204,14 @@ typedef enum { Random5 = 0xbadbeef, Random6 } UIP8_3; + +// rdar://15200602 +#define NS_AVAILABLE_MAC(X) __attribute__((availability(macosx,introduced=X))) +#define NS_ENUM_AVAILABLE_MAC(X) __attribute__((availability(macosx,introduced=X))) + +enum { + NSModalResponseStop = (-1000), // Also used as the default response for sheets + NSModalResponseAbort = (-1001), + NSModalResponseContinue = (-1002), +} NS_ENUM_AVAILABLE_MAC(10.9); +typedef NSInteger NSModalResponse NS_AVAILABLE_MAC(10.9); diff --git a/test/ARCMT/objcmt-ns-macros.m.result b/test/ARCMT/objcmt-ns-macros.m.result index 4218603696..f8bbbefe66 100644 --- a/test/ARCMT/objcmt-ns-macros.m.result +++ b/test/ARCMT/objcmt-ns-macros.m.result @@ -195,3 +195,13 @@ typedef NS_ENUM(NSInteger, UIP8_3) { Random5 = 0xbadbeef, Random6 } ; + +// rdar://15200602 +#define NS_AVAILABLE_MAC(X) __attribute__((availability(macosx,introduced=X))) +#define NS_ENUM_AVAILABLE_MAC(X) __attribute__((availability(macosx,introduced=X))) + +typedef NS_ENUM(NSInteger, NSModalResponse) { + NSModalResponseStop = (-1000), // Also used as the default response for sheets + NSModalResponseAbort = (-1001), + NSModalResponseContinue = (-1002), +} NS_ENUM_AVAILABLE_MAC(10.9);