forked from OSchip/llvm-project
[arcmt] Fix the ARC migrator. -arcmt-modify requires running before the initialization of SourceManager
because it is going to modify the input file. llvm-svn: 133323
This commit is contained in:
parent
0f3f9f78f8
commit
90b6a2a6a7
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -30,6 +30,8 @@ public:
|
|||
bool hasDiagnostic(llvm::ArrayRef<unsigned> IDs, SourceRange range) const;
|
||||
|
||||
void reportDiagnostics(Diagnostic &diags) const;
|
||||
|
||||
bool hasErrors() const;
|
||||
};
|
||||
|
||||
class TransformActions {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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")))
|
||||
|
|
|
@ -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")))
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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}}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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) {
|
||||
}
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue