diff --git a/CHANGELOG.md b/CHANGELOG.md index d7037b47e..b49e47641 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +**Features** + +- Updated libswift demangle to v6.3.1. ([#980](https://github.com/getsentry/symbolic/pull/980)) + ## 13.0.0 **Features** diff --git a/symbolic-demangle/build.rs b/symbolic-demangle/build.rs index 1ec58b0a7..ef354b003 100644 --- a/symbolic-demangle/build.rs +++ b/symbolic-demangle/build.rs @@ -7,14 +7,11 @@ fn main() { .files(&[ "src/swiftdemangle.cpp", "vendor/swift/lib/Demangling/Context.cpp", - "vendor/swift/lib/Demangling/CrashReporter.cpp", "vendor/swift/lib/Demangling/Demangler.cpp", "vendor/swift/lib/Demangling/Errors.cpp", "vendor/swift/lib/Demangling/ManglingUtils.cpp", "vendor/swift/lib/Demangling/NodeDumper.cpp", "vendor/swift/lib/Demangling/NodePrinter.cpp", - // "vendor/swift/lib/Demangling/OldDemangler.cpp", - // "vendor/swift/lib/Demangling/OldRemangler.cpp", "vendor/swift/lib/Demangling/Punycode.cpp", "vendor/swift/lib/Demangling/Remangler.cpp", ]) diff --git a/symbolic-demangle/tests/test_swift.rs b/symbolic-demangle/tests/test_swift.rs index d3994accc..082c43a14 100644 --- a/symbolic-demangle/tests/test_swift.rs +++ b/symbolic-demangle/tests/test_swift.rs @@ -297,6 +297,12 @@ fn test_demangle_swift_no_args() { // Swift 6.0.3 "$ss27withTaskCancellationHandler9operation8onCancel9isolationxxyYaKXE_yyYbXEScA_pSgYitYaKlFTwb" => "withTaskCancellationHandler", - "$s11Supercharge2AXO7ElementPAAE8elements33_35EDDAA799FBB5B74D2F426690B0D99DLL3for2asSayqd__GSo28NSAccessibilityAttributeNamea_qd__mtSo7AXErrorVYKAcDRd__lFAC3AppC_AC6WindowCTgm5" => "specialized AX.Element.elements", + + // Swift 6.1.0 + "$sTB" => "$sTB", + + // Swift 6.3.1 + "$s12SharedDomain7ServiceC06streamC0_4bodyACXDScSyxG_yxYaYbKYCcts8SendableRzlFZyycAA06StreamC0CYbcfu_yycfu0_Tm" => "implicit closure #2 in implicit closure #1 in static Service.streamService", + "$s18OrderedCollections0A10DictionaryV20uniqueKeysWithValuesACyxq_Gqd___tcSTRd__x_q_t7ElementRtd__lufC6TaggedAHVy8SportsUI0J23ParticipantRowViewModelVSSG_ALs15LazyMapSequenceVySayALGAM_ALtGTt0g5Tf4g_n" => "specialized OrderedDictionary.init", }); } diff --git a/symbolic-demangle/vendor/swift/1-arguments.patch b/symbolic-demangle/vendor/swift/1-arguments.patch index 5209fc4c2..f01f37bfe 100644 --- a/symbolic-demangle/vendor/swift/1-arguments.patch +++ b/symbolic-demangle/vendor/swift/1-arguments.patch @@ -1,14 +1,14 @@ -commit 80e772078494a73f2fbb5e385de2092e6057d913 +commit 7dddbd0e4b5ba23e640c1a4d531dc148f6d18aca Author: David Herberth -Date: Thu Jan 9 10:54:28 2025 +0100 +Date: Mon May 18 14:50:49 2026 +0200 - apply patch + patch diff --git a/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangle.h b/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangle.h -index f66dd7fd..940c3652 100644 +index 7a1b6c4a..3df6b0b9 100644 --- a/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangle.h +++ b/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangle.h -@@ -58,6 +58,7 @@ struct DemangleOptions { +@@ -62,6 +62,7 @@ struct DemangleOptions { bool ShortenArchetype = false; bool ShowPrivateDiscriminators = true; bool ShowFunctionArgumentTypes = true; @@ -16,7 +16,7 @@ index f66dd7fd..940c3652 100644 bool DisplayDebuggerGeneratedModule = true; bool DisplayStdlibModule = true; bool DisplayObjCModule = true; -@@ -90,6 +91,7 @@ struct DemangleOptions { +@@ -94,6 +95,7 @@ struct DemangleOptions { Opt.ShortenArchetype = true; Opt.ShowPrivateDiscriminators = false; Opt.ShowFunctionArgumentTypes = false; @@ -25,32 +25,21 @@ index f66dd7fd..940c3652 100644 return Opt; }; diff --git a/symbolic-demangle/vendor/swift/lib/Demangling/NodePrinter.cpp b/symbolic-demangle/vendor/swift/lib/Demangling/NodePrinter.cpp -index 6c309bbf..5b251e8d 100644 +index 66840b56..7430062a 100644 --- a/symbolic-demangle/vendor/swift/lib/Demangling/NodePrinter.cpp +++ b/symbolic-demangle/vendor/swift/lib/Demangling/NodePrinter.cpp -@@ -955,10 +955,11 @@ private: - if (isSendable) - Printer << "@Sendable "; - -- printFunctionParameters(LabelList, node->getChild(argIndex), depth, -- Options.ShowFunctionArgumentTypes); -+ if (Options.ShowFunctionArgumentTypes) { -+ printFunctionParameters(LabelList, node->getChild(argIndex), depth, true); -+ } - -- if (!Options.ShowFunctionArgumentTypes) -+ if (!Options.ShowFunctionReturnType) - return; - - if (isAsync) -diff --git a/symbolic-demangle/vendor/swift/lib/Demangling/Demangler.cpp b/symbolic-demangle/vendor/swift/lib/Demangling/Demangler.cpp -index 6c309bbf..5b251e8d 100644 ---- a/symbolic-demangle/vendor/swift/lib/Demangling/Demangler.cpp -+++ b/symbolic-demangle/vendor/swift/lib/Demangling/Demangler.cpp -@@ -3423,7 +3423,6 @@ NodePointer Demangler::demangleSpecAttributes(Node::Kind SpecKind) { +@@ -945,10 +945,11 @@ void NodePrinter::printFunctionType(NodePointer LabelList, NodePointer node, + if (isSendable) + Printer << "@Sendable "; - int PassID = (int)nextChar() - '0'; - if (PassID < 0 || PassID >= MAX_SPECIALIZATION_PASS) { -- assert(false && "unexpected pass id"); - return nullptr; - } +- printFunctionParameters(LabelList, node->getChild(argIndex), depth, +- Options.ShowFunctionArgumentTypes); ++ if (Options.ShowFunctionArgumentTypes) { ++ printFunctionParameters(LabelList, node->getChild(argIndex), depth, true); ++ } + +- if (!Options.ShowFunctionArgumentTypes) ++ if (!Options.ShowFunctionReturnType) + return; + + if (isAsync) diff --git a/symbolic-demangle/vendor/swift/README.md b/symbolic-demangle/vendor/swift/README.md index 4bd7fddaf..95a944809 100644 --- a/symbolic-demangle/vendor/swift/README.md +++ b/symbolic-demangle/vendor/swift/README.md @@ -3,7 +3,7 @@ This folder contains a vendored subset of the [Swift Programming Language]. The Swift library is reduced to the demangler only to reduce the size of this package. -The current version is **Swift 5.5.1**. +The current version is **Swift 6.3.1**. ## Sentry Modifications @@ -21,15 +21,15 @@ patch is maintained in `1-arguments.patch`. ``` $ git clone https://github.com/apple/swift.git ``` - 3. Check out dependencies: - ``` - $ ./swift/utils/update-checkout --clone - ``` - 4. Check out the release branch of the latest release: + 3. Check out the release branch of the latest release: ``` $ cd swift $ git checkout swift-5.5.1-RELEASE ``` + 4. Check out dependencies: + ``` + $ ./utils/update-checkout --clone + ``` 5. Build the complete swift project (be very patient, this may take long): ``` $ ./utils/build-script --skip-build diff --git a/symbolic-demangle/vendor/swift/include/llvm/ADT/DenseMapInfo.h b/symbolic-demangle/vendor/swift/include/llvm/ADT/DenseMapInfo.h index 07c37e353..b850223c9 100644 --- a/symbolic-demangle/vendor/swift/include/llvm/ADT/DenseMapInfo.h +++ b/symbolic-demangle/vendor/swift/include/llvm/ADT/DenseMapInfo.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -320,6 +321,28 @@ struct DenseMapInfo>> { static bool isEqual(const Enum &LHS, const Enum &RHS) { return LHS == RHS; } }; + +template struct DenseMapInfo> { + using Optional = std::optional; + using Info = DenseMapInfo; + + static inline Optional getEmptyKey() { return {Info::getEmptyKey()}; } + + static inline Optional getTombstoneKey() { return {Info::getTombstoneKey()}; } + + static unsigned getHashValue(const Optional &OptionalVal) { + return detail::combineHashValue( + OptionalVal.has_value(), + Info::getHashValue(OptionalVal.value_or(Info::getEmptyKey()))); + } + + static bool isEqual(const Optional &LHS, const Optional &RHS) { + if (LHS && RHS) { + return Info::isEqual(LHS.value(), RHS.value()); + } + return !LHS && !RHS; + } +}; } // end namespace llvm #endif // LLVM_ADT_DENSEMAPINFO_H diff --git a/symbolic-demangle/vendor/swift/include/llvm/ADT/Hashing.h b/symbolic-demangle/vendor/swift/include/llvm/ADT/Hashing.h index a5477362a..2bebff2cb 100644 --- a/symbolic-demangle/vendor/swift/include/llvm/ADT/Hashing.h +++ b/symbolic-demangle/vendor/swift/include/llvm/ADT/Hashing.h @@ -44,6 +44,7 @@ #ifndef LLVM_ADT_HASHING_H #define LLVM_ADT_HASHING_H +#include "llvm/ADT/ADL.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/SwapByteOrder.h" @@ -151,7 +152,7 @@ namespace detail { inline uint64_t fetch64(const char *p) { uint64_t result; - memcpy(&result, p, sizeof(result)); + std::memcpy(&result, p, sizeof(result)); if (sys::IsBigEndianHost) sys::swapByteOrder(result); return result; @@ -159,7 +160,7 @@ inline uint64_t fetch64(const char *p) { inline uint32_t fetch32(const char *p) { uint32_t result; - memcpy(&result, p, sizeof(result)); + std::memcpy(&result, p, sizeof(result)); if (sys::IsBigEndianHost) sys::swapByteOrder(result); return result; @@ -328,7 +329,7 @@ struct hash_state { /// This variable can be set using the \see llvm::set_fixed_execution_seed /// function. See that function for details. Do not, under any circumstances, /// set or read this variable. -extern uint64_t fixed_seed_override; +LLVM_ABI extern uint64_t fixed_seed_override; inline uint64_t get_execution_seed() { // FIXME: This needs to be a per-execution seed. This is just a placeholder @@ -401,7 +402,7 @@ bool store_and_advance(char *&buffer_ptr, char *buffer_end, const T& value, if (buffer_ptr + store_size > buffer_end) return false; const char *value_data = reinterpret_cast(&value); - memcpy(buffer_ptr, value_data + offset, store_size); + std::memcpy(buffer_ptr, value_data + offset, store_size); buffer_ptr += store_size; return true; } @@ -492,6 +493,10 @@ hash_code hash_combine_range(InputIteratorT first, InputIteratorT last) { return ::llvm::hashing::detail::hash_combine_range_impl(first, last); } +// A wrapper for hash_combine_range above. +template hash_code hash_combine_range(RangeT &&R) { + return hash_combine_range(adl_begin(R), adl_end(R)); +} // Implementation details for hash_combine. namespace hashing { @@ -531,7 +536,7 @@ struct hash_combine_recursive_helper { // with the variadic combine because that formation can have varying // argument types. size_t partial_store_size = buffer_end - buffer_ptr; - memcpy(buffer_ptr, &data, partial_store_size); + std::memcpy(buffer_ptr, &data, partial_store_size); // If the store fails, our buffer is full and ready to hash. We have to // either initialize the hash state (on the first full buffer) or mix @@ -667,7 +672,7 @@ template hash_code hash_value(const std::tuple &arg) { // infrastructure is available. template hash_code hash_value(const std::basic_string &arg) { - return hash_combine_range(arg.begin(), arg.end()); + return hash_combine_range(arg); } template hash_code hash_value(const std::optional &arg) { diff --git a/symbolic-demangle/vendor/swift/include/llvm/ADT/PointerIntPair.h b/symbolic-demangle/vendor/swift/include/llvm/ADT/PointerIntPair.h new file mode 100644 index 000000000..9cfc65846 --- /dev/null +++ b/symbolic-demangle/vendor/swift/include/llvm/ADT/PointerIntPair.h @@ -0,0 +1,293 @@ +//===- llvm/ADT/PointerIntPair.h - Pair for pointer and int -----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file defines the PointerIntPair class. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_POINTERINTPAIR_H +#define LLVM_ADT_POINTERINTPAIR_H + +#include "llvm/Support/Compiler.h" +#include "llvm/Support/PointerLikeTypeTraits.h" +#include "llvm/Support/type_traits.h" +#include +#include +#include +#include + +namespace llvm { + +namespace detail { +template struct PunnedPointer { + static_assert(sizeof(Ptr) == sizeof(intptr_t), ""); + + // Asserts that allow us to let the compiler implement the destructor and + // copy/move constructors + static_assert(std::is_trivially_destructible::value, ""); + static_assert(std::is_trivially_copy_constructible::value, ""); + static_assert(std::is_trivially_move_constructible::value, ""); + + explicit constexpr PunnedPointer(intptr_t i = 0) { *this = i; } + + constexpr intptr_t asInt() const { + intptr_t R = 0; + std::memcpy(&R, Data, sizeof(R)); + return R; + } + + constexpr operator intptr_t() const { return asInt(); } + + constexpr PunnedPointer &operator=(intptr_t V) { + std::memcpy(Data, &V, sizeof(Data)); + return *this; + } + + Ptr *getPointerAddress() { return reinterpret_cast(Data); } + const Ptr *getPointerAddress() const { return reinterpret_cast(Data); } + +private: + alignas(Ptr) unsigned char Data[sizeof(Ptr)]; +}; +} // namespace detail + +template struct DenseMapInfo; +template +struct PointerIntPairInfo; + +/// PointerIntPair - This class implements a pair of a pointer and small +/// integer. It is designed to represent this in the space required by one +/// pointer by bitmangling the integer into the low part of the pointer. This +/// can only be done for small integers: typically up to 3 bits, but it depends +/// on the number of bits available according to PointerLikeTypeTraits for the +/// type. +/// +/// Note that PointerIntPair always puts the IntVal part in the highest bits +/// possible. For example, PointerIntPair will put the bit for +/// the bool into bit #2, not bit #0, which allows the low two bits to be used +/// for something else. For example, this allows: +/// PointerIntPair, 1, bool> +/// ... and the two bools will land in different bits. +template , + typename Info = PointerIntPairInfo> +class PointerIntPair { + // Used by MSVC visualizer and generally helpful for debugging/visualizing. + using InfoTy = Info; + detail::PunnedPointer Value; + +public: + constexpr PointerIntPair() = default; + + PointerIntPair(PointerTy PtrVal, IntType IntVal) { + setPointerAndInt(PtrVal, IntVal); + } + + explicit PointerIntPair(PointerTy PtrVal) { initWithPointer(PtrVal); } + + PointerTy getPointer() const { return Info::getPointer(Value); } + + IntType getInt() const { return (IntType)Info::getInt(Value); } + + void setPointer(PointerTy PtrVal) & { + Value = Info::updatePointer(Value, PtrVal); + } + + void setInt(IntType IntVal) & { + Value = Info::updateInt(Value, static_cast(IntVal)); + } + + void initWithPointer(PointerTy PtrVal) & { + Value = Info::updatePointer(0, PtrVal); + } + + void setPointerAndInt(PointerTy PtrVal, IntType IntVal) & { + Value = Info::updateInt(Info::updatePointer(0, PtrVal), + static_cast(IntVal)); + } + + PointerTy const *getAddrOfPointer() const { + return const_cast(this)->getAddrOfPointer(); + } + + PointerTy *getAddrOfPointer() { + assert(Value == reinterpret_cast(getPointer()) && + "Can only return the address if IntBits is cleared and " + "PtrTraits doesn't change the pointer"); + return Value.getPointerAddress(); + } + + void *getOpaqueValue() const { + return reinterpret_cast(Value.asInt()); + } + + void setFromOpaqueValue(void *Val) & { + Value = reinterpret_cast(Val); + } + + static PointerIntPair getFromOpaqueValue(void *V) { + PointerIntPair P; + P.setFromOpaqueValue(V); + return P; + } + + // Allow PointerIntPairs to be created from const void * if and only if the + // pointer type could be created from a const void *. + static PointerIntPair getFromOpaqueValue(const void *V) { + (void)PtrTraits::getFromVoidPointer(V); + return getFromOpaqueValue(const_cast(V)); + } + + bool operator==(const PointerIntPair &RHS) const { + return Value == RHS.Value; + } + + bool operator!=(const PointerIntPair &RHS) const { + return Value != RHS.Value; + } + + bool operator<(const PointerIntPair &RHS) const { return Value < RHS.Value; } + bool operator>(const PointerIntPair &RHS) const { return Value > RHS.Value; } + + bool operator<=(const PointerIntPair &RHS) const { + return Value <= RHS.Value; + } + + bool operator>=(const PointerIntPair &RHS) const { + return Value >= RHS.Value; + } +}; + +template +struct PointerIntPairInfo { + static_assert(PtrTraits::NumLowBitsAvailable < + std::numeric_limits::digits, + "cannot use a pointer type that has all bits free"); + static_assert(IntBits <= PtrTraits::NumLowBitsAvailable, + "PointerIntPair with integer size too large for pointer"); + enum MaskAndShiftConstants : uintptr_t { + /// PointerBitMask - The bits that come from the pointer. + PointerBitMask = + ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable) - 1), + + /// IntShift - The number of low bits that we reserve for other uses, and + /// keep zero. + IntShift = (uintptr_t)PtrTraits::NumLowBitsAvailable - IntBits, + + /// IntMask - This is the unshifted mask for valid bits of the int type. + IntMask = (uintptr_t)(((intptr_t)1 << IntBits) - 1), + + // ShiftedIntMask - This is the bits for the integer shifted in place. + ShiftedIntMask = (uintptr_t)(IntMask << IntShift) + }; + + static PointerT getPointer(intptr_t Value) { + return PtrTraits::getFromVoidPointer( + reinterpret_cast(Value & PointerBitMask)); + } + + static intptr_t getInt(intptr_t Value) { + return (Value >> IntShift) & IntMask; + } + + static intptr_t updatePointer(intptr_t OrigValue, PointerT Ptr) { + intptr_t PtrWord = + reinterpret_cast(PtrTraits::getAsVoidPointer(Ptr)); + assert((PtrWord & ~PointerBitMask) == 0 && + "Pointer is not sufficiently aligned"); + // Preserve all low bits, just update the pointer. + return PtrWord | (OrigValue & ~PointerBitMask); + } + + static intptr_t updateInt(intptr_t OrigValue, intptr_t Int) { + assert((Int & ~IntMask) == 0 && "Integer too large for field"); + + // Preserve all bits other than the ones we are updating. + return (OrigValue & ~ShiftedIntMask) | Int << IntShift; + } +}; + +// Provide specialization of DenseMapInfo for PointerIntPair. +template +struct DenseMapInfo, void> { + using Ty = PointerIntPair; + + static Ty getEmptyKey() { + uintptr_t Val = static_cast(-1); + Val <<= PointerLikeTypeTraits::NumLowBitsAvailable; + return Ty::getFromOpaqueValue(reinterpret_cast(Val)); + } + + static Ty getTombstoneKey() { + uintptr_t Val = static_cast(-2); + Val <<= PointerLikeTypeTraits::NumLowBitsAvailable; + return Ty::getFromOpaqueValue(reinterpret_cast(Val)); + } + + static unsigned getHashValue(Ty V) { + uintptr_t IV = reinterpret_cast(V.getOpaqueValue()); + return unsigned(IV) ^ unsigned(IV >> 9); + } + + static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; } +}; + +// Teach SmallPtrSet that PointerIntPair is "basically a pointer". +template +struct PointerLikeTypeTraits< + PointerIntPair> { + static inline void * + getAsVoidPointer(const PointerIntPair &P) { + return P.getOpaqueValue(); + } + + static inline PointerIntPair + getFromVoidPointer(void *P) { + return PointerIntPair::getFromOpaqueValue(P); + } + + static inline PointerIntPair + getFromVoidPointer(const void *P) { + return PointerIntPair::getFromOpaqueValue(P); + } + + static constexpr int NumLowBitsAvailable = + PtrTraits::NumLowBitsAvailable - IntBits; +}; + +// Allow structured bindings on PointerIntPair. +template +decltype(auto) +get(const PointerIntPair &Pair) { + static_assert(I < 2); + if constexpr (I == 0) + return Pair.getPointer(); + else + return Pair.getInt(); +} + +} // end namespace llvm + +namespace std { +template +struct tuple_size< + llvm::PointerIntPair> + : std::integral_constant {}; + +template +struct tuple_element< + I, llvm::PointerIntPair> + : std::conditional {}; +} // namespace std + +#endif // LLVM_ADT_POINTERINTPAIR_H diff --git a/symbolic-demangle/vendor/swift/include/llvm/ADT/STLExtras.h b/symbolic-demangle/vendor/swift/include/llvm/ADT/STLExtras.h index 8f988d01c..45acb75cf 100644 --- a/symbolic-demangle/vendor/swift/include/llvm/ADT/STLExtras.h +++ b/symbolic-demangle/vendor/swift/include/llvm/ADT/STLExtras.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -320,10 +321,19 @@ template class Callable { /// Returns true if the given container only contains a single element. template bool hasSingleElement(ContainerTy &&C) { - auto B = std::begin(C), E = std::end(C); + auto B = adl_begin(C); + auto E = adl_end(C); return B != E && std::next(B) == E; } +/// Asserts that the given container has a single element and returns that +/// element. +template +decltype(auto) getSingleElement(ContainerTy &&C) { + assert(hasSingleElement(C) && "expected container with single element"); + return *adl_begin(C); +} + /// Return a range covering \p RangeOrContainer with the first N elements /// excluded. template auto drop_begin(T &&RangeOrContainer, size_t N = 1) { @@ -375,8 +385,7 @@ inline mapped_iterator map_iterator(ItTy I, FuncTy F) { template auto map_range(ContainerTy &&C, FuncTy F) { - return make_range(map_iterator(std::begin(C), F), - map_iterator(std::end(C), F)); + return make_range(map_iterator(adl_begin(C), F), map_iterator(adl_end(C), F)); } /// A base type of mapped iterator, that is useful for building derived @@ -416,7 +425,8 @@ static constexpr bool HasFreeFunctionRBegin = } // namespace detail // Returns an iterator_range over the given container which iterates in reverse. -template auto reverse(ContainerTy &&C) { +// Does not mutate the container. +template [[nodiscard]] auto reverse(ContainerTy &&C) { if constexpr (detail::HasFreeFunctionRBegin) return make_range(adl_rbegin(C), adl_rend(C)); else @@ -572,11 +582,9 @@ iterator_range, PredicateT>> make_filter_range(RangeT &&Range, PredicateT Pred) { using FilterIteratorT = filter_iterator, PredicateT>; - return make_range( - FilterIteratorT(std::begin(std::forward(Range)), - std::end(std::forward(Range)), Pred), - FilterIteratorT(std::end(std::forward(Range)), - std::end(std::forward(Range)), Pred)); + auto B = adl_begin(Range); + auto E = adl_end(Range); + return make_range(FilterIteratorT(B, E, Pred), FilterIteratorT(E, E, Pred)); } /// A pseudo-iterator adaptor that is designed to implement "early increment" @@ -656,8 +664,8 @@ iterator_range>> make_early_inc_range(RangeT &&Range) { using EarlyIncIteratorT = early_inc_iterator_impl>; - return make_range(EarlyIncIteratorT(std::begin(std::forward(Range))), - EarlyIncIteratorT(std::end(std::forward(Range)))); + return make_range(EarlyIncIteratorT(adl_begin(Range)), + EarlyIncIteratorT(adl_end(Range))); } // Forward declarations required by zip_shortest/zip_equal/zip_first/zip_longest @@ -1023,6 +1031,16 @@ class concat_iterator std::forward_iterator_tag, ValueT> { using BaseT = typename concat_iterator::iterator_facade_base; + static constexpr bool ReturnsByValue = + !(std::is_reference_v())> && ...); + + using reference_type = + typename std::conditional_t; + + using handle_type = + typename std::conditional_t, + ValueT *>; + /// We store both the current and end iterators for each concatenated /// sequence in a tuple of pairs. /// @@ -1065,27 +1083,30 @@ class concat_iterator /// Returns null if the specified iterator is at the end. Otherwise, /// dereferences the iterator and returns the address of the resulting /// reference. - template ValueT *getHelper() const { + template handle_type getHelper() const { auto &Begin = std::get(Begins); auto &End = std::get(Ends); if (Begin == End) - return nullptr; + return {}; - return &*Begin; + if constexpr (ReturnsByValue) + return *Begin; + else + return &*Begin; } /// Finds the first non-end iterator, dereferences, and returns the resulting /// reference. /// /// It is an error to call this with all iterators at the end. - template ValueT &get(std::index_sequence) const { + template reference_type get(std::index_sequence) const { // Build a sequence of functions to get from iterator if possible. - ValueT *(concat_iterator::*GetHelperFns[])() const = { - &concat_iterator::getHelper...}; + handle_type (concat_iterator::*GetHelperFns[])() + const = {&concat_iterator::getHelper...}; // Loop over them, and return the first result we find. for (auto &GetHelperFn : GetHelperFns) - if (ValueT *P = (this->*GetHelperFn)()) + if (auto P = (this->*GetHelperFn)()) return *P; llvm_unreachable("Attempted to get a pointer from an end concat iterator!"); @@ -1097,8 +1118,8 @@ class concat_iterator /// We need the full range to know how to switch between each of the /// iterators. template - explicit concat_iterator(RangeTs &&... Ranges) - : Begins(std::begin(Ranges)...), Ends(std::end(Ranges)...) {} + explicit concat_iterator(RangeTs &&...Ranges) + : Begins(adl_begin(Ranges)...), Ends(adl_end(Ranges)...) {} using BaseT::operator++; @@ -1107,7 +1128,7 @@ class concat_iterator return *this; } - ValueT &operator*() const { + reference_type operator*() const { return get(std::index_sequence_for()); } @@ -1127,13 +1148,12 @@ template class concat_range { public: using iterator = concat_iterator()))...>; + decltype(adl_begin(std::declval()))...>; private: std::tuple Ranges; - template - iterator begin_impl(std::index_sequence) { + template iterator begin_impl(std::index_sequence) { return iterator(std::get(Ranges)...); } template @@ -1141,12 +1161,12 @@ template class concat_range { return iterator(std::get(Ranges)...); } template iterator end_impl(std::index_sequence) { - return iterator(make_range(std::end(std::get(Ranges)), - std::end(std::get(Ranges)))...); + return iterator(make_range(adl_end(std::get(Ranges)), + adl_end(std::get(Ranges)))...); } template iterator end_impl(std::index_sequence) const { - return iterator(make_range(std::end(std::get(Ranges)), - std::end(std::get(Ranges)))...); + return iterator(make_range(adl_end(std::get(Ranges)), + adl_end(std::get(Ranges)))...); } public: @@ -1169,11 +1189,13 @@ template class concat_range { } // end namespace detail -/// Concatenated range across two or more ranges. +/// Returns a concatenated range across two or more ranges. Does not modify the +/// ranges. /// /// The desired value type must be explicitly specified. template -detail::concat_range concat(RangeTs &&... Ranges) { +[[nodiscard]] detail::concat_range +concat(RangeTs &&...Ranges) { static_assert(sizeof...(RangeTs) > 1, "Need more than one range to concatenate!"); return detail::concat_range( @@ -1194,7 +1216,8 @@ class indexed_accessor_iterator return index - rhs.index; } bool operator==(const indexed_accessor_iterator &rhs) const { - return base == rhs.base && index == rhs.index; + assert(base == rhs.base && "incompatible iterators"); + return index == rhs.index; } bool operator<(const indexed_accessor_iterator &rhs) const { assert(base == rhs.base && "incompatible iterators"); @@ -1420,7 +1443,7 @@ template class first_or_second_type { /// Given a container of pairs, return a range over the first elements. template auto make_first_range(ContainerTy &&c) { - using EltTy = decltype((*std::begin(c))); + using EltTy = decltype(*adl_begin(c)); return llvm::map_range(std::forward(c), [](EltTy elt) -> typename detail::first_or_second_type< EltTy, decltype((elt.first))>::type { @@ -1430,7 +1453,7 @@ template auto make_first_range(ContainerTy &&c) { /// Given a container of pairs, return a range over the second elements. template auto make_second_range(ContainerTy &&c) { - using EltTy = decltype((*std::begin(c))); + using EltTy = decltype(*adl_begin(c)); return llvm::map_range( std::forward(c), [](EltTy elt) -> @@ -1709,6 +1732,34 @@ template constexpr size_t range_size(R &&Range) { return static_cast(std::distance(adl_begin(Range), adl_end(Range))); } +/// Wrapper for std::accumulate. +template auto accumulate(R &&Range, E &&Init) { + return std::accumulate(adl_begin(Range), adl_end(Range), + std::forward(Init)); +} + +/// Wrapper for std::accumulate with a binary operator. +template +auto accumulate(R &&Range, E &&Init, BinaryOp &&Op) { + return std::accumulate(adl_begin(Range), adl_end(Range), + std::forward(Init), std::forward(Op)); +} + +/// Returns the sum of all values in `Range` with `Init` initial value. +/// The default initial value is 0. +template > +auto sum_of(R &&Range, E Init = E{0}) { + return accumulate(std::forward(Range), std::move(Init)); +} + +/// Returns the product of all values in `Range` with `Init` initial value. +/// The default initial value is 1. +template > +auto product_of(R &&Range, E Init = E{1}) { + return accumulate(std::forward(Range), std::move(Init), + std::multiplies<>{}); +} + /// Provide wrappers to std::for_each which take ranges instead of having to /// pass begin/end explicitly. template @@ -1737,6 +1788,12 @@ bool none_of(R &&Range, UnaryPredicate P) { return std::none_of(adl_begin(Range), adl_end(Range), P); } +/// Provide wrappers to std::fill which take ranges instead of having to pass +/// begin/end explicitly. +template void fill(R &&Range, T &&Value) { + std::fill(adl_begin(Range), adl_end(Range), std::forward(Value)); +} + /// Provide wrappers to std::find which take ranges instead of having to pass /// begin/end explicitly. template auto find(R &&Range, const T &Val) { @@ -1782,8 +1839,9 @@ T *find_singleton(R &&Range, Predicate P, bool AllowRepeats = false) { if (RC) { if (!AllowRepeats || PRC != RC) return nullptr; - } else + } else { RC = PRC; + } } } return RC; @@ -1813,8 +1871,9 @@ std::pair find_singleton_nested(R &&Range, Predicate P, if (RC) { if (!AllowRepeats || PRC.first != RC) return {nullptr, true}; - } else + } else { RC = PRC.first; + } } } return {RC, false}; @@ -1843,6 +1902,13 @@ OutputIt replace_copy(R &&Range, OutputIt Out, const T &OldValue, NewValue); } +/// Provide wrappers to std::replace which take ranges instead of having to pass +/// begin/end explicitly. +template +void replace(R &&Range, const T &OldValue, const T &NewValue) { + std::replace(adl_begin(Range), adl_end(Range), OldValue, NewValue); +} + /// Provide wrappers to std::move which take ranges instead of having to /// pass begin/end explicitly. template @@ -1909,6 +1975,28 @@ template bool is_sorted(R &&Range) { return std::is_sorted(adl_begin(Range), adl_end(Range)); } +/// Provide wrappers to std::includes which take ranges instead of having to +/// pass begin/end explicitly. +/// This function checks if the sorted range \p R2 is a subsequence of the +/// sorted range \p R1. The ranges must be sorted in non-descending order. +template bool includes(R1 &&Range1, R2 &&Range2) { + assert(is_sorted(Range1) && "Range1 must be sorted in non-descending order"); + assert(is_sorted(Range2) && "Range2 must be sorted in non-descending order"); + return std::includes(adl_begin(Range1), adl_end(Range1), adl_begin(Range2), + adl_end(Range2)); +} + +/// This function checks if the sorted range \p R2 is a subsequence of the +/// sorted range \p R1. The ranges must be sorted with respect to a comparator +/// \p C. +template +bool includes(R1 &&Range1, R2 &&Range2, Compare &&C) { + assert(is_sorted(Range1, C) && "Range1 must be sorted with respect to C"); + assert(is_sorted(Range2, C) && "Range2 must be sorted with respect to C"); + return std::includes(adl_begin(Range1), adl_end(Range1), adl_begin(Range2), + adl_end(Range2), std::forward(C)); +} + /// Wrapper function around std::count to count the number of times an element /// \p Element occurs in the given range \p Range. template auto count(R &&Range, const E &Element) { @@ -1975,6 +2063,8 @@ auto upper_bound(R &&Range, T &&Value, Compare C) { std::forward(Value), C); } +/// Provide wrappers to std::min_element which take ranges instead of having to +/// pass begin/end explicitly. template auto min_element(R &&Range) { return std::min_element(adl_begin(Range), adl_end(Range)); } @@ -1983,6 +2073,8 @@ template auto min_element(R &&Range, Compare C) { return std::min_element(adl_begin(Range), adl_end(Range), C); } +/// Provide wrappers to std::max_element which take ranges instead of having to +/// pass begin/end explicitly. template auto max_element(R &&Range) { return std::max_element(adl_begin(Range), adl_end(Range)); } @@ -1991,6 +2083,25 @@ template auto max_element(R &&Range, Compare C) { return std::max_element(adl_begin(Range), adl_end(Range), C); } +/// Provide wrappers to std::mismatch which take ranges instead of having to +/// pass begin/end explicitly. +/// This function returns a pair of iterators for the first mismatching elements +/// from `R1` and `R2`. As an example, if: +/// +/// R1 = [0, 1, 4, 6], R2 = [0, 1, 5, 6] +/// +/// this function will return a pair of iterators, first pointing to R1[2] and +/// second pointing to R2[2]. +template auto mismatch(R1 &&Range1, R2 &&Range2) { + return std::mismatch(adl_begin(Range1), adl_end(Range1), adl_begin(Range2), + adl_end(Range2)); +} + +template +auto uninitialized_copy(R &&Src, IterTy Dst) { + return std::uninitialized_copy(adl_begin(Src), adl_end(Src), Dst); +} + template void stable_sort(R &&Range) { std::stable_sort(adl_begin(Range), adl_end(Range)); @@ -2037,7 +2148,7 @@ bool equal(L &&LRange, R &&RRange, BinaryPredicate P) { template bool all_equal(R &&Range) { auto Begin = adl_begin(Range); auto End = adl_end(Range); - return Begin == End || std::equal(Begin + 1, End, Begin); + return Begin == End || std::equal(std::next(Begin), End, Begin); } /// Returns true if all Values in the initializer lists are equal or the list @@ -2084,7 +2195,7 @@ void append_values(Container &C, Args &&...Values) { /// Given a sequence container Cont, replace the range [ContIt, ContEnd) with /// the range [ValIt, ValEnd) (which is not from the same container). -template +template void replace(Container &Cont, typename Container::iterator ContIt, typename Container::iterator ContEnd, RandomAccessIterator ValIt, RandomAccessIterator ValEnd) { @@ -2092,21 +2203,24 @@ void replace(Container &Cont, typename Container::iterator ContIt, if (ValIt == ValEnd) { Cont.erase(ContIt, ContEnd); return; - } else if (ContIt == ContEnd) { + } + if (ContIt == ContEnd) { Cont.insert(ContIt, ValIt, ValEnd); return; } - *ContIt++ = *ValIt++; + *ContIt = *ValIt; + ++ContIt; + ++ValIt; } } /// Given a sequence container Cont, replace the range [ContIt, ContEnd) with /// the range R. -template> +template > void replace(Container &Cont, typename Container::iterator ContIt, - typename Container::iterator ContEnd, Range R) { - replace(Cont, ContIt, ContEnd, R.begin(), R.end()); + typename Container::iterator ContEnd, Range &&R) { + replace(Cont, ContIt, ContEnd, adl_begin(R), adl_end(R)); } /// An STL-style algorithm similar to std::for_each that applies a second @@ -2366,7 +2480,7 @@ class index_range { detail::index_iterator end() const { return {End}; } }; -/// Given two or more input ranges, returns a new range whose values are are +/// Given two or more input ranges, returns a new range whose values are /// tuples (A, B, C, ...), such that A is the 0-based index of the item in the /// sequence, and B, C, ..., are the values from the original input ranges. All /// input ranges are required to have equal lengths. Note that the returned @@ -2519,19 +2633,19 @@ bool hasNItemsOrLess( /// Returns true if the given container has exactly N items template bool hasNItems(ContainerTy &&C, unsigned N) { - return hasNItems(std::begin(C), std::end(C), N); + return hasNItems(adl_begin(C), adl_end(C), N); } /// Returns true if the given container has N or more items template bool hasNItemsOrMore(ContainerTy &&C, unsigned N) { - return hasNItemsOrMore(std::begin(C), std::end(C), N); + return hasNItemsOrMore(adl_begin(C), adl_end(C), N); } /// Returns true if the given container has N or less items template bool hasNItemsOrLess(ContainerTy &&C, unsigned N) { - return hasNItemsOrLess(std::begin(C), std::end(C), N); + return hasNItemsOrLess(adl_begin(C), adl_end(C), N); } /// Returns a raw pointer that represents the same address as the argument. diff --git a/symbolic-demangle/vendor/swift/include/llvm/ADT/STLForwardCompat.h b/symbolic-demangle/vendor/swift/include/llvm/ADT/STLForwardCompat.h index 6afe3610b..7bd2c8705 100644 --- a/symbolic-demangle/vendor/swift/include/llvm/ADT/STLForwardCompat.h +++ b/symbolic-demangle/vendor/swift/include/llvm/ADT/STLForwardCompat.h @@ -36,6 +36,19 @@ template using remove_cvref_t // NOLINT(readability-identifier-naming) = typename llvm::remove_cvref::type; +// TODO: Remove this in favor of std::type_identity once we switch to C++23. +template +struct type_identity // NOLINT(readability-identifier-naming) +{ + using type = T; +}; + +// TODO: Remove this in favor of std::type_identity_t once we switch to +// C++23. +template +using type_identity_t // NOLINT(readability-identifier-naming) + = typename llvm::type_identity::type; + //===----------------------------------------------------------------------===// // Features from C++23 //===----------------------------------------------------------------------===// @@ -67,6 +80,11 @@ template return static_cast>(E); } +// A tag for constructors accepting ranges. +struct from_range_t { + explicit from_range_t() = default; +}; +inline constexpr from_range_t from_range{}; } // namespace llvm #endif // LLVM_ADT_STLFORWARDCOMPAT_H diff --git a/symbolic-demangle/vendor/swift/include/llvm/ADT/STLFunctionalExtras.h b/symbolic-demangle/vendor/swift/include/llvm/ADT/STLFunctionalExtras.h index dd7fc6dc7..a4d50dc36 100644 --- a/symbolic-demangle/vendor/swift/include/llvm/ADT/STLFunctionalExtras.h +++ b/symbolic-demangle/vendor/swift/include/llvm/ADT/STLFunctionalExtras.h @@ -16,6 +16,7 @@ #define LLVM_ADT_STLFUNCTIONALEXTRAS_H #include "llvm/ADT/STLForwardCompat.h" +#include "llvm/Support/Compiler.h" #include #include @@ -35,8 +36,8 @@ namespace llvm { /// a function_ref. template class function_ref; -template -class function_ref { +template +class LLVM_GSL_POINTER function_ref { Ret (*callback)(intptr_t callable, Params ...params) = nullptr; intptr_t callable; @@ -52,7 +53,7 @@ class function_ref { template function_ref( - Callable &&callable, + Callable &&callable LLVM_LIFETIME_BOUND, // This is not the copy-constructor. std::enable_if_t, function_ref>::value> * = nullptr, @@ -69,6 +70,10 @@ class function_ref { } explicit operator bool() const { return callback; } + + bool operator==(const function_ref &Other) const { + return callable == Other.callable; + } }; } // end namespace llvm diff --git a/symbolic-demangle/vendor/swift/include/llvm/ADT/StringRef.h b/symbolic-demangle/vendor/swift/include/llvm/ADT/StringRef.h index 049f22b03..16aca4d45 100644 --- a/symbolic-demangle/vendor/swift/include/llvm/ADT/StringRef.h +++ b/symbolic-demangle/vendor/swift/include/llvm/ADT/StringRef.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -31,14 +32,18 @@ namespace llvm { class StringRef; /// Helper functions for StringRef::getAsInteger. - bool getAsUnsignedInteger(StringRef Str, unsigned Radix, - unsigned long long &Result); + LLVM_ABI bool getAsUnsignedInteger(StringRef Str, unsigned Radix, + unsigned long long &Result); - bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result); + LLVM_ABI bool getAsSignedInteger(StringRef Str, unsigned Radix, + long long &Result); - bool consumeUnsignedInteger(StringRef &Str, unsigned Radix, - unsigned long long &Result); - bool consumeSignedInteger(StringRef &Str, unsigned Radix, long long &Result); + LLVM_ABI unsigned getAutoSenseRadix(StringRef &Str); + + LLVM_ABI bool consumeUnsignedInteger(StringRef &Str, unsigned Radix, + unsigned long long &Result); + LLVM_ABI bool consumeSignedInteger(StringRef &Str, unsigned Radix, + long long &Result); /// StringRef - Represent a constant reference to a string, i.e. a character /// array and a length, which need not be null terminated. @@ -54,6 +59,9 @@ namespace llvm { using iterator = const char *; using const_iterator = const char *; using size_type = size_t; + using value_type = char; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; private: /// The start of the string, in an external buffer. @@ -81,7 +89,7 @@ namespace llvm { StringRef(std::nullptr_t) = delete; /// Construct a string ref from a cstring. - /*implicit*/ constexpr StringRef(const char *Str) + /*implicit*/ constexpr StringRef(const char *Str LLVM_LIFETIME_BOUND) : Data(Str), Length(Str ? // GCC 7 doesn't have constexpr char_traits. Fall back to __builtin_strlen. #if defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE < 8 @@ -93,12 +101,13 @@ namespace llvm { } /// Construct a string ref from a pointer and length. - /*implicit*/ constexpr StringRef(const char *data, size_t length) + /*implicit*/ constexpr StringRef(const char *data LLVM_LIFETIME_BOUND, + size_t length) : Data(data), Length(length) {} /// Construct a string ref from an std::string. /*implicit*/ StringRef(const std::string &Str) - : Data(Str.data()), Length(Str.length()) {} + : Data(Str.data()), Length(Str.length()) {} /// Construct a string ref from an std::string_view. /*implicit*/ constexpr StringRef(std::string_view Str) @@ -108,9 +117,17 @@ namespace llvm { /// @name Iterators /// @{ - iterator begin() const { return Data; } + iterator begin() const { return data(); } + + iterator end() const { return data() + size(); } - iterator end() const { return Data + Length; } + reverse_iterator rbegin() const { + return std::make_reverse_iterator(end()); + } + + reverse_iterator rend() const { + return std::make_reverse_iterator(begin()); + } const unsigned char *bytes_begin() const { return reinterpret_cast(begin()); @@ -131,7 +148,7 @@ namespace llvm { [[nodiscard]] constexpr const char *data() const { return Data; } /// empty - Check if the string is empty. - [[nodiscard]] constexpr bool empty() const { return Length == 0; } + [[nodiscard]] constexpr bool empty() const { return size() == 0; } /// size - Get the string size. [[nodiscard]] constexpr size_t size() const { return Length; } @@ -139,13 +156,13 @@ namespace llvm { /// front - Get the first character in the string. [[nodiscard]] char front() const { assert(!empty()); - return Data[0]; + return data()[0]; } /// back - Get the last character in the string. [[nodiscard]] char back() const { assert(!empty()); - return Data[Length-1]; + return data()[size() - 1]; } // copy - Allocate copy in Allocator and return StringRef to it. @@ -154,14 +171,14 @@ namespace llvm { // Don't request a length 0 copy from the allocator. if (empty()) return StringRef(); - char *S = A.template Allocate(Length); + char *S = A.template Allocate(size()); std::copy(begin(), end(), S); - return StringRef(S, Length); + return StringRef(S, size()); } /// Check for string equality, ignoring case. [[nodiscard]] bool equals_insensitive(StringRef RHS) const { - return Length == RHS.Length && compare_insensitive(RHS) == 0; + return size() == RHS.size() && compare_insensitive(RHS) == 0; } /// compare - Compare two strings; the result is negative, zero, or positive @@ -169,21 +186,22 @@ namespace llvm { /// the \p RHS. [[nodiscard]] int compare(StringRef RHS) const { // Check the prefix for a mismatch. - if (int Res = compareMemory(Data, RHS.Data, std::min(Length, RHS.Length))) + if (int Res = + compareMemory(data(), RHS.data(), std::min(size(), RHS.size()))) return Res < 0 ? -1 : 1; // Otherwise the prefixes match, so we only need to check the lengths. - if (Length == RHS.Length) + if (size() == RHS.size()) return 0; - return Length < RHS.Length ? -1 : 1; + return size() < RHS.size() ? -1 : 1; } /// Compare two strings, ignoring case. - [[nodiscard]] int compare_insensitive(StringRef RHS) const; + [[nodiscard]] LLVM_ABI int compare_insensitive(StringRef RHS) const; /// compare_numeric - Compare two strings, treating sequences of digits as /// numbers. - [[nodiscard]] int compare_numeric(StringRef RHS) const; + [[nodiscard]] LLVM_ABI int compare_numeric(StringRef RHS) const; /// Determine the edit distance between this string and another /// string. @@ -203,18 +221,19 @@ namespace llvm { /// or (if \p AllowReplacements is \c true) replacements needed to /// transform one of the given strings into the other. If zero, /// the strings are identical. - [[nodiscard]] unsigned edit_distance(StringRef Other, - bool AllowReplacements = true, - unsigned MaxEditDistance = 0) const; + [[nodiscard]] LLVM_ABI unsigned + edit_distance(StringRef Other, bool AllowReplacements = true, + unsigned MaxEditDistance = 0) const; - [[nodiscard]] unsigned + [[nodiscard]] LLVM_ABI unsigned edit_distance_insensitive(StringRef Other, bool AllowReplacements = true, unsigned MaxEditDistance = 0) const; /// str - Get the contents as an std::string. [[nodiscard]] std::string str() const { - if (!Data) return std::string(); - return std::string(Data, Length); + if (!data()) + return std::string(); + return std::string(data(), size()); } /// @} @@ -222,8 +241,8 @@ namespace llvm { /// @{ [[nodiscard]] char operator[](size_t Index) const { - assert(Index < Length && "Invalid index!"); - return Data[Index]; + assert(Index < size() && "Invalid index!"); + return data()[Index]; } /// Disallow accidental assignment from a temporary std::string. @@ -248,28 +267,28 @@ namespace llvm { /// Check if this string starts with the given \p Prefix. [[nodiscard]] bool starts_with(StringRef Prefix) const { - return Length >= Prefix.Length && - compareMemory(Data, Prefix.Data, Prefix.Length) == 0; + return size() >= Prefix.size() && + compareMemory(data(), Prefix.data(), Prefix.size()) == 0; } [[nodiscard]] bool starts_with(char Prefix) const { return !empty() && front() == Prefix; } /// Check if this string starts with the given \p Prefix, ignoring case. - [[nodiscard]] bool starts_with_insensitive(StringRef Prefix) const; + [[nodiscard]] LLVM_ABI bool starts_with_insensitive(StringRef Prefix) const; /// Check if this string ends with the given \p Suffix. [[nodiscard]] bool ends_with(StringRef Suffix) const { - return Length >= Suffix.Length && - compareMemory(end() - Suffix.Length, Suffix.Data, Suffix.Length) == - 0; + return size() >= Suffix.size() && + compareMemory(end() - Suffix.size(), Suffix.data(), + Suffix.size()) == 0; } [[nodiscard]] bool ends_with(char Suffix) const { return !empty() && back() == Suffix; } /// Check if this string ends with the given \p Suffix, ignoring case. - [[nodiscard]] bool ends_with_insensitive(StringRef Suffix) const; + [[nodiscard]] LLVM_ABI bool ends_with_insensitive(StringRef Suffix) const; /// @} /// @name String Searching @@ -287,7 +306,8 @@ namespace llvm { /// /// \returns The index of the first occurrence of \p C, or npos if not /// found. - [[nodiscard]] size_t find_insensitive(char C, size_t From = 0) const; + [[nodiscard]] LLVM_ABI size_t find_insensitive(char C, + size_t From = 0) const; /// Search for the first character satisfying the predicate \p F /// @@ -317,23 +337,24 @@ namespace llvm { /// /// \returns The index of the first occurrence of \p Str, or npos if not /// found. - [[nodiscard]] size_t find(StringRef Str, size_t From = 0) const; + [[nodiscard]] LLVM_ABI size_t find(StringRef Str, size_t From = 0) const; /// Search for the first string \p Str in the string, ignoring case. /// /// \returns The index of the first occurrence of \p Str, or npos if not /// found. - [[nodiscard]] size_t find_insensitive(StringRef Str, size_t From = 0) const; + [[nodiscard]] LLVM_ABI size_t find_insensitive(StringRef Str, + size_t From = 0) const; /// Search for the last character \p C in the string. /// /// \returns The index of the last occurrence of \p C, or npos if not /// found. [[nodiscard]] size_t rfind(char C, size_t From = npos) const { - size_t I = std::min(From, Length); + size_t I = std::min(From, size()); while (I) { --I; - if (Data[I] == C) + if (data()[I] == C) return I; } return npos; @@ -343,19 +364,20 @@ namespace llvm { /// /// \returns The index of the last occurrence of \p C, or npos if not /// found. - [[nodiscard]] size_t rfind_insensitive(char C, size_t From = npos) const; + [[nodiscard]] LLVM_ABI size_t rfind_insensitive(char C, + size_t From = npos) const; /// Search for the last string \p Str in the string. /// /// \returns The index of the last occurrence of \p Str, or npos if not /// found. - [[nodiscard]] size_t rfind(StringRef Str) const; + [[nodiscard]] LLVM_ABI size_t rfind(StringRef Str) const; /// Search for the last string \p Str in the string, ignoring case. /// /// \returns The index of the last occurrence of \p Str, or npos if not /// found. - [[nodiscard]] size_t rfind_insensitive(StringRef Str) const; + [[nodiscard]] LLVM_ABI size_t rfind_insensitive(StringRef Str) const; /// Find the first character in the string that is \p C, or npos if not /// found. Same as find. @@ -367,18 +389,20 @@ namespace llvm { /// not found. /// /// Complexity: O(size() + Chars.size()) - [[nodiscard]] size_t find_first_of(StringRef Chars, size_t From = 0) const; + [[nodiscard]] LLVM_ABI size_t find_first_of(StringRef Chars, + size_t From = 0) const; /// Find the first character in the string that is not \p C or npos if not /// found. - [[nodiscard]] size_t find_first_not_of(char C, size_t From = 0) const; + [[nodiscard]] LLVM_ABI size_t find_first_not_of(char C, + size_t From = 0) const; /// Find the first character in the string that is not in the string /// \p Chars, or npos if not found. /// /// Complexity: O(size() + Chars.size()) - [[nodiscard]] size_t find_first_not_of(StringRef Chars, - size_t From = 0) const; + [[nodiscard]] LLVM_ABI size_t find_first_not_of(StringRef Chars, + size_t From = 0) const; /// Find the last character in the string that is \p C, or npos if not /// found. @@ -390,19 +414,20 @@ namespace llvm { /// found. /// /// Complexity: O(size() + Chars.size()) - [[nodiscard]] size_t find_last_of(StringRef Chars, - size_t From = npos) const; + [[nodiscard]] LLVM_ABI size_t find_last_of(StringRef Chars, + size_t From = npos) const; /// Find the last character in the string that is not \p C, or npos if not /// found. - [[nodiscard]] size_t find_last_not_of(char C, size_t From = npos) const; + [[nodiscard]] LLVM_ABI size_t find_last_not_of(char C, + size_t From = npos) const; /// Find the last character in the string that is not in \p Chars, or /// npos if not found. /// /// Complexity: O(size() + Chars.size()) - [[nodiscard]] size_t find_last_not_of(StringRef Chars, - size_t From = npos) const; + [[nodiscard]] LLVM_ABI size_t find_last_not_of(StringRef Chars, + size_t From = npos) const; /// Return true if the given string is a substring of *this, and false /// otherwise. @@ -435,15 +460,15 @@ namespace llvm { /// Return the number of occurrences of \p C in the string. [[nodiscard]] size_t count(char C) const { size_t Count = 0; - for (size_t I = 0; I != Length; ++I) - if (Data[I] == C) + for (size_t I = 0; I != size(); ++I) + if (data()[I] == C) ++Count; return Count; } /// Return the number of non-overlapped occurrences of \p Str in /// the string. - size_t count(StringRef Str) const; + LLVM_ABI size_t count(StringRef Str) const; /// Parse the current string as an integer of the specified radix. If /// \p Radix is specified as zero, this does radix autosensing using @@ -508,7 +533,7 @@ namespace llvm { /// /// APInt::fromString is superficially similar but assumes the /// string is well-formed in the given radix. - bool getAsInteger(unsigned Radix, APInt &Result) const; + LLVM_ABI bool getAsInteger(unsigned Radix, APInt &Result) const; /// Parse the current string as an integer of the specified \p Radix. If /// \p Radix is specified as zero, this does radix autosensing using @@ -519,7 +544,7 @@ namespace llvm { /// erroneous if empty. /// The portion of the string representing the discovered numeric value /// is removed from the beginning of the string. - bool consumeInteger(unsigned Radix, APInt &Result); + LLVM_ABI bool consumeInteger(unsigned Radix, APInt &Result); /// Parse the current string as an IEEE double-precision floating /// point value. The string must be a well-formed double. @@ -528,17 +553,17 @@ namespace llvm { /// cannot be represented exactly. Otherwise, the function only fails /// in case of an overflow or underflow, or an invalid floating point /// representation. - bool getAsDouble(double &Result, bool AllowInexact = true) const; + LLVM_ABI bool getAsDouble(double &Result, bool AllowInexact = true) const; /// @} /// @name String Operations /// @{ // Convert the given ASCII string to lowercase. - [[nodiscard]] std::string lower() const; + [[nodiscard]] LLVM_ABI std::string lower() const; /// Convert the given ASCII string to uppercase. - [[nodiscard]] std::string upper() const; + [[nodiscard]] LLVM_ABI std::string upper() const; /// @} /// @name Substring Operations @@ -555,8 +580,8 @@ namespace llvm { /// suffix (starting with \p Start) will be returned. [[nodiscard]] constexpr StringRef substr(size_t Start, size_t N = npos) const { - Start = std::min(Start, Length); - return StringRef(Data + Start, std::min(N, Length - Start)); + Start = std::min(Start, size()); + return StringRef(data() + Start, std::min(N, size() - Start)); } /// Return a StringRef equal to 'this' but with only the first \p N @@ -667,9 +692,9 @@ namespace llvm { /// will be returned. If this is less than \p Start, an empty string will /// be returned. [[nodiscard]] StringRef slice(size_t Start, size_t End) const { - Start = std::min(Start, Length); - End = std::clamp(End, Start, Length); - return StringRef(Data + Start, End - Start); + Start = std::min(Start, size()); + End = std::clamp(End, Start, size()); + return StringRef(data() + Start, End - Start); } /// Split into two substrings around the first occurrence of a separator @@ -701,7 +726,7 @@ namespace llvm { size_t Idx = find(Separator); if (Idx == npos) return std::make_pair(*this, StringRef()); - return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos)); + return std::make_pair(slice(0, Idx), substr(Idx + Separator.size())); } /// Split into two substrings around the last occurrence of a separator @@ -719,7 +744,7 @@ namespace llvm { size_t Idx = rfind(Separator); if (Idx == npos) return std::make_pair(*this, StringRef()); - return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos)); + return std::make_pair(slice(0, Idx), substr(Idx + Separator.size())); } /// Split into substrings around the occurrences of a separator string. @@ -736,9 +761,8 @@ namespace llvm { /// \param Separator - The string to split on. /// \param MaxSplit - The maximum number of times the string is split. /// \param KeepEmpty - True if empty substring should be added. - void split(SmallVectorImpl &A, - StringRef Separator, int MaxSplit = -1, - bool KeepEmpty = true) const; + LLVM_ABI void split(SmallVectorImpl &A, StringRef Separator, + int MaxSplit = -1, bool KeepEmpty = true) const; /// Split into substrings around the occurrences of a separator character. /// @@ -754,8 +778,8 @@ namespace llvm { /// \param Separator - The string to split on. /// \param MaxSplit - The maximum number of times the string is split. /// \param KeepEmpty - True if empty substring should be added. - void split(SmallVectorImpl &A, char Separator, int MaxSplit = -1, - bool KeepEmpty = true) const; + LLVM_ABI void split(SmallVectorImpl &A, char Separator, + int MaxSplit = -1, bool KeepEmpty = true) const; /// Split into two substrings around the last occurrence of a separator /// character. @@ -774,25 +798,25 @@ namespace llvm { /// Return string with consecutive \p Char characters starting from the /// the left removed. [[nodiscard]] StringRef ltrim(char Char) const { - return drop_front(std::min(Length, find_first_not_of(Char))); + return drop_front(std::min(size(), find_first_not_of(Char))); } /// Return string with consecutive characters in \p Chars starting from /// the left removed. [[nodiscard]] StringRef ltrim(StringRef Chars = " \t\n\v\f\r") const { - return drop_front(std::min(Length, find_first_not_of(Chars))); + return drop_front(std::min(size(), find_first_not_of(Chars))); } /// Return string with consecutive \p Char characters starting from the /// right removed. [[nodiscard]] StringRef rtrim(char Char) const { - return drop_back(Length - std::min(Length, find_last_not_of(Char) + 1)); + return drop_back(size() - std::min(size(), find_last_not_of(Char) + 1)); } /// Return string with consecutive characters in \p Chars starting from /// the right removed. [[nodiscard]] StringRef rtrim(StringRef Chars = " \t\n\v\f\r") const { - return drop_back(Length - std::min(Length, find_last_not_of(Chars) + 1)); + return drop_back(size() - std::min(size(), find_last_not_of(Chars) + 1)); } /// Return string with consecutive \p Char characters starting from the @@ -819,9 +843,9 @@ namespace llvm { // If there is no carriage return, assume unix return "\n"; } - if (Pos + 1 < Length && Data[Pos + 1] == '\n') + if (Pos + 1 < size() && data()[Pos + 1] == '\n') return "\r\n"; // Windows - if (Pos > 0 && Data[Pos - 1] == '\n') + if (Pos > 0 && data()[Pos - 1] == '\n') return "\n\r"; // You monster! return "\r"; // Classic Mac } @@ -896,7 +920,7 @@ namespace llvm { /// @} /// Compute a hash_code for a StringRef. - [[nodiscard]] hash_code hash_value(StringRef S); + [[nodiscard]] LLVM_ABI hash_code hash_value(StringRef S); // Provide DenseMapInfo for StringRefs. template <> struct DenseMapInfo { @@ -910,7 +934,7 @@ namespace llvm { reinterpret_cast(~static_cast(1)), 0); } - static unsigned getHashValue(StringRef Val); + LLVM_ABI static unsigned getHashValue(StringRef Val); static bool isEqual(StringRef LHS, StringRef RHS) { if (RHS.data() == getEmptyKey().data()) diff --git a/symbolic-demangle/vendor/swift/include/llvm/ADT/StringSwitch.h b/symbolic-demangle/vendor/swift/include/llvm/ADT/StringSwitch.h index 7093da076..31297aa85 100644 --- a/symbolic-demangle/vendor/swift/include/llvm/ADT/StringSwitch.h +++ b/symbolic-demangle/vendor/swift/include/llvm/ADT/StringSwitch.h @@ -14,9 +14,9 @@ #define LLVM_ADT_STRINGSWITCH_H #include "llvm/ADT/StringRef.h" -#include "llvm/Support/Compiler.h" #include #include +#include #include namespace llvm { @@ -67,9 +67,7 @@ class StringSwitch { // Case-sensitive case matchers StringSwitch &Case(StringLiteral S, T Value) { - if (!Result && Str == S) { - Result = std::move(Value); - } + CaseImpl(Value, S); return *this; } @@ -87,62 +85,65 @@ class StringSwitch { return *this; } + StringSwitch &Cases(std::initializer_list CaseStrings, + T Value) { + return CasesImpl(Value, CaseStrings); + } + StringSwitch &Cases(StringLiteral S0, StringLiteral S1, T Value) { - return Case(S0, Value).Case(S1, Value); + return CasesImpl(Value, {S0, S1}); } StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, T Value) { - return Case(S0, Value).Cases(S1, S2, Value); + return CasesImpl(Value, {S0, S1, S2}); } StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, T Value) { - return Case(S0, Value).Cases(S1, S2, S3, Value); + return CasesImpl(Value, {S0, S1, S2, S3}); } StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, T Value) { - return Case(S0, Value).Cases(S1, S2, S3, S4, Value); + return CasesImpl(Value, {S0, S1, S2, S3, S4}); } StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, StringLiteral S5, T Value) { - return Case(S0, Value).Cases(S1, S2, S3, S4, S5, Value); + return CasesImpl(Value, {S0, S1, S2, S3, S4, S5}); } StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, StringLiteral S5, StringLiteral S6, T Value) { - return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, Value); + return CasesImpl(Value, {S0, S1, S2, S3, S4, S5, S6}); } StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, StringLiteral S5, StringLiteral S6, StringLiteral S7, T Value) { - return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, Value); + return CasesImpl(Value, {S0, S1, S2, S3, S4, S5, S6, S7}); } StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, StringLiteral S5, StringLiteral S6, StringLiteral S7, StringLiteral S8, T Value) { - return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, S8, Value); + return CasesImpl(Value, {S0, S1, S2, S3, S4, S5, S6, S7, S8}); } StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, StringLiteral S5, StringLiteral S6, StringLiteral S7, StringLiteral S8, StringLiteral S9, T Value) { - return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, S8, S9, Value); + return CasesImpl(Value, {S0, S1, S2, S3, S4, S5, S6, S7, S8, S9}); } // Case-insensitive case matchers. StringSwitch &CaseLower(StringLiteral S, T Value) { - if (!Result && Str.equals_insensitive(S)) - Result = std::move(Value); - + CaseLowerImpl(Value, S); return *this; } @@ -160,23 +161,28 @@ class StringSwitch { return *this; } + StringSwitch &CasesLower(std::initializer_list CaseStrings, + T Value) { + return CasesLowerImpl(Value, CaseStrings); + } + StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, T Value) { - return CaseLower(S0, Value).CaseLower(S1, Value); + return CasesLowerImpl(Value, {S0, S1}); } StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2, T Value) { - return CaseLower(S0, Value).CasesLower(S1, S2, Value); + return CasesLowerImpl(Value, {S0, S1, S2}); } StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, T Value) { - return CaseLower(S0, Value).CasesLower(S1, S2, S3, Value); + return CasesLowerImpl(Value, {S0, S1, S2, S3}); } StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2, StringLiteral S3, StringLiteral S4, T Value) { - return CaseLower(S0, Value).CasesLower(S1, S2, S3, S4, Value); + return CasesLowerImpl(Value, {S0, S1, S2, S3, S4}); } [[nodiscard]] R Default(T Value) { @@ -189,6 +195,44 @@ class StringSwitch { assert(Result && "Fell off the end of a string-switch"); return std::move(*Result); } + +private: + // Returns true when `Str` matches the `S` argument, and stores the result. + bool CaseImpl(T &Value, StringLiteral S) { + if (!Result && Str == S) { + Result = std::move(Value); + return true; + } + return false; + } + + // Returns true when `Str` matches the `S` argument (case-insensitive), and + // stores the result. + bool CaseLowerImpl(T &Value, StringLiteral S) { + if (!Result && Str.equals_insensitive(S)) { + Result = std::move(Value); + return true; + } + return false; + } + + StringSwitch &CasesImpl(T &Value, + std::initializer_list Cases) { + // Stop matching after the string is found. + for (StringLiteral S : Cases) + if (CaseImpl(Value, S)) + break; + return *this; + } + + StringSwitch &CasesLowerImpl(T &Value, + std::initializer_list Cases) { + // Stop matching after the string is found. + for (StringLiteral S : Cases) + if (CaseLowerImpl(Value, S)) + break; + return *this; + } }; } // end namespace llvm diff --git a/symbolic-demangle/vendor/swift/include/llvm/ADT/bit.h b/symbolic-demangle/vendor/swift/include/llvm/ADT/bit.h index c42b5e686..d6e33c3e6 100644 --- a/symbolic-demangle/vendor/swift/include/llvm/ADT/bit.h +++ b/symbolic-demangle/vendor/swift/include/llvm/ADT/bit.h @@ -15,6 +15,7 @@ #define LLVM_ADT_BIT_H #include "llvm/Support/Compiler.h" +#include // for std::size_t #include #include #include @@ -29,7 +30,7 @@ #if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) || \ defined(__Fuchsia__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || \ - defined(__OpenBSD__) || defined(__DragonFly__) + defined(__OpenBSD__) || defined(__DragonFly__) || defined(__managarm__) #include #elif defined(_AIX) #include @@ -147,36 +148,20 @@ template >> return (Value != 0) && ((Value & (Value - 1)) == 0); } -namespace detail { -template struct TrailingZerosCounter { - static unsigned count(T Val) { - if (!Val) - return std::numeric_limits::digits; - if (Val & 0x1) - return 0; - - // Bisection method. - unsigned ZeroBits = 0; - T Shift = std::numeric_limits::digits >> 1; - T Mask = std::numeric_limits::max() >> Shift; - while (Shift) { - if ((Val & Mask) == 0) { - Val >>= Shift; - ZeroBits |= Shift; - } - Shift >>= 1; - Mask >>= Shift; - } - return ZeroBits; - } -}; - -#if defined(__GNUC__) || defined(_MSC_VER) -template struct TrailingZerosCounter { - static unsigned count(T Val) { - if (Val == 0) - return 32; +/// Count number of 0's from the least significant bit to the most +/// stopping at the first 1. +/// +/// Only unsigned integral types are allowed. +/// +/// Returns std::numeric_limits::digits on an input of 0. +template [[nodiscard]] int countr_zero(T Val) { + static_assert(std::is_unsigned_v, + "Only unsigned integral types are allowed."); + if (!Val) + return std::numeric_limits::digits; + // Use the intrinsic if available. + if constexpr (sizeof(T) == 4) { #if __has_builtin(__builtin_ctz) || defined(__GNUC__) return __builtin_ctz(Val); #elif defined(_MSC_VER) @@ -184,65 +169,45 @@ template struct TrailingZerosCounter { _BitScanForward(&Index, Val); return Index; #endif - } -}; - -#if !defined(_MSC_VER) || defined(_M_X64) -template struct TrailingZerosCounter { - static unsigned count(T Val) { - if (Val == 0) - return 64; - + } else if constexpr (sizeof(T) == 8) { #if __has_builtin(__builtin_ctzll) || defined(__GNUC__) return __builtin_ctzll(Val); -#elif defined(_MSC_VER) +#elif defined(_MSC_VER) && defined(_M_X64) unsigned long Index; _BitScanForward64(&Index, Val); return Index; #endif } -}; -#endif -#endif -} // namespace detail -/// Count number of 0's from the least significant bit to the most + // Fall back to the bisection method. + unsigned ZeroBits = 0; + T Shift = std::numeric_limits::digits >> 1; + T Mask = std::numeric_limits::max() >> Shift; + while (Shift) { + if ((Val & Mask) == 0) { + Val >>= Shift; + ZeroBits |= Shift; + } + Shift >>= 1; + Mask >>= Shift; + } + return ZeroBits; +} + +/// Count number of 0's from the most significant bit to the least /// stopping at the first 1. /// /// Only unsigned integral types are allowed. /// /// Returns std::numeric_limits::digits on an input of 0. -template [[nodiscard]] int countr_zero(T Val) { +template [[nodiscard]] int countl_zero(T Val) { static_assert(std::is_unsigned_v, "Only unsigned integral types are allowed."); - return llvm::detail::TrailingZerosCounter::count(Val); -} - -namespace detail { -template struct LeadingZerosCounter { - static unsigned count(T Val) { - if (!Val) - return std::numeric_limits::digits; - - // Bisection method. - unsigned ZeroBits = 0; - for (T Shift = std::numeric_limits::digits >> 1; Shift; Shift >>= 1) { - T Tmp = Val >> Shift; - if (Tmp) - Val = Tmp; - else - ZeroBits |= Shift; - } - return ZeroBits; - } -}; - -#if defined(__GNUC__) || defined(_MSC_VER) -template struct LeadingZerosCounter { - static unsigned count(T Val) { - if (Val == 0) - return 32; + if (!Val) + return std::numeric_limits::digits; + // Use the intrinsic if available. + if constexpr (sizeof(T) == 4) { #if __has_builtin(__builtin_clz) || defined(__GNUC__) return __builtin_clz(Val); #elif defined(_MSC_VER) @@ -250,38 +215,26 @@ template struct LeadingZerosCounter { _BitScanReverse(&Index, Val); return Index ^ 31; #endif - } -}; - -#if !defined(_MSC_VER) || defined(_M_X64) -template struct LeadingZerosCounter { - static unsigned count(T Val) { - if (Val == 0) - return 64; - + } else if constexpr (sizeof(T) == 8) { #if __has_builtin(__builtin_clzll) || defined(__GNUC__) return __builtin_clzll(Val); -#elif defined(_MSC_VER) +#elif defined(_MSC_VER) && defined(_M_X64) unsigned long Index; _BitScanReverse64(&Index, Val); return Index ^ 63; #endif } -}; -#endif -#endif -} // namespace detail -/// Count number of 0's from the most significant bit to the least -/// stopping at the first 1. -/// -/// Only unsigned integral types are allowed. -/// -/// Returns std::numeric_limits::digits on an input of 0. -template [[nodiscard]] int countl_zero(T Val) { - static_assert(std::is_unsigned_v, - "Only unsigned integral types are allowed."); - return llvm::detail::LeadingZerosCounter::count(Val); + // Fall back to the bisection method. + unsigned ZeroBits = 0; + for (T Shift = std::numeric_limits::digits >> 1; Shift; Shift >>= 1) { + T Tmp = Val >> Shift; + if (Tmp) + Val = Tmp; + else + ZeroBits |= Shift; + } + return ZeroBits; } /// Count the number of ones from the most significant bit to the first @@ -347,11 +300,12 @@ template [[nodiscard]] T bit_ceil(T Value) { return T(1) << llvm::bit_width(Value - 1u); } -namespace detail { -template struct PopulationCounter { - static int count(T Value) { - // Generic version, forward to 32 bits. - static_assert(SizeOfT <= 4, "Not implemented!"); +/// Count the number of set bits in a value. +/// Ex. popcount(0xF000F000) = 8 +/// Returns 0 if the word is zero. +template >> +[[nodiscard]] inline int popcount(T Value) noexcept { + if constexpr (sizeof(T) <= 4) { #if defined(__GNUC__) return (int)__builtin_popcount(Value); #else @@ -360,11 +314,7 @@ template struct PopulationCounter { v = (v & 0x33333333) + ((v >> 2) & 0x33333333); return int(((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24); #endif - } -}; - -template struct PopulationCounter { - static int count(T Value) { + } else if constexpr (sizeof(T) <= 8) { #if defined(__GNUC__) return (int)__builtin_popcountll(Value); #else @@ -374,16 +324,9 @@ template struct PopulationCounter { v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL; return int((uint64_t)(v * 0x0101010101010101ULL) >> 56); #endif + } else { + static_assert(sizeof(T) == 0, "T must be 8 bytes or less"); } -}; -} // namespace detail - -/// Count the number of set bits in a value. -/// Ex. popcount(0xF000F000) = 8 -/// Returns 0 if the word is zero. -template >> -[[nodiscard]] inline int popcount(T Value) noexcept { - return detail::PopulationCounter::count(Value); } // Forward-declare rotr so that rotl can use it. diff --git a/symbolic-demangle/vendor/swift/include/llvm/ADT/iterator_range.h b/symbolic-demangle/vendor/swift/include/llvm/ADT/iterator_range.h index 6c66def0f..8e9b22f2d 100644 --- a/symbolic-demangle/vendor/swift/include/llvm/ADT/iterator_range.h +++ b/symbolic-demangle/vendor/swift/include/llvm/ADT/iterator_range.h @@ -43,7 +43,8 @@ class iterator_range { IteratorT begin_iterator, end_iterator; public: -#if __GNUC__ == 7 || (__GNUC__ == 8 && __GNUC_MINOR__ < 4) +#if defined(__GNUC__) && \ + (__GNUC__ == 7 || (__GNUC__ == 8 && __GNUC_MINOR__ < 4)) // Be careful no to break gcc-7 and gcc-8 < 8.4 on the mlir target. // See https://github.com/llvm/llvm-project/issues/63843 template diff --git a/symbolic-demangle/vendor/swift/include/llvm/Support/Casting.h b/symbolic-demangle/vendor/swift/include/llvm/Support/Casting.h index 14a32ccd0..66fdcb44e 100644 --- a/symbolic-demangle/vendor/swift/include/llvm/Support/Casting.h +++ b/symbolic-demangle/vendor/swift/include/llvm/Support/Casting.h @@ -755,7 +755,7 @@ template auto dyn_cast_if_present(Y *Val) { // Forwards to dyn_cast_if_present to avoid breaking current users. This is // deprecated and will be removed in a future patch, use -// cast_if_present instead. +// dyn_cast_if_present instead. template auto dyn_cast_or_null(const Y &Val) { return dyn_cast_if_present(Val); } diff --git a/symbolic-demangle/vendor/swift/include/llvm/Support/Compiler.h b/symbolic-demangle/vendor/swift/include/llvm/Support/Compiler.h index d8e3794ba..297d3e9b0 100644 --- a/symbolic-demangle/vendor/swift/include/llvm/Support/Compiler.h +++ b/symbolic-demangle/vendor/swift/include/llvm/Support/Compiler.h @@ -39,8 +39,8 @@ # define __has_builtin(x) 0 #endif -#ifndef __has_include -# define __has_include(x) 0 +#ifndef __has_warning +# define __has_warning(x) 0 #endif // Only use __has_cpp_attribute in C++ mode. GCC defines __has_cpp_attribute in @@ -114,7 +114,8 @@ /// this attribute will be made public and visible outside of any shared library /// they are linked in to. -#if LLVM_HAS_CPP_ATTRIBUTE(gnu::visibility) +#if LLVM_HAS_CPP_ATTRIBUTE(gnu::visibility) && defined(__GNUC__) && \ + !defined(__clang__) #define LLVM_ATTRIBUTE_VISIBILITY_HIDDEN [[gnu::visibility("hidden")]] #define LLVM_ATTRIBUTE_VISIBILITY_DEFAULT [[gnu::visibility("default")]] #elif __has_attribute(visibility) @@ -125,18 +126,96 @@ #define LLVM_ATTRIBUTE_VISIBILITY_DEFAULT #endif - -#if (!(defined(_WIN32) || defined(__CYGWIN__)) || \ - (defined(__MINGW32__) && defined(__clang__))) -#define LLVM_LIBRARY_VISIBILITY LLVM_ATTRIBUTE_VISIBILITY_HIDDEN #if defined(LLVM_BUILD_LLVM_DYLIB) || defined(LLVM_BUILD_SHARED_LIBS) #define LLVM_EXTERNAL_VISIBILITY LLVM_ATTRIBUTE_VISIBILITY_DEFAULT #else #define LLVM_EXTERNAL_VISIBILITY #endif + +#if (!(defined(_WIN32) || defined(__CYGWIN__)) || \ + ((defined(__MINGW32__) || defined(__CYGWIN__)) && defined(__clang__))) +#define LLVM_LIBRARY_VISIBILITY LLVM_ATTRIBUTE_VISIBILITY_HIDDEN +// Clang compilers older then 15 do not support gnu style attributes on +// namespaces. +#if defined(__clang__) && __clang_major__ < 15 +#define LLVM_LIBRARY_VISIBILITY_NAMESPACE [[gnu::visibility("hidden")]] #else +#define LLVM_LIBRARY_VISIBILITY_NAMESPACE LLVM_ATTRIBUTE_VISIBILITY_HIDDEN +#endif +#define LLVM_ALWAYS_EXPORT LLVM_ATTRIBUTE_VISIBILITY_DEFAULT +#elif defined(_WIN32) +#define LLVM_ALWAYS_EXPORT __declspec(dllexport) #define LLVM_LIBRARY_VISIBILITY -#define LLVM_EXTERNAL_VISIBILITY +#define LLVM_LIBRARY_VISIBILITY_NAMESPACE +#else +#define LLVM_LIBRARY_VISIBILITY +#define LLVM_ALWAYS_EXPORT +#define LLVM_LIBRARY_VISIBILITY_NAMESPACE +#endif + +/// LLVM_ABI is the main export/visibility macro to mark something as explicitly +/// exported when llvm is built as a shared library with everything else that is +/// unannotated will have internal visibility. +/// +/// LLVM_ABI_EXPORT is for the special case for things like plugin symbol +/// declarations or definitions where we don't want the macro to be switching +/// between dllexport and dllimport on windows based on what codebase is being +/// built, it will only be dllexport. For non windows platforms this macro +/// behaves the same as LLVM_ABI. +/// +/// LLVM_EXPORT_TEMPLATE is used on explicit template instantiations in source +/// files that were declared extern in a header. This macro is only set as a +/// compiler export attribute on windows, on other platforms it does nothing. +/// +/// LLVM_TEMPLATE_ABI is for annotating extern template declarations in headers +/// for both functions and classes. On windows its turned in to dllimport for +/// library consumers, for other platforms its a default visibility attribute. +/// +/// LLVM_ABI_FOR_TEST is for annotating symbols that are only exported because +/// they are imported from a test. These symbols are not technically part of the +/// LLVM public interface and could be conditionally excluded when not building +/// tests in the future. +/// +#ifndef LLVM_ABI_GENERATING_ANNOTATIONS +// Marker to add to classes or functions in public headers that should not have +// export macros added to them by the clang tool +#define LLVM_ABI_NOT_EXPORTED +// TODO(https://github.com/llvm/llvm-project/issues/145406): eliminate need for +// two preprocessor definitions to gate LLVM_ABI macro definitions. +#if defined(LLVM_ENABLE_LLVM_EXPORT_ANNOTATIONS) && !defined(LLVM_BUILD_STATIC) +#if defined(_WIN32) && !defined(__MINGW32__) +#if defined(LLVM_EXPORTS) +#define LLVM_ABI __declspec(dllexport) +#define LLVM_TEMPLATE_ABI +#define LLVM_EXPORT_TEMPLATE __declspec(dllexport) +#else +#define LLVM_ABI __declspec(dllimport) +#define LLVM_TEMPLATE_ABI __declspec(dllimport) +#define LLVM_EXPORT_TEMPLATE +#endif +#define LLVM_ABI_EXPORT __declspec(dllexport) +#elif __has_attribute(visibility) +#if defined(__ELF__) || defined(__MINGW32__) || defined(_AIX) || \ + defined(__MVS__) || defined(__CYGWIN__) +#define LLVM_ABI __attribute__((visibility("default"))) +#define LLVM_TEMPLATE_ABI LLVM_ABI +#define LLVM_EXPORT_TEMPLATE +#define LLVM_ABI_EXPORT LLVM_ABI +#elif defined(__MACH__) || defined(__WASM__) || defined(__EMSCRIPTEN__) +#define LLVM_ABI __attribute__((visibility("default"))) +#define LLVM_TEMPLATE_ABI +#define LLVM_EXPORT_TEMPLATE +#define LLVM_ABI_EXPORT LLVM_ABI +#endif +#endif +#endif +#if !defined(LLVM_ABI) +#define LLVM_ABI +#define LLVM_TEMPLATE_ABI +#define LLVM_EXPORT_TEMPLATE +#define LLVM_ABI_EXPORT +#endif +#define LLVM_ABI_FOR_TEST LLVM_ABI #endif #if defined(__GNUC__) @@ -145,12 +224,28 @@ #define LLVM_PREFETCH(addr, rw, locality) #endif +#if __has_attribute(uninitialized) +#define LLVM_ATTRIBUTE_UNINITIALIZED __attribute__((uninitialized)) +#else +#define LLVM_ATTRIBUTE_UNINITIALIZED +#endif + #if __has_attribute(used) #define LLVM_ATTRIBUTE_USED __attribute__((__used__)) #else #define LLVM_ATTRIBUTE_USED #endif +// Only enabled for clang: +// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99587 +// GCC may produce "warning: 'retain' attribute ignored" (despite +// __has_attribute(retain) being 1). +#if defined(__clang__) && __has_attribute(retain) +#define LLVM_ATTRIBUTE_RETAIN __attribute__((__retain__)) +#else +#define LLVM_ATTRIBUTE_RETAIN +#endif + #if defined(__clang__) #define LLVM_DEPRECATED(MSG, FIX) __attribute__((deprecated(MSG, FIX))) #else @@ -334,6 +429,12 @@ #define LLVM_GSL_POINTER #endif +#if LLVM_HAS_CPP_ATTRIBUTE(clang::lifetimebound) +#define LLVM_LIFETIME_BOUND [[clang::lifetimebound]] +#else +#define LLVM_LIFETIME_BOUND +#endif + #if LLVM_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L #define LLVM_CTOR_NODISCARD [[nodiscard]] #else @@ -534,7 +635,8 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); /// get stripped in release builds. // FIXME: Move this to a private config.h as it's not usable in public headers. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -#define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE LLVM_ATTRIBUTE_USED +#define LLVM_DUMP_METHOD \ + LLVM_ATTRIBUTE_NOINLINE LLVM_ATTRIBUTE_USED LLVM_ATTRIBUTE_RETAIN #else #define LLVM_DUMP_METHOD LLVM_ATTRIBUTE_NOINLINE #endif @@ -604,4 +706,28 @@ void AnnotateIgnoreWritesEnd(const char *file, int line); #define LLVM_PREFERRED_TYPE(T) #endif +/// \macro LLVM_VIRTUAL_ANCHOR_FUNCTION +/// This macro is used to adhere to LLVM's policy that each class with a vtable +/// must have at least one out-of-line virtual function. This macro allows us +/// to declare such a function in `final` classes without triggering a warning. +// clang-format off +// Autoformatting makes this look awful. +#if defined(__clang__) + // Make sure this is only parsed if __clang__ is defined + #if __has_warning("-Wunnecessary-virtual-specifier") + #define LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION() \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wunnecessary-virtual-specifier\"") \ + virtual void anchor() \ + _Pragma("clang diagnostic pop") + #else // __has_warning + #define LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION() \ + virtual void anchor() + #endif +#else // defined(__clang__) + #define LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION() \ + virtual void anchor() +#endif +// clang-format on + #endif diff --git a/symbolic-demangle/vendor/swift/include/llvm/Support/ErrorHandling.h b/symbolic-demangle/vendor/swift/include/llvm/Support/ErrorHandling.h index 9c8e3448f..4c17b6e83 100644 --- a/symbolic-demangle/vendor/swift/include/llvm/Support/ErrorHandling.h +++ b/symbolic-demangle/vendor/swift/include/llvm/Support/ErrorHandling.h @@ -17,63 +17,84 @@ #include "llvm/Support/Compiler.h" namespace llvm { - class StringRef; - class Twine; - - /// An error handler callback. - typedef void (*fatal_error_handler_t)(void *user_data, - const char *reason, - bool gen_crash_diag); - - /// install_fatal_error_handler - Installs a new error handler to be used - /// whenever a serious (non-recoverable) error is encountered by LLVM. - /// - /// If no error handler is installed the default is to print the error message - /// to stderr, and call exit(1). If an error handler is installed then it is - /// the handler's responsibility to log the message, it will no longer be - /// printed to stderr. If the error handler returns, then exit(1) will be - /// called. - /// - /// It is dangerous to naively use an error handler which throws an exception. - /// Even though some applications desire to gracefully recover from arbitrary - /// faults, blindly throwing exceptions through unfamiliar code isn't a way to - /// achieve this. - /// - /// \param user_data - An argument which will be passed to the install error - /// handler. - void install_fatal_error_handler(fatal_error_handler_t handler, - void *user_data = nullptr); - - /// Restores default error handling behaviour. - void remove_fatal_error_handler(); - - /// ScopedFatalErrorHandler - This is a simple helper class which just - /// calls install_fatal_error_handler in its constructor and - /// remove_fatal_error_handler in its destructor. - struct ScopedFatalErrorHandler { - explicit ScopedFatalErrorHandler(fatal_error_handler_t handler, - void *user_data = nullptr) { - install_fatal_error_handler(handler, user_data); - } - - ~ScopedFatalErrorHandler() { remove_fatal_error_handler(); } - }; - -/// Reports a serious error, calling any installed error handler. These -/// functions are intended to be used for error conditions which are outside -/// the control of the compiler (I/O errors, invalid user input, etc.) +class StringRef; +class Twine; + +/// An error handler callback. +typedef void (*fatal_error_handler_t)(void *user_data, const char *reason, + bool gen_crash_diag); + +/// install_fatal_error_handler - Installs a new error handler to be used +/// whenever a serious (non-recoverable) error is encountered by LLVM. +/// +/// If no error handler is installed the default is to print the error message +/// to stderr, and call exit(1). If an error handler is installed then it is +/// the handler's responsibility to log the message, it will no longer be +/// printed to stderr. If the error handler returns, then exit(1) will be +/// called. /// -/// If no error handler is installed the default is to print the message to -/// standard error, followed by a newline. -/// After the error handler is called this function will call abort(), it -/// does not return. -/// NOTE: The std::string variant was removed to avoid a dependency. -[[noreturn]] void report_fatal_error(const char *reason, - bool gen_crash_diag = true); -[[noreturn]] void report_fatal_error(StringRef reason, - bool gen_crash_diag = true); -[[noreturn]] void report_fatal_error(const Twine &reason, - bool gen_crash_diag = true); +/// It is dangerous to naively use an error handler which throws an exception. +/// Even though some applications desire to gracefully recover from arbitrary +/// faults, blindly throwing exceptions through unfamiliar code isn't a way to +/// achieve this. +/// +/// \param user_data - An argument which will be passed to the install error +/// handler. +LLVM_ABI void install_fatal_error_handler(fatal_error_handler_t handler, + void *user_data = nullptr); + +/// Restores default error handling behaviour. +LLVM_ABI void remove_fatal_error_handler(); + +/// ScopedFatalErrorHandler - This is a simple helper class which just +/// calls install_fatal_error_handler in its constructor and +/// remove_fatal_error_handler in its destructor. +struct ScopedFatalErrorHandler { + explicit ScopedFatalErrorHandler(fatal_error_handler_t handler, + void *user_data = nullptr) { + install_fatal_error_handler(handler, user_data); + } + + ~ScopedFatalErrorHandler() { remove_fatal_error_handler(); } +}; + +/// @deprecated Use reportFatalInternalError() or reportFatalUsageError() +/// instead. +[[noreturn]] LLVM_ABI void report_fatal_error(const char *reason, + bool gen_crash_diag = true); +[[noreturn]] LLVM_ABI void report_fatal_error(StringRef reason, + bool gen_crash_diag = true); +[[noreturn]] LLVM_ABI void report_fatal_error(const Twine &reason, + bool gen_crash_diag = true); + +/// Report a fatal error that likely indicates a bug in LLVM. It serves a +/// similar purpose as an assertion, but is always enabled, regardless of the +/// value of NDEBUG. +/// +/// This will call installed error handlers (or print the message by default) +/// and then abort. This will produce a crash trace and *will* ask users to +/// report an LLVM bug. +[[noreturn]] LLVM_ABI void reportFatalInternalError(const char *reason); +[[noreturn]] LLVM_ABI void reportFatalInternalError(StringRef reason); +[[noreturn]] LLVM_ABI void reportFatalInternalError(const Twine &reason); + +/// Report a fatal error that does not indicate a bug in LLVM. +/// +/// This can be used in contexts where a proper error reporting mechanism +/// (such as Error/Expected or DiagnosticInfo) is currently not supported, and +/// would be too involved to introduce at the moment. +/// +/// Examples where this function should be used instead of +/// reportFatalInternalError() include invalid inputs or options, but also +/// environment error conditions outside LLVM's control. It should also be used +/// for known unsupported/unimplemented functionality. +/// +/// This will call installed error handlers (or print the message by default) +/// and then exit with code 1. It will not produce a crash trace and will +/// *not* ask users to report an LLVM bug. +[[noreturn]] LLVM_ABI void reportFatalUsageError(const char *reason); +[[noreturn]] LLVM_ABI void reportFatalUsageError(StringRef reason); +[[noreturn]] LLVM_ABI void reportFatalUsageError(const Twine &reason); /// Installs a new bad alloc error handler that should be used whenever a /// bad alloc error, e.g. failing malloc/calloc, is encountered by LLVM. @@ -91,13 +112,13 @@ namespace llvm { /// /// \param user_data - An argument which will be passed to the installed error /// handler. -void install_bad_alloc_error_handler(fatal_error_handler_t handler, - void *user_data = nullptr); +LLVM_ABI void install_bad_alloc_error_handler(fatal_error_handler_t handler, + void *user_data = nullptr); /// Restores default bad alloc error handling behavior. -void remove_bad_alloc_error_handler(); +LLVM_ABI void remove_bad_alloc_error_handler(); -void install_out_of_memory_new_handler(); +LLVM_ABI void install_out_of_memory_new_handler(); /// Reports a bad alloc error, calling any user defined bad alloc /// error handler. In contrast to the generic 'report_fatal_error' @@ -111,16 +132,16 @@ void install_out_of_memory_new_handler(); /// If no error handler is installed (default), throws a bad_alloc exception /// if LLVM is compiled with exception support. Otherwise prints the error /// to standard error and calls abort(). -[[noreturn]] void report_bad_alloc_error(const char *Reason, - bool GenCrashDiag = true); +[[noreturn]] LLVM_ABI void report_bad_alloc_error(const char *Reason, + bool GenCrashDiag = true); /// This function calls abort(), and prints the optional message to stderr. /// Use the llvm_unreachable macro (that adds location info), instead of /// calling this function directly. -[[noreturn]] void -llvm_unreachable_internal(const char *msg = nullptr, const char *file = nullptr, - unsigned line = 0); -} +[[noreturn]] LLVM_ABI void llvm_unreachable_internal(const char *msg = nullptr, + const char *file = nullptr, + unsigned line = 0); +} // namespace llvm /// Marks that the current location is not supposed to be reachable. /// In !NDEBUG builds, prints the message and location info to stderr. @@ -140,7 +161,7 @@ llvm_unreachable_internal(const char *msg = nullptr, const char *file = nullptr, /// diagnostics for unreachable code paths, and allows compilers to omit /// unnecessary code. #ifndef NDEBUG -#define llvm_unreachable(msg) \ +#define llvm_unreachable(msg) \ ::llvm::llvm_unreachable_internal(msg, __FILE__, __LINE__) #elif !defined(LLVM_BUILTIN_UNREACHABLE) #define llvm_unreachable(msg) ::llvm::llvm_unreachable_internal() diff --git a/symbolic-demangle/vendor/swift/include/llvm/Support/PointerLikeTypeTraits.h b/symbolic-demangle/vendor/swift/include/llvm/Support/PointerLikeTypeTraits.h new file mode 100644 index 000000000..1b15f930b --- /dev/null +++ b/symbolic-demangle/vendor/swift/include/llvm/Support/PointerLikeTypeTraits.h @@ -0,0 +1,152 @@ +//===- llvm/Support/PointerLikeTypeTraits.h - Pointer Traits ----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the PointerLikeTypeTraits class. This allows data +// structures to reason about pointers and other things that are pointer sized. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_POINTERLIKETYPETRAITS_H +#define LLVM_SUPPORT_POINTERLIKETYPETRAITS_H + +#include "llvm/Support/DataTypes.h" +#include +#include + +namespace llvm { + +/// A traits type that is used to handle pointer types and things that are just +/// wrappers for pointers as a uniform entity. +template struct PointerLikeTypeTraits; + +namespace detail { +/// A tiny meta function to compute the log2 of a compile time constant. +template +struct ConstantLog2 + : std::integral_constant::value + 1> {}; +template <> struct ConstantLog2<1> : std::integral_constant {}; + +// Provide a trait to check if T is pointer-like. +template struct HasPointerLikeTypeTraits { + static const bool value = false; +}; + +// sizeof(T) is valid only for a complete T. +template +struct HasPointerLikeTypeTraits< + T, decltype((sizeof(PointerLikeTypeTraits) + sizeof(T)), void())> { + static const bool value = true; +}; + +template struct IsPointerLike { + static const bool value = HasPointerLikeTypeTraits::value; +}; + +template struct IsPointerLike { + static const bool value = true; +}; +} // namespace detail + +// Provide PointerLikeTypeTraits for non-cvr pointers. +template struct PointerLikeTypeTraits { + static inline void *getAsVoidPointer(T *P) { return P; } + static inline T *getFromVoidPointer(void *P) { return static_cast(P); } + + static constexpr int NumLowBitsAvailable = + detail::ConstantLog2::value; +}; + +template <> struct PointerLikeTypeTraits { + static inline void *getAsVoidPointer(void *P) { return P; } + static inline void *getFromVoidPointer(void *P) { return P; } + + /// Note, we assume here that void* is related to raw malloc'ed memory and + /// that malloc returns objects at least 4-byte aligned. However, this may be + /// wrong, or pointers may be from something other than malloc. In this case, + /// you should specify a real typed pointer or avoid this template. + /// + /// All clients should use assertions to do a run-time check to ensure that + /// this is actually true. + static constexpr int NumLowBitsAvailable = 2; +}; + +// Provide PointerLikeTypeTraits for const things. +template struct PointerLikeTypeTraits { + typedef PointerLikeTypeTraits NonConst; + + static inline const void *getAsVoidPointer(const T P) { + return NonConst::getAsVoidPointer(P); + } + static inline const T getFromVoidPointer(const void *P) { + return NonConst::getFromVoidPointer(const_cast(P)); + } + static constexpr int NumLowBitsAvailable = NonConst::NumLowBitsAvailable; +}; + +// Provide PointerLikeTypeTraits for const pointers. +template struct PointerLikeTypeTraits { + typedef PointerLikeTypeTraits NonConst; + + static inline const void *getAsVoidPointer(const T *P) { + return NonConst::getAsVoidPointer(const_cast(P)); + } + static inline const T *getFromVoidPointer(const void *P) { + return NonConst::getFromVoidPointer(const_cast(P)); + } + static constexpr int NumLowBitsAvailable = NonConst::NumLowBitsAvailable; +}; + +// Provide PointerLikeTypeTraits for uintptr_t. +template <> struct PointerLikeTypeTraits { + static inline void *getAsVoidPointer(uintptr_t P) { + return reinterpret_cast(P); + } + static inline uintptr_t getFromVoidPointer(void *P) { + return reinterpret_cast(P); + } + // No bits are available! + static constexpr int NumLowBitsAvailable = 0; +}; + +/// Provide suitable custom traits struct for function pointers. +/// +/// Function pointers can't be directly given these traits as functions can't +/// have their alignment computed with `alignof` and we need different casting. +/// +/// To rely on higher alignment for a specialized use, you can provide a +/// customized form of this template explicitly with higher alignment, and +/// potentially use alignment attributes on functions to satisfy that. +template +struct FunctionPointerLikeTypeTraits { + static constexpr int NumLowBitsAvailable = + detail::ConstantLog2::value; + static inline void *getAsVoidPointer(FunctionPointerT P) { + assert((reinterpret_cast(P) & + ~((uintptr_t)-1 << NumLowBitsAvailable)) == 0 && + "Alignment not satisfied for an actual function pointer!"); + return reinterpret_cast(P); + } + static inline FunctionPointerT getFromVoidPointer(void *P) { + return reinterpret_cast(P); + } +}; + +/// Provide a default specialization for function pointers that assumes 4-byte +/// alignment. +/// +/// We assume here that functions used with this are always at least 4-byte +/// aligned. This means that, for example, thumb functions won't work or systems +/// with weird unaligned function pointers won't work. But all practical systems +/// we support satisfy this requirement. +template +struct PointerLikeTypeTraits + : FunctionPointerLikeTypeTraits<4, ReturnT (*)(ParamTs...)> {}; + +} // end namespace llvm + +#endif diff --git a/symbolic-demangle/vendor/swift/include/swift/Basic/InlineBitfield.h b/symbolic-demangle/vendor/swift/include/swift/Basic/InlineBitfield.h index b41ae018d..1378115ae 100644 --- a/symbolic-demangle/vendor/swift/include/swift/Basic/InlineBitfield.h +++ b/symbolic-demangle/vendor/swift/include/swift/Basic/InlineBitfield.h @@ -41,7 +41,7 @@ namespace swift { uint64_t : 64 - (C); /* Better code gen */ \ } T; \ LLVM_PACKED_END \ - enum { Num##T##Bits = (C) }; \ + enum { NumberOf##T##Bits = (C) }; \ static_assert(sizeof(T##Bitfield) <= 8, "Bitfield overflow") /// Define an bitfield for type 'T' with parent class 'U' and 'C' bits used. @@ -49,11 +49,11 @@ namespace swift { LLVM_PACKED_START \ class T##Bitfield { \ friend class T; \ - uint64_t : Num##U##Bits, __VA_ARGS__; \ - uint64_t : 64 - (Num##U##Bits + (HC) + (C)); /* Better code gen */ \ + uint64_t : NumberOf##U##Bits, __VA_ARGS__; \ + uint64_t : 64 - (NumberOf##U##Bits + (HC) + (C)); /* Better code gen */ \ } T; \ LLVM_PACKED_END \ - enum { Num##T##Bits = Num##U##Bits + (C) }; \ + enum { NumberOf##T##Bits = NumberOf##U##Bits + (C) }; \ static_assert(sizeof(T##Bitfield) <= 8, "Bitfield overflow") #define SWIFT_INLINE_BITFIELD(T, U, C, ...) \ @@ -75,8 +75,8 @@ namespace swift { LLVM_PACKED_START \ class T##Bitfield { \ friend class T; \ - enum { NumPadBits = 64 - (Num##U##Bits + (C)) }; \ - uint64_t : Num##U##Bits, __VA_ARGS__; \ + enum { NumPadBits = 64 - (NumberOf##U##Bits + (C)) }; \ + uint64_t : NumberOf##U##Bits, __VA_ARGS__; \ } T; \ LLVM_PACKED_END \ static_assert(sizeof(T##Bitfield) <= 8, "Bitfield overflow") @@ -101,15 +101,15 @@ namespace swift { class T##Bitfield { \ template \ friend class T; \ - enum { NumPadBits = 64 - (Num##U##Bits + (C)) }; \ - uint64_t : Num##U##Bits, __VA_ARGS__; \ + enum { NumPadBits = 64 - (NumberOf##U##Bits + (C)) }; \ + uint64_t : NumberOf##U##Bits, __VA_ARGS__; \ } T; \ LLVM_PACKED_END \ static_assert(sizeof(T##Bitfield) <= 8, "Bitfield overflow") /// Define an empty bitfield for type 'T'. #define SWIFT_INLINE_BITFIELD_EMPTY(T, U) \ - enum { Num##T##Bits = Num##U##Bits } + enum { NumberOf##T##Bits = NumberOf##U##Bits } // XXX/HACK: templated max() doesn't seem to work in a bitfield size context. constexpr unsigned bitmax(unsigned a, unsigned b) { diff --git a/symbolic-demangle/vendor/swift/include/swift/Basic/LLVM.h b/symbolic-demangle/vendor/swift/include/swift/Basic/LLVM.h index 827d360b8..3a8c25b53 100644 --- a/symbolic-demangle/vendor/swift/include/swift/Basic/LLVM.h +++ b/symbolic-demangle/vendor/swift/include/swift/Basic/LLVM.h @@ -34,10 +34,10 @@ // Don't pre-declare certain LLVM types in the runtime, which must // not put things in namespace llvm for ODR reasons. -#if !defined(swiftCore_EXPORTS) -#define SWIFT_LLVM_ODR_SAFE 1 -#else +#if defined(SWIFT_RUNTIME) #define SWIFT_LLVM_ODR_SAFE 0 +#else +#define SWIFT_LLVM_ODR_SAFE 1 #endif // Forward declarations. diff --git a/symbolic-demangle/vendor/swift/include/swift/Basic/STLExtras.h b/symbolic-demangle/vendor/swift/include/swift/Basic/STLExtras.h index 28a721317..4b844224a 100644 --- a/symbolic-demangle/vendor/swift/include/swift/Basic/STLExtras.h +++ b/symbolic-demangle/vendor/swift/include/swift/Basic/STLExtras.h @@ -793,6 +793,82 @@ auto transform(const std::optional &value, } return std::nullopt; } + +/// A little wrapper that either wraps a `T &&` or a `const T &`. +/// It allows you to defer the optimal decision about how to +/// forward the value to runtime. +template +class maybe_movable_ref { + /// Actually a T&& if movable is true. + const T &ref; + bool movable; + +public: + // The maybe_movable_ref wrapper itself is, basically, either an + // r-value reference or an l-value reference. It is therefore + // move-only so that code working with it has to properly + // forward it around. + maybe_movable_ref(maybe_movable_ref &&other) = default; + maybe_movable_ref &operator=(maybe_movable_ref &&other) = default; + + maybe_movable_ref(const maybe_movable_ref &other) = delete; + maybe_movable_ref &operator=(const maybe_movable_ref &other) = delete; + + /// Allow the wrapper to be statically constructed from an r-value + /// reference in the movable state. + maybe_movable_ref(T &&ref) : ref(ref), movable(true) {} + + /// Allow the wrapper to be statically constructed from a + /// const l-value reference in the non-movable state. + maybe_movable_ref(const T &ref) : ref(ref), movable(false) {} + + /// Don't allow the wrapper to be statically constructed from + /// a non-const l-value reference without passing a flag + /// dynamically. + maybe_movable_ref(T &ref) = delete; + + /// The fully-general constructor. + maybe_movable_ref(T &ref, bool movable) : ref(ref), movable(movable) {} + + /// Check dynamically whether the reference is movable. + bool isMovable() const { + return movable; + } + + /// Construct a T from the wrapped reference. + T construct() && { + if (isMovable()) { + return T(move()); + } else { + return T(ref); + } + } + + /// Get access to the value, conservatively returning a const + /// reference. + const T &get() const { + return ref; + } + + /// Get access to the value, dynamically aserting that it is movable. + T &get_mutable() const { + assert(isMovable()); + return const_cast(ref); + } + + /// Return an r-value reference to the value, dynamically asserting + /// that it is movable. + T &&move() { + assert(isMovable()); + return static_cast(const_cast(ref)); + } +}; + +template +maybe_movable_ref move_if(T &ref, bool movable) { + return maybe_movable_ref(ref, movable); +} + } // end namespace swift #endif // SWIFT_BASIC_STLEXTRAS_H diff --git a/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangle.h b/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangle.h index 940c36520..e24aa0a3b 100644 --- a/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangle.h +++ b/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangle.h @@ -19,13 +19,17 @@ #ifndef SWIFT_DEMANGLING_DEMANGLE_H #define SWIFT_DEMANGLING_DEMANGLE_H +#include "swift/Demangling/Demangle.h" #include "swift/Demangling/Errors.h" +#include "swift/Demangling/ManglingFlavor.h" #include "swift/Demangling/NamespaceMacros.h" +#include "swift/Strings.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Compiler.h" #include #include +#include #include #include #include @@ -99,6 +103,7 @@ struct DemangleOptions { class Node; using NodePointer = Node *; +class NodePrinter; enum class FunctionSigSpecializationParamKind : unsigned { // Option Flags use bits 0-5. This give us 6 bits implying 64 entries to @@ -113,6 +118,8 @@ enum class FunctionSigSpecializationParamKind : unsigned { BoxToStack = 7, InOutToOut = 8, ConstantPropKeyPath = 9, + ConstantPropStruct = 10, + ClosurePropPreviousArg = 11, // Option Set Flags use bits 6-31. This gives us 26 bits to use for option // flags. @@ -138,7 +145,10 @@ enum class MangledDifferentiabilityKind : char { Linear = 'l', }; -enum class MangledLifetimeDependenceKind : char { Inherit = 'i', Scope = 's' }; +enum class MangledSILThunkKind : char { + Invalid = 0, + Identity = 'I', +}; /// The pass that caused the specialization to occur. We use this to make sure /// that two passes that generate similar changes do not yield the same @@ -156,7 +166,9 @@ enum class SpecializationPass : uint8_t { GenericSpecializer, MoveDiagnosticInOutToOut, AsyncDemotion, - LAST = AsyncDemotion + PackSpecialization, + EmbeddedWitnessCallSpecialization, + LAST = EmbeddedWitnessCallSpecialization }; constexpr uint8_t MAX_SPECIALIZATION_PASS = 10; @@ -187,6 +199,7 @@ class Node { }; using IndexType = uint64_t; + using RemoteAddressType = std::pair; friend class NodeFactory; @@ -203,14 +216,20 @@ class Node { IndexType Index; NodePointer InlineChildren[2]; NodeVector Children; + RemoteAddressType RemoteAddress; }; Kind NodeKind; enum class PayloadKind : uint8_t { - None = 0, OneChild = 1, TwoChildren = 2, - Text, Index, ManyChildren + None = 0, + OneChild = 1, + TwoChildren = 2, + Text, + Index, + ManyChildren, + RemoteAddress }; PayloadKind NodePayloadKind; @@ -225,6 +244,10 @@ class Node { : NodeKind(k), NodePayloadKind(PayloadKind::Index) { Index = index; } + Node(Kind k, uint64_t remoteAddress, uint8_t addressSpace) + : NodeKind(k), NodePayloadKind(PayloadKind::RemoteAddress) { + RemoteAddress = {remoteAddress, addressSpace}; + } Node(const Node &) = delete; Node &operator=(const Node &) = delete; @@ -247,6 +270,25 @@ class Node { } } + static bool deepEquals(const Node *lhs, const Node *rhs) { + if (lhs == rhs) + return true; + if ((!lhs && rhs) || (lhs && !rhs)) + return false; + if (!lhs->isSimilarTo(rhs)) + return false; + for (auto li = lhs->begin(), ri = rhs->begin(), le = lhs->end(); li != le; + ++li, ++ri) { + if (!deepEquals(*li, *ri)) + return false; + } + return true; + } + + bool isDeepEqualTo(const Node *other) const { + return deepEquals(this, other); + } + bool hasText() const { return NodePayloadKind == PayloadKind::Text; } llvm::StringRef getText() const { assert(hasText()); @@ -259,6 +301,14 @@ class Node { return Index; } + bool hasRemoteAddress() const { + return NodePayloadKind == PayloadKind::RemoteAddress; + } + std::pair getRemoteAddress() const { + assert(hasRemoteAddress()); + return RemoteAddress; + } + using iterator = const NodePointer *; size_t getNumChildren() const { @@ -443,16 +493,26 @@ class Context { /// The lifetime of the returned node tree ends with the lifetime of the /// context or with a call of clear(). NodePointer demangleTypeAsNode(llvm::StringRef MangledName); - + /// Demangle the given symbol and return the readable name. /// /// \param MangledName The mangled symbol string, which start a mangling /// prefix: _T, _T0, $S, _$S. /// /// \returns The demangled string. - std::string demangleSymbolAsString( - llvm::StringRef MangledName, - const DemangleOptions &Options = DemangleOptions()); + std::string + demangleSymbolAsString(llvm::StringRef MangledName, + const DemangleOptions &Options = DemangleOptions()); + + /// Demangle the given symbol and store the result in the `printer`. + /// + /// \param MangledName The mangled symbol string, which start a mangling + /// prefix: _T, _T0, $S, _$S. + /// \param Printer The NodePrinter that will be used to demangle the symbol. + /// + /// \returns The demangled string. + void demangleSymbolAsString(llvm::StringRef MangledName, + NodePrinter &Printer); /// Demangle the given type and return the readable name. /// @@ -511,6 +571,16 @@ std::string demangleSymbolAsString(const char *mangledName, size_t mangledNameLength, const DemangleOptions &options = DemangleOptions()); +/// Standalone utility function to demangle the given symbol as string. The +/// demangled string is stored in the `printer`. +/// +/// If performance is an issue when demangling multiple symbols, +/// \param mangledName The mangled name string pointer. +/// \param mangledNameLength The length of the mangledName string. +/// \param printer The NodePrinter that will be used to demangle the symbol. +void demangleSymbolAsString(const llvm::StringRef mangledName, + NodePrinter &printer); + /// Standalone utility function to demangle the given symbol as string. /// /// If performance is an issue when demangling multiple symbols, @@ -523,7 +593,7 @@ demangleSymbolAsString(const std::string &mangledName, return demangleSymbolAsString(mangledName.data(), mangledName.size(), options); } - + /// Standalone utility function to demangle the given symbol as string. /// /// If performance is an issue when demangling multiple symbols, @@ -601,9 +671,10 @@ struct [[nodiscard]] ManglingError { UnknownEncoding, InvalidImplCalleeConvention, InvalidImplDifferentiability, + InvalidImplCoroutineKind, InvalidImplFunctionAttribute, InvalidImplParameterConvention, - InvalidImplParameterSending, + InvalidImplParameterAttr, InvalidMetatypeRepresentation, MultiByteRelatedEntity, BadValueWitnessKind, @@ -651,24 +722,27 @@ class [[nodiscard]] ManglingErrorOr { }; /// Remangle a demangled parse tree. -ManglingErrorOr mangleNode(NodePointer root); +ManglingErrorOr +mangleNode(NodePointer root, + Mangle::ManglingFlavor Flavor = Mangle::ManglingFlavor::Default); -using SymbolicResolver = - llvm::function_ref; +using SymbolicResolver = llvm::function_ref; /// Remangle a demangled parse tree, using a callback to resolve /// symbolic references. -ManglingErrorOr mangleNode(NodePointer root, SymbolicResolver resolver); +ManglingErrorOr +mangleNode(NodePointer root, SymbolicResolver resolver, + Mangle::ManglingFlavor Flavor = Mangle::ManglingFlavor::Default); /// Remangle a demangled parse tree, using a callback to resolve /// symbolic references. /// /// The returned string is owned by \p Factory. This means \p Factory must stay /// alive as long as the returned string is used. -ManglingErrorOr mangleNode(NodePointer root, - SymbolicResolver resolver, - NodeFactory &Factory); +ManglingErrorOr +mangleNode(NodePointer root, SymbolicResolver resolver, NodeFactory &Factory, + Mangle::ManglingFlavor Flavor = Mangle::ManglingFlavor::Default); /// Remangle in the old mangling scheme. /// @@ -699,13 +773,19 @@ ManglingErrorOr mangleNodeAsObjcCString(NodePointer node, /// \endcode /// /// \param Root A pointer to a parse tree generated by the demangler. -/// \param Options An object encapsulating options to use to perform this demangling. +/// \param Options An object encapsulating options to use to perform this +/// demangling. /// /// \returns A string representing the demangled name. -/// std::string nodeToString(NodePointer Root, const DemangleOptions &Options = DemangleOptions()); +/// Transform the node structure to a string, which is stored in the `Printer`. +/// +/// \param Root A pointer to a parse tree generated by the demangler. +/// \param Printer A NodePrinter used to pretty print the demangled Node. +void nodeToString(NodePointer Root, NodePrinter &Printer); + /// Transforms a mangled key path accessor thunk helper /// into the identfier/subscript that would be used to invoke it in swift code. std::string keyPathSourceString(const char *MangledName, @@ -751,11 +831,14 @@ class DemanglerPrinter { llvm::StringRef getStringRef() const { return Stream; } + size_t getStreamLength() { return Stream.length(); } + /// Shrinks the buffer. void resetSize(size_t toPos) { assert(toPos <= Stream.size()); Stream.resize(toPos); } + private: std::string Stream; }; @@ -788,9 +871,165 @@ llvm::StringRef makeSymbolicMangledNameStringRef(const char *base); /// Produce the mangled name for the nominal type descriptor of a type /// referenced by its module and type name. -std::string mangledNameForTypeMetadataAccessor(llvm::StringRef moduleName, - llvm::StringRef typeName, - Node::Kind typeKind); +std::string mangledNameForTypeMetadataAccessor( + llvm::StringRef moduleName, llvm::StringRef typeName, Node::Kind typeKind, + Mangle::ManglingFlavor Flavor = Mangle::ManglingFlavor::Default); + +/// Base class for printing a Swift demangled node tree. +/// +/// NodePrinter is used to convert demangled Swift symbol nodes into +/// human-readable string representations. It handles formatting, indentation, +/// and Swift-specific syntax. +/// +/// The virtual methods in this class are meant to be overriden to allow +/// external consumers (e.g lldb) to track the ranges of components of the +/// demangled name. +class NodePrinter { +protected: + DemanglerPrinter Printer; + DemangleOptions Options; + bool SpecializationPrefixPrinted = false; + bool isValid = true; + +public: + NodePrinter(DemangleOptions options) : Options(options) {} + + virtual ~NodePrinter() = default; + + virtual void printRoot(NodePointer root) { + isValid = true; + print(root, 0); + } + + std::string takeString() { + if (isValid) + return std::move(Printer).str(); + return ""; + } + +protected: + static const unsigned MaxDepth = 768; + + size_t getStreamLength() { return Printer.getStreamLength(); } + + /// Called when the node tree in valid. + /// + /// The demangler already catches most error cases and mostly produces valid + /// node trees. But some cases are difficult to catch in the demangler and + /// instead the NodePrinter bails. + void setInvalid() { isValid = false; } + + void printChildren(Node::iterator begin, Node::iterator end, unsigned depth, + const char *sep = nullptr); + + void printChildren(NodePointer Node, unsigned depth, + const char *sep = nullptr); + + NodePointer getFirstChildOfKind(NodePointer Node, Node::Kind kind); + + void printBoundGenericNoSugar(NodePointer Node, unsigned depth); + + void printOptionalIndex(NodePointer node); + + static bool isSwiftModule(NodePointer node) { + return (node->getKind() == Node::Kind::Module && + node->getText() == STDLIB_NAME); + } + + static bool isIdentifier(NodePointer node, StringRef desired) { + return (node->getKind() == Node::Kind::Identifier && + node->getText() == desired); + } + + bool printContext(NodePointer Context); + + enum class SugarType { + None, + Optional, + ImplicitlyUnwrappedOptional, + Array, + Dictionary + }; + + enum class TypePrinting { NoType, WithColon, FunctionStyle }; + + /// Determine whether this is a "simple" type, from the type-simple + /// production. + bool isSimpleType(NodePointer Node); + + void printWithParens(NodePointer type, unsigned depth); + + SugarType findSugar(NodePointer Node); + + void printBoundGeneric(NodePointer Node, unsigned depth); + + NodePointer getChildIf(NodePointer Node, Node::Kind Kind); + + virtual void printFunctionParameters(NodePointer LabelList, + NodePointer ParameterType, + unsigned depth, bool showTypes); + + void printFunctionType(NodePointer LabelList, NodePointer node, + unsigned depth); + + void printImplFunctionType(NodePointer fn, unsigned depth); + + virtual void printGenericSignature(NodePointer Node, unsigned depth); + + void printFunctionSigSpecializationParams(NodePointer Node, unsigned depth); + void printNextParamChildNode(NodePointer nd, unsigned &idx, + FunctionSigSpecializationParamKind kind, + unsigned depth); + + void printSpecializationPrefix(NodePointer node, StringRef Description, + unsigned depth, + StringRef ParamPrefix = StringRef()); + + /// The main big print function. + NodePointer print(NodePointer Node, unsigned depth, + bool asPrefixContext = false); + + NodePointer printAbstractStorage(NodePointer Node, unsigned depth, + bool asPrefixContent, StringRef ExtraName); + + /// Utility function to print entities. + /// + /// \param Entity The entity node to print + /// \param depth The depth in the print() call tree. + /// \param asPrefixContext Should the entity printed as a context which as a + /// prefix to another entity, e.g. the Abc in Abc.def() + /// \param TypePr How should the type of the entity be printed, if at all. + /// E.g. with a colon for properties or as a function type. + /// \param hasName Does the entity has a name, e.g. a function in contrast to + /// an initializer. + /// \param ExtraName An extra name added to the entity name (if any). + /// \param ExtraIndex An extra index added to the entity name (if any), + /// e.g. closure #1 + /// \param OverwriteName If non-empty, print this name instead of the one + /// provided by the node. Gets printed even if hasName is false. + /// \return If a non-null node is returned it's a context which must be + /// printed in postfix-form after the entity: " in ". + NodePointer printEntity(NodePointer Entity, unsigned depth, + bool asPrefixContext, TypePrinting TypePr, + bool hasName, StringRef ExtraName = "", + int ExtraIndex = -1, StringRef OverwriteName = ""); + + virtual void printFunctionName(bool hasName, llvm::StringRef &OverwriteName, + llvm::StringRef &ExtraName, bool MultiWordName, + int &ExtraIndex, + swift::Demangle::NodePointer Entity, + unsigned int depth); + + /// Print the type of an entity. + /// + /// \param Entity The entity. + /// \param type The type of the entity. + /// \param genericFunctionTypeList If not null, the generic argument types + /// which is printed in the generic signature. + /// \param depth The depth in the print() call tree. + void printEntityType(NodePointer Entity, NodePointer type, + NodePointer genericFunctionTypeList, unsigned depth); +}; SWIFT_END_INLINE_NAMESPACE } // end namespace Demangle diff --git a/symbolic-demangle/vendor/swift/include/swift/Demangling/DemangleNodes.def b/symbolic-demangle/vendor/swift/include/swift/Demangling/DemangleNodes.def index c872f1be9..13c70245f 100644 --- a/symbolic-demangle/vendor/swift/include/swift/Demangling/DemangleNodes.def +++ b/symbolic-demangle/vendor/swift/include/swift/Demangling/DemangleNodes.def @@ -46,6 +46,7 @@ NODE(BoundGenericTypeAlias) NODE(BoundGenericFunction) NODE(BuiltinTypeName) NODE(BuiltinTupleType) +NODE(BuiltinFixedArray) NODE(CFunctionPointer) NODE(ClangType) CONTEXT_NODE(Class) @@ -74,6 +75,7 @@ NODE(DependentPseudogenericSignature) NODE(DependentProtocolConformanceRoot) NODE(DependentProtocolConformanceInherited) NODE(DependentProtocolConformanceAssociated) +NODE(DependentProtocolConformanceOpaque) CONTEXT_NODE(Destructor) CONTEXT_NODE(DidSet) NODE(Directness) @@ -136,10 +138,13 @@ NODE(ImplErasedIsolation) NODE(ImplSendingResult) NODE(ImplParameterResultDifferentiability) NODE(ImplParameterSending) +NODE(ImplParameterIsolated) +NODE(ImplParameterImplicitLeading) NODE(ImplFunctionAttribute) NODE(ImplFunctionConvention) NODE(ImplFunctionConventionName) NODE(ImplFunctionType) +NODE(ImplCoroutineKind) NODE(ImplInvocationSubstitutions) CONTEXT_NODE(ImplicitClosure) NODE(ImplParameter) @@ -152,11 +157,15 @@ NODE(InfixOperator) CONTEXT_NODE(Initializer) CONTEXT_NODE(InitAccessor) NODE(Isolated) +CONTEXT_NODE(IsolatedDeallocator) NODE(Sending) NODE(IsolatedAnyFunctionType) +NODE(NonIsolatedCallerFunctionType) NODE(SendingResultFunctionType) NODE(KeyPathGetterThunkHelper) NODE(KeyPathSetterThunkHelper) +NODE(KeyPathUnappliedMethodThunkHelper) +NODE(KeyPathAppliedMethodThunkHelper) NODE(KeyPathEqualsThunkHelper) NODE(KeyPathHashThunkHelper) NODE(LazyProtocolWitnessTableAccessor) @@ -177,6 +186,7 @@ NODE(ObjCMetadataUpdateFunction) NODE(ObjCResilientClassStub) NODE(FullObjCResilientClassStub) CONTEXT_NODE(ModifyAccessor) +CONTEXT_NODE(Modify2Accessor) CONTEXT_NODE(Module) CONTEXT_NODE(NativeOwningAddressor) CONTEXT_NODE(NativeOwningMutableAddressor) @@ -187,7 +197,7 @@ NODE(NominalTypeDescriptorRecord) NODE(NonObjCAttribute) NODE(Number) NODE(ObjCAsyncCompletionHandlerImpl) -NODE(PredefinedObjCAsyncCompletionHandlerImpl) +NODE(CheckedObjCAsyncCompletionHandlerImpl) NODE(ObjCAttribute) NODE(ObjCBlock) NODE(EscapingObjCBlock) @@ -203,6 +213,7 @@ NODE(PrefixOperator) NODE(PrivateDeclName) NODE(PropertyDescriptor) CONTEXT_NODE(PropertyWrapperBackingInitializer) +CONTEXT_NODE(PropertyWrappedFieldInitAccessor) CONTEXT_NODE(PropertyWrapperInitFromProjectedValue) CONTEXT_NODE(Protocol) CONTEXT_NODE(ProtocolSymbolicReference) @@ -229,6 +240,7 @@ NODE(ReabstractionThunkHelper) NODE(ReabstractionThunkHelperWithSelf) NODE(ReabstractionThunkHelperWithGlobalActor) CONTEXT_NODE(ReadAccessor) +CONTEXT_NODE(Read2Accessor) NODE(RelatedEntityDeclName) NODE(RetroactiveConformance) NODE(ReturnType) @@ -287,6 +299,7 @@ NODE(ReflectionMetadataAssocTypeDescriptor) NODE(ReflectionMetadataSuperclassDescriptor) NODE(GenericTypeParamDecl) NODE(CurryThunk) +NODE(SILThunkIdentity) NODE(DispatchThunk) NODE(MethodDescriptor) NODE(ProtocolRequirementsBaseDescriptor) @@ -321,7 +334,8 @@ NODE(AssociatedTypeGenericParamRef) NODE(SugaredOptional) NODE(SugaredArray) NODE(SugaredDictionary) -NODE(SugaredParen) +NODE(SugaredInlineArray) +NODE(SugaredParen) // Removed in Swift 6.TBD // Added in Swift 5.1 NODE(AccessorFunctionReference) @@ -362,7 +376,7 @@ NODE(AsyncSuspendResumePartialFunction) // Added in Swift 5.6 NODE(AccessibleFunctionRecord) -NODE(CompileTimeConst) +NODE(CompileTimeLiteral) // Added in Swift 5.7 NODE(BackDeploymentThunk) @@ -374,7 +388,7 @@ NODE(NonUniqueExtendedExistentialTypeShapeSymbolicReference) NODE(SymbolicExtendedExistentialType) // Added in Swift 5.8 -NODE(MetatypeParamsRemoved) +NODE(DroppedArgument) NODE(HasSymbolQuery) NODE(OpaqueReturnTypeIndex) NODE(OpaqueReturnTypeParent) @@ -385,12 +399,13 @@ NODE(OutlinedEnumProjectDataForLoad) NODE(OutlinedEnumGetTag) // Added in Swift 5.9 + 1 NODE(AsyncRemoved) +// Added in Swift 6.3 + 1 +NODE(RepresentationChanged) // Added in Swift 5.TBD NODE(ObjectiveCProtocolSymbolicReference) -NODE(ParamLifetimeDependence) -NODE(SelfLifetimeDependence) +NODE(OutlinedInitializeWithTakeNoValueWitness) NODE(OutlinedInitializeWithCopyNoValueWitness) NODE(OutlinedAssignWithTakeNoValueWitness) NODE(OutlinedAssignWithCopyNoValueWitness) @@ -398,5 +413,17 @@ NODE(OutlinedDestroyNoValueWitness) NODE(DependentGenericInverseConformanceRequirement) +// Added in Swift 6.2 +NODE(Integer) +NODE(NegativeInteger) +NODE(DependentGenericParamValueMarker) +NODE(CoroFunctionPointer) +NODE(DefaultOverride) +NODE(ConstValue) + +// Added in Swift 6.TBD +CONTEXT_NODE(BorrowAccessor) +CONTEXT_NODE(MutateAccessor) + #undef CONTEXT_NODE #undef NODE diff --git a/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangler.h b/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangler.h index a3b62f2c0..62f0298cf 100644 --- a/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangler.h +++ b/symbolic-demangle/vendor/swift/include/swift/Demangling/Demangler.h @@ -20,6 +20,7 @@ #define SWIFT_DEMANGLING_DEMANGLER_H #include "swift/Demangling/Demangle.h" +#include "swift/Demangling/ManglingFlavor.h" #include "swift/Demangling/NamespaceMacros.h" //#define NODE_FACTORY_DEBUGGING @@ -44,14 +45,14 @@ class NodeFactory { /// The end of the current slab. char *End = nullptr; - struct Slab { + struct AllocatedSlab { // The previously allocated slab. - Slab *Previous; + AllocatedSlab *Previous; // Tail allocated memory starts here. }; /// The head of the single-linked slab list. - Slab *CurrentSlab = nullptr; + AllocatedSlab *CurrentSlab = nullptr; /// The size of the previously allocated slab. This may NOT be the size of /// CurrentSlab, in the case where a checkpoint has been popped. @@ -66,7 +67,7 @@ class NodeFactory { & ~((uintptr_t)Alignment - 1)); } - static void freeSlabs(Slab *slab); + static void freeSlabs(AllocatedSlab *slab); /// If not null, the NodeFactory from which this factory borrowed free memory. NodeFactory *BorrowedFrom = nullptr; @@ -149,8 +150,8 @@ class NodeFactory { // No. We have to malloc a new slab. // We double the slab size for each allocated slab. SlabSize = std::max(SlabSize * 2, ObjectSize + alignof(T)); - size_t AllocSize = sizeof(Slab) + SlabSize; - Slab *newSlab = (Slab *)malloc(AllocSize); + size_t AllocSize = sizeof(AllocatedSlab) + SlabSize; + AllocatedSlab *newSlab = (AllocatedSlab *)malloc(AllocSize); // Insert the new slab in the single-linked list of slabs. newSlab->Previous = CurrentSlab; @@ -225,7 +226,7 @@ class NodeFactory { /// A checkpoint which captures the allocator's state at any given time. A /// checkpoint can be popped to free all allocations made since it was made. struct Checkpoint { - Slab *Slab; + AllocatedSlab *Slab; char *CurPtr; char *End; }; @@ -248,6 +249,12 @@ class NodeFactory { /// Creates a node of kind \p K with an \p Index payload. NodePointer createNode(Node::Kind K, Node::IndexType Index); + /// Creates a node of kind \p K with a \p RemoteAddress payload. + /// + /// These nodes are created and consumed by the reflection library. + NodePointer createNode(Node::Kind K, uint64_t RemoteAddress, + uint8_t AddressSpace); + /// Creates a node of kind \p K with a \p Text payload. /// /// The \p Text string must be already allocated with the Factory and therefore @@ -405,6 +412,8 @@ class Demangler : public NodeFactory { /// as part of the name. bool IsOldFunctionTypeMangling = false; + Mangle::ManglingFlavor Flavor = Mangle::ManglingFlavor::Default; + Vector NodeStack; Vector Substitutions; @@ -567,6 +576,8 @@ class Demangler : public NodeFactory { NodePointer demangleImplParamConvention(Node::Kind ConvKind); NodePointer demangleImplResultConvention(Node::Kind ConvKind); NodePointer demangleImplParameterSending(); + NodePointer demangleImplParameterIsolated(); + NodePointer demangleImplParameterImplicitLeading(); NodePointer demangleImplParameterResultDifferentiability(); NodePointer demangleImplFunctionType(); NodePointer demangleClangType(); @@ -593,8 +604,11 @@ class Demangler : public NodeFactory { NodePointer demangleDependentProtocolConformanceInherited(); NodePointer popDependentAssociatedConformance(); NodePointer demangleDependentProtocolConformanceAssociated(); + NodePointer demangleDependentProtocolConformanceOpaque(); NodePointer demangleThunkOrSpecialization(); - NodePointer demangleGenericSpecialization(Node::Kind SpecKind); + NodePointer demangleGenericSpecialization(Node::Kind SpecKind, + NodePointer droppedArguments); + NodePointer demangleGenericSpecializationWithDroppedArguments(); NodePointer demangleFunctionSpecialization(); NodePointer demangleFuncSpecParam(Node::Kind Kind); NodePointer addFuncSpecParamNumber(NodePointer Param, @@ -635,7 +649,7 @@ class Demangler : public NodeFactory { bool demangleBoundGenerics(Vector &TypeListList, NodePointer &RetroactiveConformances); - NodePointer demangleLifetimeDependenceKind(bool isSelfDependence); + NodePointer demangleIntegerType(); void dump(); diff --git a/symbolic-demangle/vendor/swift/include/swift/Demangling/ManglingFlavor.h b/symbolic-demangle/vendor/swift/include/swift/Demangling/ManglingFlavor.h new file mode 100644 index 000000000..db5374d2c --- /dev/null +++ b/symbolic-demangle/vendor/swift/include/swift/Demangling/ManglingFlavor.h @@ -0,0 +1,36 @@ +//===--- ManglingFlavor.h - Swift name mangling -----------------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2024 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_DEMANGLING_MANGLINGFLAVOR_H +#define SWIFT_DEMANGLING_MANGLINGFLAVOR_H + +#include "swift/Demangling/NamespaceMacros.h" + +#include + +namespace swift { +namespace Mangle { +SWIFT_BEGIN_INLINE_NAMESPACE + +/// Which mangling style and prefix to use. +enum class ManglingFlavor: uint8_t { + /// Default mangling with the ABI stable $s prefix + Default, + /// Embedded Swift's mangling with $e prefix + Embedded, +}; + +SWIFT_END_INLINE_NAMESPACE +} // end namespace Mangle +} // end namespace swift + +#endif // SWIFT_DEMANGLING_MANGLINGFLAVOR_H diff --git a/symbolic-demangle/vendor/swift/include/swift/Demangling/ManglingMacros.h b/symbolic-demangle/vendor/swift/include/swift/Demangling/ManglingMacros.h index 5cf386314..d47422806 100644 --- a/symbolic-demangle/vendor/swift/include/swift/Demangling/ManglingMacros.h +++ b/symbolic-demangle/vendor/swift/include/swift/Demangling/ManglingMacros.h @@ -17,16 +17,18 @@ #define MANGLE_AS_STRING(M) STRINGIFY_MANGLING(M) /// The mangling prefix for the new mangling. -#if !defined(_MSC_VER) || _MSC_VER-0 >= 1926 +#if defined(__clang__) _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wdollar-in-identifier-extension\"") #endif #define MANGLING_PREFIX $s -#if !defined(_MSC_VER) || _MSC_VER-0 >= 1926 +#define MANGLING_PREFIX_EMBEDDED $e +#if defined(__clang__) _Pragma("clang diagnostic pop") #endif #define MANGLING_PREFIX_STR MANGLE_AS_STRING(MANGLING_PREFIX) +#define MANGLING_PREFIX_EMBEDDED_STR MANGLE_AS_STRING(MANGLING_PREFIX_EMBEDDED) // The following macros help to create symbol manglings. They can be used // if a mangled name is needed at compile-time, e.g. for variable names in the diff --git a/symbolic-demangle/vendor/swift/include/swift/Demangling/ManglingUtils.h b/symbolic-demangle/vendor/swift/include/swift/Demangling/ManglingUtils.h index 7c20ccd00..4fa68577d 100644 --- a/symbolic-demangle/vendor/swift/include/swift/Demangling/ManglingUtils.h +++ b/symbolic-demangle/vendor/swift/include/swift/Demangling/ManglingUtils.h @@ -58,10 +58,16 @@ inline bool isWordEnd(char ch, char prevCh) { return false; } +/// Returns true if \p ch is a valid character which may appear at the start +/// of a symbol mangling. +inline bool isValidSymbolStart(char ch) { + return isLetter(ch) || ch == '_' || ch == '$'; +} + /// Returns true if \p ch is a valid character which may appear in a symbol -/// mangling. +/// mangling anywhere other than the first character. inline bool isValidSymbolChar(char ch) { - return isLetter(ch) || isDigit(ch) || ch == '_' || ch == '$'; + return isValidSymbolStart(ch) || isDigit(ch); } /// Returns true if \p str contains any character which may not appear in a diff --git a/symbolic-demangle/vendor/swift/include/swift/Strings.h b/symbolic-demangle/vendor/swift/include/swift/Strings.h index 8538e6931..91a18da8c 100644 --- a/symbolic-demangle/vendor/swift/include/swift/Strings.h +++ b/symbolic-demangle/vendor/swift/include/swift/Strings.h @@ -33,8 +33,6 @@ constexpr static const StringLiteral SWIFT_MODULE_ABI_NAME_PREFIX = "Compiler"; constexpr static const StringLiteral SWIFT_DISTRIBUTED_NAME = "Distributed"; /// The name of the StringProcessing module, which supports that extension. constexpr static const StringLiteral SWIFT_STRING_PROCESSING_NAME = "_StringProcessing"; -/// The name of the Backtracing module, which supports that extension. -constexpr static const StringLiteral SWIFT_BACKTRACING_NAME = "_Backtracing"; /// The name of the SwiftShims module, which contains private stdlib decls. constexpr static const StringLiteral SWIFT_SHIMS_NAME = "SwiftShims"; /// The name of the CxxShim module, which contains a cxx casting utility. @@ -85,6 +83,10 @@ constexpr static const StringLiteral CLANG_MODULE_DEFAULT_SPI_GROUP_NAME = constexpr static const StringLiteral SPI_AVAILABLE_ATTRNAME = "_spi_available"; +/// The attribute name for @_unavailableInEmbedded +constexpr static const StringLiteral UNAVAILABLE_IN_EMBEDDED_ATTRNAME = + "_unavailableInEmbedded"; + /// A composition class containing a StringLiteral for the names of /// Swift builtins. The reason we use this is to ensure that we when /// necessary slice off the "Builtin." prefix from these names in a @@ -142,6 +144,8 @@ constexpr static BuiltinNameStringLiteral BUILTIN_TYPE_NAME_NATIVEOBJECT = { /// The name of the Builtin type for BridgeObject constexpr static BuiltinNameStringLiteral BUILTIN_TYPE_NAME_BRIDGEOBJECT = { "Builtin.BridgeObject"}; +constexpr static BuiltinNameStringLiteral BUILTIN_TYPE_NAME_IMPLICITACTOR = { + "Builtin.ImplicitActor"}; /// The name of the Builtin type for RawPointer constexpr static BuiltinNameStringLiteral BUILTIN_TYPE_NAME_RAWPOINTER = { "Builtin.RawPointer"}; @@ -172,6 +176,8 @@ constexpr static BuiltinNameStringLiteral BUILTIN_TYPE_NAME_UNKNOWNOBJECT = { /// The name of the Builtin type for Vector constexpr static BuiltinNameStringLiteral BUILTIN_TYPE_NAME_VEC = { "Builtin.Vec"}; +constexpr static BuiltinNameStringLiteral BUILTIN_TYPE_NAME_FIXEDARRAY = { + "Builtin.FixedArray"}; /// The name of the Builtin type for SILToken constexpr static BuiltinNameStringLiteral BUILTIN_TYPE_NAME_SILTOKEN = { "Builtin.SILToken"}; diff --git a/symbolic-demangle/vendor/swift/lib/Demangling/Context.cpp b/symbolic-demangle/vendor/swift/lib/Demangling/Context.cpp index 69f366140..c28d754bb 100644 --- a/symbolic-demangle/vendor/swift/lib/Demangling/Context.cpp +++ b/symbolic-demangle/vendor/swift/lib/Demangling/Context.cpp @@ -66,11 +66,17 @@ std::string Context::demangleSymbolAsString(llvm::StringRef MangledName, return demangling; } +void Context::demangleSymbolAsString(llvm::StringRef MangledName, + NodePrinter &Printer) { + NodePointer root = demangleSymbolAsNode(MangledName); + nodeToString(root, Printer); +} + std::string Context::demangleTypeAsString(llvm::StringRef MangledName, const DemangleOptions &Options) { NodePointer root = demangleTypeAsNode(MangledName); if (!root) return MangledName.str(); - + std::string demangling = nodeToString(root, Options); if (demangling.empty()) return MangledName.str(); @@ -275,6 +281,11 @@ std::string demangleSymbolAsString(const char *MangledName, Options); } +void demangleSymbolAsString(StringRef MangledName, NodePrinter &Printer) { + Context Ctx; + return Ctx.demangleSymbolAsString(MangledName, Printer); +} + std::string demangleTypeAsString(const char *MangledName, size_t MangledNameLength, const DemangleOptions &Options) { diff --git a/symbolic-demangle/vendor/swift/lib/Demangling/CrashReporter.cpp b/symbolic-demangle/vendor/swift/lib/Demangling/CrashReporter.cpp deleted file mode 100644 index ece5fb61c..000000000 --- a/symbolic-demangle/vendor/swift/lib/Demangling/CrashReporter.cpp +++ /dev/null @@ -1,35 +0,0 @@ -//===--- CrashReporter.cpp - Crash Reporter integration ---------*- C++ -*-===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2022 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 -// -//===----------------------------------------------------------------------===// -// -// Declares gCRAnnotations. This lets us link with other static libraries -// that also declare gCRAnnotations, because we'll pull in their copy -// (assuming they're linked first). -// -//===----------------------------------------------------------------------===// - -#include "CrashReporter.h" - -#if SWIFT_HAVE_CRASHREPORTERCLIENT - -// Instead of linking to CrashReporterClient.a (because it complicates the -// build system), define the only symbol from that static archive ourselves. -// -// The layout of this struct is CrashReporter ABI, so there are no ABI concerns -// here. -extern "C" { -SWIFT_LIBRARY_VISIBILITY -struct crashreporter_annotations_t gCRAnnotations __attribute__(( - __section__("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION))) = { - CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0, 0}; -} - -#endif diff --git a/symbolic-demangle/vendor/swift/lib/Demangling/CrashReporter.h b/symbolic-demangle/vendor/swift/lib/Demangling/CrashReporter.h deleted file mode 100644 index 929c83dec..000000000 --- a/symbolic-demangle/vendor/swift/lib/Demangling/CrashReporter.h +++ /dev/null @@ -1,50 +0,0 @@ -//===--- CrashReporter.h - Crash Reporter integration -----------*- C++ -*-===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2022 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 -// -//===----------------------------------------------------------------------===// -// -// Declares gCRAnnotations. This lets us link with other static libraries -// that also declare gCRAnnotations, because we'll pull in their copy -// (assuming they're linked first). -// -//===----------------------------------------------------------------------===// - -#ifndef SWIFT_DEMANGLING_CRASHREPORTER_H -#define SWIFT_DEMANGLING_CRASHREPORTER_H - -#if SWIFT_HAVE_CRASHREPORTERCLIENT - -// For SWIFT_LIBRARY_VISIBILITY -#include "swift/shims/Visibility.h" - -#include - -#define CRASHREPORTER_ANNOTATIONS_VERSION 5 -#define CRASHREPORTER_ANNOTATIONS_SECTION "__crash_info" - -struct crashreporter_annotations_t { - uint64_t version; // unsigned long - uint64_t message; // char * - uint64_t signature_string; // char * - uint64_t backtrace; // char * - uint64_t message2; // char * - uint64_t thread; // uint64_t - uint64_t dialog_mode; // unsigned int - uint64_t abort_cause; // unsigned int -}; - -extern "C" { -SWIFT_LIBRARY_VISIBILITY -extern struct crashreporter_annotations_t gCRAnnotations; -} - -#endif // SWIFT_HAVE_CRASHREPORTERCLIENT - -#endif // SWIFT_DEMANGLING_CRASHREPORTER_H diff --git a/symbolic-demangle/vendor/swift/lib/Demangling/Demangler.cpp b/symbolic-demangle/vendor/swift/lib/Demangling/Demangler.cpp index 0d460c5e5..4f7bbbcb9 100644 --- a/symbolic-demangle/vendor/swift/lib/Demangling/Demangler.cpp +++ b/symbolic-demangle/vendor/swift/lib/Demangling/Demangler.cpp @@ -80,6 +80,7 @@ static bool isEntity(Node::Kind kind) { static bool isRequirement(Node::Kind kind) { switch (kind) { case Node::Kind::DependentGenericParamPackMarker: + case Node::Kind::DependentGenericParamValueMarker: case Node::Kind::DependentGenericSameTypeRequirement: case Node::Kind::DependentGenericSameShapeRequirement: case Node::Kind::DependentGenericLayoutRequirement: @@ -154,6 +155,8 @@ bool swift::Demangle::isFunctionAttr(Node::Kind kind) { case Node::Kind::BackDeploymentThunk: case Node::Kind::BackDeploymentFallback: case Node::Kind::HasSymbolQuery: + case Node::Kind::CoroFunctionPointer: + case Node::Kind::DefaultOverride: return true; default: return false; @@ -184,6 +187,7 @@ int swift::Demangle::getManglingPrefixLength(llvm::StringRef mangledName) { /*Swift 4*/ "_T0", /*Swift 4.x*/ "$S", "_$S", /*Swift 5+*/ "$s", "_$s", + /*Swift 5+ Embedded Swift*/ "$e", "_$e", /*Swift 5+ for filenames*/ "@__swiftmacro_", }; @@ -223,6 +227,8 @@ llvm::StringRef swift::Demangle::dropSwiftManglingPrefix(StringRef mangledName){ } static bool isAliasNode(Demangle::NodePointer Node) { + if (!Node) + return false; switch (Node->getKind()) { case Demangle::Node::Kind::Type: return isAliasNode(Node->getChild(0)); @@ -240,6 +246,8 @@ bool swift::Demangle::isAlias(llvm::StringRef mangledName) { } static bool isClassNode(Demangle::NodePointer Node) { + if (!Node) + return false; switch (Node->getKind()) { case Demangle::Node::Kind::Type: return isClassNode(Node->getChild(0)); @@ -258,6 +266,8 @@ bool swift::Demangle::isClass(llvm::StringRef mangledName) { } static bool isEnumNode(Demangle::NodePointer Node) { + if (!Node) + return false; switch (Node->getKind()) { case Demangle::Node::Kind::Type: return isEnumNode(Node->getChild(0)); @@ -276,6 +286,8 @@ bool swift::Demangle::isEnum(llvm::StringRef mangledName) { } static bool isProtocolNode(Demangle::NodePointer Node) { + if (!Node) + return false; switch (Node->getKind()) { case Demangle::Node::Kind::Type: return isProtocolNode(Node->getChild(0)); @@ -295,6 +307,8 @@ bool swift::Demangle::isProtocol(llvm::StringRef mangledName) { } static bool isStructNode(Demangle::NodePointer Node) { + if (!Node) + return false; switch (Node->getKind()) { case Demangle::Node::Kind::Type: return isStructNode(Node->getChild(0)); @@ -313,7 +327,8 @@ bool swift::Demangle::isStruct(llvm::StringRef mangledName) { } std::string swift::Demangle::mangledNameForTypeMetadataAccessor( - StringRef moduleName, StringRef typeName, Node::Kind typeKind) { + StringRef moduleName, StringRef typeName, Node::Kind typeKind, + Mangle::ManglingFlavor Flavor) { using namespace Demangle; // kind=Global @@ -342,7 +357,7 @@ std::string swift::Demangle::mangledNameForTypeMetadataAccessor( global->addChild(nominalDescriptor, D); } - auto mangleResult = mangleNode(global); + auto mangleResult = mangleNode(global, Flavor); assert(mangleResult.isSuccess()); return mangleResult.result(); } @@ -470,9 +485,9 @@ Node* Node::findByKind(Node::Kind kind, int maxDepth) { // NodeFactory member functions // ////////////////////////////////// -void NodeFactory::freeSlabs(Slab *slab) { +void NodeFactory::freeSlabs(AllocatedSlab *slab) { while (slab) { - Slab *prev = slab->Previous; + AllocatedSlab *prev = slab->Previous; free(slab); slab = prev; } @@ -532,7 +547,7 @@ void NodeFactory::popCheckpoint(NodeFactory::Checkpoint checkpoint) { // checkpoint's slab is less than 1/16th of the current slab's space. We // won't repeatedly allocate and deallocate the current slab. The size // doubles each time so we'll quickly pass the threshold. - Slab *savedSlab = nullptr; + AllocatedSlab *savedSlab = nullptr; if (CurrentSlab) { size_t checkpointSlabFreeSpace = checkpoint.End - checkpoint.CurPtr; size_t currentSlabSize = End - (char *)(CurrentSlab + 1); @@ -586,6 +601,11 @@ NodePointer NodeFactory::createNode(Node::Kind K) { NodePointer NodeFactory::createNode(Node::Kind K, Node::IndexType Index) { return new (Allocate()) Node(K, Index); } +NodePointer NodeFactory::createNode(Node::Kind K, uint64_t RemoteAddress, + uint8_t AddressSpace) { + return new (Allocate()) Node(K, RemoteAddress, AddressSpace); +} + NodePointer NodeFactory::createNodeWithAllocatedText(Node::Kind K, llvm::StringRef Text) { return new (Allocate()) Node(K, Text); @@ -736,6 +756,9 @@ NodePointer Demangler::demangleSymbol(StringRef MangledName, if (PrefixLength == 0) return nullptr; + if (MangledName.starts_with(MANGLING_PREFIX_EMBEDDED_STR)) + Flavor = ManglingFlavor::Embedded; + IsOldFunctionTypeMangling = isOldFunctionTypeMangling(MangledName); Pos += PrefixLength; @@ -746,6 +769,8 @@ NodePointer Demangler::demangleSymbol(StringRef MangledName, NodePointer topLevel = createNode(Node::Kind::Global); + NodePointer suffix = popNode(Node::Kind::Suffix); + NodePointer Parent = topLevel; while (NodePointer FuncAttr = popNode(isFunctionAttr)) { Parent->addChild(FuncAttr, *this); @@ -763,6 +788,9 @@ NodePointer Demangler::demangleSymbol(StringRef MangledName, break; } } + if (suffix) + topLevel->addChild(suffix, *this); + if (topLevel->getNumChildren() == 0) return nullptr; @@ -773,17 +801,27 @@ NodePointer Demangler::demangleType(StringRef MangledName, std::function Resolver) { DemangleInitRAII state(*this, MangledName, std::move(Resolver)); - parseAndPushNodes(); + if (!parseAndPushNodes()) + return nullptr; - if (NodePointer Result = popNode()) - return Result; + NodePointer Result = popNode(); - return createNode(Node::Kind::Suffix, Text); + // The result is only valid if it was the only node on the stack. + if (popNode()) + return nullptr; + + return Result; } bool Demangler::parseAndPushNodes() { const auto textSize = Text.size(); while (Pos < textSize) { + // Programs may look up a type by NUL-terminated name with an excessive + // length. Keep them working by returning success if we encounter a NUL in + // the middle of the string where an operator is expected. + if (peekChar() == '\0') + return true; + NodePointer Node = demangleOperator(); if (!Node) return false; @@ -947,7 +985,7 @@ NodePointer Demangler::demangleSymbolicReference(unsigned char rawKind) { } NodePointer Demangler::demangleTypeAnnotation() { - switch (char c2 = nextChar()) { + switch (nextChar()) { case 'a': return createNode(Node::Kind::AsyncAnnotation); case 'A': @@ -957,6 +995,8 @@ NodePointer Demangler::demangleTypeAnnotation() { case 'c': return createWithChild( Node::Kind::GlobalActorFunctionType, popTypeAndGetChild()); + case 'C': + return createNode(Node::Kind::NonIsolatedCallerFunctionType); case 'i': return createType( createWithChild(Node::Kind::Isolated, popTypeAndGetChild())); @@ -969,16 +1009,15 @@ NodePointer Demangler::demangleTypeAnnotation() { return createWithChild(Node::Kind::TypedThrowsAnnotation, popTypeAndGetChild()); case 't': return createType( - createWithChild(Node::Kind::CompileTimeConst, popTypeAndGetChild())); + createWithChild(Node::Kind::CompileTimeLiteral, popTypeAndGetChild())); + case 'g': + return createType( + createWithChild(Node::Kind::ConstValue, popTypeAndGetChild())); case 'T': return createNode(Node::Kind::SendingResultFunctionType); case 'u': return createType( createWithChild(Node::Kind::Sending, popTypeAndGetChild())); - case 'l': - return demangleLifetimeDependenceKind(/*isSelfDependence*/ false); - case 'L': - return demangleLifetimeDependenceKind(/*isSelfDependence*/ true); default: return nullptr; } @@ -1003,11 +1042,12 @@ NodePointer Demangler::demangleOperator() { case 'F': return demanglePlainFunction(); case 'G': return demangleBoundGenericType(); case 'H': - switch (char c2 = nextChar()) { + switch (nextChar()) { case 'A': return demangleDependentProtocolConformanceAssociated(); case 'C': return demangleConcreteProtocolConformance(); case 'D': return demangleDependentProtocolConformanceRoot(); case 'I': return demangleDependentProtocolConformanceInherited(); + case 'O': return demangleDependentProtocolConformanceOpaque(); case 'P': return createWithChild( Node::Kind::ProtocolConformanceRefInTypeModule, popProtocol()); @@ -1085,6 +1125,8 @@ NodePointer Demangler::demangleOperator() { // outlined copy functions. We treat such a suffix as "unmangled suffix". pushBack(); return createNode(Node::Kind::Suffix, consumeAll()); + case '$': + return demangleIntegerType(); default: pushBack(); return demangleIdentifier(); @@ -1184,7 +1226,7 @@ NodePointer Demangler::createSwiftType(Node::Kind typeKind, const char *name) { } NodePointer Demangler::demangleStandardSubstitution() { - switch (char c = nextChar()) { + switch (nextChar()) { case 'o': return createNode(Node::Kind::Module, MANGLING_MODULE_OBJC); case 'C': @@ -1399,6 +1441,10 @@ NodePointer Demangler::demangleBuiltinType() { NodePointer Ty = nullptr; const int maxTypeSize = 4096; // a very conservative upper bound switch (nextChar()) { + case 'A': + Ty = createNode(Node::Kind::BuiltinTypeName, + BUILTIN_TYPE_NAME_IMPLICITACTOR); + break; case 'b': Ty = createNode(Node::Kind::BuiltinTypeName, BUILTIN_TYPE_NAME_BRIDGEOBJECT); @@ -1452,6 +1498,18 @@ NodePointer Demangler::demangleBuiltinType() { Ty = createNode(Node::Kind::BuiltinTypeName, name); break; } + case 'V': { + NodePointer element = popNode(Node::Kind::Type); + if (!element) + return nullptr; + NodePointer size = popNode(Node::Kind::Type); + if (!size) + return nullptr; + Ty = createNode(Node::Kind::BuiltinFixedArray); + Ty->addChild(size, *this); + Ty->addChild(element, *this); + break; + } case 'O': Ty = createNode(Node::Kind::BuiltinTypeName, BUILTIN_TYPE_NAME_UNKNOWNOBJECT); @@ -1520,34 +1578,54 @@ NodePointer Demangler::demangleExtensionContext() { /// Associate any \c OpaqueReturnType nodes with the declaration whose opaque /// return type they refer back to. -static Node *setParentForOpaqueReturnTypeNodes(Demangler &D, - Node *parent, - Node *visitedNode) { - if (!parent || !visitedNode) - return nullptr; - if (visitedNode->getKind() == Node::Kind::OpaqueReturnType) { +/// Implementation for \c setParentForOpaqueReturnTypeNodes. Don't invoke +/// directly. +static void setParentForOpaqueReturnTypeNodesImpl( + Demangler &D, Node &visitedNode, + llvm::function_ref getParentID) { + if (visitedNode.getKind() == Node::Kind::OpaqueReturnType) { // If this node is not already parented, parent it. - if (visitedNode->hasChildren() - && visitedNode->getLastChild()->getKind() == Node::Kind::OpaqueReturnTypeParent) { - return parent; + if (visitedNode.hasChildren() && visitedNode.getLastChild()->getKind() == + Node::Kind::OpaqueReturnTypeParent) { + return; } - visitedNode->addChild(D.createNode(Node::Kind::OpaqueReturnTypeParent, - (Node::IndexType)parent), D); - return parent; + visitedNode.addChild(D.createNode(Node::Kind::OpaqueReturnTypeParent, + StringRef(getParentID())), + D); + return; } - + // If this node is one that may in turn define its own opaque return type, // stop recursion, since any opaque return type nodes underneath would refer // to the nested declaration rather than the one we're looking at. - if (visitedNode->getKind() == Node::Kind::Function - || visitedNode->getKind() == Node::Kind::Variable - || visitedNode->getKind() == Node::Kind::Subscript) { - return parent; + if (visitedNode.getKind() == Node::Kind::Function || + visitedNode.getKind() == Node::Kind::Variable || + visitedNode.getKind() == Node::Kind::Subscript) { + return; } - - for (size_t i = 0, e = visitedNode->getNumChildren(); i < e; ++i) { - setParentForOpaqueReturnTypeNodes(D, parent, visitedNode->getChild(i)); + + for (Node *child : visitedNode) { + assert(child); + setParentForOpaqueReturnTypeNodesImpl(D, *child, getParentID); } +} + +/// Associate any \c OpaqueReturnType nodes with the declaration whose opaque +/// return type they refer back to. +static Node *setParentForOpaqueReturnTypeNodes(Demangler &D, Node *parent, + Node *visitedNode, + ManglingFlavor Flavor) { + if (!parent || !visitedNode) + return nullptr; + std::string parentID; + setParentForOpaqueReturnTypeNodesImpl(D, *visitedNode, [&] { + if (!parentID.empty()) + return StringRef(parentID); + const auto mangleResult = mangleNode(parent, Flavor); + assert(mangleResult.isSuccess()); + parentID = mangleResult.result(); + return StringRef(parentID); + }); return parent; } @@ -1568,31 +1646,58 @@ NodePointer Demangler::demanglePlainFunction() { ? createWithChildren(Node::Kind::Function, Ctx, Name, LabelList, Type) : createWithChildren(Node::Kind::Function, Ctx, Name, Type); - result = setParentForOpaqueReturnTypeNodes(*this, result, Type); + result = setParentForOpaqueReturnTypeNodes(*this, result, Type, Flavor); return result; } NodePointer Demangler::popFunctionType(Node::Kind kind, bool hasClangType) { NodePointer FuncType = createNode(kind); + + // Demangle a C function type if the function node kind says that + // one follows. NodePointer ClangType = nullptr; if (hasClangType) { ClangType = demangleClangType(); } addChild(FuncType, ClangType); - addChild(FuncType, popNode(Node::Kind::SelfLifetimeDependence)); - addChild(FuncType, popNode(Node::Kind::GlobalActorFunctionType)); - addChild(FuncType, popNode(Node::Kind::IsolatedAnyFunctionType)); + + // The components of function-signature. Note that these need to be + // popped in the reverse of the order they're mangled. If you add a + // new component, be sure to add a demangling test case for combinations + // of specifiers. + + // sending-result? addChild(FuncType, popNode(Node::Kind::SendingResultFunctionType)); + + // function-isolation? + auto isFunctionIsolation = [](Node::Kind kind) { + return kind == Node::Kind::GlobalActorFunctionType || + kind == Node::Kind::IsolatedAnyFunctionType || + kind == Node::Kind::NonIsolatedCallerFunctionType; + }; + addChild(FuncType, popNode(isFunctionIsolation)); + + // differentiable? addChild(FuncType, popNode(Node::Kind::DifferentiableFunctionType)); + + // throws? addChild(FuncType, popNode([](Node::Kind kind) { return kind == Node::Kind::ThrowsAnnotation || kind == Node::Kind::TypedThrowsAnnotation; })); + + // sendable? addChild(FuncType, popNode(Node::Kind::ConcurrentFunctionType)); + + // async? addChild(FuncType, popNode(Node::Kind::AsyncAnnotation)); + // params-type FuncType = addChild(FuncType, popFunctionParams(Node::Kind::ArgumentTuple)); + + // result-type FuncType = addChild(FuncType, popFunctionParams(Node::Kind::ReturnType)); + return createType(FuncType); } @@ -1623,7 +1728,7 @@ NodePointer Demangler::popFunctionParamLabels(NodePointer Type) { unsigned FirstChildIdx = 0; if (FuncType->getChild(FirstChildIdx)->getKind() == - Node::Kind::SelfLifetimeDependence) + Node::Kind::SendingResultFunctionType) ++FirstChildIdx; if (FuncType->getChild(FirstChildIdx)->getKind() == Node::Kind::GlobalActorFunctionType) @@ -1631,8 +1736,8 @@ NodePointer Demangler::popFunctionParamLabels(NodePointer Type) { if (FuncType->getChild(FirstChildIdx)->getKind() == Node::Kind::IsolatedAnyFunctionType) ++FirstChildIdx; - if (FuncType->getChild(FirstChildIdx)->getKind() == - Node::Kind::SendingResultFunctionType) + if (FuncType->getChild(FirstChildIdx)->getKind() + == Node::Kind::NonIsolatedCallerFunctionType) ++FirstChildIdx; if (FuncType->getChild(FirstChildIdx)->getKind() == Node::Kind::DifferentiableFunctionType) @@ -1648,9 +1753,6 @@ NodePointer Demangler::popFunctionParamLabels(NodePointer Type) { if (FuncType->getChild(FirstChildIdx)->getKind() == Node::Kind::AsyncAnnotation) ++FirstChildIdx; - if (FuncType->getChild(FirstChildIdx)->getKind() == - Node::Kind::ParamLifetimeDependence) - ++FirstChildIdx; auto ParameterType = FuncType->getChild(FirstChildIdx); assert(ParameterType->getKind() == Node::Kind::ArgumentTuple); @@ -1870,6 +1972,7 @@ NodePointer Demangler::popAnyProtocolConformance() { case Node::Kind::DependentProtocolConformanceRoot: case Node::Kind::DependentProtocolConformanceInherited: case Node::Kind::DependentProtocolConformanceAssociated: + case Node::Kind::DependentProtocolConformanceOpaque: return true; default: @@ -1969,6 +2072,13 @@ NodePointer Demangler::demangleDependentConformanceIndex() { return createNode(Node::Kind::Index, unsigned(index) - 2); } +NodePointer Demangler::demangleDependentProtocolConformanceOpaque() { + NodePointer type = popNode(Node::Kind::Type); + NodePointer conformance = popDependentProtocolConformance(); + return createWithChildren(Node::Kind::DependentProtocolConformanceOpaque, + conformance, type); +} + NodePointer Demangler::demangleRetroactiveConformance() { NodePointer index = demangleIndexAsNode(); NodePointer conformance = popAnyProtocolConformance(); @@ -2035,6 +2145,7 @@ bool Demangle::nodeConsumesGenericArgs(Node *node) { case Node::Kind::DefaultArgumentInitializer: case Node::Kind::Initializer: case Node::Kind::PropertyWrapperBackingInitializer: + case Node::Kind::PropertyWrappedFieldInitAccessor: case Node::Kind::PropertyWrapperInitFromProjectedValue: case Node::Kind::Static: return false; @@ -2160,6 +2271,7 @@ NodePointer Demangler::demangleImplParamConvention(Node::Kind ConvKind) { case 'l': attr = "@inout"; break; case 'b': attr = "@inout_aliasable"; break; case 'n': attr = "@in_guaranteed"; break; + case 'X': attr = "@in_cxx"; break; case 'x': attr = "@owned"; break; case 'g': attr = "@guaranteed"; break; case 'e': attr = "@deallocating"; break; @@ -2184,6 +2296,15 @@ NodePointer Demangler::demangleImplResultConvention(Node::Kind ConvKind) { case 'u': attr = "@unowned_inner_pointer"; break; case 'a': attr = "@autoreleased"; break; case 'k': attr = "@pack_out"; break; + case 'l': + attr = "@guaranteed_address"; + break; + case 'g': + attr = "@guaranteed"; + break; + case 'm': + attr = "@inout"; + break; default: pushBack(); return nullptr; @@ -2200,6 +2321,22 @@ NodePointer Demangler::demangleImplParameterSending() { return createNode(Node::Kind::ImplParameterSending, attr); } +NodePointer Demangler::demangleImplParameterIsolated() { + // Empty string represents default differentiability. + if (!nextIf('I')) + return nullptr; + const char *attr = "isolated"; + return createNode(Node::Kind::ImplParameterIsolated, attr); +} + +NodePointer Demangler::demangleImplParameterImplicitLeading() { + // Empty string represents default differentiability. + if (!nextIf('L')) + return nullptr; + const char *attr = "sil_implicit_leading_param"; + return createNode(Node::Kind::ImplParameterImplicitLeading, attr); +} + NodePointer Demangler::demangleImplParameterResultDifferentiability() { // Empty string represents default differentiability. const char *attr = ""; @@ -2319,11 +2456,13 @@ NodePointer Demangler::demangleImplFunctionType() { const char *CoroAttr = nullptr; if (nextIf('A')) - CoroAttr = "@yield_once"; + CoroAttr = "yield_once"; + else if (nextIf('I')) + CoroAttr = "yield_once_2"; else if (nextIf('G')) - CoroAttr = "@yield_many"; + CoroAttr = "yield_many"; if (CoroAttr) - type->addChild(createNode(Node::Kind::ImplFunctionAttribute, CoroAttr), *this); + type->addChild(createNode(Node::Kind::ImplCoroutineKind, CoroAttr), *this); if (nextIf('h')) { type->addChild(createNode(Node::Kind::ImplFunctionAttribute, "@Sendable"), @@ -2335,6 +2474,10 @@ NodePointer Demangler::demangleImplFunctionType() { *this); } + if (nextIf('T')) { + type->addChild(createNode(Node::Kind::ImplSendingResult), *this); + } + addChild(type, GenSig); int NumTypesToAdd = 0; @@ -2345,13 +2488,13 @@ NodePointer Demangler::demangleImplFunctionType() { Param = addChild(Param, Diff); if (auto Sending = demangleImplParameterSending()) Param = addChild(Param, Sending); + if (auto Sending = demangleImplParameterIsolated()) + Param = addChild(Param, Sending); + if (auto Sending = demangleImplParameterImplicitLeading()) + Param = addChild(Param, Sending); ++NumTypesToAdd; } - if (nextIf('T')) { - type->addChild(createNode(Node::Kind::ImplSendingResult), *this); - } - while (NodePointer Result = demangleImplResultConvention( Node::Kind::ImplResult)) { type = addChild(type, Result); @@ -2384,7 +2527,7 @@ NodePointer Demangler::demangleImplFunctionType() { return nullptr; type->getChild(type->getNumChildren() - Idx - 1)->addChild(ConvTy, *this); } - + return createType(type); } @@ -2764,6 +2907,15 @@ NodePointer Demangler::popProtocolConformance() { NodePointer Demangler::demangleThunkOrSpecialization() { switch (char c = nextChar()) { + // Thunks that are from a thunk inst. We take the TT namespace. + case 'T': { + switch (nextChar()) { + case 'I': + return createWithChild(Node::Kind::SILThunkIdentity, popNode(isEntity)); + default: + return nullptr; + } + } case 'c': return createWithChild(Node::Kind::CurryThunk, popNode(isEntity)); case 'j': return createWithChild(Node::Kind::DispatchThunk, popNode(isEntity)); case 'q': return createWithChild(Node::Kind::MethodDescriptor, popNode(isEntity)); @@ -2799,7 +2951,7 @@ NodePointer Demangler::demangleThunkOrSpecialization() { NodePointer implType = popNode(Node::Kind::Type); auto node = createWithChildren(c == 'z' ? Node::Kind::ObjCAsyncCompletionHandlerImpl - : Node::Kind::PredefinedObjCAsyncCompletionHandlerImpl, + : Node::Kind::CheckedObjCAsyncCompletionHandlerImpl, implType, resultType, flagMode); if (sig) addChild(node, sig); @@ -2834,19 +2986,22 @@ NodePointer Demangler::demangleThunkOrSpecialization() { addChild(Thunk, popNode(Node::Kind::Type)); return Thunk; } - case 'g': - return demangleGenericSpecialization(Node::Kind::GenericSpecialization); + case 'g': { + return demangleGenericSpecialization(Node::Kind::GenericSpecialization, nullptr); + } case 'G': return demangleGenericSpecialization(Node::Kind:: - GenericSpecializationNotReAbstracted); + GenericSpecializationNotReAbstracted, nullptr); case 'B': return demangleGenericSpecialization(Node::Kind:: - GenericSpecializationInResilienceDomain); + GenericSpecializationInResilienceDomain, nullptr); + case 't': + return demangleGenericSpecializationWithDroppedArguments(); case 's': return demangleGenericSpecialization( - Node::Kind::GenericSpecializationPrespecialized); + Node::Kind::GenericSpecializationPrespecialized, nullptr); case 'i': - return demangleGenericSpecialization(Node::Kind::InlinedGenericFunction); + return demangleGenericSpecialization(Node::Kind::InlinedGenericFunction, nullptr); case 'p': { NodePointer Spec = demangleSpecAttributes(Node::Kind:: GenericPartialSpecialization); @@ -2865,8 +3020,15 @@ NodePointer Demangler::demangleThunkOrSpecialization() { return demangleFunctionSpecialization(); case 'K': case 'k': { - auto nodeKind = c == 'K' ? Node::Kind::KeyPathGetterThunkHelper - : Node::Kind::KeyPathSetterThunkHelper; + Node::Kind nodeKind; + if (nextIf("mu")) { + nodeKind = Node::Kind::KeyPathUnappliedMethodThunkHelper; + } else if (nextIf("MA")) { + nodeKind = Node::Kind::KeyPathAppliedMethodThunkHelper; + } else { + nodeKind = c == 'K' ? Node::Kind::KeyPathGetterThunkHelper + : Node::Kind::KeyPathSetterThunkHelper; + } bool isSerialized = nextIf('q'); @@ -3031,6 +3193,10 @@ NodePointer Demangler::demangleThunkOrSpecialization() { switch (nextChar()) { case 'b': return createNode(Node::Kind::BackDeploymentThunk); case 'B': return createNode(Node::Kind::BackDeploymentFallback); + case 'c': + return createNode(Node::Kind::CoroFunctionPointer); + case 'd': + return createNode(Node::Kind::DefaultOverride); case 'S': return createNode(Node::Kind::HasSymbolQuery); default: return nullptr; @@ -3102,7 +3268,7 @@ NodePointer Demangler::demangleDifferentiabilityWitness() { result = addChild(result, node); result->reverseChildren(); MangledDifferentiabilityKind kind; - switch (auto c = nextChar()) { + switch (nextChar()) { case 'f': kind = MangledDifferentiabilityKind::Forward; break; case 'r': kind = MangledDifferentiabilityKind::Reverse; break; case 'd': kind = MangledDifferentiabilityKind::Normal; break; @@ -3134,7 +3300,7 @@ NodePointer Demangler::demangleIndexSubset() { NodePointer Demangler::demangleDifferentiableFunctionType() { MangledDifferentiabilityKind kind; - switch (auto c = nextChar()) { + switch (nextChar()) { case 'f': kind = MangledDifferentiabilityKind::Forward; break; case 'r': kind = MangledDifferentiabilityKind::Reverse; break; case 'd': kind = MangledDifferentiabilityKind::Normal; break; @@ -3145,28 +3311,6 @@ NodePointer Demangler::demangleDifferentiableFunctionType() { Node::Kind::DifferentiableFunctionType, (Node::IndexType)kind); } -NodePointer Demangler::demangleLifetimeDependenceKind(bool isSelfDependence) { - MangledLifetimeDependenceKind kind; - switch (auto c = nextChar()) { - case 's': - kind = MangledLifetimeDependenceKind::Scope; - break; - case 'i': - kind = MangledLifetimeDependenceKind::Inherit; - break; - default: - return nullptr; - } - if (isSelfDependence) { - return createNode(Node::Kind::SelfLifetimeDependence, - (Node::IndexType)kind); - } - auto node = createWithChildren(Node::Kind::ParamLifetimeDependence, - createNode(Node::Kind::Index, unsigned(kind)), - popTypeAndGetChild()); - return createType(node); -} - std::string Demangler::demangleBridgedMethodParams() { if (nextIf('_')) return std::string(); @@ -3190,10 +3334,18 @@ std::string Demangler::demangleBridgedMethodParams() { return Str; } -NodePointer Demangler::demangleGenericSpecialization(Node::Kind SpecKind) { +NodePointer Demangler::demangleGenericSpecialization(Node::Kind SpecKind, + NodePointer droppedArguments) { NodePointer Spec = demangleSpecAttributes(SpecKind); if (!Spec) return nullptr; + + if (droppedArguments) { + for (NodePointer a : *droppedArguments) { + Spec->addChild(a, *this); + } + } + NodePointer TyList = popTypeList(); if (!TyList) return nullptr; @@ -3204,9 +3356,29 @@ NodePointer Demangler::demangleGenericSpecialization(Node::Kind SpecKind) { return Spec; } +NodePointer Demangler::demangleGenericSpecializationWithDroppedArguments() { + pushBack(); + NodePointer tmp = createNode(Node::Kind::GenericSpecialization); + while (nextIf('t')) { + int n = demangleNatural(); + addChild(tmp, createNode(Node::Kind::DroppedArgument, n < 0 ? 0 : n + 1)); + } + Node::Kind specKind; + switch (nextChar()) { + case 'g': specKind = Node::Kind::GenericSpecialization; break; + case 'G': specKind = Node::Kind::GenericSpecializationNotReAbstracted; break; + case 'B': specKind = Node::Kind::GenericSpecializationInResilienceDomain; break; + default: + return nullptr; + } + return demangleGenericSpecialization(specKind, tmp); +} + NodePointer Demangler::demangleFunctionSpecialization() { NodePointer Spec = demangleSpecAttributes( Node::Kind::FunctionSignatureSpecialization); + if (Spec && Spec->getFirstChild()->getKind() == Node::Kind::RepresentationChanged) + return Spec; while (Spec && !nextIf('_')) { Spec = addChild(Spec, demangleFuncSpecParam(Node::Kind::FunctionSignatureSpecializationParam)); } @@ -3222,43 +3394,40 @@ NodePointer Demangler::demangleFunctionSpecialization() { if (Param->getKind() != Node::Kind::FunctionSignatureSpecializationParam) continue; - if (Param->getNumChildren() == 0) - continue; - NodePointer KindNd = Param->getFirstChild(); - assert(KindNd->getKind() == - Node::Kind::FunctionSignatureSpecializationParamKind); - auto ParamKind = (FunctionSigSpecializationParamKind)KindNd->getIndex(); - switch (ParamKind) { - case FunctionSigSpecializationParamKind::ConstantPropFunction: - case FunctionSigSpecializationParamKind::ConstantPropGlobal: - case FunctionSigSpecializationParamKind::ConstantPropString: - case FunctionSigSpecializationParamKind::ConstantPropKeyPath: - case FunctionSigSpecializationParamKind::ClosureProp: { - size_t FixedChildren = Param->getNumChildren(); - while (NodePointer Ty = popNode(Node::Kind::Type)) { - if (ParamKind != FunctionSigSpecializationParamKind::ClosureProp && - ParamKind != FunctionSigSpecializationParamKind::ConstantPropKeyPath) - return nullptr; - Param = addChild(Param, Ty); - } - NodePointer Name = popNode(Node::Kind::Identifier); - if (!Name) - return nullptr; - StringRef Text = Name->getText(); - if (ParamKind == - FunctionSigSpecializationParamKind::ConstantPropString && - !Text.empty() && Text[0] == '_') { - // A '_' escapes a leading digit or '_' of a string constant. - Text = Text.drop_front(1); + size_t fixedChildren = Param->getNumChildren(); + NodePointer paramToAdd = Param; + for (size_t childIdx = 0; childIdx < fixedChildren; ++childIdx) { + NodePointer KindNd = Param->getChild(fixedChildren - childIdx - 1); + if (KindNd->getKind() != Node::Kind::FunctionSignatureSpecializationParamKind) + continue; + + auto ParamKind = (FunctionSigSpecializationParamKind)KindNd->getIndex(); + switch (ParamKind) { + case FunctionSigSpecializationParamKind::ClosureProp: { + while (NodePointer Ty = popNode(Node::Kind::Type)) { + paramToAdd = addChild(paramToAdd, Ty); + } + break; } - addChild(Param, createNodeWithAllocatedText( - Node::Kind::FunctionSignatureSpecializationParamPayload, Text)); - Param->reverseChildren(FixedChildren); - break; + case FunctionSigSpecializationParamKind::ConstantPropKeyPath: + paramToAdd = addChild(paramToAdd, popNode(Node::Kind::Type)); + paramToAdd = addChild(paramToAdd, popNode(Node::Kind::Type)); + break; + case FunctionSigSpecializationParamKind::ConstantPropStruct: + paramToAdd = addChild(paramToAdd, popNode(Node::Kind::Type)); + continue; + case FunctionSigSpecializationParamKind::ConstantPropFunction: + case FunctionSigSpecializationParamKind::ConstantPropGlobal: + case FunctionSigSpecializationParamKind::ConstantPropString: + break; + default: + continue; } - default: - break; + paramToAdd = addChild(paramToAdd, popNode(Node::Kind::Identifier)); } + if (!paramToAdd) + return nullptr; + Param->reverseChildren(fixedChildren); } return Spec; } @@ -3276,59 +3445,92 @@ NodePointer Demangler::demangleFuncSpecParam(Node::Kind Kind) { return addChild(Param, createNode( Node::Kind::FunctionSignatureSpecializationParamKind, uint64_t(FunctionSigSpecializationParamKind::ClosureProp))); + case 'C': { + // Consumes an identifier and multiple type parameters. + // The parameters will be added later. + addChild(Param, createNode( + Node::Kind::FunctionSignatureSpecializationParamKind, + uint64_t(FunctionSigSpecializationParamKind::ClosurePropPreviousArg))); + int prevArgIdx = demangleNatural(); + if (prevArgIdx < 0) + return nullptr; + return addChild(Param, createNode( + Node::Kind::FunctionSignatureSpecializationParamPayload, (Node::IndexType)prevArgIdx)); + } case 'p': { - switch (nextChar()) { - case 'f': - // Consumes an identifier parameter, which will be added later. - return addChild( - Param, - createNode(Node::Kind::FunctionSignatureSpecializationParamKind, - Node::IndexType(FunctionSigSpecializationParamKind:: - ConstantPropFunction))); - case 'g': - // Consumes an identifier parameter, which will be added later. - return addChild( - Param, - createNode( - Node::Kind::FunctionSignatureSpecializationParamKind, - Node::IndexType( - FunctionSigSpecializationParamKind::ConstantPropGlobal))); - case 'i': - return addFuncSpecParamNumber(Param, - FunctionSigSpecializationParamKind::ConstantPropInteger); - case 'd': - return addFuncSpecParamNumber(Param, - FunctionSigSpecializationParamKind::ConstantPropFloat); - case 's': { - // Consumes an identifier parameter (the string constant), - // which will be added later. - const char *Encoding = nullptr; - switch (nextChar()) { - case 'b': Encoding = "u8"; break; - case 'w': Encoding = "u16"; break; - case 'c': Encoding = "objc"; break; - default: return nullptr; + for (;;) { + switch (nextChar()) { + case 'S': + // Consumes an identifier parameter, which will be added later. + addChild( + Param, + createNode(Node::Kind::FunctionSignatureSpecializationParamKind, + Node::IndexType(FunctionSigSpecializationParamKind:: + ConstantPropStruct))); + break; + case 'f': + // Consumes an identifier parameter, which will be added later. + addChild( + Param, + createNode(Node::Kind::FunctionSignatureSpecializationParamKind, + Node::IndexType(FunctionSigSpecializationParamKind:: + ConstantPropFunction))); + break; + case 'g': + // Consumes an identifier parameter, which will be added later. + addChild( + Param, + createNode( + Node::Kind::FunctionSignatureSpecializationParamKind, + Node::IndexType( + FunctionSigSpecializationParamKind::ConstantPropGlobal))); + break; + case 'i': + if (!addFuncSpecParamNumber(Param, + FunctionSigSpecializationParamKind::ConstantPropInteger)) { + return nullptr; + } + break; + case 'd': + if (!addFuncSpecParamNumber(Param, + FunctionSigSpecializationParamKind::ConstantPropFloat)) { + return nullptr; + } + break; + case 's': { + // Consumes an identifier parameter (the string constant), + // which will be added later. + const char *Encoding = nullptr; + switch (nextChar()) { + case 'b': Encoding = "u8"; break; + case 'w': Encoding = "u16"; break; + case 'c': Encoding = "objc"; break; + default: return nullptr; + } + addChild(Param, + createNode( + Node::Kind::FunctionSignatureSpecializationParamKind, + Node::IndexType( + swift::Demangle::FunctionSigSpecializationParamKind:: + ConstantPropString))); + addChild(Param, createNode( + Node::Kind::FunctionSignatureSpecializationParamPayload, + Encoding)); + break; } - addChild(Param, - createNode( - Node::Kind::FunctionSignatureSpecializationParamKind, - Node::IndexType( - swift::Demangle::FunctionSigSpecializationParamKind:: - ConstantPropString))); - return addChild(Param, createNode( - Node::Kind::FunctionSignatureSpecializationParamPayload, - Encoding)); - } - case 'k': { - // Consumes two types and a SHA1 identifier. - return addChild( - Param, - createNode(Node::Kind::FunctionSignatureSpecializationParamKind, - Node::IndexType(FunctionSigSpecializationParamKind:: - ConstantPropKeyPath))); + case 'k': { + // Consumes two types and a SHA1 identifier. + addChild( + Param, + createNode(Node::Kind::FunctionSignatureSpecializationParamKind, + Node::IndexType(FunctionSigSpecializationParamKind:: + ConstantPropKeyPath))); + break; + } + default: + pushBack(); + return Param; } - default: - return nullptr; } } case 'e': { @@ -3417,9 +3619,9 @@ NodePointer Demangler::addFuncSpecParamNumber(NodePointer Param, } NodePointer Demangler::demangleSpecAttributes(Node::Kind SpecKind) { - bool metatypeParamsRemoved = nextIf('m'); bool isSerialized = nextIf('q'); bool asyncRemoved = nextIf('a'); + bool representationChanged = nextIf('r'); int PassID = (int)nextChar() - '0'; if (PassID < 0 || PassID >= MAX_SPECIALIZATION_PASS) { @@ -3428,9 +3630,6 @@ NodePointer Demangler::demangleSpecAttributes(Node::Kind SpecKind) { NodePointer SpecNd = createNode(SpecKind); - if (metatypeParamsRemoved) - SpecNd->addChild(createNode(Node::Kind::MetatypeParamsRemoved), *this); - if (isSerialized) SpecNd->addChild(createNode(Node::Kind::IsSerialized), *this); @@ -3439,6 +3638,10 @@ NodePointer Demangler::demangleSpecAttributes(Node::Kind SpecKind) { SpecNd->addChild(createNode(Node::Kind::AsyncRemoved), *this); + if (representationChanged) + SpecNd->addChild(createNode(Node::Kind::RepresentationChanged), + *this); + SpecNd->addChild(createNode(Node::Kind::SpecializationPassID, PassID), *this); return SpecNd; @@ -3520,6 +3723,15 @@ NodePointer Demangler::demangleWitness() { } case 'O': { switch (nextChar()) { + case 'B': { + if (auto sig = popNode(Node::Kind::DependentGenericSignature)) + return createWithChildren( + Node::Kind::OutlinedInitializeWithTakeNoValueWitness, + popNode(Node::Kind::Type), sig); + return createWithChild( + Node::Kind::OutlinedInitializeWithTakeNoValueWitness, + popNode(Node::Kind::Type)); + } case 'C': { if (auto sig = popNode(Node::Kind::DependentGenericSignature)) return createWithChildren(Node::Kind::OutlinedInitializeWithCopyNoValueWitness, @@ -3646,7 +3858,7 @@ NodePointer Demangler::demangleWitness() { case 'z': { auto declList = createNode(Node::Kind::GlobalVariableOnceDeclList); std::vector vars; - while (auto sig = popNode(Node::Kind::FirstElementMarker)) { + while (popNode(Node::Kind::FirstElementMarker)) { auto identifier = popNode(isDeclName); if (!identifier) return nullptr; @@ -3697,7 +3909,7 @@ NodePointer Demangler::demangleSpecialType() { case 'j': return demangleSymbolicExtendedExistentialType(); case 'z': - switch (auto cchar = nextChar()) { + switch (nextChar()) { case 'B': return popFunctionType(Node::Kind::ObjCBlock, true); case 'C': @@ -3816,6 +4028,12 @@ NodePointer Demangler::demangleSpecialType() { case 'a': return createType(createWithChild(Node::Kind::SugaredArray, popNode(Node::Kind::Type))); + case 'A': { + NodePointer element = popNode(Node::Kind::Type); + NodePointer count = popNode(Node::Kind::Type); + return createType(createWithChildren(Node::Kind::SugaredInlineArray, + count, element)); + } case 'D': { NodePointer value = popNode(Node::Kind::Type); NodePointer key = popNode(Node::Kind::Type); @@ -3905,8 +4123,16 @@ NodePointer Demangler::demangleAccessor(NodePointer ChildNode) { case 'w': Kind = Node::Kind::WillSet; break; case 'W': Kind = Node::Kind::DidSet; break; case 'r': Kind = Node::Kind::ReadAccessor; break; + case 'y': Kind = Node::Kind::Read2Accessor; break; case 'M': Kind = Node::Kind::ModifyAccessor; break; + case 'x': Kind = Node::Kind::Modify2Accessor; break; case 'i': Kind = Node::Kind::InitAccessor; break; + case 'b': + Kind = Node::Kind::BorrowAccessor; + break; + case 'z': + Kind = Node::Kind::MutateAccessor; + break; case 'a': switch (nextChar()) { case 'O': Kind = Node::Kind::OwningMutableAddressor; break; @@ -3946,6 +4172,10 @@ NodePointer Demangler::demangleFunctionEntity() { switch (nextChar()) { case 'D': Args = None; Kind = Node::Kind::Deallocator; break; case 'd': Args = None; Kind = Node::Kind::Destructor; break; + case 'Z': + Args = None; + Kind = Node::Kind::IsolatedDeallocator; + break; case 'E': Args = None; Kind = Node::Kind::IVarDestroyer; break; case 'e': Args = None; Kind = Node::Kind::IVarInitializer; break; case 'i': Args = None; Kind = Node::Kind::Initializer; break; @@ -3963,6 +4193,10 @@ NodePointer Demangler::demangleFunctionEntity() { Args = None; Kind = Node::Kind::PropertyWrapperBackingInitializer; break; + case 'F': + Args = None; + Kind = Node::Kind::PropertyWrappedFieldInitAccessor; + break; case 'W': Args = None; Kind = Node::Kind::PropertyWrapperInitFromProjectedValue; @@ -4022,7 +4256,7 @@ NodePointer Demangler::demangleEntity(Node::Kind Kind) { auto result = LabelList ? createWithChildren(Kind, Context, Name, LabelList, Type) : createWithChildren(Kind, Context, Name, Type); - result = setParentForOpaqueReturnTypeNodes(*this, result, Type); + result = setParentForOpaqueReturnTypeNodes(*this, result, Type, Flavor); return result; } @@ -4046,7 +4280,7 @@ NodePointer Demangler::demangleSubscript() { Subscript = addChild(Subscript, Type); addChild(Subscript, PrivateName); - Subscript = setParentForOpaqueReturnTypeNodes(*this, Subscript, Type); + Subscript = setParentForOpaqueReturnTypeNodes(*this, Subscript, Type, Flavor); return demangleAccessor(Subscript); } @@ -4117,10 +4351,21 @@ NodePointer Demangler::demangleGenericSignature(bool hasParamCounts) { NodePointer Demangler::demangleGenericRequirement() { enum { Generic, Assoc, CompoundAssoc, Substitution } TypeKind; - enum { Protocol, BaseClass, SameType, SameShape, Layout, PackMarker, Inverse } ConstraintKind; + + enum { + Protocol, + BaseClass, + SameType, + SameShape, + Layout, + PackMarker, + Inverse, + ValueMarker + } ConstraintKind; NodePointer inverseKind = nullptr; switch (nextChar()) { + case 'V': ConstraintKind = ValueMarker; TypeKind = Generic; break; case 'v': ConstraintKind = PackMarker; TypeKind = Generic; break; case 'c': ConstraintKind = BaseClass; TypeKind = Assoc; break; case 'C': ConstraintKind = BaseClass; TypeKind = CompoundAssoc; break; @@ -4175,6 +4420,10 @@ NodePointer Demangler::demangleGenericRequirement() { } switch (ConstraintKind) { + case ValueMarker: + return createWithChildren( + Node::Kind::DependentGenericParamValueMarker, ConstrTy, + popNode(Node::Kind::Type)); case PackMarker: return createWithChild( Node::Kind::DependentGenericParamPackMarker, ConstrTy); @@ -4354,7 +4603,7 @@ NodePointer Demangler::demangleMacroExpansion() { context = popContext(); NodePointer discriminator = demangleIndexAsNode(); NodePointer result; - if (isAttached) { + if (isAttached && attachedName) { result = createWithChildren( kind, context, attachedName, macroName, discriminator); } else { @@ -4364,3 +4613,20 @@ NodePointer Demangler::demangleMacroExpansion() { result->addChild(privateDiscriminator, *this); return result; } + +NodePointer Demangler::demangleIntegerType() { + NodePointer integer = nullptr; + + switch (peekChar()) { + case 'n': + nextChar(); + integer = createNode(Node::Kind::NegativeInteger, -demangleIndex()); + break; + + default: + integer = createNode(Node::Kind::Integer, demangleIndex()); + break; + } + + return createType(integer); +} diff --git a/symbolic-demangle/vendor/swift/lib/Demangling/ManglingUtils.cpp b/symbolic-demangle/vendor/swift/lib/Demangling/ManglingUtils.cpp index 0a1655e39..4105221d9 100644 --- a/symbolic-demangle/vendor/swift/lib/Demangling/ManglingUtils.cpp +++ b/symbolic-demangle/vendor/swift/lib/Demangling/ManglingUtils.cpp @@ -26,9 +26,16 @@ bool Mangle::isNonAscii(StringRef str) { } bool Mangle::needsPunycodeEncoding(StringRef str) { - for (unsigned char c : str) { - if (!isValidSymbolChar(c)) + if (str.empty()) { + return false; + } + if (!isValidSymbolStart(str.front())) { + return true; + } + for (unsigned char c : str.substr(1)) { + if (!isValidSymbolChar(c)) { return true; + } } return false; } diff --git a/symbolic-demangle/vendor/swift/lib/Demangling/NodePrinter.cpp b/symbolic-demangle/vendor/swift/lib/Demangling/NodePrinter.cpp index 5b251e8da..7431e548e 100644 --- a/symbolic-demangle/vendor/swift/lib/Demangling/NodePrinter.cpp +++ b/symbolic-demangle/vendor/swift/lib/Demangling/NodePrinter.cpp @@ -166,381 +166,352 @@ static StringRef toString(ValueWitnessKind k) { } printer_unreachable("bad value witness kind"); } +} // end anonymous namespace -class NodePrinter { -private: - DemanglerPrinter Printer; - DemangleOptions Options; - bool SpecializationPrefixPrinted = false; - bool isValid = true; - -public: - NodePrinter(DemangleOptions options) : Options(options) {} - - std::string printRoot(NodePointer root) { - isValid = true; - print(root, 0); - if (isValid) - return std::move(Printer).str(); - return ""; +void NodePrinter::printChildren(Node::iterator begin, Node::iterator end, + unsigned depth, const char *sep) { + for (; begin != end;) { + print(*begin, depth + 1); + ++begin; + if (sep && begin != end) + Printer << sep; } +} -private: - static const unsigned MaxDepth = 768; - - /// Called when the node tree in valid. - /// - /// The demangler already catches most error cases and mostly produces valid - /// node trees. But some cases are difficult to catch in the demangler and - /// instead the NodePrinter bails. - void setInvalid() { isValid = false; } +void NodePrinter::printChildren(NodePointer Node, unsigned depth, + const char *sep) { + if (!Node) + return; + Node::iterator begin = Node->begin(), end = Node->end(); + printChildren(begin, end, depth, sep); +} - void printChildren(Node::iterator begin, Node::iterator end, unsigned depth, - const char *sep = nullptr) { - for (; begin != end;) { - print(*begin, depth + 1); - ++begin; - if (sep && begin != end) - Printer << sep; - } +NodePointer NodePrinter::getFirstChildOfKind(NodePointer Node, + Node::Kind kind) { + if (!Node) + return nullptr; + for (NodePointer child : *Node) { + if (child && child->getKind() == kind) + return child; } + return nullptr; +} - void printChildren(NodePointer Node, unsigned depth, - const char *sep = nullptr) { - if (!Node) - return; - Node::iterator begin = Node->begin(), end = Node->end(); - printChildren(begin, end, depth, sep); - } +void NodePrinter::printBoundGenericNoSugar(NodePointer Node, unsigned depth) { + if (Node->getNumChildren() < 2) + return; + NodePointer typelist = Node->getChild(1); + print(Node->getChild(0), depth + 1); + Printer << "<"; + printChildren(typelist, depth, ", "); + Printer << ">"; +} - NodePointer getFirstChildOfKind(NodePointer Node, Node::Kind kind) { - if (!Node) - return nullptr; - for (NodePointer child : *Node) { - if (child && child->getKind() == kind) - return child; - } - return nullptr; - } +static bool isExistentialType(NodePointer node) { + return (node->getKind() == Node::Kind::ExistentialMetatype || + node->getKind() == Node::Kind::ProtocolList || + node->getKind() == Node::Kind::ProtocolListWithClass || + node->getKind() == Node::Kind::ProtocolListWithAnyObject); +} - void printBoundGenericNoSugar(NodePointer Node, unsigned depth) { - if (Node->getNumChildren() < 2) - return; - NodePointer typelist = Node->getChild(1); - print(Node->getChild(0), depth + 1); - Printer << "<"; - printChildren(typelist, depth, ", "); - Printer << ">"; - } +void NodePrinter::printOptionalIndex(NodePointer node) { + assert(node->getKind() == Node::Kind::Index || + node->getKind() == Node::Kind::UnknownIndex); + if (node->hasIndex()) + Printer << "#" << node->getIndex() << " "; +} - void printOptionalIndex(NodePointer node) { - assert(node->getKind() == Node::Kind::Index || - node->getKind() == Node::Kind::UnknownIndex); - if (node->hasIndex()) - Printer << "#" << node->getIndex() << " "; - } +bool NodePrinter::printContext(NodePointer Context) { + if (!Options.QualifyEntities) + return false; - static bool isSwiftModule(NodePointer node) { - return (node->getKind() == Node::Kind::Module && - node->getText() == STDLIB_NAME); - } - - bool printContext(NodePointer Context) { - if (!Options.QualifyEntities) + if (Context->getKind() == Node::Kind::Module) { + if (Context->getText() == swift::STDLIB_NAME) + return Options.DisplayStdlibModule; + if (Context->getText() == swift::MANGLING_MODULE_OBJC) + return Options.DisplayObjCModule; + if (Context->getText() == Options.HidingCurrentModule) return false; + if (Context->getText().starts_with(LLDB_EXPRESSIONS_MODULE_NAME_PREFIX)) + return Options.DisplayDebuggerGeneratedModule; + } + return true; +} - if (Context->getKind() == Node::Kind::Module) { - if (Context->getText() == swift::STDLIB_NAME) - return Options.DisplayStdlibModule; - if (Context->getText() == swift::MANGLING_MODULE_OBJC) - return Options.DisplayObjCModule; - if (Context->getText() == Options.HidingCurrentModule) - return false; - if (Context->getText().starts_with(LLDB_EXPRESSIONS_MODULE_NAME_PREFIX)) - return Options.DisplayDebuggerGeneratedModule; - } +bool NodePrinter::isSimpleType(NodePointer Node) { + switch (Node->getKind()) { + case Node::Kind::AssociatedType: + case Node::Kind::AssociatedTypeRef: + case Node::Kind::BoundGenericClass: + case Node::Kind::BoundGenericEnum: + case Node::Kind::BoundGenericStructure: + case Node::Kind::BoundGenericProtocol: + case Node::Kind::BoundGenericOtherNominalType: + case Node::Kind::BoundGenericTypeAlias: + case Node::Kind::BoundGenericFunction: + case Node::Kind::BuiltinTypeName: + case Node::Kind::BuiltinTupleType: + case Node::Kind::BuiltinFixedArray: + case Node::Kind::Class: + case Node::Kind::DependentGenericType: + case Node::Kind::DependentMemberType: + case Node::Kind::DependentGenericParamType: + case Node::Kind::DynamicSelf: + case Node::Kind::Enum: + case Node::Kind::ErrorType: + case Node::Kind::ExistentialMetatype: + case Node::Kind::Metatype: + case Node::Kind::MetatypeRepresentation: + case Node::Kind::Module: + case Node::Kind::Tuple: + case Node::Kind::Pack: + case Node::Kind::SILPackDirect: + case Node::Kind::SILPackIndirect: + case Node::Kind::ConstrainedExistentialRequirementList: + case Node::Kind::ConstrainedExistentialSelf: + case Node::Kind::Protocol: + case Node::Kind::ProtocolSymbolicReference: + case Node::Kind::ReturnType: + case Node::Kind::SILBoxType: + case Node::Kind::SILBoxTypeWithLayout: + case Node::Kind::Structure: + case Node::Kind::OtherNominalType: + case Node::Kind::TupleElementName: + case Node::Kind::TypeAlias: + case Node::Kind::TypeList: + case Node::Kind::LabelList: + case Node::Kind::TypeSymbolicReference: + case Node::Kind::SugaredOptional: + case Node::Kind::SugaredArray: + case Node::Kind::SugaredInlineArray: + case Node::Kind::SugaredDictionary: + case Node::Kind::SugaredParen: + case Node::Kind::Integer: + case Node::Kind::NegativeInteger: return true; - } - static bool isIdentifier(NodePointer node, StringRef desired) { - return (node->getKind() == Node::Kind::Identifier && - node->getText() == desired); - } - - enum class SugarType { - None, - Optional, - ImplicitlyUnwrappedOptional, - Array, - Dictionary - }; + case Node::Kind::Type: + return isSimpleType(Node->getChild(0)); - enum class TypePrinting { - NoType, - WithColon, - FunctionStyle - }; + case Node::Kind::ProtocolList: + return Node->getChild(0)->getNumChildren() <= 1; - /// Determine whether this is a "simple" type, from the type-simple - /// production. - bool isSimpleType(NodePointer Node) { - switch (Node->getKind()) { - case Node::Kind::AssociatedType: - case Node::Kind::AssociatedTypeRef: - case Node::Kind::BoundGenericClass: - case Node::Kind::BoundGenericEnum: - case Node::Kind::BoundGenericStructure: - case Node::Kind::BoundGenericProtocol: - case Node::Kind::BoundGenericOtherNominalType: - case Node::Kind::BoundGenericTypeAlias: - case Node::Kind::BoundGenericFunction: - case Node::Kind::BuiltinTypeName: - case Node::Kind::BuiltinTupleType: - case Node::Kind::Class: - case Node::Kind::DependentGenericType: - case Node::Kind::DependentMemberType: - case Node::Kind::DependentGenericParamType: - case Node::Kind::DynamicSelf: - case Node::Kind::Enum: - case Node::Kind::ErrorType: - case Node::Kind::ExistentialMetatype: - case Node::Kind::Metatype: - case Node::Kind::MetatypeRepresentation: - case Node::Kind::Module: - case Node::Kind::Tuple: - case Node::Kind::Pack: - case Node::Kind::SILPackDirect: - case Node::Kind::SILPackIndirect: - case Node::Kind::ConstrainedExistentialRequirementList: - case Node::Kind::ConstrainedExistentialSelf: - case Node::Kind::Protocol: - case Node::Kind::ProtocolSymbolicReference: - case Node::Kind::ReturnType: - case Node::Kind::SILBoxType: - case Node::Kind::SILBoxTypeWithLayout: - case Node::Kind::Structure: - case Node::Kind::OtherNominalType: - case Node::Kind::TupleElementName: - case Node::Kind::TypeAlias: - case Node::Kind::TypeList: - case Node::Kind::LabelList: - case Node::Kind::TypeSymbolicReference: - case Node::Kind::SugaredOptional: - case Node::Kind::SugaredArray: - case Node::Kind::SugaredDictionary: - case Node::Kind::SugaredParen: - return true; + case Node::Kind::ProtocolListWithAnyObject: + return Node->getChild(0)->getChild(0)->getNumChildren() == 0; - case Node::Kind::Type: - return isSimpleType(Node->getChild(0)); - - case Node::Kind::ProtocolList: - return Node->getChild(0)->getNumChildren() <= 1; - - case Node::Kind::ProtocolListWithAnyObject: - return Node->getChild(0)->getChild(0)->getNumChildren() == 0; - - case Node::Kind::ConstrainedExistential: - case Node::Kind::PackElement: - case Node::Kind::PackElementLevel: - case Node::Kind::PackExpansion: - case Node::Kind::ProtocolListWithClass: - case Node::Kind::AccessorAttachedMacroExpansion: - case Node::Kind::AccessorFunctionReference: - case Node::Kind::Allocator: - case Node::Kind::ArgumentTuple: - case Node::Kind::AssociatedConformanceDescriptor: - case Node::Kind::AssociatedTypeDescriptor: - case Node::Kind::AssociatedTypeMetadataAccessor: - case Node::Kind::AssociatedTypeWitnessTableAccessor: - case Node::Kind::AsyncRemoved: - case Node::Kind::AutoClosureType: - case Node::Kind::BaseConformanceDescriptor: - case Node::Kind::BaseWitnessTableAccessor: - case Node::Kind::BodyAttachedMacroExpansion: - case Node::Kind::ClangType: - case Node::Kind::ClassMetadataBaseOffset: - case Node::Kind::CFunctionPointer: - case Node::Kind::ConformanceAttachedMacroExpansion: - case Node::Kind::Constructor: - case Node::Kind::CoroutineContinuationPrototype: - case Node::Kind::CurryThunk: - case Node::Kind::DispatchThunk: - case Node::Kind::Deallocator: - case Node::Kind::DeclContext: - case Node::Kind::DefaultArgumentInitializer: - case Node::Kind::DefaultAssociatedTypeMetadataAccessor: - case Node::Kind::DefaultAssociatedConformanceAccessor: - case Node::Kind::DependentAssociatedTypeRef: - case Node::Kind::DependentGenericSignature: - case Node::Kind::DependentGenericParamPackMarker: - case Node::Kind::DependentGenericParamCount: - case Node::Kind::DependentGenericConformanceRequirement: - case Node::Kind::DependentGenericLayoutRequirement: - case Node::Kind::DependentGenericSameTypeRequirement: - case Node::Kind::DependentGenericSameShapeRequirement: - case Node::Kind::DependentPseudogenericSignature: - case Node::Kind::Destructor: - case Node::Kind::DidSet: - case Node::Kind::DirectMethodReferenceAttribute: - case Node::Kind::Directness: - case Node::Kind::DynamicAttribute: - case Node::Kind::EscapingAutoClosureType: - case Node::Kind::EscapingObjCBlock: - case Node::Kind::NoEscapeFunctionType: - case Node::Kind::ExplicitClosure: - case Node::Kind::Extension: - case Node::Kind::ExtensionAttachedMacroExpansion: - case Node::Kind::EnumCase: - case Node::Kind::FieldOffset: - case Node::Kind::FreestandingMacroExpansion: - case Node::Kind::FullObjCResilientClassStub: - case Node::Kind::FullTypeMetadata: - case Node::Kind::Function: - case Node::Kind::FunctionSignatureSpecialization: - case Node::Kind::FunctionSignatureSpecializationParam: - case Node::Kind::FunctionSignatureSpecializationReturn: - case Node::Kind::FunctionSignatureSpecializationParamKind: - case Node::Kind::FunctionSignatureSpecializationParamPayload: - case Node::Kind::FunctionType: - case Node::Kind::GenericProtocolWitnessTable: - case Node::Kind::GenericProtocolWitnessTableInstantiationFunction: - case Node::Kind::GenericPartialSpecialization: - case Node::Kind::GenericPartialSpecializationNotReAbstracted: - case Node::Kind::GenericSpecialization: - case Node::Kind::GenericSpecializationNotReAbstracted: - case Node::Kind::GenericSpecializationInResilienceDomain: - case Node::Kind::GenericSpecializationParam: - case Node::Kind::GenericSpecializationPrespecialized: - case Node::Kind::InlinedGenericFunction: - case Node::Kind::GenericTypeMetadataPattern: - case Node::Kind::Getter: - case Node::Kind::Global: - case Node::Kind::GlobalGetter: - case Node::Kind::Identifier: - case Node::Kind::Index: - case Node::Kind::InitAccessor: - case Node::Kind::IVarInitializer: - case Node::Kind::IVarDestroyer: - case Node::Kind::ImplDifferentiabilityKind: - case Node::Kind::ImplEscaping: - case Node::Kind::ImplErasedIsolation: - case Node::Kind::ImplSendingResult: - case Node::Kind::ImplConvention: - case Node::Kind::ImplParameterResultDifferentiability: - case Node::Kind::ImplParameterSending: - case Node::Kind::ImplFunctionAttribute: - case Node::Kind::ImplFunctionConvention: - case Node::Kind::ImplFunctionConventionName: - case Node::Kind::ImplFunctionType: - case Node::Kind::ImplInvocationSubstitutions: - case Node::Kind::ImplPatternSubstitutions: - case Node::Kind::ImplicitClosure: - case Node::Kind::ImplParameter: - case Node::Kind::ImplResult: - case Node::Kind::ImplYield: - case Node::Kind::ImplErrorResult: - case Node::Kind::InOut: - case Node::Kind::InfixOperator: - case Node::Kind::Initializer: - case Node::Kind::Isolated: - case Node::Kind::Sending: - case Node::Kind::CompileTimeConst: - case Node::Kind::PropertyWrapperBackingInitializer: - case Node::Kind::PropertyWrapperInitFromProjectedValue: - case Node::Kind::KeyPathGetterThunkHelper: - case Node::Kind::KeyPathSetterThunkHelper: - case Node::Kind::KeyPathEqualsThunkHelper: - case Node::Kind::KeyPathHashThunkHelper: - case Node::Kind::LazyProtocolWitnessTableAccessor: - case Node::Kind::LazyProtocolWitnessTableCacheVariable: - case Node::Kind::LocalDeclName: - case Node::Kind::Macro: - case Node::Kind::MacroExpansionLoc: - case Node::Kind::MacroExpansionUniqueName: - case Node::Kind::MaterializeForSet: - case Node::Kind::MemberAttributeAttachedMacroExpansion: - case Node::Kind::MemberAttachedMacroExpansion: - case Node::Kind::MergedFunction: - case Node::Kind::Metaclass: - case Node::Kind::MethodDescriptor: - case Node::Kind::MethodLookupFunction: - case Node::Kind::ModifyAccessor: - case Node::Kind::NativeOwningAddressor: - case Node::Kind::NativeOwningMutableAddressor: - case Node::Kind::NativePinningAddressor: - case Node::Kind::NativePinningMutableAddressor: - case Node::Kind::NominalTypeDescriptor: - case Node::Kind::NominalTypeDescriptorRecord: - case Node::Kind::NonObjCAttribute: - case Node::Kind::Number: - case Node::Kind::ObjCAsyncCompletionHandlerImpl: - case Node::Kind::ObjCAttribute: - case Node::Kind::ObjCBlock: - case Node::Kind::ObjCMetadataUpdateFunction: - case Node::Kind::ObjCResilientClassStub: - case Node::Kind::OpaqueTypeDescriptor: - case Node::Kind::OpaqueTypeDescriptorRecord: - case Node::Kind::OpaqueTypeDescriptorAccessor: - case Node::Kind::OpaqueTypeDescriptorAccessorImpl: - case Node::Kind::OpaqueTypeDescriptorAccessorKey: - case Node::Kind::OpaqueTypeDescriptorAccessorVar: - case Node::Kind::Owned: - case Node::Kind::OwningAddressor: - case Node::Kind::OwningMutableAddressor: - case Node::Kind::PartialApplyForwarder: - case Node::Kind::PartialApplyObjCForwarder: - case Node::Kind::PeerAttachedMacroExpansion: - case Node::Kind::PostfixOperator: - case Node::Kind::PreambleAttachedMacroExpansion: - case Node::Kind::PredefinedObjCAsyncCompletionHandlerImpl: - case Node::Kind::PrefixOperator: - case Node::Kind::PrivateDeclName: - case Node::Kind::PropertyDescriptor: - case Node::Kind::ProtocolConformance: - case Node::Kind::ProtocolConformanceDescriptor: - case Node::Kind::ProtocolConformanceDescriptorRecord: - case Node::Kind::MetadataInstantiationCache: - case Node::Kind::ProtocolDescriptor: - case Node::Kind::ProtocolDescriptorRecord: - case Node::Kind::ProtocolRequirementsBaseDescriptor: - case Node::Kind::ProtocolSelfConformanceDescriptor: - case Node::Kind::ProtocolSelfConformanceWitness: - case Node::Kind::ProtocolSelfConformanceWitnessTable: - case Node::Kind::ProtocolWitness: - case Node::Kind::ProtocolWitnessTable: - case Node::Kind::ProtocolWitnessTableAccessor: - case Node::Kind::ProtocolWitnessTablePattern: - case Node::Kind::ReabstractionThunk: - case Node::Kind::ReabstractionThunkHelper: - case Node::Kind::ReabstractionThunkHelperWithSelf: - case Node::Kind::ReabstractionThunkHelperWithGlobalActor: - case Node::Kind::ReadAccessor: - case Node::Kind::RelatedEntityDeclName: - case Node::Kind::RetroactiveConformance: - case Node::Kind::Setter: - case Node::Kind::Shared: - case Node::Kind::SILBoxLayout: - case Node::Kind::SILBoxMutableField: - case Node::Kind::SILBoxImmutableField: - case Node::Kind::IsSerialized: - case Node::Kind::MetatypeParamsRemoved: - case Node::Kind::SpecializationPassID: - case Node::Kind::Static: - case Node::Kind::Subscript: - case Node::Kind::Suffix: - case Node::Kind::ThinFunctionType: - case Node::Kind::TupleElement: - case Node::Kind::TypeMangling: - case Node::Kind::TypeMetadata: - case Node::Kind::TypeMetadataAccessFunction: - case Node::Kind::TypeMetadataCompletionFunction: - case Node::Kind::TypeMetadataInstantiationCache: - case Node::Kind::TypeMetadataInstantiationFunction: - case Node::Kind::TypeMetadataSingletonInitializationCache: - case Node::Kind::TypeMetadataDemanglingCache: - case Node::Kind::TypeMetadataLazyCache: - case Node::Kind::UncurriedFunctionType: + case Node::Kind::ConstrainedExistential: + case Node::Kind::PackElement: + case Node::Kind::PackElementLevel: + case Node::Kind::PackExpansion: + case Node::Kind::ProtocolListWithClass: + case Node::Kind::AccessorAttachedMacroExpansion: + case Node::Kind::AccessorFunctionReference: + case Node::Kind::Allocator: + case Node::Kind::ArgumentTuple: + case Node::Kind::AssociatedConformanceDescriptor: + case Node::Kind::AssociatedTypeDescriptor: + case Node::Kind::AssociatedTypeMetadataAccessor: + case Node::Kind::AssociatedTypeWitnessTableAccessor: + case Node::Kind::AsyncRemoved: + case Node::Kind::AutoClosureType: + case Node::Kind::BaseConformanceDescriptor: + case Node::Kind::BaseWitnessTableAccessor: + case Node::Kind::BodyAttachedMacroExpansion: + case Node::Kind::ClangType: + case Node::Kind::ClassMetadataBaseOffset: + case Node::Kind::CFunctionPointer: + case Node::Kind::ConformanceAttachedMacroExpansion: + case Node::Kind::Constructor: + case Node::Kind::CoroutineContinuationPrototype: + case Node::Kind::CurryThunk: + case Node::Kind::SILThunkIdentity: + case Node::Kind::DispatchThunk: + case Node::Kind::Deallocator: + case Node::Kind::IsolatedDeallocator: + case Node::Kind::DeclContext: + case Node::Kind::DefaultArgumentInitializer: + case Node::Kind::DefaultAssociatedTypeMetadataAccessor: + case Node::Kind::DefaultAssociatedConformanceAccessor: + case Node::Kind::DependentAssociatedTypeRef: + case Node::Kind::DependentGenericSignature: + case Node::Kind::DependentGenericParamPackMarker: + case Node::Kind::DependentGenericParamCount: + case Node::Kind::DependentGenericConformanceRequirement: + case Node::Kind::DependentGenericLayoutRequirement: + case Node::Kind::DependentGenericSameTypeRequirement: + case Node::Kind::DependentGenericSameShapeRequirement: + case Node::Kind::DependentPseudogenericSignature: + case Node::Kind::Destructor: + case Node::Kind::DidSet: + case Node::Kind::DirectMethodReferenceAttribute: + case Node::Kind::Directness: + case Node::Kind::DynamicAttribute: + case Node::Kind::EscapingAutoClosureType: + case Node::Kind::EscapingObjCBlock: + case Node::Kind::NoEscapeFunctionType: + case Node::Kind::ExplicitClosure: + case Node::Kind::Extension: + case Node::Kind::ExtensionAttachedMacroExpansion: + case Node::Kind::EnumCase: + case Node::Kind::FieldOffset: + case Node::Kind::FreestandingMacroExpansion: + case Node::Kind::FullObjCResilientClassStub: + case Node::Kind::FullTypeMetadata: + case Node::Kind::Function: + case Node::Kind::FunctionSignatureSpecialization: + case Node::Kind::FunctionSignatureSpecializationParam: + case Node::Kind::FunctionSignatureSpecializationReturn: + case Node::Kind::FunctionSignatureSpecializationParamKind: + case Node::Kind::FunctionSignatureSpecializationParamPayload: + case Node::Kind::FunctionType: + case Node::Kind::GenericProtocolWitnessTable: + case Node::Kind::GenericProtocolWitnessTableInstantiationFunction: + case Node::Kind::GenericPartialSpecialization: + case Node::Kind::GenericPartialSpecializationNotReAbstracted: + case Node::Kind::GenericSpecialization: + case Node::Kind::GenericSpecializationNotReAbstracted: + case Node::Kind::GenericSpecializationInResilienceDomain: + case Node::Kind::GenericSpecializationParam: + case Node::Kind::GenericSpecializationPrespecialized: + case Node::Kind::InlinedGenericFunction: + case Node::Kind::GenericTypeMetadataPattern: + case Node::Kind::Getter: + case Node::Kind::Global: + case Node::Kind::GlobalGetter: + case Node::Kind::Identifier: + case Node::Kind::Index: + case Node::Kind::InitAccessor: + case Node::Kind::IVarInitializer: + case Node::Kind::IVarDestroyer: + case Node::Kind::ImplDifferentiabilityKind: + case Node::Kind::ImplEscaping: + case Node::Kind::ImplErasedIsolation: + case Node::Kind::ImplSendingResult: + case Node::Kind::ImplConvention: + case Node::Kind::ImplParameterResultDifferentiability: + case Node::Kind::ImplParameterSending: + case Node::Kind::ImplParameterIsolated: + case Node::Kind::ImplParameterImplicitLeading: + case Node::Kind::ImplFunctionAttribute: + case Node::Kind::ImplFunctionConvention: + case Node::Kind::ImplFunctionConventionName: + case Node::Kind::ImplFunctionType: + case Node::Kind::ImplCoroutineKind: + case Node::Kind::ImplInvocationSubstitutions: + case Node::Kind::ImplPatternSubstitutions: + case Node::Kind::ImplicitClosure: + case Node::Kind::ImplParameter: + case Node::Kind::ImplResult: + case Node::Kind::ImplYield: + case Node::Kind::ImplErrorResult: + case Node::Kind::InOut: + case Node::Kind::InfixOperator: + case Node::Kind::Initializer: + case Node::Kind::Isolated: + case Node::Kind::Sending: + case Node::Kind::CompileTimeLiteral: + case Node::Kind::ConstValue: + case Node::Kind::PropertyWrapperBackingInitializer: + case Node::Kind::PropertyWrappedFieldInitAccessor: + case Node::Kind::PropertyWrapperInitFromProjectedValue: + case Node::Kind::KeyPathGetterThunkHelper: + case Node::Kind::KeyPathSetterThunkHelper: + case Node::Kind::KeyPathUnappliedMethodThunkHelper: + case Node::Kind::KeyPathAppliedMethodThunkHelper: + case Node::Kind::KeyPathEqualsThunkHelper: + case Node::Kind::KeyPathHashThunkHelper: + case Node::Kind::LazyProtocolWitnessTableAccessor: + case Node::Kind::LazyProtocolWitnessTableCacheVariable: + case Node::Kind::LocalDeclName: + case Node::Kind::Macro: + case Node::Kind::MacroExpansionLoc: + case Node::Kind::MacroExpansionUniqueName: + case Node::Kind::MaterializeForSet: + case Node::Kind::MemberAttributeAttachedMacroExpansion: + case Node::Kind::MemberAttachedMacroExpansion: + case Node::Kind::MergedFunction: + case Node::Kind::Metaclass: + case Node::Kind::MethodDescriptor: + case Node::Kind::MethodLookupFunction: + case Node::Kind::ModifyAccessor: + case Node::Kind::Modify2Accessor: + case Node::Kind::NativeOwningAddressor: + case Node::Kind::NativeOwningMutableAddressor: + case Node::Kind::NativePinningAddressor: + case Node::Kind::NativePinningMutableAddressor: + case Node::Kind::NominalTypeDescriptor: + case Node::Kind::NominalTypeDescriptorRecord: + case Node::Kind::NonObjCAttribute: + case Node::Kind::Number: + case Node::Kind::ObjCAsyncCompletionHandlerImpl: + case Node::Kind::ObjCAttribute: + case Node::Kind::ObjCBlock: + case Node::Kind::ObjCMetadataUpdateFunction: + case Node::Kind::ObjCResilientClassStub: + case Node::Kind::OpaqueTypeDescriptor: + case Node::Kind::OpaqueTypeDescriptorRecord: + case Node::Kind::OpaqueTypeDescriptorAccessor: + case Node::Kind::OpaqueTypeDescriptorAccessorImpl: + case Node::Kind::OpaqueTypeDescriptorAccessorKey: + case Node::Kind::OpaqueTypeDescriptorAccessorVar: + case Node::Kind::Owned: + case Node::Kind::OwningAddressor: + case Node::Kind::OwningMutableAddressor: + case Node::Kind::PartialApplyForwarder: + case Node::Kind::PartialApplyObjCForwarder: + case Node::Kind::PeerAttachedMacroExpansion: + case Node::Kind::PostfixOperator: + case Node::Kind::PreambleAttachedMacroExpansion: + case Node::Kind::CheckedObjCAsyncCompletionHandlerImpl: + case Node::Kind::PrefixOperator: + case Node::Kind::PrivateDeclName: + case Node::Kind::PropertyDescriptor: + case Node::Kind::ProtocolConformance: + case Node::Kind::ProtocolConformanceDescriptor: + case Node::Kind::ProtocolConformanceDescriptorRecord: + case Node::Kind::MetadataInstantiationCache: + case Node::Kind::ProtocolDescriptor: + case Node::Kind::ProtocolDescriptorRecord: + case Node::Kind::ProtocolRequirementsBaseDescriptor: + case Node::Kind::ProtocolSelfConformanceDescriptor: + case Node::Kind::ProtocolSelfConformanceWitness: + case Node::Kind::ProtocolSelfConformanceWitnessTable: + case Node::Kind::ProtocolWitness: + case Node::Kind::ProtocolWitnessTable: + case Node::Kind::ProtocolWitnessTableAccessor: + case Node::Kind::ProtocolWitnessTablePattern: + case Node::Kind::ReabstractionThunk: + case Node::Kind::ReabstractionThunkHelper: + case Node::Kind::ReabstractionThunkHelperWithSelf: + case Node::Kind::ReabstractionThunkHelperWithGlobalActor: + case Node::Kind::ReadAccessor: + case Node::Kind::Read2Accessor: + case Node::Kind::RelatedEntityDeclName: + case Node::Kind::RepresentationChanged: + case Node::Kind::RetroactiveConformance: + case Node::Kind::Setter: + case Node::Kind::Shared: + case Node::Kind::SILBoxLayout: + case Node::Kind::SILBoxMutableField: + case Node::Kind::SILBoxImmutableField: + case Node::Kind::IsSerialized: + case Node::Kind::DroppedArgument: + case Node::Kind::SpecializationPassID: + case Node::Kind::Static: + case Node::Kind::Subscript: + case Node::Kind::Suffix: + case Node::Kind::ThinFunctionType: + case Node::Kind::TupleElement: + case Node::Kind::TypeMangling: + case Node::Kind::TypeMetadata: + case Node::Kind::TypeMetadataAccessFunction: + case Node::Kind::TypeMetadataCompletionFunction: + case Node::Kind::TypeMetadataInstantiationCache: + case Node::Kind::TypeMetadataInstantiationFunction: + case Node::Kind::TypeMetadataSingletonInitializationCache: + case Node::Kind::TypeMetadataDemanglingCache: + case Node::Kind::TypeMetadataLazyCache: + case Node::Kind::UncurriedFunctionType: #define REF_STORAGE(Name, ...) \ case Node::Kind::Name: #include "swift/AST/ReferenceStorage.def" @@ -563,6 +534,7 @@ class NodePrinter { case Node::Kind::DifferentiableFunctionType: case Node::Kind::GlobalActorFunctionType: case Node::Kind::IsolatedAnyFunctionType: + case Node::Kind::NonIsolatedCallerFunctionType: case Node::Kind::SendingResultFunctionType: case Node::Kind::AsyncAnnotation: case Node::Kind::ThrowsAnnotation: @@ -576,6 +548,7 @@ class NodePrinter { case Node::Kind::OutlinedRetain: case Node::Kind::OutlinedRelease: case Node::Kind::OutlinedInitializeWithTake: + case Node::Kind::OutlinedInitializeWithTakeNoValueWitness: case Node::Kind::OutlinedInitializeWithCopy: case Node::Kind::OutlinedAssignWithTake: case Node::Kind::OutlinedAssignWithCopy: @@ -602,6 +575,7 @@ class NodePrinter { case Node::Kind::DependentProtocolConformanceAssociated: case Node::Kind::DependentProtocolConformanceInherited: case Node::Kind::DependentProtocolConformanceRoot: + case Node::Kind::DependentProtocolConformanceOpaque: case Node::Kind::ProtocolConformanceRefInTypeModule: case Node::Kind::ProtocolConformanceRefInProtocolModule: case Node::Kind::ProtocolConformanceRefInOtherModule: @@ -645,555 +619,558 @@ class NodePrinter { case Node::Kind::SymbolicExtendedExistentialType: case Node::Kind::HasSymbolQuery: case Node::Kind::ObjectiveCProtocolSymbolicReference: - case Node::Kind::ParamLifetimeDependence: - case Node::Kind::SelfLifetimeDependence: case Node::Kind::DependentGenericInverseConformanceRequirement: + case Node::Kind::DependentGenericParamValueMarker: + case Node::Kind::CoroFunctionPointer: + case Node::Kind::DefaultOverride: + case Node::Kind::BorrowAccessor: + case Node::Kind::MutateAccessor: return false; } printer_unreachable("bad node kind"); - } +} - void printWithParens(NodePointer type, unsigned depth) { - bool needs_parens = !isSimpleType(type); - if (needs_parens) - Printer << "("; - print(type, depth + 1); - if (needs_parens) - Printer << ")"; - } +void NodePrinter::printWithParens(NodePointer type, unsigned depth) { + bool needs_parens = !isSimpleType(type); + if (needs_parens) + Printer << "("; + print(type, depth + 1); + if (needs_parens) + Printer << ")"; +} - SugarType findSugar(NodePointer Node) { - if (Node->getNumChildren() == 1 && - Node->getKind() == Node::Kind::Type) - return findSugar(Node->getChild(0)); - - if (Node->getNumChildren() != 2) - return SugarType::None; - - if (Node->getKind() != Node::Kind::BoundGenericEnum && - Node->getKind() != Node::Kind::BoundGenericStructure) - return SugarType::None; - - auto unboundType = Node->getChild(0)->getChild(0); // drill through Type - auto typeArgs = Node->getChild(1); - - if (Node->getKind() == Node::Kind::BoundGenericEnum) { - // Swift.Optional - if (isIdentifier(unboundType->getChild(1), "Optional") && - typeArgs->getNumChildren() == 1 && - isSwiftModule(unboundType->getChild(0))) { - return SugarType::Optional; - } +NodePrinter::SugarType NodePrinter::findSugar(NodePointer Node) { + if (Node->getNumChildren() == 1 && Node->getKind() == Node::Kind::Type) + return findSugar(Node->getChild(0)); - // Swift.ImplicitlyUnwrappedOptional - if (isIdentifier(unboundType->getChild(1), - "ImplicitlyUnwrappedOptional") && - typeArgs->getNumChildren() == 1 && - isSwiftModule(unboundType->getChild(0))) { - return SugarType::ImplicitlyUnwrappedOptional; - } + if (Node->getNumChildren() != 2) + return SugarType::None; - return SugarType::None; - } + if (Node->getKind() != Node::Kind::BoundGenericEnum && + Node->getKind() != Node::Kind::BoundGenericStructure) + return SugarType::None; - assert(Node->getKind() == Node::Kind::BoundGenericStructure); + auto unboundType = Node->getChild(0)->getChild(0); // drill through Type + auto typeArgs = Node->getChild(1); - // Array - if (isIdentifier(unboundType->getChild(1), "Array") && + if (Node->getKind() == Node::Kind::BoundGenericEnum) { + // Swift.Optional + if (isIdentifier(unboundType->getChild(1), "Optional") && typeArgs->getNumChildren() == 1 && isSwiftModule(unboundType->getChild(0))) { - return SugarType::Array; + return SugarType::Optional; } - // Dictionary - if (isIdentifier(unboundType->getChild(1), "Dictionary") && - typeArgs->getNumChildren() == 2 && + // Swift.ImplicitlyUnwrappedOptional + if (isIdentifier(unboundType->getChild(1), "ImplicitlyUnwrappedOptional") && + typeArgs->getNumChildren() == 1 && isSwiftModule(unboundType->getChild(0))) { - return SugarType::Dictionary; + return SugarType::ImplicitlyUnwrappedOptional; } return SugarType::None; } - void printBoundGeneric(NodePointer Node, unsigned depth) { - if (Node->getNumChildren() < 2) - return; - if (Node->getNumChildren() != 2) { - printBoundGenericNoSugar(Node, depth); - return; - } + assert(Node->getKind() == Node::Kind::BoundGenericStructure); - if (!Options.SynthesizeSugarOnTypes || - Node->getKind() == Node::Kind::BoundGenericClass) - { - // no sugar here - printBoundGenericNoSugar(Node, depth); - return; - } + // Array + if (isIdentifier(unboundType->getChild(1), "Array") && + typeArgs->getNumChildren() == 1 && + isSwiftModule(unboundType->getChild(0))) { + return SugarType::Array; + } - // Print the conforming type for a "bound" protocol node "as" the protocol - // type. - if (Node->getKind() == Node::Kind::BoundGenericProtocol) { - printChildren(Node->getChild(1), depth); - Printer << " as "; - print(Node->getChild(0), depth + 1); - return; - } + // Dictionary + if (isIdentifier(unboundType->getChild(1), "Dictionary") && + typeArgs->getNumChildren() == 2 && + isSwiftModule(unboundType->getChild(0))) { + return SugarType::Dictionary; + } - SugarType sugarType = findSugar(Node); - - switch (sugarType) { - case SugarType::None: - printBoundGenericNoSugar(Node, depth); - break; - case SugarType::Optional: - case SugarType::ImplicitlyUnwrappedOptional: { - NodePointer type = Node->getChild(1)->getChild(0); - printWithParens(type, depth); - Printer << (sugarType == SugarType::Optional ? "?" : "!"); - break; - } - case SugarType::Array: { - NodePointer type = Node->getChild(1)->getChild(0); - Printer << "["; - print(type, depth + 1); - Printer << "]"; - break; - } - case SugarType::Dictionary: { - NodePointer keyType = Node->getChild(1)->getChild(0); - NodePointer valueType = Node->getChild(1)->getChild(1); - Printer << "["; - print(keyType, depth + 1); - Printer << " : "; - print(valueType, depth + 1); - Printer << "]"; - break; - } - } + return SugarType::None; +} + +void NodePrinter::printBoundGeneric(NodePointer Node, unsigned depth) { + if (Node->getNumChildren() < 2) + return; + if (Node->getNumChildren() != 2) { + printBoundGenericNoSugar(Node, depth); + return; } - NodePointer getChildIf(NodePointer Node, Node::Kind Kind) { - auto result = - std::find_if(Node->begin(), Node->end(), [&](NodePointer child) { - return child->getKind() == Kind; - }); - return result != Node->end() ? *result : nullptr; + if (!Options.SynthesizeSugarOnTypes || + Node->getKind() == Node::Kind::BoundGenericClass) { + // no sugar here + printBoundGenericNoSugar(Node, depth); + return; } - void printFunctionParameters(NodePointer LabelList, NodePointer ParameterType, - unsigned depth, bool showTypes) { - if (ParameterType->getKind() != Node::Kind::ArgumentTuple) { - setInvalid(); - return; - } + // Print the conforming type for a "bound" protocol node "as" the protocol + // type. + if (Node->getKind() == Node::Kind::BoundGenericProtocol) { + printChildren(Node->getChild(1), depth); + Printer << " as "; + print(Node->getChild(0), depth + 1); + return; + } - NodePointer Parameters = ParameterType->getFirstChild(); - assert(Parameters->getKind() == Node::Kind::Type); - Parameters = Parameters->getFirstChild(); - if (Parameters->getKind() != Node::Kind::Tuple) { - // only a single not-named parameter - if (showTypes) { - Printer << '('; - print(Parameters, depth + 1); - Printer << ')'; - } else { - Printer << "(_:)"; - } - return; + SugarType sugarType = findSugar(Node); + + switch (sugarType) { + case SugarType::None: + printBoundGenericNoSugar(Node, depth); + break; + case SugarType::Optional: + case SugarType::ImplicitlyUnwrappedOptional: { + NodePointer type = Node->getChild(1)->getChild(0); + printWithParens(type, depth); + Printer << (sugarType == SugarType::Optional ? "?" : "!"); + break; + } + case SugarType::Array: { + NodePointer type = Node->getChild(1)->getChild(0); + Printer << "["; + print(type, depth + 1); + Printer << "]"; + break; + } + case SugarType::Dictionary: { + NodePointer keyType = Node->getChild(1)->getChild(0); + NodePointer valueType = Node->getChild(1)->getChild(1); + Printer << "["; + print(keyType, depth + 1); + Printer << " : "; + print(valueType, depth + 1); + Printer << "]"; + break; + } + } +} + +NodePointer NodePrinter::getChildIf(NodePointer Node, Node::Kind Kind) { + auto result = + std::find_if(Node->begin(), Node->end(), + [&](NodePointer child) { return child->getKind() == Kind; }); + return result != Node->end() ? *result : nullptr; +} + +void NodePrinter::printFunctionParameters(NodePointer LabelList, + NodePointer ParameterType, + unsigned depth, bool showTypes) { + if (ParameterType->getKind() != Node::Kind::ArgumentTuple) { + setInvalid(); + return; + } + + NodePointer Parameters = ParameterType->getFirstChild(); + assert(Parameters->getKind() == Node::Kind::Type); + Parameters = Parameters->getFirstChild(); + if (Parameters->getKind() != Node::Kind::Tuple) { + // only a single not-named parameter + if (showTypes) { + Printer << '('; + print(Parameters, depth + 1); + Printer << ')'; + } else { + Printer << "(_:)"; } + return; + } - auto getLabelFor = [&](NodePointer Param, unsigned Index) -> std::string { - auto Label = LabelList->getChild(Index); - assert(Label && (Label->getKind() == Node::Kind::Identifier || - Label->getKind() == Node::Kind::FirstElementMarker)); - return Label->getKind() == Node::Kind::Identifier ? Label->getText().str() - : "_"; - }; - - unsigned ParamIndex = 0; - bool hasLabels = LabelList && LabelList->getNumChildren() > 0; - - Printer << '('; - llvm::interleave( - Parameters->begin(), Parameters->end(), - [&](NodePointer Param) { - assert(Param->getKind() == Node::Kind::TupleElement); - - if (hasLabels) { - Printer << getLabelFor(Param, ParamIndex) << ':'; - } else if (!showTypes) { - if (auto Label = getChildIf(Param, Node::Kind::TupleElementName)) - Printer << Label->getText() << ":"; - else - Printer << "_:"; - } + auto getLabelFor = [&](NodePointer Param, unsigned Index) -> std::string { + auto Label = LabelList->getChild(Index); + assert(Label && (Label->getKind() == Node::Kind::Identifier || + Label->getKind() == Node::Kind::FirstElementMarker)); + return Label->getKind() == Node::Kind::Identifier ? Label->getText().str() + : "_"; + }; - if (hasLabels && showTypes) - Printer << ' '; + unsigned ParamIndex = 0; + bool hasLabels = LabelList && LabelList->getNumChildren() > 0; + + Printer << '('; + llvm::interleave( + Parameters->begin(), Parameters->end(), + [&](NodePointer Param) { + assert(Param->getKind() == Node::Kind::TupleElement); + + if (hasLabels) { + Printer << getLabelFor(Param, ParamIndex) << ':'; + } else if (!showTypes) { + if (auto Label = getChildIf(Param, Node::Kind::TupleElementName)) + Printer << Label->getText() << ":"; + else + Printer << "_:"; + } - ++ParamIndex; + if (hasLabels && showTypes) + Printer << ' '; - if (showTypes) - print(Param, depth + 1); - }, - [&]() { Printer << (showTypes ? ", " : ""); }); - Printer << ')'; + ++ParamIndex; + + if (showTypes) + print(Param, depth + 1); + }, + [&]() { Printer << (showTypes ? ", " : ""); }); + Printer << ')'; +} + +void NodePrinter::printFunctionType(NodePointer LabelList, NodePointer node, + unsigned depth) { + if (node->getNumChildren() < 2) { + setInvalid(); + return; } - void printFunctionType(NodePointer LabelList, NodePointer node, - unsigned depth) { - if (node->getNumChildren() < 2) { - setInvalid(); - return; + auto printConventionWithMangledCType = [this, node, + depth](const char *convention) { + Printer << "@convention(" << convention; + if (node->getFirstChild()->getKind() == Node::Kind::ClangType) { + Printer << ", mangledCType: \""; + print(node->getFirstChild(), depth + 1); + Printer << '"'; } + Printer << ") "; + }; - auto printConventionWithMangledCType = [this, node, - depth](const char *convention) { - Printer << "@convention(" << convention; - if (node->getFirstChild()->getKind() == Node::Kind::ClangType) { - Printer << ", mangledCType: \""; - print(node->getFirstChild(), depth + 1); - Printer << '"'; - } - Printer << ") "; - }; + switch (node->getKind()) { + case Node::Kind::FunctionType: + case Node::Kind::UncurriedFunctionType: + case Node::Kind::NoEscapeFunctionType: + break; + case Node::Kind::AutoClosureType: + case Node::Kind::EscapingAutoClosureType: + Printer << "@autoclosure "; + break; + case Node::Kind::ThinFunctionType: + Printer << "@convention(thin) "; + break; + case Node::Kind::CFunctionPointer: + printConventionWithMangledCType("c"); + break; + case Node::Kind::EscapingObjCBlock: + Printer << "@escaping "; + LLVM_FALLTHROUGH; + case Node::Kind::ObjCBlock: + printConventionWithMangledCType("block"); + break; + default: + assert(false && "Unhandled function type in printFunctionType!"); + } - switch (node->getKind()) { - case Node::Kind::FunctionType: - case Node::Kind::UncurriedFunctionType: - case Node::Kind::NoEscapeFunctionType: - break; - case Node::Kind::AutoClosureType: - case Node::Kind::EscapingAutoClosureType: - Printer << "@autoclosure "; break; - case Node::Kind::ThinFunctionType: - Printer << "@convention(thin) "; break; - case Node::Kind::CFunctionPointer: - printConventionWithMangledCType("c"); - break; - case Node::Kind::EscapingObjCBlock: - Printer << "@escaping "; - LLVM_FALLTHROUGH; - case Node::Kind::ObjCBlock: - printConventionWithMangledCType("block"); - break; - default: - assert(false && "Unhandled function type in printFunctionType!"); - } + unsigned argIndex = node->getNumChildren() - 2; + unsigned startIndex = 0; + bool isSendable = false, isAsync = false, hasSendingResult = false; + auto diffKind = MangledDifferentiabilityKind::NonDifferentiable; + if (node->getChild(startIndex)->getKind() == Node::Kind::ClangType) { + // handled earlier + ++startIndex; + } - unsigned argIndex = node->getNumChildren() - 2; - unsigned startIndex = 0; - bool isSendable = false, isAsync = false, hasSendingResult = false; - auto diffKind = MangledDifferentiabilityKind::NonDifferentiable; - if (node->getChild(startIndex)->getKind() == Node::Kind::ClangType) { - // handled earlier - ++startIndex; - } - if (node->getChild(startIndex)->getKind() - == Node::Kind::IsolatedAnyFunctionType) { - print(node->getChild(startIndex), depth + 1); - ++startIndex; - } - if (node->getChild(startIndex)->getKind() == - Node::Kind::GlobalActorFunctionType) { - print(node->getChild(startIndex), depth + 1); - ++startIndex; - } - if (node->getChild(startIndex)->getKind() == - Node::Kind::DifferentiableFunctionType) { - diffKind = - (MangledDifferentiabilityKind)node->getChild(startIndex)->getIndex(); - ++startIndex; - } - if (node->getChild(startIndex)->getKind() == - Node::Kind::SelfLifetimeDependence) { - print(node->getChild(startIndex), depth + 1); - ++startIndex; - } + // Be sure to check for function signature components in the same + // order that they're added by the demangler, which is the reverse + // of the order that they appear in the mangling grammar. - Node *thrownErrorNode = nullptr; - if (node->getChild(startIndex)->getKind() == Node::Kind::ThrowsAnnotation || - node->getChild(startIndex)->getKind() - == Node::Kind::TypedThrowsAnnotation) { - thrownErrorNode = node->getChild(startIndex); - ++startIndex; - } + if (node->getChild(startIndex)->getKind() == + Node::Kind::SendingResultFunctionType) { + ++startIndex; + hasSendingResult = true; + } - if (node->getChild(startIndex)->getKind() - == Node::Kind::ConcurrentFunctionType) { - ++startIndex; - isSendable = true; - } - if (node->getChild(startIndex)->getKind() == Node::Kind::AsyncAnnotation) { - ++startIndex; - isAsync = true; - } - if (node->getChild(startIndex)->getKind() == - Node::Kind::SendingResultFunctionType) { - ++startIndex; - hasSendingResult = true; - } + // function-isolation; note that these can't actually both appear. + if (node->getChild(startIndex)->getKind() == + Node::Kind::IsolatedAnyFunctionType) { + print(node->getChild(startIndex), depth + 1); + ++startIndex; + } - switch (diffKind) { - case MangledDifferentiabilityKind::Forward: - Printer << "@differentiable(_forward) "; - break; - case MangledDifferentiabilityKind::Reverse: - Printer << "@differentiable(reverse) "; - break; - case MangledDifferentiabilityKind::Linear: - Printer << "@differentiable(_linear) "; - break; - case MangledDifferentiabilityKind::Normal: - Printer << "@differentiable "; - break; - case MangledDifferentiabilityKind::NonDifferentiable: - break; - } + Node *nonIsolatedCallerNode = nullptr; + if (node->getChild(startIndex)->getKind() == + Node::Kind::NonIsolatedCallerFunctionType) { + nonIsolatedCallerNode = node->getChild(startIndex); + ++startIndex; + } + + if (node->getChild(startIndex)->getKind() == + Node::Kind::GlobalActorFunctionType) { + print(node->getChild(startIndex), depth + 1); + ++startIndex; + } + + if (node->getChild(startIndex)->getKind() == + Node::Kind::DifferentiableFunctionType) { + diffKind = + (MangledDifferentiabilityKind)node->getChild(startIndex)->getIndex(); + ++startIndex; + } + + Node *thrownErrorNode = nullptr; + if (node->getChild(startIndex)->getKind() == Node::Kind::ThrowsAnnotation || + node->getChild(startIndex)->getKind() == + Node::Kind::TypedThrowsAnnotation) { + thrownErrorNode = node->getChild(startIndex); + ++startIndex; + } + + if (node->getChild(startIndex)->getKind() == + Node::Kind::ConcurrentFunctionType) { + ++startIndex; + isSendable = true; + } + if (node->getChild(startIndex)->getKind() == Node::Kind::AsyncAnnotation) { + ++startIndex; + isAsync = true; + } + + switch (diffKind) { + case MangledDifferentiabilityKind::Forward: + Printer << "@differentiable(_forward) "; + break; + case MangledDifferentiabilityKind::Reverse: + Printer << "@differentiable(reverse) "; + break; + case MangledDifferentiabilityKind::Linear: + Printer << "@differentiable(_linear) "; + break; + case MangledDifferentiabilityKind::Normal: + Printer << "@differentiable "; + break; + case MangledDifferentiabilityKind::NonDifferentiable: + break; + } + + if (nonIsolatedCallerNode) + print(nonIsolatedCallerNode, depth + 1); + + if (isSendable) + Printer << "@Sendable "; + + if (Options.ShowFunctionArgumentTypes) { + printFunctionParameters(LabelList, node->getChild(argIndex), depth, true); + } + + if (!Options.ShowFunctionReturnType) + return; + + if (isAsync) + Printer << " async"; - if (isSendable) - Printer << "@Sendable "; + if (thrownErrorNode) { + print(thrownErrorNode, depth + 1); + } - if (Options.ShowFunctionArgumentTypes) { - printFunctionParameters(LabelList, node->getChild(argIndex), depth, true); - } + Printer << " -> "; - if (!Options.ShowFunctionReturnType) - return; + if (hasSendingResult) + Printer << "sending "; - if (isAsync) - Printer << " async"; + print(node->getChild(argIndex + 1), depth + 1); +} - if (thrownErrorNode) { - print(thrownErrorNode, depth + 1); +void NodePrinter::printImplFunctionType(NodePointer fn, unsigned depth) { + NodePointer patternSubs = nullptr; + NodePointer invocationSubs = nullptr; + NodePointer sendingResult = nullptr; + enum State { Attrs, Inputs, Results } curState = Attrs; + auto transitionTo = [&](State newState) { + assert(newState >= curState); + for (; curState != newState; curState = State(curState + 1)) { + switch (curState) { + case Attrs: + if (patternSubs) { + Printer << "@substituted "; + print(patternSubs->getChild(0), depth + 1); + Printer << ' '; + } + Printer << '('; + continue; + case Inputs: + Printer << ") -> "; + if (sendingResult) { + print(sendingResult, depth + 1); + Printer << " "; + } + Printer << "("; + continue; + case Results: + printer_unreachable("no state after Results"); + } + printer_unreachable("bad state"); } + }; - Printer << " -> "; - - if (hasSendingResult) - Printer << "sending "; + for (auto &child : *fn) { + if (child->getKind() == Node::Kind::ImplParameter) { + if (curState == Inputs) + Printer << ", "; + transitionTo(Inputs); + print(child, depth + 1); + } else if (child->getKind() == Node::Kind::ImplResult || + child->getKind() == Node::Kind::ImplYield || + child->getKind() == Node::Kind::ImplErrorResult) { + if (curState == Results) + Printer << ", "; + transitionTo(Results); + print(child, depth + 1); + } else if (child->getKind() == Node::Kind::ImplPatternSubstitutions) { + patternSubs = child; + } else if (child->getKind() == Node::Kind::ImplInvocationSubstitutions) { + invocationSubs = child; + } else if (child->getKind() == Node::Kind::ImplSendingResult) { + sendingResult = child; + } else { + assert(curState == Attrs); + print(child, depth + 1); + Printer << ' '; + } + } + transitionTo(Results); + Printer << ')'; - print(node->getChild(argIndex + 1), depth + 1); + if (patternSubs) { + Printer << " for <"; + printChildren(patternSubs->getChild(1), depth); + Printer << '>'; + } + if (invocationSubs) { + Printer << " for <"; + printChildren(invocationSubs->getChild(0), depth); + Printer << '>'; } +} - void printImplFunctionType(NodePointer fn, unsigned depth) { - NodePointer patternSubs = nullptr; - NodePointer invocationSubs = nullptr; - NodePointer sendingResult = nullptr; - enum State { Attrs, Inputs, Results } curState = Attrs; - auto transitionTo = [&](State newState) { - assert(newState >= curState); - for (; curState != newState; curState = State(curState + 1)) { - switch (curState) { - case Attrs: - if (patternSubs) { - Printer << "@substituted "; - print(patternSubs->getChild(0), depth + 1); - Printer << ' '; - } - Printer << '('; - continue; - case Inputs: - Printer << ") -> "; - if (sendingResult) { - print(sendingResult, depth + 1); - Printer << " "; - } - Printer << "("; - continue; - case Results: printer_unreachable("no state after Results"); - } - printer_unreachable("bad state"); - } - }; +void NodePrinter::printGenericSignature(NodePointer Node, unsigned depth) { + Printer << '<'; - for (auto &child : *fn) { - if (child->getKind() == Node::Kind::ImplParameter) { - if (curState == Inputs) Printer << ", "; - transitionTo(Inputs); - print(child, depth + 1); - } else if (child->getKind() == Node::Kind::ImplResult - || child->getKind() == Node::Kind::ImplYield - || child->getKind() == Node::Kind::ImplErrorResult) { - if (curState == Results) Printer << ", "; - transitionTo(Results); - print(child, depth + 1); - } else if (child->getKind() == Node::Kind::ImplPatternSubstitutions) { - patternSubs = child; - } else if (child->getKind() == Node::Kind::ImplInvocationSubstitutions) { - invocationSubs = child; - } else if (child->getKind() == Node::Kind::ImplSendingResult) { - sendingResult = child; - } else { - assert(curState == Attrs); - print(child, depth + 1); - Printer << ' '; - } - } - transitionTo(Results); - Printer << ')'; + unsigned numChildren = Node->getNumChildren(); - if (patternSubs) { - Printer << " for <"; - printChildren(patternSubs->getChild(1), depth); - Printer << '>'; + unsigned numGenericParams = 0; + for (; numGenericParams < numChildren; ++numGenericParams) { + if (Node->getChild(numGenericParams)->getKind() != + Node::Kind::DependentGenericParamCount) { + break; } - if (invocationSubs) { - Printer << " for <"; - printChildren(invocationSubs->getChild(0), depth); - Printer << '>'; + } + + unsigned firstRequirement = numGenericParams; + for (; firstRequirement < numChildren; ++firstRequirement) { + auto child = Node->getChild(firstRequirement); + if (child->getKind() == Node::Kind::Type) + child = child->getChild(0); + if (child->getKind() != Node::Kind::DependentGenericParamPackMarker && + child->getKind() != Node::Kind::DependentGenericParamValueMarker) { + break; } } - void printGenericSignature(NodePointer Node, unsigned depth) { - Printer << '<'; + auto isGenericParamPack = [&](unsigned depth, unsigned index) { + for (unsigned i = numGenericParams; i < firstRequirement; ++i) { + auto child = Node->getChild(i); + if (child->getKind() != Node::Kind::DependentGenericParamPackMarker) + continue; + child = child->getChild(0); + + if (child->getKind() != Node::Kind::Type) + continue; - unsigned numChildren = Node->getNumChildren(); + child = child->getChild(0); + if (child->getKind() != Node::Kind::DependentGenericParamType) + continue; - unsigned numGenericParams = 0; - for (; numGenericParams < numChildren; ++numGenericParams) { - if (Node->getChild(numGenericParams)->getKind() - != Node::Kind::DependentGenericParamCount) { - break; + if (index == child->getChild(0)->getIndex() && + depth == child->getChild(1)->getIndex()) { + return true; } } - unsigned firstRequirement = numGenericParams; - for (; firstRequirement < numChildren; ++firstRequirement) { - auto child = Node->getChild(firstRequirement); - if (child->getKind() == Node::Kind::Type) - child = child->getChild(0); - if (child->getKind() != Node::Kind::DependentGenericParamPackMarker) { - break; + return false; + }; + + auto isGenericParamValue = [&](unsigned depth, unsigned index) { + for (unsigned i = numGenericParams; i < firstRequirement; ++i) { + auto child = Node->getChild(i); + if (child->getKind() != Node::Kind::DependentGenericParamValueMarker) + continue; + child = child->getChild(0); + + if (child->getKind() != Node::Kind::Type) + continue; + + auto param = child->getChild(0); + auto type = child->getChild(1); + if (param->getKind() != Node::Kind::DependentGenericParamType) + continue; + + if (index == param->getChild(0)->getIndex() && + depth == param->getChild(1)->getIndex()) { + return std::make_pair(true, type); } } - auto isGenericParamPack = [&](unsigned depth, unsigned index) { - for (unsigned i = numGenericParams; i < firstRequirement; ++i) { - auto child = Node->getChild(i); - if (child->getKind() != Node::Kind::DependentGenericParamPackMarker) - continue; - child = child->getChild(0); + return std::make_pair(false, NodePointer()); + }; - if (child->getKind() != Node::Kind::Type) - continue; + unsigned gpDepth = 0; + for (; gpDepth < numGenericParams; ++gpDepth) { + if (gpDepth != 0) + Printer << "><"; - child = child->getChild(0); - if (child->getKind() != Node::Kind::DependentGenericParamType) - continue; + unsigned count = Node->getChild(gpDepth)->getIndex(); + for (unsigned index = 0; index < count; ++index) { + if (index != 0) + Printer << ", "; - if (index == child->getChild(0)->getIndex() && - depth == child->getChild(1)->getIndex()) { - return true; - } + // Limit the number of printed generic parameters. In practice this + // it will never be exceeded. The limit is only important for malformed + // symbols where count can be really huge. + if (index >= 128) { + Printer << "..."; + break; } - return false; - }; - - unsigned gpDepth = 0; - for (; gpDepth < numGenericParams; ++gpDepth) { - if (gpDepth != 0) - Printer << "><"; + if (isGenericParamPack(gpDepth, index)) + Printer << "each "; - unsigned count = Node->getChild(gpDepth)->getIndex(); - for (unsigned index = 0; index < count; ++index) { - if (index != 0) - Printer << ", "; + auto value = isGenericParamValue(gpDepth, index); - // Limit the number of printed generic parameters. In practice this - // it will never be exceeded. The limit is only important for malformed - // symbols where count can be really huge. - if (index >= 128) { - Printer << "..."; - break; - } + if (value.first) + Printer << "let "; - if (isGenericParamPack(gpDepth, index)) - Printer << "each "; + // FIXME: Depth won't match when a generic signature applies to a + // method in generic type context. + Printer << Options.GenericParameterName(gpDepth, index); - // FIXME: Depth won't match when a generic signature applies to a - // method in generic type context. - Printer << Options.GenericParameterName(gpDepth, index); + if (value.second) { + Printer << ": "; + print(value.second, depth + 1); } } + } - if (firstRequirement != numChildren) { - if (Options.DisplayWhereClauses) { - Printer << " where "; - for (unsigned i = firstRequirement; i < numChildren; ++i) { - if (i > firstRequirement) - Printer << ", "; - print(Node->getChild(i), depth + 1); - } + if (firstRequirement != numChildren) { + if (Options.DisplayWhereClauses) { + Printer << " where "; + for (unsigned i = firstRequirement; i < numChildren; ++i) { + if (i > firstRequirement) + Printer << ", "; + print(Node->getChild(i), depth + 1); } } - Printer << '>'; } - - void printFunctionSigSpecializationParams(NodePointer Node, unsigned depth); - - void printSpecializationPrefix(NodePointer node, StringRef Description, - unsigned depth, - StringRef ParamPrefix = StringRef()); - - /// The main big print function. - NodePointer print(NodePointer Node, unsigned depth, - bool asPrefixContext = false); - - NodePointer printAbstractStorage(NodePointer Node, unsigned depth, - bool asPrefixContent, StringRef ExtraName); - - /// Utility function to print entities. - /// - /// \param Entity The entity node to print - /// \param depth The depth in the print() call tree. - /// \param asPrefixContext Should the entity printed as a context which as a - /// prefix to another entity, e.g. the Abc in Abc.def() - /// \param TypePr How should the type of the entity be printed, if at all. - /// E.g. with a colon for properties or as a function type. - /// \param hasName Does the entity has a name, e.g. a function in contrast to - /// an initializer. - /// \param ExtraName An extra name added to the entity name (if any). - /// \param ExtraIndex An extra index added to the entity name (if any), - /// e.g. closure #1 - /// \param OverwriteName If non-empty, print this name instead of the one - /// provided by the node. Gets printed even if hasName is false. - /// \return If a non-null node is returned it's a context which must be - /// printed in postfix-form after the entity: " in ". - NodePointer printEntity(NodePointer Entity, unsigned depth, - bool asPrefixContext, TypePrinting TypePr, - bool hasName, StringRef ExtraName = "", - int ExtraIndex = -1, StringRef OverwriteName = ""); - - /// Print the type of an entity. - /// - /// \param Entity The entity. - /// \param type The type of the entity. - /// \param genericFunctionTypeList If not null, the generic argument types - /// which is printed in the generic signature. - /// \param depth The depth in the print() call tree. - void printEntityType(NodePointer Entity, NodePointer type, - NodePointer genericFunctionTypeList, unsigned depth); -}; -} // end anonymous namespace - -static bool isExistentialType(NodePointer node) { - return (node->getKind() == Node::Kind::ExistentialMetatype || - node->getKind() == Node::Kind::ProtocolList || - node->getKind() == Node::Kind::ProtocolListWithClass || - node->getKind() == Node::Kind::ProtocolListWithAnyObject); + Printer << '>'; } /// Print the relevant parameters and return the new index. void NodePrinter::printFunctionSigSpecializationParams(NodePointer Node, unsigned depth) { unsigned Idx = 0; + unsigned argIdx = 0; unsigned End = Node->getNumChildren(); while (Idx < End) { - NodePointer firstChild = Node->getChild(Idx); - unsigned V = firstChild->getIndex(); + NodePointer child = Node->getChild(Idx); + if (!child->hasIndex()) + return; + unsigned V = child->getIndex(); auto K = FunctionSigSpecializationParamKind(V); switch (K) { case FunctionSigSpecializationParamKind::BoxToValue: @@ -1206,18 +1183,14 @@ void NodePrinter::printFunctionSigSpecializationParams(NodePointer Node, Printer << "["; print(Node->getChild(Idx++), depth + 1); Printer << " : "; - const auto &text = Node->getChild(Idx++)->getText(); - std::string demangledName = demangleSymbolAsString(text); - if (demangledName.empty()) { - Printer << text; - } else { - Printer << demangledName; - } + printNextParamChildNode(Node, argIdx, K, depth); Printer << "]"; break; } case FunctionSigSpecializationParamKind::ConstantPropInteger: case FunctionSigSpecializationParamKind::ConstantPropFloat: + if (Idx + 2 > End) + return; Printer << "["; print(Node->getChild(Idx++), depth + 1); Printer << " : "; @@ -1225,12 +1198,14 @@ void NodePrinter::printFunctionSigSpecializationParams(NodePointer Node, Printer << "]"; break; case FunctionSigSpecializationParamKind::ConstantPropString: + if (Idx + 2 > End) + return; Printer << "["; print(Node->getChild(Idx++), depth + 1); Printer << " : "; print(Node->getChild(Idx++), depth + 1); Printer << "'"; - print(Node->getChild(Idx++), depth + 1); + printNextParamChildNode(Node, argIdx, K, depth); Printer << "'"; Printer << "]"; break; @@ -1238,14 +1213,23 @@ void NodePrinter::printFunctionSigSpecializationParams(NodePointer Node, Printer << "["; print(Node->getChild(Idx++), depth + 1); Printer << " : "; - print(Node->getChild(Idx++), depth + 1); + printNextParamChildNode(Node, argIdx, K, depth); Printer << "<"; - print(Node->getChild(Idx++), depth + 1); + printNextParamChildNode(Node, argIdx, K, depth); Printer << ","; - print(Node->getChild(Idx++), depth + 1); + printNextParamChildNode(Node, argIdx, K, depth); Printer << ">]"; break; + case FunctionSigSpecializationParamKind::ConstantPropStruct: + Printer << "["; + print(Node->getChild(Idx++), depth + 1); + Printer << " : "; + printNextParamChildNode(Node, argIdx, K, depth); + Printer << "]"; + break; case FunctionSigSpecializationParamKind::ClosureProp: + if (Idx + 2 > End) + return; Printer << "["; print(Node->getChild(Idx++), depth + 1); Printer << " : "; @@ -1265,6 +1249,15 @@ void NodePrinter::printFunctionSigSpecializationParams(NodePointer Node, } Printer << "]"; break; + case FunctionSigSpecializationParamKind::ClosurePropPreviousArg: + if (Idx + 2 > End) + return; + Printer << "["; + print(Node->getChild(Idx++), depth + 1); + Printer << " "; + print(Node->getChild(Idx++), depth + 1); + Printer << "]"; + break; default: assert( ((V & unsigned(FunctionSigSpecializationParamKind::OwnedToGuaranteed)) || @@ -1279,6 +1272,56 @@ void NodePrinter::printFunctionSigSpecializationParams(NodePointer Node, } } +void NodePrinter::printNextParamChildNode(NodePointer nd, unsigned &idx, + FunctionSigSpecializationParamKind kind, + unsigned depth) { + while (idx < nd->getNumChildren()) { + NodePointer child = nd->getChild(idx++); + if (child->getKind() == Node::Kind::FunctionSignatureSpecializationParamKind || + child->getKind() == Node::Kind::FunctionSignatureSpecializationParamPayload) { + continue; + } + switch (kind) { + case FunctionSigSpecializationParamKind::ConstantPropInteger: + case FunctionSigSpecializationParamKind::ConstantPropFloat: { + if (!child->hasText()) + return; + const auto &text = child->getText(); + std::string demangledName = demangleSymbolAsString(text); + if (demangledName.empty()) { + Printer << text; + } else { + Printer << demangledName; + } + break; + } + case FunctionSigSpecializationParamKind::ConstantPropString: + if (child->hasText()) { + StringRef text = child->getText(); + if (!text.empty() && text[0] == '_') { + Printer << text.drop_front(1); + return; + } + } + print(child, depth + 1); + break; + case FunctionSigSpecializationParamKind::ConstantPropFunction: + case FunctionSigSpecializationParamKind::ConstantPropGlobal: { + std::string demangledName = demangleSymbolAsString(child->getText()); + if (demangledName.empty()) { + Printer << child->getText(); + } else { + Printer << demangledName; + } + break; + } + default: + print(child, depth + 1); + } + return; + } +} + void NodePrinter::printSpecializationPrefix(NodePointer node, StringRef Description, unsigned depth, @@ -1290,13 +1333,17 @@ void NodePrinter::printSpecializationPrefix(NodePointer node, } return; } + if (node->getFirstChild()->getKind() == Node::Kind::RepresentationChanged) { + Printer << "representation changed of "; + return; + } Printer << Description << " <"; const char *Separator = ""; int argNum = 0; for (NodePointer child : *node) { switch (child->getKind()) { case Node::Kind::SpecializationPassID: - case Node::Kind::MetatypeParamsRemoved: + case Node::Kind::DroppedArgument: // We skip those nodes since it does not contain any // information that is useful to our users. break; @@ -1356,11 +1403,11 @@ static bool shouldShowEntityType(Node::Kind EntityKind, switch (EntityKind) { case Node::Kind::ExplicitClosure: case Node::Kind::ImplicitClosure: - // The signature of a closure (its `Type` node) can optionally be omitted. - // Unlike functions which can have overloads, the signature of a closure is - // not needed to be uniquely identified. A closure is uniquely identified by - // its index and parent. Omitting the signature improves the readability - // when long type names are in use. + /// The signature of a closure (its `Type` node) can optionally be omitted. + /// Unlike functions which can have overloads, the signature of a closure is + /// not needed to be uniquely identified. A closure is uniquely identified + /// by its index and parent. Omitting the signature improves the readability + /// when long type names are in use. return Options.ShowClosureSignature; default: return true; @@ -1388,10 +1435,18 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, Printer << "async demotion of "; print(Node->getChild(0), depth + 1); return nullptr; + case Node::Kind::RepresentationChanged: + Printer << "representation changed of "; + print(Node->getChild(0), depth + 1); + return nullptr; case Node::Kind::CurryThunk: Printer << "curry thunk of "; print(Node->getChild(0), depth + 1); return nullptr; + case Node::Kind::SILThunkIdentity: + Printer << "identity thunk of "; + print(Node->getChild(0), depth + 1); + return nullptr; case Node::Kind::DispatchThunk: Printer << "dispatch thunk of "; print(Node->getChild(0), depth + 1); @@ -1440,6 +1495,7 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, print(Node->getChild(0), depth + 1); return nullptr; case Node::Kind::OutlinedInitializeWithTake: + case Node::Kind::OutlinedInitializeWithTakeNoValueWitness: Printer << "outlined init with take of "; print(Node->getChild(0), depth + 1); return nullptr; @@ -1599,6 +1655,10 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType, /*hasName*/ false, "property wrapper backing initializer"); + case Node::Kind::PropertyWrappedFieldInitAccessor: + return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType, + /*hasName*/ false, + "property wrapped field init accessor"); case Node::Kind::PropertyWrapperInitFromProjectedValue: return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType, /*hasName*/ false, @@ -1767,10 +1827,14 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, Printer << "sending "; print(Node->getChild(0), depth + 1); return nullptr; - case Node::Kind::CompileTimeConst: + case Node::Kind::CompileTimeLiteral: Printer << "_const "; print(Node->getChild(0), depth + 1); return nullptr; + case Node::Kind::ConstValue: + Printer << "@const "; + print(Node->getChild(0), depth + 1); + return nullptr; case Node::Kind::Shared: Printer << "__shared "; print(Node->getChild(0), depth + 1); @@ -1783,33 +1847,6 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, Printer << "@noDerivative "; print(Node->getChild(0), depth + 1); return nullptr; - case Node::Kind::ParamLifetimeDependence: { - Printer << "lifetime dependence: "; - auto kind = (MangledLifetimeDependenceKind)Node->getChild(0)->getIndex(); - switch (kind) { - case MangledLifetimeDependenceKind::Inherit: - Printer << "inherit "; - break; - case MangledLifetimeDependenceKind::Scope: - Printer << "scope "; - break; - } - print(Node->getChild(1), depth + 1); - return nullptr; - } - case Node::Kind::SelfLifetimeDependence: { - Printer << "(self lifetime dependence: "; - auto kind = (MangledLifetimeDependenceKind)Node->getIndex(); - switch (kind) { - case MangledLifetimeDependenceKind::Inherit: - Printer << "inherit) "; - break; - case MangledLifetimeDependenceKind::Scope: - Printer << "scope) "; - break; - } - return nullptr; - } case Node::Kind::NonObjCAttribute: Printer << "@nonobjc "; return nullptr; @@ -1854,8 +1891,8 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, case Node::Kind::IsSerialized: Printer << "serialized"; return nullptr; - case Node::Kind::MetatypeParamsRemoved: - Printer << "metatypes-removed"; + case Node::Kind::DroppedArgument: + Printer << "param" << Node->getIndex() << "-removed"; return nullptr; case Node::Kind::GenericSpecializationParam: print(Node->getChild(0), depth + 1); @@ -1871,11 +1908,15 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, case Node::Kind::FunctionSignatureSpecializationParam: printer_unreachable("should be handled in printSpecializationPrefix"); case Node::Kind::FunctionSignatureSpecializationParamPayload: { - std::string demangledName = demangleSymbolAsString(Node->getText()); - if (demangledName.empty()) { - Printer << Node->getText(); - } else { - Printer << demangledName; + if (Node->hasText()) { + std::string demangledName = demangleSymbolAsString(Node->getText()); + if (demangledName.empty()) { + Printer << Node->getText(); + } else { + Printer << demangledName; + } + } else if (Node->hasIndex()) { + Printer << Node->getIndex(); } return nullptr; } @@ -1947,9 +1988,15 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, case FunctionSigSpecializationParamKind::ConstantPropKeyPath: Printer << "Constant Propagated KeyPath"; return nullptr; + case FunctionSigSpecializationParamKind::ConstantPropStruct: + Printer << "Constant Propagated Struct"; + return nullptr; case FunctionSigSpecializationParamKind::ClosureProp: Printer << "Closure Propagated"; return nullptr; + case FunctionSigSpecializationParamKind::ClosurePropPreviousArg: + Printer << "Same As Argument"; + return nullptr; case FunctionSigSpecializationParamKind::ExistentialToGeneric: case FunctionSigSpecializationParamKind::Dead: case FunctionSigSpecializationParamKind::OwnedToGuaranteed: @@ -1968,6 +2015,13 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, case Node::Kind::BuiltinTupleType: Printer << "Builtin.TheTupleType"; return nullptr; + case Node::Kind::BuiltinFixedArray: + Printer << "Builtin.FixedArray<"; + print(Node->getChild(0), depth + 1); + Printer << ", "; + print(Node->getChild(1), depth + 1); + Printer << ">"; + return nullptr; case Node::Kind::Number: Printer << Node->getIndex(); return nullptr; @@ -2063,10 +2117,16 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, return nullptr; case Node::Kind::KeyPathGetterThunkHelper: case Node::Kind::KeyPathSetterThunkHelper: + case Node::Kind::KeyPathUnappliedMethodThunkHelper: + case Node::Kind::KeyPathAppliedMethodThunkHelper: if (Node->getKind() == Node::Kind::KeyPathGetterThunkHelper) Printer << "key path getter for "; - else + else if (Node->getKind() == Node::Kind::KeyPathSetterThunkHelper) Printer << "key path setter for "; + else if (Node->getKind() == Node::Kind::KeyPathUnappliedMethodThunkHelper) + Printer << "key path unapplied method "; + else if (Node->getKind() == Node::Kind::KeyPathAppliedMethodThunkHelper) + Printer << "key path applied method "; print(Node->getChild(0), depth + 1); Printer << " : "; @@ -2337,14 +2397,28 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, Printer << "merged "; } return nullptr; - case Node::Kind::TypeSymbolicReference: + case Node::Kind::TypeSymbolicReference: { Printer << "type symbolic reference 0x"; - Printer.writeHex(Node->getIndex()); + if (Node->hasRemoteAddress()) { + auto ra = Node->getRemoteAddress(); + Printer.writeHex(ra.first); + Printer << " (" << ra.second << ")"; + } else if (Node->hasIndex()) { + Printer.writeHex(Node->getIndex()); + } return nullptr; - case Node::Kind::OpaqueTypeDescriptorSymbolicReference: + } + case Node::Kind::OpaqueTypeDescriptorSymbolicReference: { Printer << "opaque type symbolic reference 0x"; - Printer.writeHex(Node->getIndex()); + if (Node->hasRemoteAddress()) { + auto ra = Node->getRemoteAddress(); + Printer.writeHex(ra.first); + Printer << " (" << ra.second << ")"; + } else if (Node->hasIndex()) { + Printer.writeHex(Node->getIndex()); + } return nullptr; + } case Node::Kind::DistributedThunk: if (!Options.ShortenThunk) { Printer << "distributed thunk "; @@ -2717,12 +2791,24 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, case Node::Kind::ReadAccessor: return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext, "read"); + case Node::Kind::Read2Accessor: + return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext, + "read2"); case Node::Kind::ModifyAccessor: return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext, "modify"); + case Node::Kind::Modify2Accessor: + return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext, + "modify2"); case Node::Kind::InitAccessor: return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext, "init"); + case Node::Kind::BorrowAccessor: + return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext, + "borrow"); + case Node::Kind::MutateAccessor: + return printAbstractStorage(Node->getFirstChild(), depth, asPrefixContext, + "mutate"); case Node::Kind::Allocator: return printEntity( Node, depth, asPrefixContext, TypePrinting::FunctionStyle, @@ -2740,6 +2826,12 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, /*hasName*/ false, isClassType(Node->getChild(0)) ? "__deallocating_deinit" : "deinit"); + case Node::Kind::IsolatedDeallocator: + return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType, + /*hasName*/ false, + isClassType(Node->getChild(0)) + ? "__isolated_deallocating_deinit" + : "deinit"); case Node::Kind::IVarInitializer: return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType, /*hasName*/ false, "__ivar_initializer"); @@ -2797,6 +2889,13 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, return nullptr; case Node::Kind::ImplErasedIsolation: Printer << "@isolated(any)"; + return nullptr; + case Node::Kind::ImplCoroutineKind: + // Skip if text is empty. + if (Node->getText().empty()) + return nullptr; + // Otherwise, print with leading @. + Printer << '@' << Node->getText(); return nullptr; case Node::Kind::ImplSendingResult: Printer << "sending"; @@ -2812,6 +2911,8 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, Printer << Node->getText() << ' '; return nullptr; case Node::Kind::ImplParameterSending: + case Node::Kind::ImplParameterIsolated: + case Node::Kind::ImplParameterImplicitLeading: // Skip if text is empty. if (Node->getText().empty()) return nullptr; @@ -2891,6 +2992,7 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, } case Node::Kind::DependentGenericParamCount: case Node::Kind::DependentGenericParamPackMarker: + case Node::Kind::DependentGenericParamValueMarker: printer_unreachable("should be printed as a child of a " "DependentGenericSignature"); case Node::Kind::DependentGenericConformanceRequirement: { @@ -3055,6 +3157,9 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, case Node::Kind::IsolatedAnyFunctionType: Printer << "@isolated(any) "; return nullptr; + case Node::Kind::NonIsolatedCallerFunctionType: + Printer << "nonisolated(nonsending) "; + return nullptr; case Node::Kind::SendingResultFunctionType: Printer << "sending "; return nullptr; @@ -3196,6 +3301,12 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, Printer << " to "; print(Node->getChild(1), depth + 1); return nullptr; + case Node::Kind::DependentProtocolConformanceOpaque: + Printer << "opaque result conformance "; + print(Node->getChild(0), depth + 1); + Printer << " of "; + print(Node->getChild(1), depth + 1); + return nullptr; case Node::Kind::ProtocolConformanceRefInTypeModule: Printer << "protocol conformance ref (type's module) "; printChildren(Node, depth); @@ -3217,6 +3328,14 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, print(Node->getChild(0), depth + 1); Printer << "]"; return nullptr; + case Node::Kind::SugaredInlineArray: { + Printer << "["; + print(Node->getChild(0), depth + 1); + Printer << " of "; + print(Node->getChild(1), depth + 1); + Printer << "]"; + return nullptr; + } case Node::Kind::SugaredDictionary: Printer << "["; print(Node->getChild(0), depth + 1); @@ -3287,8 +3406,8 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, Printer << ')'; } return nullptr; - case Node::Kind::PredefinedObjCAsyncCompletionHandlerImpl: - Printer << "predefined "; + case Node::Kind::CheckedObjCAsyncCompletionHandlerImpl: + Printer << "checked "; LLVM_FALLTHROUGH; case Node::Kind::ObjCAsyncCompletionHandlerImpl: Printer << "@objc completion handler block implementation for "; @@ -3401,6 +3520,21 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, case Node::Kind::OpaqueReturnTypeIndex: case Node::Kind::OpaqueReturnTypeParent: return nullptr; + case Node::Kind::Integer: + Printer << Node->getIndex(); + return nullptr; + case Node::Kind::NegativeInteger: { + intptr_t signedValue = Node->getIndex(); + + Printer << signedValue; + return nullptr; + } + case Node::Kind::CoroFunctionPointer: + Printer << "coro function pointer to "; + return nullptr; + case Node::Kind::DefaultOverride: + Printer << "default override of "; + return nullptr; } printer_unreachable("bad node kind!"); @@ -3465,35 +3599,9 @@ NodePointer NodePrinter::printEntity(NodePointer Entity, unsigned depth, } } - if (hasName || !OverwriteName.empty()) { - if (!ExtraName.empty() && MultiWordName) { - Printer << ExtraName; - if (ExtraIndex >= 0) - Printer << ExtraIndex; - - Printer << " of "; - ExtraName = ""; - ExtraIndex = -1; - } - size_t CurrentPos = Printer.getStringRef().size(); - if (!OverwriteName.empty()) { - Printer << OverwriteName; - } else { - auto Name = Entity->getChild(1); - if (Name->getKind() != Node::Kind::PrivateDeclName) - print(Name, depth + 1); + printFunctionName(hasName, OverwriteName, ExtraName, MultiWordName, + ExtraIndex, Entity, depth); - if (auto PrivateName = getChildIf(Entity, Node::Kind::PrivateDeclName)) - print(PrivateName, depth + 1); - } - if (Printer.getStringRef().size() != CurrentPos && !ExtraName.empty()) - Printer << '.'; - } - if (!ExtraName.empty()) { - Printer << ExtraName; - if (ExtraIndex >= 0) - Printer << ExtraIndex; - } if (TypePr != TypePrinting::NoType) { NodePointer type = getChildIf(Entity, Node::Kind::Type); assert(type && "malformed entity"); @@ -3534,7 +3642,9 @@ NodePointer NodePrinter::printEntity(NodePointer Entity, unsigned depth, if (Entity->getKind() == Node::Kind::DefaultArgumentInitializer || Entity->getKind() == Node::Kind::Initializer || Entity->getKind() == Node::Kind::PropertyWrapperBackingInitializer || - Entity->getKind() == Node::Kind::PropertyWrapperInitFromProjectedValue) { + Entity->getKind() == Node::Kind::PropertyWrappedFieldInitAccessor || + Entity->getKind() == + Node::Kind::PropertyWrapperInitFromProjectedValue) { Printer << " of "; } else { Printer << " in "; @@ -3545,6 +3655,43 @@ NodePointer NodePrinter::printEntity(NodePointer Entity, unsigned depth, return PostfixContext; } +void NodePrinter::printFunctionName(bool hasName, + llvm::StringRef &OverwriteName, + llvm::StringRef &ExtraName, + bool MultiWordName, int &ExtraIndex, + swift::Demangle::NodePointer Entity, + unsigned int depth) { + if (hasName || !OverwriteName.empty()) { + if (!ExtraName.empty() && MultiWordName) { + Printer << ExtraName; + if (ExtraIndex >= 0) + Printer << ExtraIndex; + + Printer << " of "; + ExtraName = ""; + ExtraIndex = -1; + } + size_t CurrentPos = Printer.getStringRef().size(); + if (!OverwriteName.empty()) { + Printer << OverwriteName; + } else { + auto Name = Entity->getChild(1); + if (Name->getKind() != Node::Kind::PrivateDeclName) + print(Name, depth + 1); + + if (auto PrivateName = getChildIf(Entity, Node::Kind::PrivateDeclName)) + print(PrivateName, depth + 1); + } + if (Printer.getStringRef().size() != CurrentPos && !ExtraName.empty()) + Printer << '.'; + } + if (!ExtraName.empty()) { + Printer << ExtraName; + if (ExtraIndex >= 0) + Printer << ExtraIndex; + } +} + void NodePrinter::printEntityType(NodePointer Entity, NodePointer type, NodePointer genericFunctionTypeList, unsigned depth) { @@ -3723,12 +3870,32 @@ std::string Demangle::keyPathSourceString(const char *MangledName, return invalid; } +/// Converts a demangled node to a string. +/// +/// \param root The root of the AST to demangle. +/// \param options The `DemangleOptions` which will be used to create the +/// NodePrinter. +/// +/// \return The demangled node as a string. std::string Demangle::nodeToString(NodePointer root, const DemangleOptions &options) { if (!root) return ""; - return NodePrinter(options).printRoot(root); + NodePrinter printer = NodePrinter(options); + nodeToString(root, printer); + return printer.takeString(); +} + +/// Converts a demangled node to a string, which is stored in the `printer`. +/// +/// \param root The root of the AST to demangle. +/// \param printer The `NodePrinter` which will be used to print the AST to a +/// string. +void Demangle::nodeToString(NodePointer root, NodePrinter &printer) { + if (!root) + return; + printer.printRoot(root); } #endif diff --git a/symbolic-demangle/vendor/swift/lib/Demangling/Remangler.cpp b/symbolic-demangle/vendor/swift/lib/Demangling/Remangler.cpp index be1bca1d7..c9e81a74c 100644 --- a/symbolic-demangle/vendor/swift/lib/Demangling/Remangler.cpp +++ b/symbolic-demangle/vendor/swift/lib/Demangling/Remangler.cpp @@ -210,6 +210,7 @@ class Remangler : public RemanglerBase { friend void Mangle::mangleIdentifier(Mangler &M, StringRef ident); friend class Mangle::SubstitutionMerging; + const ManglingFlavor Flavor = ManglingFlavor::Default; const bool UsePunycode = true; Vector Words; @@ -359,7 +360,7 @@ class Remangler : public RemanglerBase { } ManglingError mangleGenericSpecializationNode(Node *node, - const char *operatorStr, + char specKind, unsigned depth); ManglingError mangleAnyNominalType(Node *node, unsigned depth); ManglingError mangleAnyGenericType(Node *node, StringRef TypeOp, @@ -374,6 +375,9 @@ class Remangler : public RemanglerBase { ManglingError mangleKeyPathThunkHelper(Node *node, StringRef op, unsigned depth); + ManglingError mangleSILThunkIdentity(Node *node, StringRef op, + unsigned depth); + ManglingError mangleAutoDiffFunctionOrSimpleThunk(Node *node, StringRef op, unsigned depth); @@ -384,8 +388,9 @@ class Remangler : public RemanglerBase { #include "swift/Demangling/DemangleNodes.def" public: - Remangler(SymbolicResolver Resolver, NodeFactory &Factory) - : RemanglerBase(Factory), Resolver(Resolver) { } + Remangler(SymbolicResolver Resolver, NodeFactory &Factory, + ManglingFlavor Flavor) + : RemanglerBase(Factory), Flavor(Flavor), Resolver(Resolver) {} ManglingError mangle(Node *node, unsigned depth) { if (depth > Remangler::MaxDepth) { @@ -627,6 +632,7 @@ ManglingError Remangler::mangleGenericArgs(Node *node, char &Separator, case Node::Kind::DefaultArgumentInitializer: case Node::Kind::Initializer: case Node::Kind::PropertyWrapperBackingInitializer: + case Node::Kind::PropertyWrappedFieldInitAccessor: case Node::Kind::PropertyWrapperInitFromProjectedValue: case Node::Kind::Static: if (!fullSubstitutionMap) @@ -720,7 +726,7 @@ ManglingError Remangler::mangleAllocator(Node *node, unsigned depth) { } ManglingError Remangler::mangleArgumentTuple(Node *node, unsigned depth) { - Node *Child = skipType(getSingleChild(node)); + Node *Child = skipType(node->getChild(0)); if (Child->getKind() == Node::Kind::Tuple && Child->getNumChildren() == 0) { Buffer << 'y'; @@ -894,11 +900,19 @@ ManglingError Remangler::mangleBoundGenericFunction(Node *node, return ManglingError::Success; } +ManglingError Remangler::mangleBuiltinFixedArray(Node *node, unsigned depth) { + RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); + Buffer << "BV"; + return ManglingError::Success; +} + ManglingError Remangler::mangleBuiltinTypeName(Node *node, unsigned depth) { Buffer << 'B'; StringRef text = node->getText(); - if (text == BUILTIN_TYPE_NAME_BRIDGEOBJECT) { + if (text == BUILTIN_TYPE_NAME_IMPLICITACTOR) { + Buffer << 'A'; + } else if (text == BUILTIN_TYPE_NAME_BRIDGEOBJECT) { Buffer << 'b'; } else if (text == BUILTIN_TYPE_NAME_UNSAFEVALUEBUFFER) { Buffer << 'B'; @@ -994,11 +1008,14 @@ ManglingError Remangler::mangleCoroutineContinuationPrototype(Node *node, } ManglingError -Remangler::manglePredefinedObjCAsyncCompletionHandlerImpl(Node *node, - unsigned depth) { - RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); +Remangler::mangleCheckedObjCAsyncCompletionHandlerImpl(Node *node, + unsigned depth) { + RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1)); + RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); + if (node->getNumChildren() == 4) + RETURN_IF_ERROR(mangleChildNode(node, 3, depth + 1)); Buffer << "TZ"; - return ManglingError::Success; + return mangleChildNode(node, 2, depth + 1); } ManglingError Remangler::mangleObjCAsyncCompletionHandlerImpl(Node *node, @@ -1017,6 +1034,12 @@ ManglingError Remangler::mangleDeallocator(Node *node, unsigned depth) { return ManglingError::Success; } +ManglingError Remangler::mangleIsolatedDeallocator(Node *node, unsigned depth) { + RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); + Buffer << "fZ"; + return ManglingError::Success; +} + ManglingError Remangler::mangleDeclContext(Node *node, unsigned depth) { return mangleSingleChildNode(node, depth + 1); } @@ -1034,6 +1057,16 @@ ManglingError Remangler::mangleAsyncFunctionPointer(Node *node, return ManglingError::Success; } +ManglingError Remangler::mangleCoroFunctionPointer(Node *node, unsigned depth) { + Buffer << "Twc"; + return ManglingError::Success; +} + +ManglingError Remangler::mangleDefaultOverride(Node *node, unsigned depth) { + Buffer << "Twd"; + return ManglingError::Success; +} + ManglingError Remangler::mangleDependentAssociatedTypeRef(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleIdentifier(node->getFirstChild(), depth)); @@ -1473,40 +1506,24 @@ ManglingError Remangler::mangleFunction(Node *node, unsigned depth) { ManglingError Remangler::mangleFunctionSignatureSpecialization(Node *node, unsigned depth) { for (NodePointer Param : *node) { - if (Param->getKind() == Node::Kind::FunctionSignatureSpecializationParam && - Param->getNumChildren() > 0) { - Node *KindNd = Param->getChild(0); - switch (FunctionSigSpecializationParamKind(KindNd->getIndex())) { - case FunctionSigSpecializationParamKind::ConstantPropFunction: - case FunctionSigSpecializationParamKind::ConstantPropGlobal: - RETURN_IF_ERROR(mangleIdentifier(Param->getChild(1), depth + 1)); - break; - case FunctionSigSpecializationParamKind::ConstantPropString: { - NodePointer TextNd = Param->getChild(2); - StringRef Text = TextNd->getText(); - if (!Text.empty() && (isDigit(Text[0]) || Text[0] == '_')) { - std::string Buffer = "_"; - Buffer.append(Text.data(), Text.size()); - TextNd = Factory.createNode(Node::Kind::Identifier, Buffer); - } - RETURN_IF_ERROR(mangleIdentifier(TextNd, depth + 1)); - break; - } - case FunctionSigSpecializationParamKind::ClosureProp: - case FunctionSigSpecializationParamKind::ConstantPropKeyPath: - RETURN_IF_ERROR(mangleIdentifier(Param->getChild(1), depth + 1)); - for (unsigned i = 2, e = Param->getNumChildren(); i != e; ++i) { - RETURN_IF_ERROR(mangleType(Param->getChild(i), depth + 1)); - } - break; - default: - break; + if (Param->getKind() != Node::Kind::FunctionSignatureSpecializationParam) + continue; + + for (NodePointer paramChild : *Param) { + if (paramChild->getKind() == Node::Kind::FunctionSignatureSpecializationParamKind || + paramChild->getKind() == Node::Kind::FunctionSignatureSpecializationParamPayload) { + continue; } + RETURN_IF_ERROR(mangle(paramChild, depth + 1)); } } + Buffer << "Tf"; bool returnValMangled = false; for (NodePointer Child : *node) { + if (Child->getKind() == Node::Kind::RepresentationChanged) { + returnValMangled = true; + } if (Child->getKind() == Node::Kind::FunctionSignatureSpecializationReturn) { Buffer << '_'; returnValMangled = true; @@ -1540,26 +1557,37 @@ Remangler::mangleFunctionSignatureSpecializationParam(Node *node, // The first child is always a kind that specifies the type of param that we // have. - Node *KindNd = node->getChild(0); - unsigned kindValue = KindNd->getIndex(); - auto kind = FunctionSigSpecializationParamKind(kindValue); + const char *constPropPrefix = "p"; + + size_t idx = 0, end = node->getNumChildren(); + while (idx < end) { + Node *kindNd = node->getChild(idx++); + if (kindNd->getKind() != Node::Kind::FunctionSignatureSpecializationParamKind) + continue; + + unsigned kindValue = kindNd->getIndex(); - switch (kind) { + switch (FunctionSigSpecializationParamKind(kindValue)) { case FunctionSigSpecializationParamKind::ConstantPropFunction: - Buffer << "pf"; + Buffer << constPropPrefix << "f"; + constPropPrefix = ""; break; case FunctionSigSpecializationParamKind::ConstantPropGlobal: - Buffer << "pg"; + Buffer << constPropPrefix << "g"; + constPropPrefix = ""; break; case FunctionSigSpecializationParamKind::ConstantPropInteger: - Buffer << "pi" << node->getChild(1)->getText(); + Buffer << constPropPrefix << "i" << node->getChild(idx++)->getText(); + constPropPrefix = ""; break; case FunctionSigSpecializationParamKind::ConstantPropFloat: - Buffer << "pd" << node->getChild(1)->getText(); + Buffer << constPropPrefix << "d" << node->getChild(idx++)->getText(); + constPropPrefix = ""; break; case FunctionSigSpecializationParamKind::ConstantPropString: { - Buffer << "ps"; - StringRef encodingStr = node->getChild(1)->getText(); + Buffer << constPropPrefix << "s"; + constPropPrefix = ""; + StringRef encodingStr = node->getChild(idx++)->getText(); if (encodingStr == "u8") { Buffer << 'b'; } else if (encodingStr == "u16") { @@ -1572,11 +1600,19 @@ Remangler::mangleFunctionSignatureSpecializationParam(Node *node, break; } case FunctionSigSpecializationParamKind::ConstantPropKeyPath: - Buffer << "pk"; + Buffer << constPropPrefix << "k"; + constPropPrefix = ""; + break; + case FunctionSigSpecializationParamKind::ConstantPropStruct: + Buffer << constPropPrefix << "S"; + constPropPrefix = ""; break; case FunctionSigSpecializationParamKind::ClosureProp: Buffer << 'c'; break; + case FunctionSigSpecializationParamKind::ClosurePropPreviousArg: + Buffer << 'C' << node->getChild(idx++)->getIndex(); + break; case FunctionSigSpecializationParamKind::BoxToValue: Buffer << 'i'; break; @@ -1622,6 +1658,7 @@ Remangler::mangleFunctionSignatureSpecializationParam(Node *node, if (kindValue & unsigned(FunctionSigSpecializationParamKind::SROA)) Buffer << 'X'; break; + } } return ManglingError::Success; @@ -1693,7 +1730,7 @@ Remangler::mangleGenericPartialSpecializationNotReAbstracted(Node *node, } ManglingError -Remangler::mangleGenericSpecializationNode(Node *node, const char *operatorStr, +Remangler::mangleGenericSpecializationNode(Node *node, char specKind, unsigned depth) { bool FirstParam = true; for (NodePointer Child : *node) { @@ -1705,11 +1742,21 @@ Remangler::mangleGenericSpecializationNode(Node *node, const char *operatorStr, DEMANGLER_ASSERT( !FirstParam && "generic specialization with no substitutions", node); - Buffer << operatorStr; + Buffer << 'T'; for (NodePointer Child : *node) { - if (Child->getKind() != Node::Kind::GenericSpecializationParam) + if (Child->getKind() == Node::Kind::DroppedArgument) + RETURN_IF_ERROR(mangle(Child, depth + 1)); + } + + + Buffer << specKind; + + for (NodePointer Child : *node) { + if (Child->getKind() != Node::Kind::GenericSpecializationParam && + Child->getKind() != Node::Kind::DroppedArgument) { RETURN_IF_ERROR(mangle(Child, depth + 1)); + } } return ManglingError::Success; @@ -1717,30 +1764,30 @@ Remangler::mangleGenericSpecializationNode(Node *node, const char *operatorStr, ManglingError Remangler::mangleGenericSpecialization(Node *node, unsigned depth) { - return mangleGenericSpecializationNode(node, "Tg", depth + 1); + return mangleGenericSpecializationNode(node, 'g', depth + 1); } ManglingError Remangler::mangleGenericSpecializationPrespecialized(Node *node, unsigned depth) { - return mangleGenericSpecializationNode(node, "Ts", depth + 1); + return mangleGenericSpecializationNode(node, 's', depth + 1); } ManglingError Remangler::mangleGenericSpecializationNotReAbstracted(Node *node, unsigned depth) { - return mangleGenericSpecializationNode(node, "TG", depth + 1); + return mangleGenericSpecializationNode(node, 'G', depth + 1); } ManglingError Remangler::mangleGenericSpecializationInResilienceDomain(Node *node, unsigned depth) { - return mangleGenericSpecializationNode(node, "TB", depth + 1); + return mangleGenericSpecializationNode(node, 'B', depth + 1); } ManglingError Remangler::mangleInlinedGenericFunction(Node *node, unsigned depth) { - return mangleGenericSpecializationNode(node, "Ti", depth + 1); + return mangleGenericSpecializationNode(node, 'i', depth + 1); } ManglingError Remangler::mangleGenericSpecializationParam(Node *node, @@ -1768,7 +1815,14 @@ ManglingError Remangler::mangleGetter(Node *node, unsigned depth) { } ManglingError Remangler::mangleGlobal(Node *node, unsigned depth) { - Buffer << MANGLING_PREFIX_STR; + switch (Flavor) { + case ManglingFlavor::Default: + Buffer << MANGLING_PREFIX_STR; + break; + case ManglingFlavor::Embedded: + Buffer << MANGLING_PREFIX_EMBEDDED_STR; + break; + } bool mangleInReverseOrder = false; for (auto Iter = node->begin(), End = node->end(); Iter != End; ++Iter) { Node *Child = *Iter; @@ -1802,6 +1856,8 @@ ManglingError Remangler::mangleGlobal(Node *node, unsigned depth) { case Node::Kind::BackDeploymentThunk: case Node::Kind::BackDeploymentFallback: case Node::Kind::HasSymbolQuery: + case Node::Kind::CoroFunctionPointer: + case Node::Kind::DefaultOverride: mangleInReverseOrder = true; break; default: @@ -1907,7 +1963,31 @@ ManglingError Remangler::mangleImplParameterSending(Node *node, char diffChar = llvm::StringSwitch(node->getText()).Case("sending", 'T').Default(0); if (!diffChar) - return MANGLING_ERROR(ManglingError::InvalidImplParameterSending, node); + return MANGLING_ERROR(ManglingError::InvalidImplParameterAttr, node); + Buffer << diffChar; + + return ManglingError::Success; +} + +ManglingError Remangler::mangleImplParameterIsolated(Node *node, + unsigned depth) { + DEMANGLER_ASSERT(node->hasText(), node); + char diffChar = + llvm::StringSwitch(node->getText()).Case("isolated", 'I').Default(0); + if (!diffChar) + return MANGLING_ERROR(ManglingError::InvalidImplParameterAttr, node); + Buffer << diffChar; + + return ManglingError::Success; +} + +ManglingError Remangler::mangleImplParameterImplicitLeading(Node *node, + unsigned depth) { + DEMANGLER_ASSERT(node->hasText(), node); + char diffChar = + llvm::StringSwitch(node->getText()).Case("sil_implicit_leading_param", 'L').Default(0); + if (!diffChar) + return MANGLING_ERROR(ManglingError::InvalidImplParameterAttr, node); Buffer << diffChar; return ManglingError::Success; @@ -1966,22 +2046,25 @@ ManglingError Remangler::mangleImplPatternSubstitutions(Node *node, return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } +ManglingError Remangler::mangleImplCoroutineKind(Node *node, + unsigned depth) { + // handled inline + return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); +} + ManglingError Remangler::mangleImplFunctionType(Node *node, unsigned depth) { const char *PseudoGeneric = ""; Node *GenSig = nullptr; Node *PatternSubs = nullptr; Node *InvocationSubs = nullptr; for (NodePointer Child : *node) { - switch (auto kind = Child->getKind()) { + switch (Child->getKind()) { case Node::Kind::ImplParameter: case Node::Kind::ImplResult: case Node::Kind::ImplYield: case Node::Kind::ImplErrorResult: // Mangle type. Type should be the last child. - DEMANGLER_ASSERT(Child->getNumChildren() == 2 || - Child->getNumChildren() == 3 || - Child->getNumChildren() == 4, - node); + DEMANGLER_ASSERT(Child->getNumChildren() >= 2, Child); RETURN_IF_ERROR(mangle(Child->getLastChild(), depth + 1)); break; case Node::Kind::DependentPseudogenericSignature: @@ -2064,13 +2147,25 @@ ManglingError Remangler::mangleImplFunctionType(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleImplFunctionConvention(Child, depth + 1)); break; } + case Node::Kind::ImplCoroutineKind: { + char CoroAttr = llvm::StringSwitch(Child->getText()) + .Case("yield_once", 'A') + .Case("yield_once_2", 'I') + .Case("yield_many", 'G') + .Default(0); + + if (!CoroAttr) { + return MANGLING_ERROR(ManglingError::InvalidImplCoroutineKind, + Child); + } + Buffer << CoroAttr; + break; + } case Node::Kind::ImplFunctionAttribute: { char FuncAttr = llvm::StringSwitch(Child->getText()) - .Case("@yield_once", 'A') - .Case("@yield_many", 'G') - .Case("@Sendable", 'h') - .Case("@async", 'H') - .Default(0); + .Case("@Sendable", 'h') + .Case("@async", 'H') + .Default(0); if (!FuncAttr) { return MANGLING_ERROR(ManglingError::InvalidImplFunctionAttribute, Child); @@ -2089,6 +2184,7 @@ ManglingError Remangler::mangleImplFunctionType(Node *node, unsigned depth) { .Case("@inout", 'l') .Case("@inout_aliasable", 'b') .Case("@in_guaranteed", 'n') + .Case("@in_cxx", 'X') .Case("@in_constant", 'c') .Case("@owned", 'x') .Case("@guaranteed", 'g') @@ -2103,15 +2199,32 @@ ManglingError Remangler::mangleImplFunctionType(Node *node, unsigned depth) { Child->getFirstChild()); } Buffer << ConvCh; - // Mangle parameter differentiability, if it exists. - if (Child->getNumChildren() == 3) { - RETURN_IF_ERROR(mangleImplParameterResultDifferentiability( - Child->getChild(1), depth + 1)); - } else if (Child->getNumChildren() == 4) { - RETURN_IF_ERROR(mangleImplParameterResultDifferentiability( - Child->getChild(1), depth + 1)); - RETURN_IF_ERROR( - mangleImplParameterSending(Child->getChild(2), depth + 1)); + + for (unsigned i = 1; i < Child->getNumChildren() - 1; ++i) { + auto *Grandchild = Child->getChild(i); + switch (Grandchild->getKind()) { + case Node::Kind::ImplParameterResultDifferentiability: + RETURN_IF_ERROR(mangleImplParameterResultDifferentiability( + Grandchild, depth + 1)); + break; + case Node::Kind::ImplParameterSending: + RETURN_IF_ERROR(mangleImplParameterSending( + Grandchild, depth + 1)); + break; + case Node::Kind::ImplParameterIsolated: + RETURN_IF_ERROR(mangleImplParameterIsolated( + Grandchild, depth + 1)); + break; + case Node::Kind::ImplParameterImplicitLeading: + RETURN_IF_ERROR(mangleImplParameterImplicitLeading( + Grandchild, depth + 1)); + break; + default: + Child->dump(); + abort(); + return MANGLING_ERROR(ManglingError::InvalidImplParameterAttr, + Grandchild); + } } break; } @@ -2119,14 +2232,18 @@ ManglingError Remangler::mangleImplFunctionType(Node *node, unsigned depth) { Buffer << 'z'; LLVM_FALLTHROUGH; case Node::Kind::ImplResult: { - char ConvCh = llvm::StringSwitch(Child->getFirstChild()->getText()) - .Case("@out", 'r') - .Case("@owned", 'o') - .Case("@unowned", 'd') - .Case("@unowned_inner_pointer", 'u') - .Case("@autoreleased", 'a') - .Case("@pack_out", 'k') - .Default(0); + char ConvCh = + llvm::StringSwitch(Child->getFirstChild()->getText()) + .Case("@out", 'r') + .Case("@owned", 'o') + .Case("@unowned", 'd') + .Case("@unowned_inner_pointer", 'u') + .Case("@autoreleased", 'a') + .Case("@pack_out", 'k') + .Case("@guaranteed_address", 'l') + .Case("@guaranteed", 'g') + .Case("@inout", 'm') + .Default(0); if (!ConvCh) { return MANGLING_ERROR(ManglingError::InvalidImplParameterConvention, Child->getFirstChild()); @@ -2198,12 +2315,18 @@ ManglingError Remangler::mangleSending(Node *node, unsigned depth) { return ManglingError::Success; } -ManglingError Remangler::mangleCompileTimeConst(Node *node, unsigned depth) { +ManglingError Remangler::mangleCompileTimeLiteral(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Yt"; return ManglingError::Success; } +ManglingError Remangler::mangleConstValue(Node *node, unsigned depth) { + RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); + Buffer << "Yg"; + return ManglingError::Success; +} + ManglingError Remangler::mangleShared(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << 'h'; @@ -2222,19 +2345,6 @@ ManglingError Remangler::mangleNoDerivative(Node *node, unsigned depth) { return ManglingError::Success; } -ManglingError Remangler::mangleParamLifetimeDependence(Node *node, - unsigned depth) { - RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); - Buffer << "Yl" << (char)node->getFirstChild()->getIndex(); - return ManglingError::Success; -} - -ManglingError Remangler::mangleSelfLifetimeDependence(Node *node, - unsigned depth) { - Buffer << "YL" << (char)node->getIndex(); - return ManglingError::Success; -} - ManglingError Remangler::mangleInfixOperator(Node *node, unsigned depth) { mangleIdentifierImpl(node, /*isOperator*/ true); Buffer << "oi"; @@ -2258,6 +2368,13 @@ Remangler::manglePropertyWrapperBackingInitializer(Node *node, unsigned depth) { return ManglingError::Success; } +ManglingError +Remangler::manglePropertyWrappedFieldInitAccessor(Node *node, unsigned depth) { + RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); + Buffer << "fF"; + return ManglingError::Success; +} + ManglingError Remangler::manglePropertyWrapperInitFromProjectedValue(Node *node, unsigned depth) { @@ -2328,6 +2445,10 @@ ManglingError Remangler::mangleModifyAccessor(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "M", depth + 1); } +ManglingError Remangler::mangleModify2Accessor(Node *node, unsigned depth) { + return mangleAbstractStorage(node->getFirstChild(), "x", depth + 1); +} + ManglingError Remangler::mangleModule(Node *node, unsigned depth) { auto text = node->getText(); if (text == STDLIB_NAME) { @@ -2715,6 +2836,16 @@ ManglingError Remangler::mangleDependentConformanceIndex(Node *node, return ManglingError::Success; } +ManglingError Remangler::mangleDependentProtocolConformanceOpaque(Node *node, + unsigned depth) { + DEMANGLER_ASSERT(node->getKind() == Node::Kind::DependentProtocolConformanceOpaque, + node); + RETURN_IF_ERROR(mangleAnyProtocolConformance(node->getChild(0), depth + 1)); + RETURN_IF_ERROR(mangleType(node->getChild(1), depth + 1)); + Buffer << "HO"; + return ManglingError::Success; +} + ManglingError Remangler::mangleAnyProtocolConformance(Node *node, unsigned depth) { switch (node->getKind()) { @@ -2728,6 +2859,8 @@ ManglingError Remangler::mangleAnyProtocolConformance(Node *node, return mangleDependentProtocolConformanceInherited(node, depth + 1); case Node::Kind::DependentProtocolConformanceAssociated: return mangleDependentProtocolConformanceAssociated(node, depth + 1); + case Node::Kind::DependentProtocolConformanceOpaque: + return mangleDependentProtocolConformanceOpaque(node, depth + 1); default: // Should this really succeed?! return ManglingError::Success; @@ -2980,6 +3113,10 @@ ManglingError Remangler::mangleReadAccessor(Node *node, unsigned depth) { return mangleAbstractStorage(node->getFirstChild(), "r", depth + 1); } +ManglingError Remangler::mangleRead2Accessor(Node *node, unsigned depth) { + return mangleAbstractStorage(node->getFirstChild(), "y", depth + 1); +} + ManglingError Remangler::mangleKeyPathThunkHelper(Node *node, StringRef op, unsigned depth) { for (NodePointer Child : *node) @@ -3002,6 +3139,16 @@ ManglingError Remangler::mangleKeyPathSetterThunkHelper(Node *node, return mangleKeyPathThunkHelper(node, "Tk", depth + 1); } +ManglingError +Remangler::mangleKeyPathUnappliedMethodThunkHelper(Node *node, unsigned depth) { + return mangleKeyPathThunkHelper(node, "Tkmu", depth + 1); +} + +ManglingError Remangler::mangleKeyPathAppliedMethodThunkHelper(Node *node, + unsigned depth) { + return mangleKeyPathThunkHelper(node, "TkMA", depth + 1); +} + ManglingError Remangler::mangleKeyPathEqualsThunkHelper(Node *node, unsigned depth) { return mangleKeyPathThunkHelper(node, "TH", depth + 1); @@ -3052,8 +3199,16 @@ ManglingError Remangler::mangleAsyncRemoved(Node *node, unsigned depth) { return ManglingError::Success; } -ManglingError Remangler::mangleMetatypeParamsRemoved(Node *node, unsigned depth) { - Buffer << 'm'; +ManglingError Remangler::mangleRepresentationChanged(Node *node, unsigned depth) { + Buffer << 'r'; + return ManglingError::Success; +} + +ManglingError Remangler::mangleDroppedArgument(Node *node, unsigned depth) { + Buffer << "t"; + int n = node->getIndex(); + if (n > 0) + Buffer << (n-1); return ManglingError::Success; } @@ -3338,6 +3493,14 @@ ManglingError Remangler::mangleCurryThunk(Node *node, unsigned depth) { return ManglingError::Success; } +ManglingError Remangler::mangleSILThunkIdentity(Node *node, unsigned depth) { + RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); // type + // TT is for a thunk that is for a thunk inst... I is for identity. + Buffer << "TT" + << "I"; + return ManglingError::Success; +} + ManglingError Remangler::mangleDispatchThunk(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleSingleChildNode(node, depth + 1)); Buffer << "Tj"; @@ -3408,6 +3571,12 @@ ManglingError Remangler::mangleIsolatedAnyFunctionType(Node *node, return ManglingError::Success; } +ManglingError Remangler::mangleNonIsolatedCallerFunctionType(Node *node, + unsigned depth) { + Buffer << "YC"; + return ManglingError::Success; +} + ManglingError Remangler::mangleSendingResultFunctionType(Node *node, unsigned depth) { Buffer << "YT"; @@ -3471,6 +3640,14 @@ ManglingError Remangler::mangleOutlinedInitializeWithTake(Node *node, return ManglingError::Success; } +ManglingError +Remangler::mangleOutlinedInitializeWithTakeNoValueWitness(Node *node, + unsigned depth) { + RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); + Buffer << "WOB"; + return ManglingError::Success; +} + ManglingError Remangler::mangleOutlinedInitializeWithCopy(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleChildNodes(node, depth + 1)); @@ -3727,6 +3904,14 @@ ManglingError Remangler::mangleSugaredArray(Node *node, unsigned depth) { return ManglingError::Success; } +ManglingError +Remangler::mangleSugaredInlineArray(Node *node, unsigned int depth) { + RETURN_IF_ERROR(mangleType(node->getChild(0), depth + 1)); + RETURN_IF_ERROR(mangleType(node->getChild(1), depth + 1)); + Buffer << "XSA"; + return ManglingError::Success; +} + ManglingError Remangler::mangleSugaredDictionary(Node *node, unsigned depth) { RETURN_IF_ERROR(mangleType(node->getChild(0), depth + 1)); RETURN_IF_ERROR(mangleType(node->getChild(1), depth + 1)); @@ -3936,23 +4121,59 @@ mangleNonUniqueExtendedExistentialTypeShapeSymbolicReference(Node *node, // We don't support absolute references in the mangling of these return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } + +ManglingError Remangler::mangleInteger(Node *node, unsigned int depth) { + Buffer << "$"; + mangleIndex(node->getIndex()); + + return ManglingError::Success; +} + +ManglingError Remangler::mangleNegativeInteger(Node *node, unsigned int depth) { + Buffer << "$n"; + mangleIndex(-node->getIndex()); + + return ManglingError::Success; +} + +ManglingError Remangler::mangleDependentGenericParamValueMarker(Node *node, + unsigned depth) { + DEMANGLER_ASSERT(node->getNumChildren() == 2, node); + DEMANGLER_ASSERT(node->getChild(0)->getChild(0)->getKind() == Node::Kind::DependentGenericParamType, node); + DEMANGLER_ASSERT(node->getChild(1)->getKind() == Node::Kind::Type, node); + RETURN_IF_ERROR(mangleType(node->getChild(1), depth + 1)); + Buffer << "RV"; + mangleDependentGenericParamIndex(node->getChild(0)->getChild(0)); + return ManglingError::Success; +} + +ManglingError Remangler::mangleBorrowAccessor(Node *node, unsigned depth) { + return mangleAbstractStorage(node->getFirstChild(), "b", depth + 1); +} + +ManglingError Remangler::mangleMutateAccessor(Node *node, unsigned depth) { + return mangleAbstractStorage(node->getFirstChild(), "z", depth + 1); +} + } // anonymous namespace /// The top-level interface to the remangler. -ManglingErrorOr Demangle::mangleNode(NodePointer node) { +ManglingErrorOr Demangle::mangleNode(NodePointer node, + ManglingFlavor Flavor) { return mangleNode(node, [](SymbolicReferenceKind, const void *) -> NodePointer { return nullptr; - }); + }, Flavor); // unreachable("should not try to mangle a symbolic reference; " // "resolve it to a non-symbolic demangling tree instead"); } -ManglingErrorOr -Demangle::mangleNode(NodePointer node, SymbolicResolver resolver) { +ManglingErrorOr Demangle::mangleNode(NodePointer node, + SymbolicResolver resolver, + ManglingFlavor Flavor) { if (!node) return std::string(); NodeFactory Factory; - Remangler remangler(resolver, Factory); + Remangler remangler(resolver, Factory, Flavor); ManglingError err = remangler.mangle(node, 0); if (!err.isSuccess()) return err; @@ -3960,13 +4181,14 @@ Demangle::mangleNode(NodePointer node, SymbolicResolver resolver) { return remangler.str(); } -ManglingErrorOr -Demangle::mangleNode(NodePointer node, SymbolicResolver resolver, - NodeFactory &Factory) { +ManglingErrorOr Demangle::mangleNode(NodePointer node, + SymbolicResolver resolver, + NodeFactory &Factory, + ManglingFlavor Flavor) { if (!node) return StringRef(); - Remangler remangler(resolver, Factory); + Remangler remangler(resolver, Factory, Flavor); ManglingError err = remangler.mangle(node, 0); if (!err.isSuccess()) return err; @@ -4009,6 +4231,7 @@ bool Demangle::isSpecialized(Node *node) { case Node::Kind::ImplicitClosure: case Node::Kind::Initializer: case Node::Kind::PropertyWrapperBackingInitializer: + case Node::Kind::PropertyWrappedFieldInitAccessor: case Node::Kind::PropertyWrapperInitFromProjectedValue: case Node::Kind::DefaultArgumentInitializer: case Node::Kind::Getter: @@ -4054,6 +4277,7 @@ ManglingErrorOr Demangle::getUnspecialized(Node *node, case Node::Kind::ImplicitClosure: case Node::Kind::Initializer: case Node::Kind::PropertyWrapperBackingInitializer: + case Node::Kind::PropertyWrappedFieldInitAccessor: case Node::Kind::PropertyWrapperInitFromProjectedValue: case Node::Kind::DefaultArgumentInitializer: case Node::Kind::Static: diff --git a/symbolic-demangle/vendor/swift/lib/Demangling/RemanglerBase.h b/symbolic-demangle/vendor/swift/lib/Demangling/RemanglerBase.h index 7a6a4fe9f..2ed698e4d 100644 --- a/symbolic-demangle/vendor/swift/lib/Demangling/RemanglerBase.h +++ b/symbolic-demangle/vendor/swift/lib/Demangling/RemanglerBase.h @@ -1,4 +1,4 @@ -//===--- Demangler.h - String to Node-Tree Demangling -----------*- C++ -*-===// +//===--- RemanglerBase.h - String to Node-Tree Demangling -------*- C++ -*-===// // // This source file is part of the Swift.org open source project // @@ -19,6 +19,7 @@ #include "swift/Demangling/Demangler.h" #include "swift/Demangling/NamespaceMacros.h" +#include "llvm/ADT/PointerIntPair.h" #include using namespace swift::Demangle; @@ -37,14 +38,19 @@ SWIFT_BEGIN_INLINE_NAMESPACE // An entry in the remangler's substitution map. class SubstitutionEntry { - Node *TheNode = nullptr; + llvm::PointerIntPair NodeAndTreatAsIdentifier; size_t StoredHash = 0; - bool treatAsIdentifier = false; + + Node *getNode() const { return NodeAndTreatAsIdentifier.getPointer(); } + + bool getTreatAsIdentifier() const { + return NodeAndTreatAsIdentifier.getInt(); + } public: void setNode(Node *node, bool treatAsIdentifier, size_t hash) { - this->treatAsIdentifier = treatAsIdentifier; - TheNode = node; + NodeAndTreatAsIdentifier.setPointer(node); + NodeAndTreatAsIdentifier.setInt(treatAsIdentifier); StoredHash = hash; } @@ -54,10 +60,10 @@ class SubstitutionEntry { } }; - bool isEmpty() const { return !TheNode; } + bool isEmpty() const { return !getNode(); } bool matches(Node *node, bool treatAsIdentifier) const { - return node == TheNode && treatAsIdentifier == this->treatAsIdentifier; + return node == getNode() && treatAsIdentifier == getTreatAsIdentifier(); } size_t hash() const { return StoredHash; } @@ -67,12 +73,12 @@ class SubstitutionEntry { const SubstitutionEntry &rhs) { if (lhs.StoredHash != rhs.StoredHash) return false; - if (lhs.treatAsIdentifier != rhs.treatAsIdentifier) + if (lhs.getTreatAsIdentifier() != rhs.getTreatAsIdentifier()) return false; - if (lhs.treatAsIdentifier) { - return identifierEquals(lhs.TheNode, rhs.TheNode); + if (lhs.getTreatAsIdentifier()) { + return identifierEquals(lhs.getNode(), rhs.getNode()); } - return lhs.deepEquals(lhs.TheNode, rhs.TheNode); + return lhs.deepEquals(lhs.getNode(), rhs.getNode()); } static bool identifierEquals(Node *lhs, Node *rhs); diff --git a/symbolic-demangle/vendor/swift/update.py b/symbolic-demangle/vendor/swift/update.py index 68a9f84ac..8be1b380e 100755 --- a/symbolic-demangle/vendor/swift/update.py +++ b/symbolic-demangle/vendor/swift/update.py @@ -8,6 +8,16 @@ SWIFT_PATH = "swift" DEMANGLING_PATH = "lib/Demangling" +# Demangling binaries/sources which aren't required. +DEMANGLING_IGNORE = [ + "CrashReporter.*", + "OldDemangler.*", + "OldRemangler.*", +] +# List of includes which `clang` can or does not infer from the sources. +MANUAL_INCLUDES = [ + "swift/include/swift/ABI/InvertibleProtocols.def", # used in `NodePrinter.cpp` +] WORKSPACE_INCLUDES = [ 'llvm-project/llvm/include', 'llbuild/include', @@ -110,11 +120,14 @@ def main(): print("> Replacing sources in %s" % (DEMANGLING_PATH)) demangler_source = os.path.join(swift_dir, DEMANGLING_PATH) + demangler_ignore = shutil.ignore_patterns(*DEMANGLING_IGNORE) demangler_target = os.path.join(vendor_dir, DEMANGLING_PATH) - shutil.copytree(demangler_source, demangler_target) + shutil.copytree(demangler_source, demangler_target, ignore=demangler_ignore) print("> Resolving required headers") - required_headers = set() + required_headers = { + os.path.join(workspace_dir, header) for header in MANUAL_INCLUDES + } for source_file in os.listdir(demangler_target): required_headers.update(get_headers(source_file, demangler_target, workspace_dir))