Skip to content

Assorted fixes for runtime metadata mangling and demangling #78729

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions include/swift/AST/RuntimeVersions.def
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ RUNTIME_VERSION(
PLATFORM(macOS, (14, 4, 0))
PLATFORM(iOS, (17, 4, 0))
PLATFORM(watchOS, (10, 4, 0))
PLATFORM(xrOS, (1, 0, 0))
PLATFORM(visionOS,(1, 0, 0))
)

END_MAJOR_VERSION(5)
Expand All @@ -147,7 +147,7 @@ RUNTIME_VERSION(
PLATFORM(macOS, (15, 0, 0))
PLATFORM(iOS, (18, 0, 0))
PLATFORM(watchOS, (11, 0, 0))
PLATFORM(xrOS, (2, 0, 0))
PLATFORM(visionOS,(2, 0, 0))
)

RUNTIME_VERSION(
Expand Down
195 changes: 195 additions & 0 deletions include/swift/Basic/Pack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
//===--- Pack.h - Helpers for wording with class template packs -*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_BASIC_PACKS_H
#define SWIFT_BASIC_PACKS_H

namespace swift {
namespace packs {

/// A pack of types.
template <class...>
struct Pack;

/// A trait indicating whether the given type is a specialization
/// of Pack<...>.
template <class>
struct IsPack {
static constexpr bool value = false;
};

template <class... Components>
struct IsPack<Pack<Components...>> {
static constexpr bool value = true;
};

/// Transform a variadic list of types using the given transform, a class
/// template which is expected to define a `result` type providing the
/// result of the transform.
///
/// template <class Arg, class Component>
/// class Transform {
/// using result = ...;
/// };
///
/// In principle, this would be cleaner as a member template, but that
/// works out poorly because in practice the member template must be
/// partially specialized in order to destructure it.
template <template <class, class> class Transform,
class TransformArg, class... Values>
struct PackMapComponents {
using result = Pack<typename Transform<TransformArg, Values>::result...>;
};

/// Transform the components of a pack using the given transform, a class
/// template which is expected to define a `result` type providing the
/// result of the transform.
///
/// template <class Arg, class Component>
/// class Transform {
/// using result = ...;
/// };
template <template <class, class> class Transform, class TransformArg,
class P>
struct PackMap;

template <template <class, class> class Transform, class TransformArg,
class... Components>
struct PackMap<Transform, TransformArg, Pack<Components...>>
: PackMapComponents<Transform, TransformArg, Components...> {};

/// Concatenate the components of a variadic list of packs.
template <class... Packs>
struct PackConcat;

template <>
struct PackConcat<> {
using result = Pack<>;
};

template <class First>
struct PackConcat<First> {
static_assert(IsPack<First>::value, "argument is not a pack");
using result = First;
};

template <class... FirstComponents, class... SecondComponents>
struct PackConcat<Pack<FirstComponents...>, Pack<SecondComponents...>> {
using result = Pack<FirstComponents..., SecondComponents...>;
};

template <class Head, class... Tail>
struct PackConcat<Head, Tail...>
: PackConcat<Head, typename PackConcat<Tail...>::result> {};

/// Flatten a pack of packs by concatenating their components.
template <class>
struct PackFlatten;

template <class... PackComponents>
struct PackFlatten<Pack<PackComponents...>>
: PackConcat<PackComponents...> {};

/// Apply the given pack-producing transform to each component of a pack,
/// then concatenate the results.
///
/// For example, if we start with Pack<A, B, C>, and the transform turns:
/// A => Pack<X, Y>
/// B => Pack<>
/// C => Pack<Z>
/// then the result will be Pack<X, Y, Z>.
template <template <class, class> class Transform, class TransformArg, class P>
struct PackFlatMap
: PackFlatten<typename PackMap<Transform, TransformArg, P>::result> {};

/// Reverse a variadic list of types.
template <class... PackComponents>
struct PackReverseComponents;

template <>
struct PackReverseComponents<> {
using result = Pack<>;
};

template <class Head>
struct PackReverseComponents<Head> {
using result = Pack<Head>;
};

template <class Head, class... Tail>
struct PackReverseComponents<Head, Tail...>
: PackConcat<typename PackReverseComponents<Tail...>::result,
Pack<Head>> {};


/// Reverse a pack.
template <class>
struct PackReverse;

template <class... PackComponents>
struct PackReverse<Pack<PackComponents...>>
: PackReverseComponents<PackComponents...> {};

/// Determine whether the given pack is transitively ordered according to
/// the given predicate:
///
/// template <class First, class Second>
/// struct IsOrdered {
/// static constexpr bool value;
/// };
template <template <class, class> class IsOrdered,
class... Components>
struct PackComponentsAreOrdered;

template <template <class, class> class IsOrdered>
struct PackComponentsAreOrdered<IsOrdered> {
static constexpr bool value = true;
};

template <template <class, class> class IsOrdered,
class A>
struct PackComponentsAreOrdered<IsOrdered, A> {
static constexpr bool value = true;
};

template <template <class, class> class IsOrdered,
class A, class B>
struct PackComponentsAreOrdered<IsOrdered, A, B> : IsOrdered<A, B> {};

template <template <class, class> class IsOrdered,
class A, class B, class... C>
struct PackComponentsAreOrdered<IsOrdered, A, B, C...> {
static constexpr bool value =
IsOrdered<A, B>::value &&
PackComponentsAreOrdered<IsOrdered, B, C...>::value;
};

/// Determine whether the given pack is well-ordered according to the given
/// predicate:
///
/// template <class First, class Second>
/// struct IsOrdered {
/// static constexpr bool value;
/// };
template <template <class, class> class IsOrdered,
class P>
struct PackIsOrdered;

template <template <class, class> class IsOrdered,
class... Components>
struct PackIsOrdered<IsOrdered, Pack<Components...>>
: PackComponentsAreOrdered<IsOrdered, Components...> {};

} // end namespace packs
} // end namespace swift

#endif
4 changes: 2 additions & 2 deletions lib/AST/Availability.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,7 @@ AvailabilityRange ASTContext::getSwiftAvailability(unsigned major,
#define PLATFORM_TEST_macOS target.isMacOSX()
#define PLATFORM_TEST_iOS target.isiOS()
#define PLATFORM_TEST_watchOS target.isWatchOS()
#define PLATFORM_TEST_xrOS target.isXROS()
#define PLATFORM_TEST_visionOS target.isXROS()

#define _SECOND(A, B) B
#define SECOND(T) _SECOND T
Expand All @@ -893,7 +893,7 @@ AvailabilityRange ASTContext::getSwiftAvailability(unsigned major,
#undef PLATFORM_TEST_macOS
#undef PLATFORM_TEST_iOS
#undef PLATFORM_TEST_watchOS
#undef PLATFORM_TEST_xrOS
#undef PLATFORM_TEST_visionOS
#undef _SECOND
#undef SECOND

Expand Down
Loading