From 2c050f6a68c4f871d26be63f8d598f1b64a8e16f Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Thu, 14 Nov 2013 16:33:29 +0000 Subject: [PATCH] [objcmt] Introduce "objcmt-white-list-dir-path=" option. This options accepts a path to a directory, collects the filenames of the files it contains, and the migrator will only modify files with the same filename. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@194710 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Driver/Options.td | 5 +- include/clang/Frontend/FrontendOptions.h | 1 + lib/ARCMigrate/ObjCMT.cpp | 50 +++++++++++++++++-- lib/Driver/Tools.cpp | 1 + lib/Frontend/CompilerInvocation.cpp | 2 + test/ARCMT/whitelisted/Inputs/header1.h | 1 + test/ARCMT/whitelisted/header1.h | 5 ++ test/ARCMT/whitelisted/header1.h.result | 4 ++ test/ARCMT/whitelisted/header2.h | 5 ++ test/ARCMT/whitelisted/header2.h.result | 4 ++ .../ARCMT/whitelisted/objcmt-with-whitelist.m | 12 +++++ 11 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 test/ARCMT/whitelisted/Inputs/header1.h create mode 100644 test/ARCMT/whitelisted/header1.h create mode 100644 test/ARCMT/whitelisted/header1.h.result create mode 100644 test/ARCMT/whitelisted/header2.h create mode 100644 test/ARCMT/whitelisted/header2.h.result create mode 100644 test/ARCMT/whitelisted/objcmt-with-whitelist.m diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 614c1dfc5b..70f8aef1be 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -178,13 +178,14 @@ def objcmt_migrate_nsmacros : Flag<["-"], "objcmt-migrate-ns-macros">, Flags<[CC HelpText<"Enable migration to NS_ENUM/NS_OPTIONS macros">; def objcmt_migrate_protocol_conformance : Flag<["-"], "objcmt-migrate-protocol-conformance">, Flags<[CC1Option]>, HelpText<"Enable migration to add protocol conformance on classes">; -def objcmt_atomic_property : Flag<["-"], "objcmt-atomic-property">, - Flags<[CC1Option]>, +def objcmt_atomic_property : Flag<["-"], "objcmt-atomic-property">, Flags<[CC1Option]>, HelpText<"Make migration to 'atomic' properties">; def objcmt_returns_innerpointer_property : Flag<["-"], "objcmt-returns-innerpointer-property">, Flags<[CC1Option]>, HelpText<"Enable migration to annotate property with NS_RETURNS_INNER_POINTER">; def objcmt_ns_nonatomic_iosonly: Flag<["-"], "objcmt-ns-nonatomic-iosonly">, Flags<[CC1Option]>, HelpText<"Enable migration to use NS_NONATOMIC_IOSONLY macro for setting property's 'atomic' attribute">; +def objcmt_white_list_dir_path: Joined<["-"], "objcmt-white-list-dir-path=">, Flags<[CC1Option]>, + HelpText<"Only modify files with a filename contained in the provided directory path">; // Make sure all other -ccc- options are rejected. def ccc_ : Joined<["-"], "ccc-">, Group, Flags<[Unsupported]>; diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h index 4fe6bbb963..4b321e86d2 100644 --- a/include/clang/Frontend/FrontendOptions.h +++ b/include/clang/Frontend/FrontendOptions.h @@ -186,6 +186,7 @@ public: ObjCMT_MigrateAll = (ObjCMT_Literals | ObjCMT_Subscripting | ObjCMT_MigrateDecls) }; unsigned ObjCMTAction; + std::string ObjCMTWhiteListPath; std::string MTMigrateDir; std::string ARCMTMigrateReportOut; diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp index 23d61cf27f..ff2ae40758 100644 --- a/lib/ARCMigrate/ObjCMT.cpp +++ b/lib/ARCMigrate/ObjCMT.cpp @@ -28,6 +28,7 @@ #include "clang/StaticAnalyzer/Checkers/ObjCRetainCount.h" #include "clang/AST/Attr.h" #include "llvm/ADT/SmallString.h" +#include "llvm/Support/Path.h" using namespace clang; using namespace arcmt; @@ -90,6 +91,7 @@ public: bool IsOutputFile; llvm::SmallPtrSet ObjCProtocolDecls; llvm::SmallVector CFFunctionIBCandidates; + llvm::StringMap WhiteListFilenames; ObjCMigrateASTConsumer(StringRef migrateDir, unsigned astMigrateActions, @@ -97,12 +99,19 @@ public: FileManager &fileMgr, const PPConditionalDirectiveRecord *PPRec, Preprocessor &PP, - bool isOutputFile = false) + bool isOutputFile, + ArrayRef WhiteList) : MigrateDir(migrateDir), ASTMigrateActions(astMigrateActions), NSIntegerTypedefed(0), NSUIntegerTypedefed(0), Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP), - IsOutputFile(isOutputFile) { } + IsOutputFile(isOutputFile) { + + for (ArrayRef::iterator + I = WhiteList.begin(), E = WhiteList.end(); I != E; ++I) { + WhiteListFilenames.GetOrCreateValue(*I); + } + } protected: virtual void Initialize(ASTContext &Context) { @@ -125,6 +134,13 @@ protected: } virtual void HandleTranslationUnit(ASTContext &Ctx); + + bool canModifyFile(StringRef Path) { + if (WhiteListFilenames.empty()) + return true; + return WhiteListFilenames.find(llvm::sys::path::filename(Path)) + != WhiteListFilenames.end(); + } }; } @@ -151,7 +167,9 @@ ASTConsumer *ObjCMigrateAction::CreateASTConsumer(CompilerInstance &CI, Remapper, CompInst->getFileManager(), PPRec, - CompInst->getPreprocessor()); + CompInst->getPreprocessor(), + false, + ArrayRef()); ASTConsumer *Consumers[] = { MTConsumer, WrappedConsumer }; return new MultiplexConsumer(Consumers); } @@ -1682,6 +1700,8 @@ 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); @@ -1705,6 +1725,25 @@ bool MigrateSourceAction::BeginInvocation(CompilerInstance &CI) { return true; } +static std::vector getWhiteListFilenames(StringRef DirPath) { + using namespace llvm::sys::fs; + using namespace llvm::sys::path; + + std::vector Filenames; + if (DirPath.empty() || !is_directory(DirPath)) + return Filenames; + + llvm::error_code EC; + directory_iterator DI = directory_iterator(DirPath, EC); + directory_iterator DE; + for (; !EC && DI != DE; DI = DI.increment(EC)) { + if (is_regular_file(DI->path())) + Filenames.push_back(filename(DI->path())); + } + + return Filenames; +} + ASTConsumer *MigrateSourceAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { PPConditionalDirectiveRecord * @@ -1721,11 +1760,14 @@ ASTConsumer *MigrateSourceAction::CreateASTConsumer(CompilerInstance &CI, FrontendOptions::ObjCMT_Subscripting; } CI.getPreprocessor().addPPCallbacks(PPRec); + std::vector WhiteList = + getWhiteListFilenames(CI.getFrontendOpts().ObjCMTWhiteListPath); return new ObjCMigrateASTConsumer(CI.getFrontendOpts().OutputFile, ObjCMTAction, Remapper, CI.getFileManager(), PPRec, CI.getPreprocessor(), - /*isOutputFile=*/true); + /*isOutputFile=*/true, + WhiteList); } diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index c8ecdc996a..9027f70c3c 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -2726,6 +2726,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_objcmt_atomic_property); Args.AddLastArg(CmdArgs, options::OPT_objcmt_returns_innerpointer_property); Args.AddLastArg(CmdArgs, options::OPT_objcmt_ns_nonatomic_iosonly); + Args.AddLastArg(CmdArgs, options::OPT_objcmt_white_list_dir_path); } // Add preprocessing options like -I, -D, etc. if we are using the diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 009d6ec094..581d56d462 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -821,6 +821,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, if (Args.hasArg(OPT_objcmt_migrate_all)) Opts.ObjCMTAction |= FrontendOptions::ObjCMT_MigrateDecls; + Opts.ObjCMTWhiteListPath = Args.getLastArgValue(OPT_objcmt_white_list_dir_path); + if (Opts.ARCMTAction != FrontendOptions::ARCMT_None && Opts.ObjCMTAction != FrontendOptions::ObjCMT_None) { Diags.Report(diag::err_drv_argument_not_allowed_with) diff --git a/test/ARCMT/whitelisted/Inputs/header1.h b/test/ARCMT/whitelisted/Inputs/header1.h new file mode 100644 index 0000000000..44430f3b77 --- /dev/null +++ b/test/ARCMT/whitelisted/Inputs/header1.h @@ -0,0 +1 @@ +// the contents are not important diff --git a/test/ARCMT/whitelisted/header1.h b/test/ARCMT/whitelisted/header1.h new file mode 100644 index 0000000000..a3014eb5b6 --- /dev/null +++ b/test/ARCMT/whitelisted/header1.h @@ -0,0 +1,5 @@ + +@interface I1 : NSObject +-(int)prop; +-(void)setProp:(int)p; +@end diff --git a/test/ARCMT/whitelisted/header1.h.result b/test/ARCMT/whitelisted/header1.h.result new file mode 100644 index 0000000000..7808fc8a6a --- /dev/null +++ b/test/ARCMT/whitelisted/header1.h.result @@ -0,0 +1,4 @@ + +@interface I1 : NSObject +@property (nonatomic) int prop; +@end diff --git a/test/ARCMT/whitelisted/header2.h b/test/ARCMT/whitelisted/header2.h new file mode 100644 index 0000000000..c7577ede4a --- /dev/null +++ b/test/ARCMT/whitelisted/header2.h @@ -0,0 +1,5 @@ + +@interface I2 : NSObject +-(int)prop; +-(void)setProp:(int)p; +@end diff --git a/test/ARCMT/whitelisted/header2.h.result b/test/ARCMT/whitelisted/header2.h.result new file mode 100644 index 0000000000..b1b5270711 --- /dev/null +++ b/test/ARCMT/whitelisted/header2.h.result @@ -0,0 +1,4 @@ + +@interface I2 : NSObject +@property (nonatomic) int prop; +@end diff --git a/test/ARCMT/whitelisted/objcmt-with-whitelist.m b/test/ARCMT/whitelisted/objcmt-with-whitelist.m new file mode 100644 index 0000000000..1b44c9a6d9 --- /dev/null +++ b/test/ARCMT/whitelisted/objcmt-with-whitelist.m @@ -0,0 +1,12 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -objcmt-migrate-readwrite-property %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: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %S/header1.h.result + +@interface NSObject ++ (id)alloc; +@end + +#include "header1.h" +#include "header2.h" -- 2.40.0