Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 7ee2049

Browse files
committed
[arcmt] Add some additional driver flags to optionally emit or save the pre-migration ARC errors.
-arcmt-migrate-emit-errors : Emits the pre-migration ARC errors but it doesn't affect anything else -arcmt-migrate-report-output : Writes out the pre-migration ARC errors to the provided plist file rdar://9791454 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@135491 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent d6dbb87 commit 7ee2049

File tree

14 files changed

+377
-14
lines changed

14 files changed

+377
-14
lines changed

include/clang/ARCMigrate/ARCMT.h

+20-2
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,19 @@ namespace arcmt {
2828
/// It then checks the AST and produces errors/warning for ARC migration issues
2929
/// that the user needs to handle manually.
3030
///
31+
/// \param emitPremigrationARCErrors if true all ARC errors will get emitted
32+
/// even if the migrator can fix them, but the function will still return false
33+
/// if all ARC errors can be fixed.
34+
///
35+
/// \param plistOut if non-empty, it is the file path to store the plist with
36+
/// the pre-migration ARC diagnostics.
37+
///
3138
/// \returns false if no error is produced, true otherwise.
3239
bool checkForManualIssues(CompilerInvocation &CI,
3340
llvm::StringRef Filename, InputKind Kind,
34-
DiagnosticClient *DiagClient);
41+
DiagnosticClient *DiagClient,
42+
bool emitPremigrationARCErrors = false,
43+
llvm::StringRef plistOut = llvm::StringRef());
3544

3645
/// \brief Works similar to checkForManualIssues but instead of checking, it
3746
/// applies automatic modifications to source files to conform to ARC.
@@ -44,11 +53,20 @@ bool applyTransformations(CompilerInvocation &origCI,
4453
/// \brief Applies automatic modifications and produces temporary files
4554
/// and metadata into the \arg outputDir path.
4655
///
56+
/// \param emitPremigrationARCErrors if true all ARC errors will get emitted
57+
/// even if the migrator can fix them, but the function will still return false
58+
/// if all ARC errors can be fixed.
59+
///
60+
/// \param plistOut if non-empty, it is the file path to store the plist with
61+
/// the pre-migration ARC diagnostics.
62+
///
4763
/// \returns false if no error is produced, true otherwise.
4864
bool migrateWithTemporaryFiles(CompilerInvocation &origCI,
4965
llvm::StringRef Filename, InputKind Kind,
5066
DiagnosticClient *DiagClient,
51-
llvm::StringRef outputDir);
67+
llvm::StringRef outputDir,
68+
bool emitPremigrationARCErrors,
69+
llvm::StringRef plistOut);
5270

5371
/// \brief Get the set of file remappings from the \arg outputDir path that
5472
/// migrateWithTemporaryFiles produced.

include/clang/ARCMigrate/ARCMTActions.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,15 @@ class ModifyAction : public WrapperFrontendAction {
3434

3535
class MigrateAction : public WrapperFrontendAction {
3636
std::string MigrateDir;
37+
std::string PlistOut;
38+
bool EmitPremigrationARCErros;
3739
protected:
3840
virtual bool BeginInvocation(CompilerInstance &CI);
3941

4042
public:
41-
MigrateAction(FrontendAction *WrappedAction, llvm::StringRef migrateDir);
43+
MigrateAction(FrontendAction *WrappedAction, llvm::StringRef migrateDir,
44+
llvm::StringRef plistOut,
45+
bool emitPremigrationARCErrors);
4246
};
4347

4448
}

include/clang/Driver/CC1Options.td

+4
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,10 @@ def arcmt_migrate : Flag<"-arcmt-migrate">,
394394
HelpText<"Apply modifications and produces temporary files that conform to ARC">;
395395
def arcmt_migrate_directory : Separate<"-arcmt-migrate-directory">,
396396
HelpText<"Directory for temporary files produced during ARC migration">;
397+
def arcmt_migrate_report_output : Separate<"-arcmt-migrate-report-output">,
398+
HelpText<"Output path for the plist report">;
399+
def arcmt_migrate_emit_arc_errors : Flag<"-arcmt-migrate-emit-errors">,
400+
HelpText<"Emit ARC errors even if the migrator can fix them">;
397401

398402
def import_module : Separate<"-import-module">,
399403
HelpText<"Import a module definition file">;

include/clang/Driver/Options.td

+4
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ def ccc_arcmt_migrate : Separate<"-ccc-arcmt-migrate">, CCCDriverOpt,
122122
HelpText<"Apply modifications and produces temporary files that conform to ARC">;
123123
def ccc_arcmt_migrate_EQ : Joined<"-ccc-arcmt-migrate=">, CCCDriverOpt,
124124
Alias<ccc_arcmt_migrate>;
125+
def arcmt_migrate_report_output : Separate<"-arcmt-migrate-report-output">,
126+
HelpText<"Output path for the plist report">;
127+
def arcmt_migrate_emit_arc_errors : Flag<"-arcmt-migrate-emit-errors">,
128+
HelpText<"Emit ARC errors even if the migrator can fix them">;
125129

126130
// Make sure all other -ccc- options are rejected.
127131
def ccc_ : Joined<"-ccc-">, Group<ccc_Group>, Flags<[Unsupported]>;

include/clang/Frontend/FrontendOptions.h

+4
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ class FrontendOptions {
7575
unsigned ShowVersion : 1; ///< Show the -version text.
7676
unsigned FixWhatYouCan : 1; ///< Apply fixes even if there are
7777
/// unfixable errors.
78+
unsigned ARCMTMigrateEmitARCErrors : 1; /// Emit ARC errors even if the
79+
/// migrator can fix them
7880

7981
enum {
8082
ARCMT_None,
@@ -84,6 +86,7 @@ class FrontendOptions {
8486
} ARCMTAction;
8587

8688
std::string ARCMTMigrateDir;
89+
std::string ARCMTMigrateReportOut;
8790

8891
/// The input files and their types.
8992
std::vector<std::pair<InputKind, std::string> > Inputs;
@@ -140,6 +143,7 @@ class FrontendOptions {
140143
ShowTimers = 0;
141144
ShowVersion = 0;
142145
ARCMTAction = ARCMT_None;
146+
ARCMTMigrateEmitARCErrors = 0;
143147
}
144148

145149
/// getInputKindForExtension - Return the appropriate input kind for a file

lib/ARCMigrate/ARCMT.cpp

+42-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "Internals.h"
1111
#include "clang/Frontend/ASTUnit.h"
1212
#include "clang/Frontend/CompilerInstance.h"
13+
#include "clang/Frontend/TextDiagnosticPrinter.h"
1314
#include "clang/Frontend/Utils.h"
1415
#include "clang/AST/ASTConsumer.h"
1516
#include "clang/Rewrite/Rewriter.h"
@@ -194,13 +195,29 @@ CompilerInvocation *createInvocationForMigration(CompilerInvocation &origCI) {
194195
return CInvok.take();
195196
}
196197

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+
197212
//===----------------------------------------------------------------------===//
198213
// checkForManualIssues.
199214
//===----------------------------------------------------------------------===//
200215

201216
bool arcmt::checkForManualIssues(CompilerInvocation &origCI,
202217
llvm::StringRef Filename, InputKind Kind,
203-
DiagnosticClient *DiagClient) {
218+
DiagnosticClient *DiagClient,
219+
bool emitPremigrationARCErrors,
220+
llvm::StringRef plistOut) {
204221
if (!origCI.getLangOpts().ObjC1)
205222
return false;
206223

@@ -241,6 +258,18 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI,
241258
return true;
242259
}
243260

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+
244273
// After parsing of source files ended, we want to reuse the
245274
// diagnostics objects to emit further diagnostics.
246275
// We call BeginSourceFile because DiagnosticClient requires that
@@ -276,13 +305,16 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI,
276305
static bool applyTransforms(CompilerInvocation &origCI,
277306
llvm::StringRef Filename, InputKind Kind,
278307
DiagnosticClient *DiagClient,
279-
llvm::StringRef outputDir) {
308+
llvm::StringRef outputDir,
309+
bool emitPremigrationARCErrors,
310+
llvm::StringRef plistOut) {
280311
if (!origCI.getLangOpts().ObjC1)
281312
return false;
282313

283314
// Make sure checking is successful first.
284315
CompilerInvocation CInvokForCheck(origCI);
285-
if (arcmt::checkForManualIssues(CInvokForCheck, Filename, Kind, DiagClient))
316+
if (arcmt::checkForManualIssues(CInvokForCheck, Filename, Kind, DiagClient,
317+
emitPremigrationARCErrors, plistOut))
286318
return true;
287319

288320
CompilerInvocation CInvok(origCI);
@@ -317,15 +349,19 @@ static bool applyTransforms(CompilerInvocation &origCI,
317349
bool arcmt::applyTransformations(CompilerInvocation &origCI,
318350
llvm::StringRef Filename, InputKind Kind,
319351
DiagnosticClient *DiagClient) {
320-
return applyTransforms(origCI, Filename, Kind, DiagClient, llvm::StringRef());
352+
return applyTransforms(origCI, Filename, Kind, DiagClient,
353+
llvm::StringRef(), false, llvm::StringRef());
321354
}
322355

323356
bool arcmt::migrateWithTemporaryFiles(CompilerInvocation &origCI,
324357
llvm::StringRef Filename, InputKind Kind,
325358
DiagnosticClient *DiagClient,
326-
llvm::StringRef outputDir) {
359+
llvm::StringRef outputDir,
360+
bool emitPremigrationARCErrors,
361+
llvm::StringRef plistOut) {
327362
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);
329365
}
330366

331367
bool arcmt::getFileRemappings(std::vector<std::pair<std::string,std::string> > &

lib/ARCMigrate/ARCMTActions.cpp

+14-4
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,26 @@ ModifyAction::ModifyAction(FrontendAction *WrappedAction)
3838
: WrapperFrontendAction(WrappedAction) {}
3939

4040
bool MigrateAction::BeginInvocation(CompilerInstance &CI) {
41-
return !arcmt::migrateWithTemporaryFiles(CI.getInvocation(),
41+
if (arcmt::migrateWithTemporaryFiles(CI.getInvocation(),
4242
getCurrentFile(),
4343
getCurrentFileKind(),
4444
CI.getDiagnostics().getClient(),
45-
MigrateDir);
45+
MigrateDir,
46+
EmitPremigrationARCErros,
47+
PlistOut))
48+
return false; // errors, stop the action.
49+
50+
// We only want to see diagnostics emitted by migrateWithTemporaryFiles.
51+
CI.getDiagnostics().setIgnoreAllWarnings(true);
52+
return true;
4653
}
4754

4855
MigrateAction::MigrateAction(FrontendAction *WrappedAction,
49-
llvm::StringRef migrateDir)
50-
: WrapperFrontendAction(WrappedAction), MigrateDir(migrateDir) {
56+
llvm::StringRef migrateDir,
57+
llvm::StringRef plistOut,
58+
bool emitPremigrationARCErrors)
59+
: WrapperFrontendAction(WrappedAction), MigrateDir(migrateDir),
60+
PlistOut(plistOut), EmitPremigrationARCErros(emitPremigrationARCErrors) {
5161
if (MigrateDir.empty())
5262
MigrateDir = "."; // user current directory if none is given.
5363
}

lib/ARCMigrate/Internals.h

+8
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,16 @@ class CapturedDiagList {
3232
void reportDiagnostics(Diagnostic &diags) const;
3333

3434
bool hasErrors() const;
35+
36+
typedef ListTy::const_iterator iterator;
37+
iterator begin() const { return List.begin(); }
38+
iterator end() const { return List.end(); }
3539
};
3640

41+
void writeARCDiagsToPlist(const std::string &outPath,
42+
llvm::ArrayRef<StoredDiagnostic> diags,
43+
SourceManager &SM, const LangOptions &LangOpts);
44+
3745
class TransformActions {
3846
Diagnostic &Diags;
3947
CapturedDiagList &CapturedDiags;

0 commit comments

Comments
 (0)