@@ -176,60 +176,65 @@ class PrintMetadataSource
176176
177177std::optional<llvm::VersionTuple>
178178getRuntimeVersionThatSupportsDemanglingType (CanType type) {
179- // The Swift 6.0 runtime is the first version able to demangle types
180- // that involve typed throws.
181- bool usesTypedThrows = type.findIf ([](CanType t) -> bool {
182- if (auto fn = dyn_cast<AnyFunctionType>(t)) {
183- if (!fn.getThrownError ().isNull ())
184- return true ;
185- }
179+ enum VersionRequirement {
180+ None,
181+ Swift_5_2,
182+ Swift_5_5,
183+ Swift_6_0,
184+
185+ // Short-circuit if we find this requirement.
186+ Latest = Swift_6_0
187+ };
186188
189+ VersionRequirement latestRequirement = None;
190+ auto addRequirement = [&](VersionRequirement req) -> bool {
191+ if (req > latestRequirement) {
192+ latestRequirement = req;
193+ return req == Latest;
194+ }
187195 return false ;
188- });
189- if (usesTypedThrows) {
190- return llvm::VersionTuple (6 , 0 );
191- }
196+ };
192197
193- // The Swift 5.5 runtime is the first version able to demangle types
194- // related to concurrency.
195- bool needsConcurrency = type.findIf ([](CanType t) -> bool {
198+ (void ) type.findIf ([&](CanType t) -> bool {
196199 if (auto fn = dyn_cast<AnyFunctionType>(t)) {
197- if (fn->isAsync () || fn->isSendable () || fn->hasGlobalActor ())
198- return true ;
199-
200- for (const auto ¶m : fn->getParams ()) {
201- if (param.isIsolated ())
202- return true ;
203- }
200+ // The Swift 6.0 runtime is the first version able to demangle types
201+ // that involve typed throws or @isolated(any), or for that matter
202+ // represent them at all at runtime.
203+ if (!fn.getThrownError ().isNull () || fn->getIsolation ().isErased ())
204+ return addRequirement (Swift_6_0);
205+
206+ // The Swift 5.5 runtime is the first version able to demangle types
207+ // related to concurrency.
208+ if (fn->isAsync () || fn->isSendable () ||
209+ !fn->getIsolation ().isNonIsolated ())
210+ return addRequirement (Swift_5_5);
204211
205212 return false ;
206213 }
214+
215+ if (auto opaqueArchetype = dyn_cast<OpaqueTypeArchetypeType>(t)) {
216+ // Associated types of opaque types weren't mangled in a usable
217+ // form by the Swift 5.1 runtime, so we needed to add a new
218+ // mangling in 5.2.
219+ if (opaqueArchetype->getInterfaceType ()->is <DependentMemberType>())
220+ return addRequirement (Swift_5_2);
221+
222+ // Although opaque types in general were only added in Swift 5.1,
223+ // declarations that use them are already covered by availability
224+ // guards, so we don't need to limit availability of mangled names
225+ // involving them.
226+ }
227+
207228 return false ;
208229 });
209- if (needsConcurrency) {
210- return llvm::VersionTuple (5 , 5 );
211- }
212230
213- // Associated types of opaque types weren't mangled in a usable form by the
214- // Swift 5.1 runtime, so we needed to add a new mangling in 5.2.
215- if (type->hasOpaqueArchetype ()) {
216- auto hasOpaqueAssocType = type.findIf ([](CanType t) -> bool {
217- if (auto a = dyn_cast<ArchetypeType>(t)) {
218- return isa<OpaqueTypeArchetypeType>(a) &&
219- a->getInterfaceType ()->is <DependentMemberType>();
220- }
221- return false ;
222- });
223-
224- if (hasOpaqueAssocType)
225- return llvm::VersionTuple (5 , 2 );
226- // Although opaque types in general were only added in Swift 5.1,
227- // declarations that use them are already covered by availability
228- // guards, so we don't need to limit availability of mangled names
229- // involving them.
231+ switch (latestRequirement) {
232+ case Swift_6_0: return llvm::VersionTuple (6 , 0 );
233+ case Swift_5_5: return llvm::VersionTuple (5 , 5 );
234+ case Swift_5_2: return llvm::VersionTuple (5 , 2 );
235+ case None: return std::nullopt ;
230236 }
231-
232- return std::nullopt ;
237+ llvm_unreachable (" bad kind" );
233238}
234239
235240// Produce a fallback mangled type name that uses an open-coded callback
0 commit comments