]> granicus.if.org Git - clang/commitdiff
[arcmt] Fix the ARC migrator. -arcmt-modify requires running before the initializatio...
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sat, 18 Jun 2011 00:53:41 +0000 (00:53 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sat, 18 Jun 2011 00:53:41 +0000 (00:53 +0000)
because it is going to modify the input file.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133323 91177308-0d34-0410-b5e6-96231b3b80d8

14 files changed:
include/clang/ARCMigrate/ARCMTActions.h
include/clang/Frontend/FrontendAction.h
lib/ARCMigrate/ARCMT.cpp
lib/ARCMigrate/ARCMTActions.cpp
lib/ARCMigrate/Internals.h
lib/Frontend/FrontendAction.cpp
test/ARCMT/alloc-with-zone-check.m
test/ARCMT/atautorelease-check.m
test/ARCMT/checking.m
test/ARCMT/cxx-checking.mm
test/ARCMT/nonobjc-to-objc-cast-2.m
test/ARCMT/releases-driver.m [new file with mode: 0644]
test/ARCMT/releases-driver.m.result [new file with mode: 0644]
tools/arcmt-test/arcmt-test.cpp

index 2dd57ab88bef5b4a22bf81bc0214bef96fb30e5d..fd85a0836af6fe556eac80281397f78b5b099388 100644 (file)
@@ -18,7 +18,7 @@ namespace arcmt {
 
 class CheckAction : public WrapperFrontendAction {
 protected:
-  virtual void ExecuteAction();
+  virtual bool BeginInvocation(CompilerInstance &CI);
 
 public:
   CheckAction(FrontendAction *WrappedAction);
@@ -26,7 +26,7 @@ public:
 
 class TransformationAction : public WrapperFrontendAction {
 protected:
-  virtual void ExecuteAction();
+  virtual bool BeginInvocation(CompilerInstance &CI);
 
 public:
   TransformationAction(FrontendAction *WrappedAction);
index 2538f55aaff9c72a1134bf2855ab15f3ae2457f6..f335475665fd27dc6ced5bd0ac9ac1744f484cd0 100644 (file)
@@ -78,6 +78,14 @@ protected:
   virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
                                          llvm::StringRef InFile) = 0;
 
+  /// \brief Callback before starting processing a single input, giving the
+  /// opportunity to modify the CompilerInvocation or do some other action
+  /// before BeginSourceFileAction is called.
+  ///
+  /// \return True on success; on failure \see BeginSourceFileAction() and
+  /// ExecutionAction() and EndSourceFileAction() will not be called.
+  virtual bool BeginInvocation(CompilerInstance &CI) { return true; }
+
   /// BeginSourceFileAction - Callback at the start of processing a single
   /// input.
   ///
@@ -265,6 +273,7 @@ class WrapperFrontendAction : public FrontendAction {
 protected:
   virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
                                          llvm::StringRef InFile);
+  virtual bool BeginInvocation(CompilerInstance &CI);
   virtual bool BeginSourceFileAction(CompilerInstance &CI,
                                      llvm::StringRef Filename);
   virtual void ExecuteAction();
index a93f1c62c0ef430bdd716e4107e430de148ae00a..99980345c4098c1b5aee32b763b78b72f56ba47f 100644 (file)
@@ -79,6 +79,14 @@ void CapturedDiagList::reportDiagnostics(Diagnostic &Diags) const {
     Diags.Report(*I);
 }
 
+bool CapturedDiagList::hasErrors() const {
+  for (ListTy::const_iterator I = List.begin(), E = List.end(); I != E; ++I)
+    if (I->getLevel() >= Diagnostic::Error)
+      return true;
+
+  return false;
+}
+
 namespace {
 
 class CaptureDiagnosticClient : public DiagnosticClient {
@@ -236,7 +244,7 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI,
 
   DiagClient->EndSourceFile();
 
-  return Diags->getClient()->getNumErrors() > 0;
+  return capturedDiags.hasErrors();
 }
 
 //===----------------------------------------------------------------------===//
index 4da928a0ebf331e765959f9e82ee5e47fd36f987..7de62d289cefbd125756c8a750e31b78f3ccd431 100644 (file)
 using namespace clang;
 using namespace arcmt;
 
-void CheckAction::ExecuteAction() {
-  CompilerInstance &CI = getCompilerInstance();
+bool CheckAction::BeginInvocation(CompilerInstance &CI) {
   if (arcmt::checkForManualIssues(CI.getInvocation(), getCurrentFile(),
                                   getCurrentFileKind(),
                                   CI.getDiagnostics().getClient()))
-    return;
+    return false; // errors, stop the action.
 
   // We only want to see warnings reported from arcmt::checkForManualIssues.
   CI.getDiagnostics().setIgnoreAllWarnings(true);
-  WrapperFrontendAction::ExecuteAction();
+  return true;
 }
 
 CheckAction::CheckAction(FrontendAction *WrappedAction)
   : WrapperFrontendAction(WrappedAction) {}
 
-void TransformationAction::ExecuteAction() {
-  CompilerInstance &CI = getCompilerInstance();
-  if (arcmt::applyTransformations(CI.getInvocation(), getCurrentFile(),
+bool TransformationAction::BeginInvocation(CompilerInstance &CI) {
+  return !arcmt::applyTransformations(CI.getInvocation(), getCurrentFile(),
                                   getCurrentFileKind(),
-                                  CI.getDiagnostics().getClient()))
-    return;
-
-  WrapperFrontendAction::ExecuteAction();
+                                  CI.getDiagnostics().getClient());
 }
 
 TransformationAction::TransformationAction(FrontendAction *WrappedAction)
index d0d545ec517887431288d142bdb48ef6c08e3583..4f9b138a06ce59c8653a01cb76106cc5df906c77 100644 (file)
@@ -30,6 +30,8 @@ public:
   bool hasDiagnostic(llvm::ArrayRef<unsigned> IDs, SourceRange range) const;
 
   void reportDiagnostics(Diagnostic &diags) const;
+
+  bool hasErrors() const;
 };
 
 class TransformActions {
index 0024818ad85d90008d0ad3f70db22e2236fdc5fd..0128d6ee053127be47a0a3b56aec1a62f4e26d75 100644 (file)
@@ -130,6 +130,9 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
   setCurrentFile(Filename, InputKind);
   setCompilerInstance(&CI);
 
+  if (!BeginInvocation(CI))
+    goto failure;
+
   // AST files follow a very different path, since they share objects via the
   // AST unit.
   if (InputKind == IK_AST) {
@@ -386,8 +389,13 @@ ASTConsumer *WrapperFrontendAction::CreateASTConsumer(CompilerInstance &CI,
                                                       llvm::StringRef InFile) {
   return WrappedAction->CreateASTConsumer(CI, InFile);
 }
+bool WrapperFrontendAction::BeginInvocation(CompilerInstance &CI) {
+  return WrappedAction->BeginInvocation(CI);
+}
 bool WrapperFrontendAction::BeginSourceFileAction(CompilerInstance &CI,
                                                   llvm::StringRef Filename) {
+  WrappedAction->setCurrentFile(getCurrentFile(), getCurrentFileKind());
+  WrappedAction->setCompilerInstance(&CI);
   return WrappedAction->BeginSourceFileAction(CI, Filename);
 }
 void WrapperFrontendAction::ExecuteAction() {
index a987fa8b84e4fe95b2dc12a401b776ebee23492d..01924a9987953ef6ced2978a8b2f1252258efd51 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: arcmt-test -check-only -verify --args %s
+// RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi %s
 
 #if __has_feature(objc_arr)
 #define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode")))
index 126642cd38088a4eb08d02e07d9bf1d8d9b18de2..6528f3e62d1e98b7684f4172caa0fa3e539e85ae 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: arcmt-test -check-only -verify --args %s 
+// RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi %s
 
 #if __has_feature(objc_arr)
 #define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode")))
index ffb245e8bb66590442fa611f26c8e69bc61f6434..62387fa23b4c8d5c42bd55f6b339c59f96bede37 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: arcmt-test -check-only -verify --args %s
+// RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi %s
 
 #include "Common.h"
 
index 667138c974744da3097be56f4d7229f974146cfa..c298b94b82bdb0be0eec8690601a51dc58697d70 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: arcmt-test -check-only -verify --args -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fblocks -Warc-abi  %s
+// RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fsyntax-only -fblocks -Warc-abi  %s
 
 // Classes that have an Objective-C object pointer.
 struct HasObjectMember0 { // expected-warning{{'HasObjectMember0' cannot be shared between ARC and non-ARC code; add a copy constructor, a copy assignment operator, and a destructor to make it ABI-compatible}}
index dba5227fae9f720f327b361832566b066e06255d..46ef02400e8cb2f773263053472dc008138d1b80 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: arcmt-test -check-only -verify --args %s
+// RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi %s
 
 typedef int BOOL;
 typedef const struct __CFString * CFStringRef;
diff --git a/test/ARCMT/releases-driver.m b/test/ARCMT/releases-driver.m
new file mode 100644 (file)
index 0000000..a016b26
--- /dev/null
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result
+// RUN: cp %s %t
+// RUN: %clang_cc1 -arcmt-modify -triple x86_64-apple-macosx10.6 -fobjc-nonfragile-abi -x objective-c %t
+// RUN: diff %t %s.result
+// RUN: rm %t
+
+typedef int BOOL;
+
+id IhaveSideEffect();
+
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (id)retain;
+- (oneway void)release;
+@end
+
+@interface NSObject <NSObject> {}
+@end
+
+@interface Foo : NSObject {
+  id bar;
+}
+@property (retain) id bar;
+-(void)test:(id)obj;
+@end
+
+@implementation Foo
+
+@synthesize bar;
+
+-(void)test:(id)obj {
+  id x = self.bar;
+  [x retain];
+  self.bar = obj;
+  // do stuff with x;
+  [x release];
+
+  [IhaveSideEffect() release];
+
+  [x release], x = 0;
+}
+  
+@end
+
+void func(Foo *p) {
+  [p release];
+  (([p release]));
+}
+
+@interface Baz {
+       id <NSObject> _foo;
+}
+@end
+
+@implementation Baz
+- dealloc {
+  [_foo release];
+  return 0;
+}
+@end
+
+#define RELEASE_MACRO(x) [x release]
+#define RELEASE_MACRO2(x) RELEASE_MACRO(x)
+
+void test2(id p) {
+  RELEASE_MACRO(p);
+  RELEASE_MACRO2(p);
+}
diff --git a/test/ARCMT/releases-driver.m.result b/test/ARCMT/releases-driver.m.result
new file mode 100644 (file)
index 0000000..247cad1
--- /dev/null
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result
+// RUN: cp %s %t
+// RUN: %clang_cc1 -arcmt-modify -triple x86_64-apple-macosx10.6 -fobjc-nonfragile-abi -x objective-c %t
+// RUN: diff %t %s.result
+// RUN: rm %t
+
+typedef int BOOL;
+
+id IhaveSideEffect();
+
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+- (id)retain;
+- (oneway void)release;
+@end
+
+@interface NSObject <NSObject> {}
+@end
+
+@interface Foo : NSObject {
+  id bar;
+}
+@property (retain) id bar;
+-(void)test:(id)obj;
+@end
+
+@implementation Foo
+
+@synthesize bar;
+
+-(void)test:(id)obj {
+  id x = self.bar;
+  self.bar = obj;
+  // do stuff with x;
+
+  IhaveSideEffect();
+
+  x = 0;
+}
+  
+@end
+
+void func(Foo *p) {
+}
+
+@interface Baz {
+       id <NSObject> _foo;
+}
+@end
+
+@implementation Baz
+- dealloc {
+  return 0;
+}
+@end
+
+#define RELEASE_MACRO(x) [x release]
+#define RELEASE_MACRO2(x) RELEASE_MACRO(x)
+
+void test2(id p) {
+}
index baa3f568c0142d2f6dc078e91e9d1efa3de5c383..702e13a4145cb846813e5825269159d37a1a3ffe 100644 (file)
@@ -111,10 +111,11 @@ static bool checkForMigration(llvm::StringRef resourcesPath,
   if (!CI.getLangOpts().ObjC1)
     return false;
 
-  return arcmt::checkForManualIssues(CI,
-                                     CI.getFrontendOpts().Inputs[0].second,
-                                     CI.getFrontendOpts().Inputs[0].first,
-                                     Diags->getClient());
+  arcmt::checkForManualIssues(CI,
+                              CI.getFrontendOpts().Inputs[0].second,
+                              CI.getFrontendOpts().Inputs[0].first,
+                              Diags->getClient());
+  return Diags->getClient()->getNumErrors() > 0;
 }
 
 static void printResult(FileRemapper &remapper, llvm::raw_ostream &OS) {