|
10 | 10 | #include "Internals.h"
|
11 | 11 | #include "clang/Frontend/ASTUnit.h"
|
12 | 12 | #include "clang/Frontend/CompilerInstance.h"
|
| 13 | +#include "clang/Frontend/TextDiagnosticPrinter.h" |
13 | 14 | #include "clang/Frontend/Utils.h"
|
14 | 15 | #include "clang/AST/ASTConsumer.h"
|
15 | 16 | #include "clang/Rewrite/Rewriter.h"
|
@@ -194,13 +195,29 @@ CompilerInvocation *createInvocationForMigration(CompilerInvocation &origCI) {
|
194 | 195 | return CInvok.take();
|
195 | 196 | }
|
196 | 197 |
|
| 198 | +void emitPremigrationErrors(const CapturedDiagList &arcDiags, |
| 199 | + const DiagnosticOptions &diagOpts, |
| 200 | + Preprocessor &PP) { |
| 201 | + TextDiagnosticPrinter printer(llvm::errs(), diagOpts); |
| 202 | + llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); |
| 203 | + llvm::IntrusiveRefCntPtr<Diagnostic> Diags( |
| 204 | + new Diagnostic(DiagID, &printer, /*ShouldOwnClient=*/false)); |
| 205 | + Diags->setSourceManager(&PP.getSourceManager()); |
| 206 | + |
| 207 | + printer.BeginSourceFile(PP.getLangOptions(), &PP); |
| 208 | + arcDiags.reportDiagnostics(*Diags); |
| 209 | + printer.EndSourceFile(); |
| 210 | +} |
| 211 | + |
197 | 212 | //===----------------------------------------------------------------------===//
|
198 | 213 | // checkForManualIssues.
|
199 | 214 | //===----------------------------------------------------------------------===//
|
200 | 215 |
|
201 | 216 | bool arcmt::checkForManualIssues(CompilerInvocation &origCI,
|
202 | 217 | llvm::StringRef Filename, InputKind Kind,
|
203 |
| - DiagnosticClient *DiagClient) { |
| 218 | + DiagnosticClient *DiagClient, |
| 219 | + bool emitPremigrationARCErrors, |
| 220 | + llvm::StringRef plistOut) { |
204 | 221 | if (!origCI.getLangOpts().ObjC1)
|
205 | 222 | return false;
|
206 | 223 |
|
@@ -241,6 +258,18 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI,
|
241 | 258 | return true;
|
242 | 259 | }
|
243 | 260 |
|
| 261 | + if (emitPremigrationARCErrors) |
| 262 | + emitPremigrationErrors(capturedDiags, origCI.getDiagnosticOpts(), |
| 263 | + Unit->getPreprocessor()); |
| 264 | + if (!plistOut.empty()) { |
| 265 | + llvm::SmallVector<StoredDiagnostic, 8> arcDiags; |
| 266 | + for (CapturedDiagList::iterator |
| 267 | + I = capturedDiags.begin(), E = capturedDiags.end(); I != E; ++I) |
| 268 | + arcDiags.push_back(*I); |
| 269 | + writeARCDiagsToPlist(plistOut, arcDiags, |
| 270 | + Ctx.getSourceManager(), Ctx.getLangOptions()); |
| 271 | + } |
| 272 | + |
244 | 273 | // After parsing of source files ended, we want to reuse the
|
245 | 274 | // diagnostics objects to emit further diagnostics.
|
246 | 275 | // We call BeginSourceFile because DiagnosticClient requires that
|
@@ -276,13 +305,16 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI,
|
276 | 305 | static bool applyTransforms(CompilerInvocation &origCI,
|
277 | 306 | llvm::StringRef Filename, InputKind Kind,
|
278 | 307 | DiagnosticClient *DiagClient,
|
279 |
| - llvm::StringRef outputDir) { |
| 308 | + llvm::StringRef outputDir, |
| 309 | + bool emitPremigrationARCErrors, |
| 310 | + llvm::StringRef plistOut) { |
280 | 311 | if (!origCI.getLangOpts().ObjC1)
|
281 | 312 | return false;
|
282 | 313 |
|
283 | 314 | // Make sure checking is successful first.
|
284 | 315 | CompilerInvocation CInvokForCheck(origCI);
|
285 |
| - if (arcmt::checkForManualIssues(CInvokForCheck, Filename, Kind, DiagClient)) |
| 316 | + if (arcmt::checkForManualIssues(CInvokForCheck, Filename, Kind, DiagClient, |
| 317 | + emitPremigrationARCErrors, plistOut)) |
286 | 318 | return true;
|
287 | 319 |
|
288 | 320 | CompilerInvocation CInvok(origCI);
|
@@ -317,15 +349,19 @@ static bool applyTransforms(CompilerInvocation &origCI,
|
317 | 349 | bool arcmt::applyTransformations(CompilerInvocation &origCI,
|
318 | 350 | llvm::StringRef Filename, InputKind Kind,
|
319 | 351 | DiagnosticClient *DiagClient) {
|
320 |
| - return applyTransforms(origCI, Filename, Kind, DiagClient, llvm::StringRef()); |
| 352 | + return applyTransforms(origCI, Filename, Kind, DiagClient, |
| 353 | + llvm::StringRef(), false, llvm::StringRef()); |
321 | 354 | }
|
322 | 355 |
|
323 | 356 | bool arcmt::migrateWithTemporaryFiles(CompilerInvocation &origCI,
|
324 | 357 | llvm::StringRef Filename, InputKind Kind,
|
325 | 358 | DiagnosticClient *DiagClient,
|
326 |
| - llvm::StringRef outputDir) { |
| 359 | + llvm::StringRef outputDir, |
| 360 | + bool emitPremigrationARCErrors, |
| 361 | + llvm::StringRef plistOut) { |
327 | 362 | assert(!outputDir.empty() && "Expected output directory path");
|
328 |
| - return applyTransforms(origCI, Filename, Kind, DiagClient, outputDir); |
| 363 | + return applyTransforms(origCI, Filename, Kind, DiagClient, |
| 364 | + outputDir, emitPremigrationARCErrors, plistOut); |
329 | 365 | }
|
330 | 366 |
|
331 | 367 | bool arcmt::getFileRemappings(std::vector<std::pair<std::string,std::string> > &
|
|
0 commit comments