From: Argyrios Kyrtzidis Date: Wed, 11 Dec 2013 21:39:00 +0000 (+0000) Subject: [objcmt] When whitelisting the headers we want to modify, allow changing the X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3b351f687a459210bee30dc60ba93ae207ad2040;p=clang [objcmt] When whitelisting the headers we want to modify, allow changing the the ObjC implementation declarations, just don't change implementations for classes that are not in the whitelisted headers. For example, if we change a method to return 'instancetype' we should also update the method definition in the implementation. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@197075 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp index c14fca2738..b2dcd4f9c7 100644 --- a/lib/ARCMigrate/ObjCMT.cpp +++ b/lib/ARCMigrate/ObjCMT.cpp @@ -144,6 +144,30 @@ protected: return WhiteListFilenames.find(llvm::sys::path::filename(Path)) != WhiteListFilenames.end(); } + bool canModifyFile(const FileEntry *FE) { + if (!FE) + return false; + return canModifyFile(FE->getName()); + } + bool canModifyFile(FileID FID) { + if (FID.isInvalid()) + return false; + return canModifyFile(PP.getSourceManager().getFileEntryForID(FID)); + } + + bool canModify(const Decl *D) { + if (!D) + return false; + if (const ObjCCategoryImplDecl *CatImpl = dyn_cast(D)) + return canModify(CatImpl->getCategoryDecl()); + if (const ObjCImplementationDecl *Impl = dyn_cast(D)) + return canModify(Impl->getClassInterface()); + if (const ObjCMethodDecl *MD = dyn_cast(D)) + return canModify(cast(MD->getDeclContext())); + + FileID FID = PP.getSourceManager().getFileID(D->getLocation()); + return canModifyFile(FID); + } }; } @@ -1651,20 +1675,25 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { } if (ObjCInterfaceDecl *CDecl = dyn_cast(*D)) - migrateObjCInterfaceDecl(Ctx, CDecl); + if (canModify(CDecl)) + migrateObjCInterfaceDecl(Ctx, CDecl); if (ObjCCategoryDecl *CatDecl = dyn_cast(*D)) { - migrateObjCInterfaceDecl(Ctx, CatDecl); + if (canModify(CatDecl)) + migrateObjCInterfaceDecl(Ctx, CatDecl); } else if (ObjCProtocolDecl *PDecl = dyn_cast(*D)) ObjCProtocolDecls.insert(PDecl); else if (const ObjCImplementationDecl *ImpDecl = dyn_cast(*D)) { - if (ASTMigrateActions & FrontendOptions::ObjCMT_ProtocolConformance) + if ((ASTMigrateActions & FrontendOptions::ObjCMT_ProtocolConformance) && + canModify(ImpDecl)) migrateProtocolConformance(Ctx, ImpDecl); } else if (const EnumDecl *ED = dyn_cast(*D)) { if (!(ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros)) continue; + if (!canModify(ED)) + continue; DeclContext::decl_iterator N = D; if (++N != DEnd) { const TypedefDecl *TD = dyn_cast(*N); @@ -1677,6 +1706,8 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { else if (const TypedefDecl *TD = dyn_cast(*D)) { if (!(ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros)) continue; + if (!canModify(TD)) + continue; DeclContext::decl_iterator N = D; if (++N == DEnd) continue; @@ -1698,22 +1729,27 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { CacheObjCNSIntegerTypedefed(TD); } else if (const FunctionDecl *FD = dyn_cast(*D)) { - if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) + if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) && + canModify(FD)) migrateCFAnnotation(Ctx, FD); } if (ObjCContainerDecl *CDecl = dyn_cast(*D)) { + bool CanModify = canModify(CDecl); // migrate methods which can have instancetype as their result type. - if (ASTMigrateActions & FrontendOptions::ObjCMT_Instancetype) + if ((ASTMigrateActions & FrontendOptions::ObjCMT_Instancetype) && + CanModify) migrateAllMethodInstaceType(Ctx, CDecl); // annotate methods with CF annotations. - if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) + if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) && + CanModify) migrateARCSafeAnnotation(Ctx, CDecl); } if (const ObjCImplementationDecl * ImplD = dyn_cast(*D)) { - if (ASTMigrateActions & FrontendOptions::ObjCMT_DesignatedInitializer) + if ((ASTMigrateActions & FrontendOptions::ObjCMT_DesignatedInitializer) && + canModify(ImplD)) inferDesignatedInitializers(Ctx, ImplD); } } @@ -1733,8 +1769,6 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) { assert(file); if (IsReallyASystemHeader(Ctx, file, FID)) continue; - if (!canModifyFile(file->getName())) - continue; SmallString<512> newText; llvm::raw_svector_ostream vecOS(newText); buf.write(vecOS); diff --git a/test/ARCMT/whitelisted/header1.h b/test/ARCMT/whitelisted/header1.h index a3014eb5b6..d94b9f7d9e 100644 --- a/test/ARCMT/whitelisted/header1.h +++ b/test/ARCMT/whitelisted/header1.h @@ -2,4 +2,5 @@ @interface I1 : NSObject -(int)prop; -(void)setProp:(int)p; ++(id)i1; @end diff --git a/test/ARCMT/whitelisted/header1.h.result b/test/ARCMT/whitelisted/header1.h.result index 7808fc8a6a..65cbd2621f 100644 --- a/test/ARCMT/whitelisted/header1.h.result +++ b/test/ARCMT/whitelisted/header1.h.result @@ -1,4 +1,5 @@ @interface I1 : NSObject @property (nonatomic) int prop; ++(instancetype)i1; @end diff --git a/test/ARCMT/whitelisted/objcmt-with-whitelist-impl.m b/test/ARCMT/whitelisted/objcmt-with-whitelist-impl.m new file mode 100644 index 0000000000..d734eaa10b --- /dev/null +++ b/test/ARCMT/whitelisted/objcmt-with-whitelist-impl.m @@ -0,0 +1,18 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype -objcmt-white-list-dir-path=%S/Inputs %s -triple x86_64-apple-darwin11 -migrate -o %t.remap +// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %S/header1.h.result %s.result + +@interface NSObject ++ (id)alloc; +@end + +#include "header1.h" +#include "header2.h" + +@interface I2(cat) +-(id)initInCat; +@end + +@implementation I1 ++(id)i1 {} +@end diff --git a/test/ARCMT/whitelisted/objcmt-with-whitelist-impl.m.result b/test/ARCMT/whitelisted/objcmt-with-whitelist-impl.m.result new file mode 100644 index 0000000000..b936b52b72 --- /dev/null +++ b/test/ARCMT/whitelisted/objcmt-with-whitelist-impl.m.result @@ -0,0 +1,18 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype -objcmt-white-list-dir-path=%S/Inputs %s -triple x86_64-apple-darwin11 -migrate -o %t.remap +// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %S/header1.h.result %s.result + +@interface NSObject ++ (id)alloc; +@end + +#include "header1.h" +#include "header2.h" + +@interface I2(cat) +-(id)initInCat; +@end + +@implementation I1 ++(instancetype)i1 {} +@end diff --git a/test/ARCMT/whitelisted/objcmt-with-whitelist.m b/test/ARCMT/whitelisted/objcmt-with-whitelist.m index 1b44c9a6d9..bef82c8667 100644 --- a/test/ARCMT/whitelisted/objcmt-with-whitelist.m +++ b/test/ARCMT/whitelisted/objcmt-with-whitelist.m @@ -1,7 +1,7 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -objcmt-migrate-readwrite-property %s -triple x86_64-apple-darwin11 -migrate -o %t.remap +// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype %s -triple x86_64-apple-darwin11 -migrate -o %t.remap // RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %S/header1.h.result %S/header2.h.result -// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-white-list-dir-path=%S/Inputs %s -triple x86_64-apple-darwin11 -migrate -o %t.remap +// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype -objcmt-white-list-dir-path=%S/Inputs %s -triple x86_64-apple-darwin11 -migrate -o %t.remap // RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %S/header1.h.result @interface NSObject