diff options
Diffstat (limited to 'clang/lib/ARCMigrate')
-rw-r--r-- | clang/lib/ARCMigrate/ObjCMT.cpp | 112 |
1 files changed, 84 insertions, 28 deletions
diff --git a/clang/lib/ARCMigrate/ObjCMT.cpp b/clang/lib/ARCMigrate/ObjCMT.cpp index 7b8aebbac5d..3801ca57150 100644 --- a/clang/lib/ARCMigrate/ObjCMT.cpp +++ b/clang/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<NSAPI> NSAPIObj; OwningPtr<edit::EditedSource> 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<EnumDecl>(*D)) { + if (!(ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros)) + continue; DeclContext::decl_iterator N = D; - ++N; - if (N != DEnd) - if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(*N)) { - if (ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros) { - if (migrateNSEnumDecl(Ctx, ED, TD)) - D++; - } - } + if (++N != DEnd) { + const TypedefDecl *TD = dyn_cast<TypedefDecl>(*N); + if (migrateNSEnumDecl(Ctx, ED, TD) && TD) + D++; + } + else + migrateNSEnumDecl(Ctx, ED, /*TypedefDecl */0); } else if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(*D)) { - DeclContext::decl_iterator N = D; - ++N; - if (N != DEnd) - if (const EnumDecl *ED = dyn_cast<EnumDecl>(*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<EnumDecl>(*N)) { + if (migrateNSEnumDecl(Ctx, ED, TD)) { ++D; + continue; + } } - } + CacheObjCNSIntegerTypedefed(TD); + } } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*D)) { if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) |