]> granicus.if.org Git - clang/commitdiff
[objcmt] When whitelisting the headers we want to modify, allow changing the
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 11 Dec 2013 21:39:00 +0000 (21:39 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 11 Dec 2013 21:39:00 +0000 (21:39 +0000)
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

lib/ARCMigrate/ObjCMT.cpp
test/ARCMT/whitelisted/header1.h
test/ARCMT/whitelisted/header1.h.result
test/ARCMT/whitelisted/objcmt-with-whitelist-impl.m [new file with mode: 0644]
test/ARCMT/whitelisted/objcmt-with-whitelist-impl.m.result [new file with mode: 0644]
test/ARCMT/whitelisted/objcmt-with-whitelist.m

index c14fca2738db976d2ed2cfd9105aa070bc156cba..b2dcd4f9c779c4a00779d2d2f8caccde63f8847e 100644 (file)
@@ -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<ObjCCategoryImplDecl>(D))
+      return canModify(CatImpl->getCategoryDecl());
+    if (const ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D))
+      return canModify(Impl->getClassInterface());
+    if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+      return canModify(cast<Decl>(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<ObjCInterfaceDecl>(*D))
-        migrateObjCInterfaceDecl(Ctx, CDecl);
+        if (canModify(CDecl))
+          migrateObjCInterfaceDecl(Ctx, CDecl);
       if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(*D)) {
-        migrateObjCInterfaceDecl(Ctx, CatDecl);
+        if (canModify(CatDecl))
+          migrateObjCInterfaceDecl(Ctx, CatDecl);
       }
       else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(*D))
         ObjCProtocolDecls.insert(PDecl);
       else if (const ObjCImplementationDecl *ImpDecl =
                dyn_cast<ObjCImplementationDecl>(*D)) {
-        if (ASTMigrateActions & FrontendOptions::ObjCMT_ProtocolConformance)
+        if ((ASTMigrateActions & FrontendOptions::ObjCMT_ProtocolConformance) &&
+            canModify(ImpDecl))
           migrateProtocolConformance(Ctx, ImpDecl);
       }
       else if (const EnumDecl *ED = dyn_cast<EnumDecl>(*D)) {
         if (!(ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros))
           continue;
+        if (!canModify(ED))
+          continue;
         DeclContext::decl_iterator N = D;
         if (++N != DEnd) {
           const TypedefDecl *TD = dyn_cast<TypedefDecl>(*N);
@@ -1677,6 +1706,8 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {
       else if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(*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<FunctionDecl>(*D)) {
-        if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation)
+        if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) &&
+            canModify(FD))
           migrateCFAnnotation(Ctx, FD);
       }
       
       if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(*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<ObjCImplementationDecl>(*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);
index a3014eb5b653f7f40ac76f3af313636769a06d2a..d94b9f7d9ebe69f0130c596e153444e81c3ca99a 100644 (file)
@@ -2,4 +2,5 @@
 @interface I1 : NSObject
 -(int)prop;
 -(void)setProp:(int)p;
++(id)i1;
 @end
index 7808fc8a6a3f0efbf0d2f3557937706d0e679308..65cbd2621f6b6a9bcf699a8bf4f019984be8b38a 100644 (file)
@@ -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 (file)
index 0000000..d734eaa
--- /dev/null
@@ -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 (file)
index 0000000..b936b52
--- /dev/null
@@ -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
index 1b44c9a6d9fe129d71c75c5f9cf72d0e3dffdf10..bef82c8667d9c7ab197b51cc20bb1ec158d53998 100644 (file)
@@ -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