aboutsummaryrefslogtreecommitdiff
path: root/lib/ARCMigrate/ARCMT.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ARCMigrate/ARCMT.cpp')
-rw-r--r--lib/ARCMigrate/ARCMT.cpp154
1 files changed, 98 insertions, 56 deletions
diff --git a/lib/ARCMigrate/ARCMT.cpp b/lib/ARCMigrate/ARCMT.cpp
index f1d947da677e..6e1b0e535bbb 100644
--- a/lib/ARCMigrate/ARCMT.cpp
+++ b/lib/ARCMigrate/ARCMT.cpp
@@ -10,6 +10,7 @@
#include "Internals.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Frontend/Utils.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/Rewrite/Rewriter.h"
@@ -18,12 +19,10 @@
#include "clang/Lex/Preprocessor.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/ADT/Triple.h"
-
using namespace clang;
using namespace arcmt;
-using llvm::StringRef;
-bool CapturedDiagList::clearDiagnostic(llvm::ArrayRef<unsigned> IDs,
+bool CapturedDiagList::clearDiagnostic(ArrayRef<unsigned> IDs,
SourceRange range) {
if (range.isInvalid())
return false;
@@ -39,7 +38,7 @@ bool CapturedDiagList::clearDiagnostic(llvm::ArrayRef<unsigned> IDs,
diagLoc.isBeforeInTranslationUnitThan(range.getEnd()))) {
cleared = true;
ListTy::iterator eraseS = I++;
- while (I != List.end() && I->getLevel() == Diagnostic::Note)
+ while (I != List.end() && I->getLevel() == DiagnosticsEngine::Note)
++I;
// Clear the diagnostic and any notes following it.
List.erase(eraseS, I);
@@ -52,7 +51,7 @@ bool CapturedDiagList::clearDiagnostic(llvm::ArrayRef<unsigned> IDs,
return cleared;
}
-bool CapturedDiagList::hasDiagnostic(llvm::ArrayRef<unsigned> IDs,
+bool CapturedDiagList::hasDiagnostic(ArrayRef<unsigned> IDs,
SourceRange range) const {
if (range.isInvalid())
return false;
@@ -74,14 +73,14 @@ bool CapturedDiagList::hasDiagnostic(llvm::ArrayRef<unsigned> IDs,
return false;
}
-void CapturedDiagList::reportDiagnostics(Diagnostic &Diags) const {
+void CapturedDiagList::reportDiagnostics(DiagnosticsEngine &Diags) const {
for (ListTy::const_iterator I = List.begin(), E = List.end(); I != E; ++I)
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)
+ if (I->getLevel() >= DiagnosticsEngine::Error)
return true;
return false;
@@ -89,18 +88,18 @@ bool CapturedDiagList::hasErrors() const {
namespace {
-class CaptureDiagnosticClient : public DiagnosticClient {
- Diagnostic &Diags;
+class CaptureDiagnosticConsumer : public DiagnosticConsumer {
+ DiagnosticsEngine &Diags;
CapturedDiagList &CapturedDiags;
public:
- CaptureDiagnosticClient(Diagnostic &diags,
- CapturedDiagList &capturedDiags)
+ CaptureDiagnosticConsumer(DiagnosticsEngine &diags,
+ CapturedDiagList &capturedDiags)
: Diags(diags), CapturedDiags(capturedDiags) { }
- virtual void HandleDiagnostic(Diagnostic::Level level,
- const DiagnosticInfo &Info) {
+ virtual void HandleDiagnostic(DiagnosticsEngine::Level level,
+ const Diagnostic &Info) {
if (arcmt::isARCDiagnostic(Info.getID(), Diags) ||
- level >= Diagnostic::Error || level == Diagnostic::Note) {
+ level >= DiagnosticsEngine::Error || level == DiagnosticsEngine::Note) {
CapturedDiags.push_back(StoredDiagnostic(level, Info));
return;
}
@@ -108,11 +107,17 @@ public:
// Non-ARC warnings are ignored.
Diags.setLastDiagnosticIgnored();
}
+
+ DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
+ // Just drop any diagnostics that come from cloned consumers; they'll
+ // have different source managers anyway.
+ return new IgnoringDiagConsumer();
+ }
};
} // end anonymous namespace
-static inline llvm::StringRef SimulatorVersionDefineName() {
+static inline StringRef SimulatorVersionDefineName() {
return "__IPHONE_OS_VERSION_MIN_REQUIRED=";
}
@@ -121,11 +126,11 @@ static inline llvm::StringRef SimulatorVersionDefineName() {
// and return the grouped values as integers, e.g:
// __IPHONE_OS_VERSION_MIN_REQUIRED=40201
// will return Major=4, Minor=2, Micro=1.
-static bool GetVersionFromSimulatorDefine(llvm::StringRef define,
+static bool GetVersionFromSimulatorDefine(StringRef define,
unsigned &Major, unsigned &Minor,
unsigned &Micro) {
assert(define.startswith(SimulatorVersionDefineName()));
- llvm::StringRef name, version;
+ StringRef name, version;
llvm::tie(name, version) = define.split('=');
if (version.empty())
return false;
@@ -154,7 +159,7 @@ static bool HasARCRuntime(CompilerInvocation &origCI) {
continue;
if (!define.startswith(SimulatorVersionDefineName()))
continue;
- unsigned Major, Minor, Micro;
+ unsigned Major = 0, Minor = 0, Micro = 0;
if (GetVersionFromSimulatorDefine(define, Major, Minor, Micro) &&
Major < 10 && Minor < 100 && Micro < 100)
return Major >= 5;
@@ -177,7 +182,8 @@ static bool HasARCRuntime(CompilerInvocation &origCI) {
return false;
}
-CompilerInvocation *createInvocationForMigration(CompilerInvocation &origCI) {
+static CompilerInvocation *
+createInvocationForMigration(CompilerInvocation &origCI) {
llvm::OwningPtr<CompilerInvocation> CInvok;
CInvok.reset(new CompilerInvocation(origCI));
CInvok->getPreprocessorOpts().ImplicitPCHInclude = std::string();
@@ -194,13 +200,29 @@ CompilerInvocation *createInvocationForMigration(CompilerInvocation &origCI) {
return CInvok.take();
}
+static void emitPremigrationErrors(const CapturedDiagList &arcDiags,
+ const DiagnosticOptions &diagOpts,
+ Preprocessor &PP) {
+ TextDiagnosticPrinter printer(llvm::errs(), diagOpts);
+ llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
+ new DiagnosticsEngine(DiagID, &printer, /*ShouldOwnClient=*/false));
+ Diags->setSourceManager(&PP.getSourceManager());
+
+ printer.BeginSourceFile(PP.getLangOptions(), &PP);
+ arcDiags.reportDiagnostics(*Diags);
+ printer.EndSourceFile();
+}
+
//===----------------------------------------------------------------------===//
// checkForManualIssues.
//===----------------------------------------------------------------------===//
bool arcmt::checkForManualIssues(CompilerInvocation &origCI,
- llvm::StringRef Filename, InputKind Kind,
- DiagnosticClient *DiagClient) {
+ StringRef Filename, InputKind Kind,
+ DiagnosticConsumer *DiagClient,
+ bool emitPremigrationARCErrors,
+ StringRef plistOut) {
if (!origCI.getLangOpts().ObjC1)
return false;
@@ -216,11 +238,11 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI,
assert(DiagClient);
llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
- llvm::IntrusiveRefCntPtr<Diagnostic> Diags(
- new Diagnostic(DiagID, DiagClient, /*ShouldOwnClient=*/false));
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
+ new DiagnosticsEngine(DiagID, DiagClient, /*ShouldOwnClient=*/false));
// Filter of all diagnostics.
- CaptureDiagnosticClient errRec(*Diags, capturedDiags);
+ CaptureDiagnosticConsumer errRec(*Diags, capturedDiags);
Diags->setClient(&errRec, /*ShouldOwnClient=*/false);
llvm::OwningPtr<ASTUnit> Unit(
@@ -241,9 +263,21 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI,
return true;
}
+ if (emitPremigrationARCErrors)
+ emitPremigrationErrors(capturedDiags, origCI.getDiagnosticOpts(),
+ Unit->getPreprocessor());
+ if (!plistOut.empty()) {
+ SmallVector<StoredDiagnostic, 8> arcDiags;
+ for (CapturedDiagList::iterator
+ I = capturedDiags.begin(), E = capturedDiags.end(); I != E; ++I)
+ arcDiags.push_back(*I);
+ writeARCDiagsToPlist(plistOut, arcDiags,
+ Ctx.getSourceManager(), Ctx.getLangOptions());
+ }
+
// After parsing of source files ended, we want to reuse the
// diagnostics objects to emit further diagnostics.
- // We call BeginSourceFile because DiagnosticClient requires that
+ // We call BeginSourceFile because DiagnosticConsumer requires that
// diagnostics with source range information are emitted only in between
// BeginSourceFile() and EndSourceFile().
DiagClient->BeginSourceFile(Ctx.getLangOptions(), &Unit->getPreprocessor());
@@ -266,7 +300,7 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI,
// to remove it so that we don't get errors from normal compilation.
origCI.getLangOpts().ObjCAutoRefCount = false;
- return capturedDiags.hasErrors();
+ return capturedDiags.hasErrors() || testAct.hasReportedErrors();
}
//===----------------------------------------------------------------------===//
@@ -274,15 +308,18 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI,
//===----------------------------------------------------------------------===//
static bool applyTransforms(CompilerInvocation &origCI,
- llvm::StringRef Filename, InputKind Kind,
- DiagnosticClient *DiagClient,
- llvm::StringRef outputDir) {
+ StringRef Filename, InputKind Kind,
+ DiagnosticConsumer *DiagClient,
+ StringRef outputDir,
+ bool emitPremigrationARCErrors,
+ StringRef plistOut) {
if (!origCI.getLangOpts().ObjC1)
return false;
// Make sure checking is successful first.
CompilerInvocation CInvokForCheck(origCI);
- if (arcmt::checkForManualIssues(CInvokForCheck, Filename, Kind, DiagClient))
+ if (arcmt::checkForManualIssues(CInvokForCheck, Filename, Kind, DiagClient,
+ emitPremigrationARCErrors, plistOut))
return true;
CompilerInvocation CInvok(origCI);
@@ -300,8 +337,8 @@ static bool applyTransforms(CompilerInvocation &origCI,
}
llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
- llvm::IntrusiveRefCntPtr<Diagnostic> Diags(
- new Diagnostic(DiagID, DiagClient, /*ShouldOwnClient=*/false));
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
+ new DiagnosticsEngine(DiagID, DiagClient, /*ShouldOwnClient=*/false));
if (outputDir.empty()) {
origCI.getLangOpts().ObjCAutoRefCount = true;
@@ -315,28 +352,32 @@ static bool applyTransforms(CompilerInvocation &origCI,
}
bool arcmt::applyTransformations(CompilerInvocation &origCI,
- llvm::StringRef Filename, InputKind Kind,
- DiagnosticClient *DiagClient) {
- return applyTransforms(origCI, Filename, Kind, DiagClient, llvm::StringRef());
+ StringRef Filename, InputKind Kind,
+ DiagnosticConsumer *DiagClient) {
+ return applyTransforms(origCI, Filename, Kind, DiagClient,
+ StringRef(), false, StringRef());
}
bool arcmt::migrateWithTemporaryFiles(CompilerInvocation &origCI,
- llvm::StringRef Filename, InputKind Kind,
- DiagnosticClient *DiagClient,
- llvm::StringRef outputDir) {
+ StringRef Filename, InputKind Kind,
+ DiagnosticConsumer *DiagClient,
+ StringRef outputDir,
+ bool emitPremigrationARCErrors,
+ StringRef plistOut) {
assert(!outputDir.empty() && "Expected output directory path");
- return applyTransforms(origCI, Filename, Kind, DiagClient, outputDir);
+ return applyTransforms(origCI, Filename, Kind, DiagClient,
+ outputDir, emitPremigrationARCErrors, plistOut);
}
bool arcmt::getFileRemappings(std::vector<std::pair<std::string,std::string> > &
remap,
- llvm::StringRef outputDir,
- DiagnosticClient *DiagClient) {
+ StringRef outputDir,
+ DiagnosticConsumer *DiagClient) {
assert(!outputDir.empty());
llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
- llvm::IntrusiveRefCntPtr<Diagnostic> Diags(
- new Diagnostic(DiagID, DiagClient, /*ShouldOwnClient=*/false));
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
+ new DiagnosticsEngine(DiagID, DiagClient, /*ShouldOwnClient=*/false));
FileRemapper remapper;
bool err = remapper.initFromDisk(outputDir, *Diags,
@@ -364,7 +405,8 @@ public:
ARCMTMacroTrackerPPCallbacks(std::vector<SourceLocation> &ARCMTMacroLocs)
: ARCMTMacroLocs(ARCMTMacroLocs) { }
- virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo *MI) {
+ virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo *MI,
+ SourceRange Range) {
if (MacroNameTok.getIdentifierInfo()->getName() == getARCMTMacroName())
ARCMTMacroLocs.push_back(MacroNameTok.getLocation());
}
@@ -378,7 +420,7 @@ public:
: ARCMTMacroLocs(ARCMTMacroLocs) { }
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- llvm::StringRef InFile) {
+ StringRef InFile) {
CI.getPreprocessor().addPPCallbacks(
new ARCMTMacroTrackerPPCallbacks(ARCMTMacroLocs));
return new ASTConsumer();
@@ -402,7 +444,7 @@ public:
Listener->finish();
}
- virtual void insert(SourceLocation loc, llvm::StringRef text) {
+ virtual void insert(SourceLocation loc, StringRef text) {
bool err = rewriter.InsertText(loc, text, /*InsertAfter=*/true,
/*indentNewLines=*/true);
if (!err && Listener)
@@ -432,13 +474,13 @@ public:
MigrationProcess::RewriteListener::~RewriteListener() { }
MigrationProcess::MigrationProcess(const CompilerInvocation &CI,
- DiagnosticClient *diagClient,
- llvm::StringRef outputDir)
+ DiagnosticConsumer *diagClient,
+ StringRef outputDir)
: OrigCI(CI), DiagClient(diagClient) {
if (!outputDir.empty()) {
llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
- llvm::IntrusiveRefCntPtr<Diagnostic> Diags(
- new Diagnostic(DiagID, DiagClient, /*ShouldOwnClient=*/false));
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
+ new DiagnosticsEngine(DiagID, DiagClient, /*ShouldOwnClient=*/false));
Remapper.initFromDisk(outputDir, *Diags, /*ignoreIfFilesChanges=*/true);
}
}
@@ -456,11 +498,11 @@ bool MigrationProcess::applyTransform(TransformFn trans,
assert(DiagClient);
llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
- llvm::IntrusiveRefCntPtr<Diagnostic> Diags(
- new Diagnostic(DiagID, DiagClient, /*ShouldOwnClient=*/false));
+ llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
+ new DiagnosticsEngine(DiagID, DiagClient, /*ShouldOwnClient=*/false));
// Filter of all diagnostics.
- CaptureDiagnosticClient errRec(*Diags, capturedDiags);
+ CaptureDiagnosticConsumer errRec(*Diags, capturedDiags);
Diags->setClient(&errRec, /*ShouldOwnClient=*/false);
llvm::OwningPtr<ARCMTMacroTrackerAction> ASTAction;
@@ -488,7 +530,7 @@ bool MigrationProcess::applyTransform(TransformFn trans,
// After parsing of source files ended, we want to reuse the
// diagnostics objects to emit further diagnostics.
- // We call BeginSourceFile because DiagnosticClient requires that
+ // We call BeginSourceFile because DiagnosticConsumer requires that
// diagnostics with source range information are emitted only in between
// BeginSourceFile() and EndSourceFile().
DiagClient->BeginSourceFile(Ctx.getLangOptions(), &Unit->getPreprocessor());
@@ -522,7 +564,7 @@ bool MigrationProcess::applyTransform(TransformFn trans,
buf.write(vecOS);
vecOS.flush();
llvm::MemoryBuffer *memBuf = llvm::MemoryBuffer::getMemBufferCopy(
- llvm::StringRef(newText.data(), newText.size()), newFname);
+ StringRef(newText.data(), newText.size()), newFname);
llvm::SmallString<64> filePath(file->getName());
Unit->getFileManager().FixupRelativePath(filePath);
Remapper.remap(filePath.str(), memBuf);
@@ -535,7 +577,7 @@ bool MigrationProcess::applyTransform(TransformFn trans,
// isARCDiagnostic.
//===----------------------------------------------------------------------===//
-bool arcmt::isARCDiagnostic(unsigned diagID, Diagnostic &Diag) {
+bool arcmt::isARCDiagnostic(unsigned diagID, DiagnosticsEngine &Diag) {
return Diag.getDiagnosticIDs()->getCategoryNumberForDiag(diagID) ==
diag::DiagCat_Automatic_Reference_Counting_Issue;
}