Skip to content

Commit

Permalink
[arcmt] Fix the ARC migrator. -arcmt-modify requires running before t…
Browse files Browse the repository at this point in the history
…he initialization of SourceManager

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
  • Loading branch information
akyrtzi committed Jun 18, 2011
1 parent 60a5e3f commit e665d69
Show file tree
Hide file tree
Showing 14 changed files with 175 additions and 23 deletions.
4 changes: 2 additions & 2 deletions include/clang/ARCMigrate/ARCMTActions.h
Expand Up @@ -18,15 +18,15 @@ namespace arcmt {

class CheckAction : public WrapperFrontendAction {
protected:
virtual void ExecuteAction();
virtual bool BeginInvocation(CompilerInstance &CI);

public:
CheckAction(FrontendAction *WrappedAction);
};

class TransformationAction : public WrapperFrontendAction {
protected:
virtual void ExecuteAction();
virtual bool BeginInvocation(CompilerInstance &CI);

public:
TransformationAction(FrontendAction *WrappedAction);
Expand Down
9 changes: 9 additions & 0 deletions include/clang/Frontend/FrontendAction.h
Expand Up @@ -78,6 +78,14 @@ class FrontendAction {
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.
///
Expand Down Expand Up @@ -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();
Expand Down
10 changes: 9 additions & 1 deletion lib/ARCMigrate/ARCMT.cpp
Expand Up @@ -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 {
Expand Down Expand Up @@ -236,7 +244,7 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI,

DiagClient->EndSourceFile();

return Diags->getClient()->getNumErrors() > 0;
return capturedDiags.hasErrors();
}

//===----------------------------------------------------------------------===//
Expand Down
17 changes: 6 additions & 11 deletions lib/ARCMigrate/ARCMTActions.cpp
Expand Up @@ -14,29 +14,24 @@
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)
Expand Down
2 changes: 2 additions & 0 deletions lib/ARCMigrate/Internals.h
Expand Up @@ -30,6 +30,8 @@ class CapturedDiagList {
bool hasDiagnostic(llvm::ArrayRef<unsigned> IDs, SourceRange range) const;

void reportDiagnostics(Diagnostic &diags) const;

bool hasErrors() const;
};

class TransformActions {
Expand Down
8 changes: 8 additions & 0 deletions lib/Frontend/FrontendAction.cpp
Expand Up @@ -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) {
Expand Down Expand Up @@ -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() {
Expand Down
2 changes: 1 addition & 1 deletion test/ARCMT/alloc-with-zone-check.m
@@ -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")))
Expand Down
2 changes: 1 addition & 1 deletion test/ARCMT/atautorelease-check.m
@@ -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")))
Expand Down
2 changes: 1 addition & 1 deletion test/ARCMT/checking.m
@@ -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"

Expand Down
2 changes: 1 addition & 1 deletion test/ARCMT/cxx-checking.mm
@@ -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}}
Expand Down
2 changes: 1 addition & 1 deletion test/ARCMT/nonobjc-to-objc-cast-2.m
@@ -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;
Expand Down
68 changes: 68 additions & 0 deletions test/ARCMT/releases-driver.m
@@ -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);
}
61 changes: 61 additions & 0 deletions test/ARCMT/releases-driver.m.result
@@ -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) {
}
9 changes: 5 additions & 4 deletions tools/arcmt-test/arcmt-test.cpp
Expand Up @@ -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) {
Expand Down

0 comments on commit e665d69

Please sign in to comment.