@@ -161,8 +161,6 @@ void UnsafeDeserializationError::anchor() {}
161
161
const char ModularizationError::ID = ' \0 ' ;
162
162
void ModularizationError::anchor () {}
163
163
164
- static llvm::Error consumeErrorIfXRefNonLoadedModule (llvm::Error &&error);
165
-
166
164
// / Skips a single record in the bitstream.
167
165
// /
168
166
// / Destroys the stream position if the next entry is not a record.
@@ -235,21 +233,15 @@ void ExtensionError::diagnose(const ModuleFile *MF) const {
235
233
diag::modularization_issue_side_effect_extension_error);
236
234
}
237
235
238
- llvm::Error ModuleFile::diagnoseFatal (llvm::Error error) const {
239
-
240
- auto &ctx = getContext ();
241
- if (FileContext) {
242
- if (ctx.LangOpts .EnableDeserializationRecovery ) {
243
- // Attempt to report relevant errors as diagnostics.
244
- // At this time, only ModularizationErrors are reported directly. They
245
- // can get here either directly or as underlying causes to a TypeError or
246
- // and ExtensionError.
247
- auto handleModularizationError =
248
- [&](const ModularizationError &modularError) -> llvm::Error {
249
- modularError.diagnose (this );
250
- return llvm::Error::success ();
251
- };
252
- error = llvm::handleErrors (std::move (error),
236
+ llvm::Error
237
+ ModuleFile::diagnoseModularizationError (llvm::Error error,
238
+ DiagnosticBehavior limit) const {
239
+ auto handleModularizationError =
240
+ [&](const ModularizationError &modularError) -> llvm::Error {
241
+ modularError.diagnose (this , limit);
242
+ return llvm::Error::success ();
243
+ };
244
+ llvm::Error outError = llvm::handleErrors (std::move (error),
253
245
handleModularizationError,
254
246
[&](TypeError &typeError) -> llvm::Error {
255
247
if (typeError.diagnoseUnderlyingReason (handleModularizationError)) {
@@ -266,6 +258,16 @@ llvm::Error ModuleFile::diagnoseFatal(llvm::Error error) const {
266
258
return llvm::make_error<ExtensionError>(std::move (extError));
267
259
});
268
260
261
+ return outError;
262
+ }
263
+
264
+ llvm::Error ModuleFile::diagnoseFatal (llvm::Error error) const {
265
+
266
+ auto &ctx = getContext ();
267
+ if (FileContext) {
268
+ if (ctx.LangOpts .EnableDeserializationRecovery ) {
269
+ error = diagnoseModularizationError (std::move (error));
270
+
269
271
// If no error is left, it was reported as a diagnostic. There's no
270
272
// need to crash.
271
273
if (!error)
@@ -1540,7 +1542,7 @@ ModuleFile::getSubstitutionMapChecked(serialization::SubstitutionMapID id) {
1540
1542
for (auto typeID : replacementTypeIDs) {
1541
1543
auto typeOrError = getTypeChecked (typeID);
1542
1544
if (!typeOrError) {
1543
- consumeError (typeOrError.takeError ());
1545
+ diagnoseAndConsumeError (typeOrError.takeError ());
1544
1546
continue ;
1545
1547
}
1546
1548
replacementTypes.push_back (typeOrError.get ());
@@ -1795,7 +1797,7 @@ ModuleFile::resolveCrossReference(ModuleID MID, uint32_t pathLen) {
1795
1797
if (maybeType.errorIsA <FatalDeserializationError>())
1796
1798
return maybeType.takeError ();
1797
1799
// FIXME: Don't throw away the inner error's information.
1798
- consumeError (maybeType.takeError ());
1800
+ diagnoseAndConsumeError (maybeType.takeError ());
1799
1801
return llvm::make_error<XRefError>(" couldn't decode type" ,
1800
1802
pathTrace, name);
1801
1803
}
@@ -2165,7 +2167,7 @@ ModuleFile::resolveCrossReference(ModuleID MID, uint32_t pathLen) {
2165
2167
return maybeType.takeError ();
2166
2168
2167
2169
// FIXME: Don't throw away the inner error's information.
2168
- consumeError (maybeType.takeError ());
2170
+ diagnoseAndConsumeError (maybeType.takeError ());
2169
2171
return llvm::make_error<XRefError>(" couldn't decode type" ,
2170
2172
pathTrace, memberName);
2171
2173
}
@@ -3004,7 +3006,7 @@ class DeclDeserializer {
3004
3006
3005
3007
auto maybeType = MF.getTypeChecked (typeID);
3006
3008
if (!maybeType) {
3007
- llvm::consumeError (maybeType.takeError ());
3009
+ MF. diagnoseAndConsumeError (maybeType.takeError ());
3008
3010
continue ;
3009
3011
}
3010
3012
inheritedTypes.push_back (
@@ -3330,10 +3332,10 @@ class DeclDeserializer {
3330
3332
return overriddenOrError.takeError ();
3331
3333
} else if (MF.allowCompilerErrors ()) {
3332
3334
// Drop overriding relationship when allowing errors.
3333
- llvm::consumeError (overriddenOrError.takeError ());
3335
+ MF. diagnoseAndConsumeError (overriddenOrError.takeError ());
3334
3336
overridden = nullptr ;
3335
3337
} else {
3336
- llvm::consumeError (overriddenOrError.takeError ());
3338
+ MF. diagnoseAndConsumeError (overriddenOrError.takeError ());
3337
3339
if (overriddenAffectsABI || !ctx.LangOpts .EnableDeserializationRecovery ) {
3338
3340
return llvm::make_error<OverrideError>(name, errorFlags,
3339
3341
numVTableEntries);
@@ -3477,7 +3479,7 @@ class DeclDeserializer {
3477
3479
if (overridden.errorIsA <FatalDeserializationError>())
3478
3480
return overridden.takeError ();
3479
3481
3480
- llvm::consumeError (overridden.takeError ());
3482
+ MF. diagnoseAndConsumeError (overridden.takeError ());
3481
3483
3482
3484
return llvm::make_error<OverrideError>(
3483
3485
name, getErrorFlags (), numVTableEntries);
@@ -3589,7 +3591,7 @@ class DeclDeserializer {
3589
3591
3590
3592
// FIXME: This is actually wrong. We can't just drop stored properties
3591
3593
// willy-nilly if the struct is @frozen.
3592
- consumeError (backingDecl.takeError ());
3594
+ MF. diagnoseAndConsumeError (backingDecl.takeError ());
3593
3595
return var;
3594
3596
}
3595
3597
@@ -3806,15 +3808,15 @@ class DeclDeserializer {
3806
3808
overridden = overriddenOrError.get ();
3807
3809
} else {
3808
3810
if (overriddenAffectsABI || !ctx.LangOpts .EnableDeserializationRecovery ) {
3809
- llvm::consumeError (overriddenOrError.takeError ());
3811
+ MF. diagnoseAndConsumeError (overriddenOrError.takeError ());
3810
3812
return llvm::make_error<OverrideError>(name, errorFlags,
3811
3813
numVTableEntries);
3812
3814
}
3813
3815
// Pass through deserialization errors.
3814
3816
if (overriddenOrError.errorIsA <FatalDeserializationError>())
3815
3817
return overriddenOrError.takeError ();
3816
3818
3817
- llvm::consumeError (overriddenOrError.takeError ());
3819
+ MF. diagnoseAndConsumeError (overriddenOrError.takeError ());
3818
3820
overridden = nullptr ;
3819
3821
}
3820
3822
@@ -4079,7 +4081,7 @@ class DeclDeserializer {
4079
4081
if (!subMapOrError) {
4080
4082
// If the underlying type references internal details, ignore it.
4081
4083
auto unconsumedError =
4082
- consumeErrorIfXRefNonLoadedModule (subMapOrError.takeError ());
4084
+ MF. consumeExpectedError (subMapOrError.takeError ());
4083
4085
if (unconsumedError)
4084
4086
return std::move (unconsumedError);
4085
4087
} else {
@@ -4136,7 +4138,7 @@ class DeclDeserializer {
4136
4138
return pattern.takeError ();
4137
4139
4138
4140
// Silently drop the pattern...
4139
- llvm::consumeError (pattern.takeError ());
4141
+ MF. diagnoseAndConsumeError (pattern.takeError ());
4140
4142
// ...but continue to read any further patterns we're expecting.
4141
4143
continue ;
4142
4144
}
@@ -4654,7 +4656,7 @@ class DeclDeserializer {
4654
4656
// Pass through deserialization errors.
4655
4657
if (overridden.errorIsA <FatalDeserializationError>())
4656
4658
return overridden.takeError ();
4657
- llvm::consumeError (overridden.takeError ());
4659
+ MF. diagnoseAndConsumeError (overridden.takeError ());
4658
4660
4659
4661
DeclDeserializationError::Flags errorFlags;
4660
4662
return llvm::make_error<OverrideError>(
@@ -5178,7 +5180,7 @@ llvm::Error DeclDeserializer::deserializeCustomAttrs() {
5178
5180
// is safe to drop when it can't be deserialized.
5179
5181
// rdar://problem/56599179. When allowing errors we're doing a best
5180
5182
// effort to create a module, so ignore in that case as well.
5181
- consumeError (deserialized.takeError ());
5183
+ MF. diagnoseAndConsumeError (deserialized.takeError ());
5182
5184
} else
5183
5185
return deserialized.takeError ();
5184
5186
} else if (!deserialized.get () && MF.allowCompilerErrors ()) {
@@ -6127,7 +6129,7 @@ Expected<Type> DESERIALIZE_TYPE(NAME_ALIAS_TYPE)(
6127
6129
6128
6130
// We're going to recover by falling back to the underlying type, so
6129
6131
// just ignore the error.
6130
- llvm::consumeError (aliasOrError.takeError ());
6132
+ MF. diagnoseAndConsumeError (aliasOrError.takeError ());
6131
6133
}
6132
6134
6133
6135
if (!alias || !alias->getDeclaredInterfaceType ()->isEqual (underlyingType)) {
@@ -7364,13 +7366,16 @@ Decl *handleErrorAndSupplyMissingProtoMember(ASTContext &context,
7364
7366
return suppliedMissingMember;
7365
7367
}
7366
7368
7367
- Decl *handleErrorAndSupplyMissingMiscMember (llvm::Error &&error) {
7368
- llvm::consumeError (std::move (error));
7369
+ Decl *
7370
+ ModuleFile::handleErrorAndSupplyMissingMiscMember (llvm::Error &&error) const {
7371
+ diagnoseAndConsumeError (std::move (error));
7369
7372
return nullptr ;
7370
7373
}
7371
7374
7372
- Decl *handleErrorAndSupplyMissingMember (ASTContext &context, Decl *container,
7373
- llvm::Error &&error) {
7375
+ Decl *
7376
+ ModuleFile::handleErrorAndSupplyMissingMember (ASTContext &context,
7377
+ Decl *container,
7378
+ llvm::Error &&error) const {
7374
7379
// Drop the member if it had a problem.
7375
7380
// FIXME: Handle overridable members in class extensions too, someday.
7376
7381
if (auto *containingClass = dyn_cast<ClassDecl>(container)) {
@@ -7444,14 +7449,14 @@ void ModuleFile::loadAllMembers(Decl *container, uint64_t contextData) {
7444
7449
}
7445
7450
}
7446
7451
7447
- static llvm::Error consumeErrorIfXRefNonLoadedModule (llvm::Error &&error) {
7452
+ llvm::Error ModuleFile::consumeExpectedError (llvm::Error &&error) {
7448
7453
// Missing module errors are most likely caused by an
7449
7454
// implementation-only import hiding types and decls.
7450
7455
// rdar://problem/60291019
7451
7456
if (error.isA <XRefNonLoadedModuleError>() ||
7452
7457
error.isA <UnsafeDeserializationError>() ||
7453
7458
error.isA <ModularizationError>()) {
7454
- consumeError (std::move (error));
7459
+ diagnoseAndConsumeError (std::move (error));
7455
7460
return llvm::Error::success ();
7456
7461
}
7457
7462
@@ -7465,7 +7470,7 @@ static llvm::Error consumeErrorIfXRefNonLoadedModule(llvm::Error &&error) {
7465
7470
if (TE->underlyingReasonIsA <XRefNonLoadedModuleError>() ||
7466
7471
TE->underlyingReasonIsA <UnsafeDeserializationError>() ||
7467
7472
TE->underlyingReasonIsA <ModularizationError>()) {
7468
- consumeError (std::move (errorInfo));
7473
+ diagnoseAndConsumeError (std::move (errorInfo));
7469
7474
return llvm::Error::success ();
7470
7475
}
7471
7476
@@ -7475,6 +7480,19 @@ static llvm::Error consumeErrorIfXRefNonLoadedModule(llvm::Error &&error) {
7475
7480
return std::move (error);
7476
7481
}
7477
7482
7483
+ void ModuleFile::diagnoseAndConsumeError (llvm::Error error) const {
7484
+ auto &ctx = getContext ();
7485
+ if (ctx.LangOpts .EnableModuleRecoveryRemarks ) {
7486
+ error = diagnoseModularizationError (std::move (error),
7487
+ DiagnosticBehavior::Remark);
7488
+ // If error was already diagnosed it was also consumed.
7489
+ if (!error)
7490
+ return ;
7491
+ }
7492
+
7493
+ consumeError (std::move (error));
7494
+ }
7495
+
7478
7496
namespace {
7479
7497
class LazyConformanceLoaderInfo final
7480
7498
: llvm::TrailingObjects<LazyConformanceLoaderInfo,
@@ -7538,12 +7556,12 @@ ModuleFile::loadAllConformances(const Decl *D, uint64_t contextData,
7538
7556
7539
7557
if (!conformance) {
7540
7558
auto unconsumedError =
7541
- consumeErrorIfXRefNonLoadedModule (conformance.takeError ());
7559
+ consumeExpectedError (conformance.takeError ());
7542
7560
if (unconsumedError) {
7543
7561
// Ignore if allowing errors, it's just doing a best effort to produce
7544
7562
// *some* module anyway.
7545
7563
if (allowCompilerErrors ())
7546
- consumeError (std::move (unconsumedError));
7564
+ diagnoseAndConsumeError (std::move (unconsumedError));
7547
7565
else
7548
7566
fatal (std::move (unconsumedError));
7549
7567
}
@@ -7633,7 +7651,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
7633
7651
if (maybeConformance) {
7634
7652
reqConformances.push_back (maybeConformance.get ());
7635
7653
} else if (allowCompilerErrors ()) {
7636
- consumeError (maybeConformance.takeError ());
7654
+ diagnoseAndConsumeError (maybeConformance.takeError ());
7637
7655
reqConformances.push_back (ProtocolConformanceRef::forInvalid ());
7638
7656
} else {
7639
7657
fatal (maybeConformance.takeError ());
@@ -7701,7 +7719,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
7701
7719
second = *secondOrError;
7702
7720
} else if (getContext ().LangOpts .EnableDeserializationRecovery ) {
7703
7721
second = ErrorType::get (getContext ());
7704
- consumeError (secondOrError.takeError ());
7722
+ diagnoseAndConsumeError (secondOrError.takeError ());
7705
7723
} else {
7706
7724
fatal (secondOrError.takeError ());
7707
7725
}
@@ -7711,7 +7729,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
7711
7729
third = cast_or_null<TypeDecl>(*thirdOrError);
7712
7730
} else if (getContext ().LangOpts .EnableDeserializationRecovery ) {
7713
7731
third = nullptr ;
7714
- consumeError (thirdOrError.takeError ());
7732
+ diagnoseAndConsumeError (thirdOrError.takeError ());
7715
7733
} else {
7716
7734
fatal (thirdOrError.takeError ());
7717
7735
}
@@ -7752,7 +7770,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
7752
7770
if (deserializedReq) {
7753
7771
req = cast_or_null<ValueDecl>(*deserializedReq);
7754
7772
} else if (getContext ().LangOpts .EnableDeserializationRecovery ) {
7755
- consumeError (deserializedReq.takeError ());
7773
+ diagnoseAndConsumeError (deserializedReq.takeError ());
7756
7774
req = nullptr ;
7757
7775
needToFillInOpaqueValueWitnesses = true ;
7758
7776
} else {
@@ -7769,7 +7787,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
7769
7787
// In that case, we want the conformance to still be available, but
7770
7788
// we can't make use of the relationship to the underlying decl.
7771
7789
} else if (getContext ().LangOpts .EnableDeserializationRecovery ) {
7772
- consumeError (deserializedWitness.takeError ());
7790
+ diagnoseAndConsumeError (deserializedWitness.takeError ());
7773
7791
isOpaque = true ;
7774
7792
witness = nullptr ;
7775
7793
} else {
@@ -7802,7 +7820,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
7802
7820
if (witnessSubstitutions.errorIsA <XRefNonLoadedModuleError>() ||
7803
7821
witnessSubstitutions.errorIsA <UnsafeDeserializationError>() ||
7804
7822
allowCompilerErrors ()) {
7805
- consumeError (witnessSubstitutions.takeError ());
7823
+ diagnoseAndConsumeError (witnessSubstitutions.takeError ());
7806
7824
isOpaque = true ;
7807
7825
}
7808
7826
else
0 commit comments