]> granicus.if.org Git - clang/commitdiff
[objcmt] Introduce "objcmt-white-list-dir-path=" option.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Thu, 14 Nov 2013 16:33:29 +0000 (16:33 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Thu, 14 Nov 2013 16:33:29 +0000 (16:33 +0000)
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
include/clang/Frontend/FrontendOptions.h
lib/ARCMigrate/ObjCMT.cpp
lib/Driver/Tools.cpp
lib/Frontend/CompilerInvocation.cpp
test/ARCMT/whitelisted/Inputs/header1.h [new file with mode: 0644]
test/ARCMT/whitelisted/header1.h [new file with mode: 0644]
test/ARCMT/whitelisted/header1.h.result [new file with mode: 0644]
test/ARCMT/whitelisted/header2.h [new file with mode: 0644]
test/ARCMT/whitelisted/header2.h.result [new file with mode: 0644]
test/ARCMT/whitelisted/objcmt-with-whitelist.m [new file with mode: 0644]

index 614c1dfc5bafa9fc3fbd64a0c7a14989bb40c436..70f8aef1be406875a63210bee75703874e7823fc 100644 (file)
@@ -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<internal_Group>, Flags<[Unsupported]>;
index 4fe6bbb963769229c80297e112b18245f7ea6b32..4b321e86d29ca6b15a603cab98e90ccc4a9fd8de 100644 (file)
@@ -186,6 +186,7 @@ public:
     ObjCMT_MigrateAll = (ObjCMT_Literals | ObjCMT_Subscripting | ObjCMT_MigrateDecls)
   };
   unsigned ObjCMTAction;
+  std::string ObjCMTWhiteListPath;
 
   std::string MTMigrateDir;
   std::string ARCMTMigrateReportOut;
index 23d61cf27f4c22600d77e4b1f4a50f4b559ac832..ff2ae40758f781831a063d850cc8ced96ac0d9f8 100644 (file)
@@ -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<ObjCProtocolDecl *, 32> ObjCProtocolDecls;
   llvm::SmallVector<const Decl *, 8> CFFunctionIBCandidates;
+  llvm::StringMap<char> WhiteListFilenames;
   
   ObjCMigrateASTConsumer(StringRef migrateDir,
                          unsigned astMigrateActions,
@@ -97,12 +99,19 @@ public:
                          FileManager &fileMgr,
                          const PPConditionalDirectiveRecord *PPRec,
                          Preprocessor &PP,
-                         bool isOutputFile = false)
+                         bool isOutputFile,
+                         ArrayRef<std::string> WhiteList)
   : MigrateDir(migrateDir),
     ASTMigrateActions(astMigrateActions),
     NSIntegerTypedefed(0), NSUIntegerTypedefed(0),
     Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP),
-    IsOutputFile(isOutputFile) { }
+    IsOutputFile(isOutputFile) {
+
+    for (ArrayRef<std::string>::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<std::string>());
   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<std::string> getWhiteListFilenames(StringRef DirPath) {
+  using namespace llvm::sys::fs;
+  using namespace llvm::sys::path;
+
+  std::vector<std::string> 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<std::string> WhiteList =
+    getWhiteListFilenames(CI.getFrontendOpts().ObjCMTWhiteListPath);
   return new ObjCMigrateASTConsumer(CI.getFrontendOpts().OutputFile,
                                     ObjCMTAction,
                                     Remapper,
                                     CI.getFileManager(),
                                     PPRec,
                                     CI.getPreprocessor(),
-                                    /*isOutputFile=*/true); 
+                                    /*isOutputFile=*/true,
+                                    WhiteList);
 }
index c8ecdc996af498671896c856220cbc0202f40f23..9027f70c3cb582b1b15757752e2b835e38add46a 100644 (file)
@@ -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
index 009d6ec094ba65bab797e867c90d60f75c644ae3..581d56d4621758445074f5c5cfa2b7adcf6ca8c4 100644 (file)
@@ -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 (file)
index 0000000..44430f3
--- /dev/null
@@ -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 (file)
index 0000000..a3014eb
--- /dev/null
@@ -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 (file)
index 0000000..7808fc8
--- /dev/null
@@ -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 (file)
index 0000000..c7577ed
--- /dev/null
@@ -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 (file)
index 0000000..b1b5270
--- /dev/null
@@ -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 (file)
index 0000000..1b44c9a
--- /dev/null
@@ -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"