@@ -161,8 +161,6 @@ void UnsafeDeserializationError::anchor() {}
161161const char ModularizationError::ID = ' \0 ' ;
162162void ModularizationError::anchor () {}
163163
164- static llvm::Error consumeErrorIfXRefNonLoadedModule (llvm::Error &&error);
165-
166164// / Skips a single record in the bitstream.
167165// /
168166// / Destroys the stream position if the next entry is not a record.
@@ -235,21 +233,15 @@ void ExtensionError::diagnose(const ModuleFile *MF) const {
235233 diag::modularization_issue_side_effect_extension_error);
236234}
237235
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),
253245 handleModularizationError,
254246 [&](TypeError &typeError) -> llvm::Error {
255247 if (typeError.diagnoseUnderlyingReason (handleModularizationError)) {
@@ -266,6 +258,16 @@ llvm::Error ModuleFile::diagnoseFatal(llvm::Error error) const {
266258 return llvm::make_error<ExtensionError>(std::move (extError));
267259 });
268260
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+
269271 // If no error is left, it was reported as a diagnostic. There's no
270272 // need to crash.
271273 if (!error)
@@ -1540,7 +1542,7 @@ ModuleFile::getSubstitutionMapChecked(serialization::SubstitutionMapID id) {
15401542 for (auto typeID : replacementTypeIDs) {
15411543 auto typeOrError = getTypeChecked (typeID);
15421544 if (!typeOrError) {
1543- consumeError (typeOrError.takeError ());
1545+ diagnoseAndConsumeError (typeOrError.takeError ());
15441546 continue ;
15451547 }
15461548 replacementTypes.push_back (typeOrError.get ());
@@ -1795,7 +1797,7 @@ ModuleFile::resolveCrossReference(ModuleID MID, uint32_t pathLen) {
17951797 if (maybeType.errorIsA <FatalDeserializationError>())
17961798 return maybeType.takeError ();
17971799 // FIXME: Don't throw away the inner error's information.
1798- consumeError (maybeType.takeError ());
1800+ diagnoseAndConsumeError (maybeType.takeError ());
17991801 return llvm::make_error<XRefError>(" couldn't decode type" ,
18001802 pathTrace, name);
18011803 }
@@ -2165,7 +2167,7 @@ ModuleFile::resolveCrossReference(ModuleID MID, uint32_t pathLen) {
21652167 return maybeType.takeError ();
21662168
21672169 // FIXME: Don't throw away the inner error's information.
2168- consumeError (maybeType.takeError ());
2170+ diagnoseAndConsumeError (maybeType.takeError ());
21692171 return llvm::make_error<XRefError>(" couldn't decode type" ,
21702172 pathTrace, memberName);
21712173 }
@@ -3004,7 +3006,7 @@ class DeclDeserializer {
30043006
30053007 auto maybeType = MF.getTypeChecked (typeID);
30063008 if (!maybeType) {
3007- llvm::consumeError (maybeType.takeError ());
3009+ MF. diagnoseAndConsumeError (maybeType.takeError ());
30083010 continue ;
30093011 }
30103012 inheritedTypes.push_back (
@@ -3330,10 +3332,10 @@ class DeclDeserializer {
33303332 return overriddenOrError.takeError ();
33313333 } else if (MF.allowCompilerErrors ()) {
33323334 // Drop overriding relationship when allowing errors.
3333- llvm::consumeError (overriddenOrError.takeError ());
3335+ MF. diagnoseAndConsumeError (overriddenOrError.takeError ());
33343336 overridden = nullptr ;
33353337 } else {
3336- llvm::consumeError (overriddenOrError.takeError ());
3338+ MF. diagnoseAndConsumeError (overriddenOrError.takeError ());
33373339 if (overriddenAffectsABI || !ctx.LangOpts .EnableDeserializationRecovery ) {
33383340 return llvm::make_error<OverrideError>(name, errorFlags,
33393341 numVTableEntries);
@@ -3477,7 +3479,7 @@ class DeclDeserializer {
34773479 if (overridden.errorIsA <FatalDeserializationError>())
34783480 return overridden.takeError ();
34793481
3480- llvm::consumeError (overridden.takeError ());
3482+ MF. diagnoseAndConsumeError (overridden.takeError ());
34813483
34823484 return llvm::make_error<OverrideError>(
34833485 name, getErrorFlags (), numVTableEntries);
@@ -3589,7 +3591,7 @@ class DeclDeserializer {
35893591
35903592 // FIXME: This is actually wrong. We can't just drop stored properties
35913593 // willy-nilly if the struct is @frozen.
3592- consumeError (backingDecl.takeError ());
3594+ MF. diagnoseAndConsumeError (backingDecl.takeError ());
35933595 return var;
35943596 }
35953597
@@ -3806,15 +3808,15 @@ class DeclDeserializer {
38063808 overridden = overriddenOrError.get ();
38073809 } else {
38083810 if (overriddenAffectsABI || !ctx.LangOpts .EnableDeserializationRecovery ) {
3809- llvm::consumeError (overriddenOrError.takeError ());
3811+ MF. diagnoseAndConsumeError (overriddenOrError.takeError ());
38103812 return llvm::make_error<OverrideError>(name, errorFlags,
38113813 numVTableEntries);
38123814 }
38133815 // Pass through deserialization errors.
38143816 if (overriddenOrError.errorIsA <FatalDeserializationError>())
38153817 return overriddenOrError.takeError ();
38163818
3817- llvm::consumeError (overriddenOrError.takeError ());
3819+ MF. diagnoseAndConsumeError (overriddenOrError.takeError ());
38183820 overridden = nullptr ;
38193821 }
38203822
@@ -4079,7 +4081,7 @@ class DeclDeserializer {
40794081 if (!subMapOrError) {
40804082 // If the underlying type references internal details, ignore it.
40814083 auto unconsumedError =
4082- consumeErrorIfXRefNonLoadedModule (subMapOrError.takeError ());
4084+ MF. consumeExpectedError (subMapOrError.takeError ());
40834085 if (unconsumedError)
40844086 return std::move (unconsumedError);
40854087 } else {
@@ -4136,7 +4138,7 @@ class DeclDeserializer {
41364138 return pattern.takeError ();
41374139
41384140 // Silently drop the pattern...
4139- llvm::consumeError (pattern.takeError ());
4141+ MF. diagnoseAndConsumeError (pattern.takeError ());
41404142 // ...but continue to read any further patterns we're expecting.
41414143 continue ;
41424144 }
@@ -4654,7 +4656,7 @@ class DeclDeserializer {
46544656 // Pass through deserialization errors.
46554657 if (overridden.errorIsA <FatalDeserializationError>())
46564658 return overridden.takeError ();
4657- llvm::consumeError (overridden.takeError ());
4659+ MF. diagnoseAndConsumeError (overridden.takeError ());
46584660
46594661 DeclDeserializationError::Flags errorFlags;
46604662 return llvm::make_error<OverrideError>(
@@ -5178,7 +5180,7 @@ llvm::Error DeclDeserializer::deserializeCustomAttrs() {
51785180 // is safe to drop when it can't be deserialized.
51795181 // rdar://problem/56599179. When allowing errors we're doing a best
51805182 // effort to create a module, so ignore in that case as well.
5181- consumeError (deserialized.takeError ());
5183+ MF. diagnoseAndConsumeError (deserialized.takeError ());
51825184 } else
51835185 return deserialized.takeError ();
51845186 } else if (!deserialized.get () && MF.allowCompilerErrors ()) {
@@ -6127,7 +6129,7 @@ Expected<Type> DESERIALIZE_TYPE(NAME_ALIAS_TYPE)(
61276129
61286130 // We're going to recover by falling back to the underlying type, so
61296131 // just ignore the error.
6130- llvm::consumeError (aliasOrError.takeError ());
6132+ MF. diagnoseAndConsumeError (aliasOrError.takeError ());
61316133 }
61326134
61336135 if (!alias || !alias->getDeclaredInterfaceType ()->isEqual (underlyingType)) {
@@ -7364,13 +7366,16 @@ Decl *handleErrorAndSupplyMissingProtoMember(ASTContext &context,
73647366 return suppliedMissingMember;
73657367}
73667368
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));
73697372 return nullptr ;
73707373}
73717374
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 {
73747379 // Drop the member if it had a problem.
73757380 // FIXME: Handle overridable members in class extensions too, someday.
73767381 if (auto *containingClass = dyn_cast<ClassDecl>(container)) {
@@ -7444,14 +7449,14 @@ void ModuleFile::loadAllMembers(Decl *container, uint64_t contextData) {
74447449 }
74457450}
74467451
7447- static llvm::Error consumeErrorIfXRefNonLoadedModule (llvm::Error &&error) {
7452+ llvm::Error ModuleFile::consumeExpectedError (llvm::Error &&error) {
74487453 // Missing module errors are most likely caused by an
74497454 // implementation-only import hiding types and decls.
74507455 // rdar://problem/60291019
74517456 if (error.isA <XRefNonLoadedModuleError>() ||
74527457 error.isA <UnsafeDeserializationError>() ||
74537458 error.isA <ModularizationError>()) {
7454- consumeError (std::move (error));
7459+ diagnoseAndConsumeError (std::move (error));
74557460 return llvm::Error::success ();
74567461 }
74577462
@@ -7465,7 +7470,7 @@ static llvm::Error consumeErrorIfXRefNonLoadedModule(llvm::Error &&error) {
74657470 if (TE->underlyingReasonIsA <XRefNonLoadedModuleError>() ||
74667471 TE->underlyingReasonIsA <UnsafeDeserializationError>() ||
74677472 TE->underlyingReasonIsA <ModularizationError>()) {
7468- consumeError (std::move (errorInfo));
7473+ diagnoseAndConsumeError (std::move (errorInfo));
74697474 return llvm::Error::success ();
74707475 }
74717476
@@ -7475,6 +7480,19 @@ static llvm::Error consumeErrorIfXRefNonLoadedModule(llvm::Error &&error) {
74757480 return std::move (error);
74767481}
74777482
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+
74787496namespace {
74797497class LazyConformanceLoaderInfo final
74807498 : llvm::TrailingObjects<LazyConformanceLoaderInfo,
@@ -7538,12 +7556,12 @@ ModuleFile::loadAllConformances(const Decl *D, uint64_t contextData,
75387556
75397557 if (!conformance) {
75407558 auto unconsumedError =
7541- consumeErrorIfXRefNonLoadedModule (conformance.takeError ());
7559+ consumeExpectedError (conformance.takeError ());
75427560 if (unconsumedError) {
75437561 // Ignore if allowing errors, it's just doing a best effort to produce
75447562 // *some* module anyway.
75457563 if (allowCompilerErrors ())
7546- consumeError (std::move (unconsumedError));
7564+ diagnoseAndConsumeError (std::move (unconsumedError));
75477565 else
75487566 fatal (std::move (unconsumedError));
75497567 }
@@ -7633,7 +7651,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
76337651 if (maybeConformance) {
76347652 reqConformances.push_back (maybeConformance.get ());
76357653 } else if (allowCompilerErrors ()) {
7636- consumeError (maybeConformance.takeError ());
7654+ diagnoseAndConsumeError (maybeConformance.takeError ());
76377655 reqConformances.push_back (ProtocolConformanceRef::forInvalid ());
76387656 } else {
76397657 fatal (maybeConformance.takeError ());
@@ -7701,7 +7719,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
77017719 second = *secondOrError;
77027720 } else if (getContext ().LangOpts .EnableDeserializationRecovery ) {
77037721 second = ErrorType::get (getContext ());
7704- consumeError (secondOrError.takeError ());
7722+ diagnoseAndConsumeError (secondOrError.takeError ());
77057723 } else {
77067724 fatal (secondOrError.takeError ());
77077725 }
@@ -7711,7 +7729,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
77117729 third = cast_or_null<TypeDecl>(*thirdOrError);
77127730 } else if (getContext ().LangOpts .EnableDeserializationRecovery ) {
77137731 third = nullptr ;
7714- consumeError (thirdOrError.takeError ());
7732+ diagnoseAndConsumeError (thirdOrError.takeError ());
77157733 } else {
77167734 fatal (thirdOrError.takeError ());
77177735 }
@@ -7752,7 +7770,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
77527770 if (deserializedReq) {
77537771 req = cast_or_null<ValueDecl>(*deserializedReq);
77547772 } else if (getContext ().LangOpts .EnableDeserializationRecovery ) {
7755- consumeError (deserializedReq.takeError ());
7773+ diagnoseAndConsumeError (deserializedReq.takeError ());
77567774 req = nullptr ;
77577775 needToFillInOpaqueValueWitnesses = true ;
77587776 } else {
@@ -7769,7 +7787,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
77697787 // In that case, we want the conformance to still be available, but
77707788 // we can't make use of the relationship to the underlying decl.
77717789 } else if (getContext ().LangOpts .EnableDeserializationRecovery ) {
7772- consumeError (deserializedWitness.takeError ());
7790+ diagnoseAndConsumeError (deserializedWitness.takeError ());
77737791 isOpaque = true ;
77747792 witness = nullptr ;
77757793 } else {
@@ -7802,7 +7820,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
78027820 if (witnessSubstitutions.errorIsA <XRefNonLoadedModuleError>() ||
78037821 witnessSubstitutions.errorIsA <UnsafeDeserializationError>() ||
78047822 allowCompilerErrors ()) {
7805- consumeError (witnessSubstitutions.takeError ());
7823+ diagnoseAndConsumeError (witnessSubstitutions.takeError ());
78067824 isOpaque = true ;
78077825 }
78087826 else
0 commit comments