From 85e988bbeaa0b77729cd631fd60318446ce81631 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Thu, 18 Jul 2013 22:17:33 +0000 Subject: [PATCH] ObjectiveC migrator: Remove semicolon after the typedef declaration when converting to NS_ENUM. This required some code refactoring. llvm-svn: 186619 --- clang/include/clang/Edit/Rewriters.h | 11 --- clang/lib/ARCMigrate/ObjCMT.cpp | 105 ++++++++++++++++++++++++++-- clang/lib/Edit/RewriteObjCFoundationAPI.cpp | 92 ------------------------ clang/test/ARCMT/objcmt-ns-macros.m.result | 2 +- 4 files changed, 102 insertions(+), 108 deletions(-) diff --git a/clang/include/clang/Edit/Rewriters.h b/clang/include/clang/Edit/Rewriters.h index ad7494f..5e3425f 100644 --- a/clang/include/clang/Edit/Rewriters.h +++ b/clang/include/clang/Edit/Rewriters.h @@ -31,19 +31,8 @@ bool rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit, const ParentMap *PMap); -bool rewriteToObjCProperty(const ObjCMethodDecl *Getter, - const ObjCMethodDecl *Setter, - const NSAPI &NS, Commit &commit); -bool rewriteToObjCInterfaceDecl(const ObjCInterfaceDecl *IDecl, - llvm::SmallVectorImpl &Protocols, - const NSAPI &NS, Commit &commit); - bool rewriteToObjCSubscriptSyntax(const ObjCMessageExpr *Msg, const NSAPI &NS, Commit &commit); - -bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl, - const TypedefDecl *TypedefDcl, - const NSAPI &NS, Commit &commit); } diff --git a/clang/lib/ARCMigrate/ObjCMT.cpp b/clang/lib/ARCMigrate/ObjCMT.cpp index 732e46a..7542a69 100644 --- a/clang/lib/ARCMigrate/ObjCMT.cpp +++ b/clang/lib/ARCMigrate/ObjCMT.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "Transforms.h" #include "clang/ARCMigrate/ARCMTActions.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" @@ -199,6 +200,53 @@ void ObjCMigrateASTConsumer::migrateDecl(Decl *D) { BodyMigrator(*this).TraverseDecl(D); } +static bool rewriteToObjCProperty(const ObjCMethodDecl *Getter, + const ObjCMethodDecl *Setter, + const NSAPI &NS, edit::Commit &commit) { + ASTContext &Context = NS.getASTContext(); + std::string PropertyString = "@property"; + const ParmVarDecl *argDecl = *Setter->param_begin(); + QualType ArgType = Context.getCanonicalType(argDecl->getType()); + Qualifiers::ObjCLifetime propertyLifetime = ArgType.getObjCLifetime(); + + if (ArgType->isObjCRetainableType() && + propertyLifetime == Qualifiers::OCL_Strong) { + if (const ObjCObjectPointerType *ObjPtrTy = + ArgType->getAs()) { + ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface(); + if (IDecl && + IDecl->lookupNestedProtocol(&Context.Idents.get("NSCopying"))) + PropertyString += "(copy)"; + } + } + else if (propertyLifetime == Qualifiers::OCL_Weak) + // TODO. More precise determination of 'weak' attribute requires + // looking into setter's implementation for backing weak ivar. + PropertyString += "(weak)"; + else + PropertyString += "(unsafe_unretained)"; + + // strip off any ARC lifetime qualifier. + QualType CanResultTy = Context.getCanonicalType(Getter->getResultType()); + if (CanResultTy.getQualifiers().hasObjCLifetime()) { + Qualifiers Qs = CanResultTy.getQualifiers(); + Qs.removeObjCLifetime(); + CanResultTy = Context.getQualifiedType(CanResultTy.getUnqualifiedType(), Qs); + } + PropertyString += " "; + PropertyString += CanResultTy.getAsString(Context.getPrintingPolicy()); + PropertyString += " "; + PropertyString += Getter->getNameAsString(); + commit.replace(CharSourceRange::getCharRange(Getter->getLocStart(), + Getter->getDeclaratorEndLoc()), + PropertyString); + SourceLocation EndLoc = Setter->getDeclaratorEndLoc(); + // Get location past ';' + EndLoc = EndLoc.getLocWithOffset(1); + commit.remove(CharSourceRange::getCharRange(Setter->getLocStart(), EndLoc)); + return true; +} + void ObjCMigrateASTConsumer::migrateObjCInterfaceDecl(ASTContext &Ctx, ObjCInterfaceDecl *D) { for (ObjCContainerDecl::method_iterator M = D->meth_begin(), MEnd = D->meth_end(); @@ -231,7 +279,7 @@ void ObjCMigrateASTConsumer::migrateObjCInterfaceDecl(ASTContext &Ctx, SetterMethod->hasAttrs()) continue; edit::Commit commit(*Editor); - edit::rewriteToObjCProperty(Method, SetterMethod, *NSAPIObj, commit); + rewriteToObjCProperty(Method, SetterMethod, *NSAPIObj, commit); Editor->commit(commit); } } @@ -300,6 +348,55 @@ ClassImplementsAllMethodsAndProperties(ASTContext &Ctx, return true; } +static bool rewriteToObjCInterfaceDecl(const ObjCInterfaceDecl *IDecl, + llvm::SmallVectorImpl &ConformingProtocols, + const NSAPI &NS, edit::Commit &commit) { + const ObjCList &Protocols = IDecl->getReferencedProtocols(); + std::string ClassString; + SourceLocation EndLoc = + IDecl->getSuperClass() ? IDecl->getSuperClassLoc() : IDecl->getLocation(); + + if (Protocols.empty()) { + ClassString = '<'; + for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) { + ClassString += ConformingProtocols[i]->getNameAsString(); + if (i != (e-1)) + ClassString += ", "; + } + ClassString += "> "; + } + else { + ClassString = ", "; + for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) { + ClassString += ConformingProtocols[i]->getNameAsString(); + if (i != (e-1)) + ClassString += ", "; + } + ObjCInterfaceDecl::protocol_loc_iterator PL = IDecl->protocol_loc_end() - 1; + EndLoc = *PL; + } + + commit.insertAfterToken(EndLoc, ClassString); + return true; +} + +static bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl, + const TypedefDecl *TypedefDcl, + const NSAPI &NS, edit::Commit &commit) { + std::string ClassString = "typedef NS_ENUM(NSInteger, "; + ClassString += TypedefDcl->getIdentifier()->getName(); + ClassString += ')'; + SourceRange R(EnumDcl->getLocStart(), EnumDcl->getLocStart()); + commit.replace(R, ClassString); + SourceLocation EndOfTypedefLoc = TypedefDcl->getLocEnd(); + EndOfTypedefLoc = trans::findLocationAfterSemi(EndOfTypedefLoc, NS.getASTContext()); + if (!EndOfTypedefLoc.isInvalid()) { + commit.remove(SourceRange(TypedefDcl->getLocStart(), EndOfTypedefLoc)); + return true; + } + return false; +} + void ObjCMigrateASTConsumer::migrateProtocolConformance(ASTContext &Ctx, const ObjCImplementationDecl *ImpDecl) { const ObjCInterfaceDecl *IDecl = ImpDecl->getClassInterface(); @@ -352,8 +449,8 @@ void ObjCMigrateASTConsumer::migrateProtocolConformance(ASTContext &Ctx, MinimalConformingProtocols.push_back(TargetPDecl); } edit::Commit commit(*Editor); - edit::rewriteToObjCInterfaceDecl(IDecl, MinimalConformingProtocols, - *NSAPIObj, commit); + rewriteToObjCInterfaceDecl(IDecl, MinimalConformingProtocols, + *NSAPIObj, commit); Editor->commit(commit); } @@ -372,7 +469,7 @@ void ObjCMigrateASTConsumer::migrateNSEnumDecl(ASTContext &Ctx, if (!Ctx.Idents.get("NS_ENUM").hasMacroDefinition()) return; edit::Commit commit(*Editor); - edit::rewriteToNSEnumDecl(EnumDcl, TypedefDcl, *NSAPIObj, commit); + rewriteToNSEnumDecl(EnumDcl, TypedefDcl, *NSAPIObj, commit); Editor->commit(commit); } diff --git a/clang/lib/Edit/RewriteObjCFoundationAPI.cpp b/clang/lib/Edit/RewriteObjCFoundationAPI.cpp index 68dcd6b..f4206fb 100644 --- a/clang/lib/Edit/RewriteObjCFoundationAPI.cpp +++ b/clang/lib/Edit/RewriteObjCFoundationAPI.cpp @@ -355,98 +355,6 @@ bool edit::rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg, return false; } -bool edit::rewriteToObjCProperty(const ObjCMethodDecl *Getter, - const ObjCMethodDecl *Setter, - const NSAPI &NS, Commit &commit) { - ASTContext &Context = NS.getASTContext(); - std::string PropertyString = "@property"; - const ParmVarDecl *argDecl = *Setter->param_begin(); - QualType ArgType = Context.getCanonicalType(argDecl->getType()); - Qualifiers::ObjCLifetime propertyLifetime = ArgType.getObjCLifetime(); - - if (ArgType->isObjCRetainableType() && - propertyLifetime == Qualifiers::OCL_Strong) { - if (const ObjCObjectPointerType *ObjPtrTy = - ArgType->getAs()) { - ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface(); - if (IDecl && - IDecl->lookupNestedProtocol(&Context.Idents.get("NSCopying"))) - PropertyString += "(copy)"; - } - } - else if (propertyLifetime == Qualifiers::OCL_Weak) - // TODO. More precise determination of 'weak' attribute requires - // looking into setter's implementation for backing weak ivar. - PropertyString += "(weak)"; - else - PropertyString += "(unsafe_unretained)"; - - // strip off any ARC lifetime qualifier. - QualType CanResultTy = Context.getCanonicalType(Getter->getResultType()); - if (CanResultTy.getQualifiers().hasObjCLifetime()) { - Qualifiers Qs = CanResultTy.getQualifiers(); - Qs.removeObjCLifetime(); - CanResultTy = Context.getQualifiedType(CanResultTy.getUnqualifiedType(), Qs); - } - PropertyString += " "; - PropertyString += CanResultTy.getAsString(Context.getPrintingPolicy()); - PropertyString += " "; - PropertyString += Getter->getNameAsString(); - commit.replace(CharSourceRange::getCharRange(Getter->getLocStart(), - Getter->getDeclaratorEndLoc()), - PropertyString); - SourceLocation EndLoc = Setter->getDeclaratorEndLoc(); - // Get location past ';' - EndLoc = EndLoc.getLocWithOffset(1); - commit.remove(CharSourceRange::getCharRange(Setter->getLocStart(), EndLoc)); - return true; -} - -bool edit::rewriteToObjCInterfaceDecl(const ObjCInterfaceDecl *IDecl, - llvm::SmallVectorImpl &ConformingProtocols, - const NSAPI &NS, Commit &commit) { - const ObjCList &Protocols = IDecl->getReferencedProtocols(); - std::string ClassString; - SourceLocation EndLoc = - IDecl->getSuperClass() ? IDecl->getSuperClassLoc() : IDecl->getLocation(); - - if (Protocols.empty()) { - ClassString = '<'; - for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) { - ClassString += ConformingProtocols[i]->getNameAsString(); - if (i != (e-1)) - ClassString += ", "; - } - ClassString += "> "; - } - else { - ClassString = ", "; - for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) { - ClassString += ConformingProtocols[i]->getNameAsString(); - if (i != (e-1)) - ClassString += ", "; - } - ObjCInterfaceDecl::protocol_loc_iterator PL = IDecl->protocol_loc_end() - 1; - EndLoc = *PL; - } - - commit.insertAfterToken(EndLoc, ClassString); - return true; -} - -bool edit::rewriteToNSEnumDecl(const EnumDecl *EnumDcl, - const TypedefDecl *TypedefDcl, - const NSAPI &NS, Commit &commit) { - std::string ClassString = "typedef NS_ENUM(NSInteger, "; - ClassString += TypedefDcl->getIdentifier()->getName(); - ClassString += ')'; - SourceRange R(EnumDcl->getLocStart(), EnumDcl->getLocStart()); - commit.replace(R, ClassString); - commit.remove(SourceRange(TypedefDcl->getLocStart(), TypedefDcl->getLocEnd())); - return true; - -} - /// \brief Returns true if the immediate message arguments of \c Msg should not /// be rewritten because it will interfere with the rewrite of the parent /// message expression. e.g. diff --git a/clang/test/ARCMT/objcmt-ns-macros.m.result b/clang/test/ARCMT/objcmt-ns-macros.m.result index ab8e8d2..c8c6686 100644 --- a/clang/test/ARCMT/objcmt-ns-macros.m.result +++ b/clang/test/ARCMT/objcmt-ns-macros.m.result @@ -10,4 +10,4 @@ typedef NS_ENUM(NSInteger, wibble) { blah, blarg }; -; + -- 2.7.4