[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.

llvm-svn: 197075
This commit is contained in:
Argyrios Kyrtzidis 2013-12-11 21:39:00 +00:00
parent e439f92a6c
commit 3f72934bba
6 changed files with 83 additions and 11 deletions

View 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);

View File

@ -2,4 +2,5 @@
@interface I1 : NSObject
-(int)prop;
-(void)setProp:(int)p;
+(id)i1;
@end

View File

@ -1,4 +1,5 @@
@interface I1 : NSObject
@property (nonatomic) int prop;
+(instancetype)i1;
@end

View File

@ -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

View File

@ -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

View 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