@@ -305,19 +305,17 @@ namespace {
305
305
// / format.
306
306
class JSONFixitWriter
307
307
: public DiagnosticConsumer, public migrator::FixitFilter {
308
+ std::string FixitsOutputPath;
308
309
std::unique_ptr<llvm::raw_ostream> OSPtr;
309
310
bool FixitAll;
310
311
std::vector<SingleEdit> AllEdits;
311
312
312
313
public:
313
- JSONFixitWriter (std::unique_ptr<llvm::raw_ostream> OS ,
314
+ JSONFixitWriter (std::string fixitsOutputPath ,
314
315
const DiagnosticOptions &DiagOpts)
315
- : OSPtr(std::move(OS) ),
316
+ : FixitsOutputPath(fixitsOutputPath ),
316
317
FixitAll (DiagOpts.FixitCodeForAllDiagnostics) {}
317
318
318
- ~JSONFixitWriter () override {
319
- swift::writeEditsInJson (llvm::makeArrayRef (AllEdits), *OSPtr);
320
- }
321
319
private:
322
320
void handleDiagnostic (SourceManager &SM, SourceLoc Loc,
323
321
DiagnosticKind Kind,
@@ -330,6 +328,27 @@ class JSONFixitWriter
330
328
AllEdits.push_back ({SM, Fix.getRange (), Fix.getText ()});
331
329
}
332
330
}
331
+
332
+ bool finishProcessing () override {
333
+ std::error_code EC;
334
+ std::unique_ptr<llvm::raw_fd_ostream> OS;
335
+ OS.reset (new llvm::raw_fd_ostream (FixitsOutputPath,
336
+ EC,
337
+ llvm::sys::fs::F_None));
338
+ if (EC) {
339
+ // Create a temporary diagnostics engine to print the error to stderr.
340
+ SourceManager dummyMgr;
341
+ DiagnosticEngine DE (dummyMgr);
342
+ PrintingDiagnosticConsumer PDC;
343
+ DE.addConsumer (PDC);
344
+ DE.diagnose (SourceLoc (), diag::cannot_open_serialized_file,
345
+ FixitsOutputPath, EC.message ());
346
+ return true ;
347
+ }
348
+
349
+ swift::writeEditsInJson (llvm::makeArrayRef (AllEdits), *OS);
350
+ return false ;
351
+ }
333
352
};
334
353
335
354
} // anonymous namespace
@@ -1026,9 +1045,23 @@ int swift::performFrontend(ArrayRef<const char *> Args,
1026
1045
llvm::make_unique<CompilerInstance>();
1027
1046
Instance->addDiagnosticConsumer (&PDC);
1028
1047
1048
+ struct FinishDiagProcessingCheckRAII {
1049
+ bool CalledFinishDiagProcessing = false ;
1050
+ ~FinishDiagProcessingCheckRAII () {
1051
+ assert (CalledFinishDiagProcessing && " returned from the function "
1052
+ " without calling finishDiagProcessing" );
1053
+ }
1054
+ } FinishDiagProcessingCheckRAII;
1055
+
1056
+ auto finishDiagProcessing = [&](int retValue) -> int {
1057
+ FinishDiagProcessingCheckRAII.CalledFinishDiagProcessing = true ;
1058
+ bool err = Instance->getDiags ().finishProcessing ();
1059
+ return retValue ? retValue : err;
1060
+ };
1061
+
1029
1062
if (Args.empty ()) {
1030
1063
Instance->getDiags ().diagnose (SourceLoc (), diag::error_no_frontend_args);
1031
- return 1 ;
1064
+ return finishDiagProcessing ( 1 ) ;
1032
1065
}
1033
1066
1034
1067
CompilerInvocation Invocation;
@@ -1041,7 +1074,7 @@ int swift::performFrontend(ArrayRef<const char *> Args,
1041
1074
1042
1075
// Parse arguments.
1043
1076
if (Invocation.parseArgs (Args, Instance->getDiags (), workingDirectory)) {
1044
- return 1 ;
1077
+ return finishDiagProcessing ( 1 ) ;
1045
1078
}
1046
1079
1047
1080
// Setting DWARF Version depend on platform
@@ -1063,14 +1096,14 @@ int swift::performFrontend(ArrayRef<const char *> Args,
1063
1096
Options->PrintHelp (llvm::outs (), displayName (MainExecutablePath).c_str (),
1064
1097
" Swift frontend" , IncludedFlagsBitmask,
1065
1098
ExcludedFlagsBitmask);
1066
- return 0 ;
1099
+ return finishDiagProcessing ( 0 ) ;
1067
1100
}
1068
1101
1069
1102
if (Invocation.getFrontendOptions ().RequestedAction ==
1070
1103
FrontendOptions::NoneAction) {
1071
1104
Instance->getDiags ().diagnose (SourceLoc (),
1072
1105
diag::error_missing_frontend_action);
1073
- return 1 ;
1106
+ return finishDiagProcessing ( 1 ) ;
1074
1107
}
1075
1108
1076
1109
// Because the serialized diagnostics consumer is initialized here,
@@ -1084,21 +1117,8 @@ int swift::performFrontend(ArrayRef<const char *> Args,
1084
1117
const std::string &SerializedDiagnosticsPath =
1085
1118
Invocation.getFrontendOptions ().SerializedDiagnosticsPath ;
1086
1119
if (!SerializedDiagnosticsPath.empty ()) {
1087
- std::error_code EC;
1088
- std::unique_ptr<llvm::raw_fd_ostream> OS;
1089
- OS.reset (new llvm::raw_fd_ostream (SerializedDiagnosticsPath,
1090
- EC,
1091
- llvm::sys::fs::F_None));
1092
-
1093
- if (EC) {
1094
- Instance->getDiags ().diagnose (SourceLoc (),
1095
- diag::cannot_open_serialized_file,
1096
- SerializedDiagnosticsPath, EC.message ());
1097
- return 1 ;
1098
- }
1099
-
1100
1120
SerializedConsumer.reset (
1101
- serialized_diagnostics::createConsumer (std::move (OS) ));
1121
+ serialized_diagnostics::createConsumer (SerializedDiagnosticsPath ));
1102
1122
Instance->addDiagnosticConsumer (SerializedConsumer.get ());
1103
1123
}
1104
1124
}
@@ -1108,20 +1128,7 @@ int swift::performFrontend(ArrayRef<const char *> Args,
1108
1128
const std::string &FixitsOutputPath =
1109
1129
Invocation.getFrontendOptions ().FixitsOutputPath ;
1110
1130
if (!FixitsOutputPath.empty ()) {
1111
- std::error_code EC;
1112
- std::unique_ptr<llvm::raw_fd_ostream> OS;
1113
- OS.reset (new llvm::raw_fd_ostream (FixitsOutputPath,
1114
- EC,
1115
- llvm::sys::fs::F_None));
1116
-
1117
- if (EC) {
1118
- Instance->getDiags ().diagnose (SourceLoc (),
1119
- diag::cannot_open_file,
1120
- FixitsOutputPath, EC.message ());
1121
- return 1 ;
1122
- }
1123
-
1124
- FixitsConsumer.reset (new JSONFixitWriter (std::move (OS),
1131
+ FixitsConsumer.reset (new JSONFixitWriter (FixitsOutputPath,
1125
1132
Invocation.getDiagnosticOptions ()));
1126
1133
Instance->addDiagnosticConsumer (FixitsConsumer.get ());
1127
1134
}
@@ -1167,7 +1174,7 @@ int swift::performFrontend(ArrayRef<const char *> Args,
1167
1174
}
1168
1175
1169
1176
if (Instance->setup (Invocation)) {
1170
- return 1 ;
1177
+ return finishDiagProcessing ( 1 ) ;
1171
1178
}
1172
1179
1173
1180
if (StatsReporter) {
@@ -1212,7 +1219,7 @@ int swift::performFrontend(ArrayRef<const char *> Args,
1212
1219
}
1213
1220
}
1214
1221
1215
- return (HadError ? 1 : ReturnValue);
1222
+ return finishDiagProcessing (HadError ? 1 : ReturnValue);
1216
1223
}
1217
1224
1218
1225
void FrontendObserver::parsedArgs (CompilerInvocation &invocation) {}
0 commit comments