/*
 * Copyright (C) 2018-2019 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include <wtf/Assertions.h>
#include <wtf/DataLog.h>

namespace WTF {

#define FOR_EACH_BASE_WTF_PTRTAG(v) \
    v(NoPtrTag) \
    v(CFunctionPtrTag) \

#define FOR_EACH_ADDITIONAL_WTF_PTRTAG(v) \
    v(FreeSpacePtrTag) \
    v(HandleMemoryPtrTag) \
    v(PlatformRegistersLRPtrTag) \
    v(PlatformRegistersPCPtrTag) \

#define FOR_EACH_WTF_PTRTAG(v) \
    FOR_EACH_BASE_WTF_PTRTAG(v) \
    FOR_EACH_ADDITIONAL_WTF_PTRTAG(v) \

enum PtrTag : uintptr_t {
    NoPtrTag,
    CFunctionPtrTag,
};

#if CPU(ARM64E)
#define WTF_PTRTAG_HASH(tag) ptrauth_string_discriminator(#tag)

#else // not CPU(ARM64E)

template<size_t N>
constexpr uintptr_t makePtrTagHash(const char (&str)[N])
{
    uintptr_t result = 134775813;
    for (size_t i = 0; i < N; ++i)
        result += ((result * str[i]) ^ (result >> 16));
    return result & 0xffff;
}

#define WTF_PTRTAG_HASH(tag) WTF::makePtrTagHash(#tag)
#endif // not CPU(ARM64E)

#define WTF_DECLARE_PTRTAG(tag) \
    constexpr PtrTag tag = static_cast<PtrTag>(WTF_PTRTAG_HASH(#tag)); \
    static_assert(tag != NoPtrTag && tag != CFunctionPtrTag, "");

static_assert(static_cast<uintptr_t>(NoPtrTag) == static_cast<uintptr_t>(0), "");
static_assert(static_cast<uintptr_t>(CFunctionPtrTag) == static_cast<uintptr_t>(1), "");

#if COMPILER(MSVC)
#pragma warning(push)
#pragma warning(disable:4307)
#endif

FOR_EACH_ADDITIONAL_WTF_PTRTAG(WTF_DECLARE_PTRTAG)

#if COMPILER(MSVC)
#pragma warning(pop)
#endif

struct PtrTagLookup {
    const char* (*tagForPtr)(const void*);
    const char* (*ptrTagName)(PtrTag);
    PtrTagLookup* next { nullptr };
};

#if CPU(ARM64E)

enum class PtrTagAction {
    ReleaseAssert,
    DebugAssert,
    NoAssert,
};

constexpr PtrTag AnyPtrTag = static_cast<PtrTag>(-1); // Only used for assertion messages.

WTF_EXPORT_PRIVATE void registerPtrTagLookup(PtrTagLookup*);
WTF_EXPORT_PRIVATE void reportBadTag(const void*, PtrTag expectedTag);

#if ASSERT_DISABLED
constexpr bool enablePtrTagDebugAssert = false;
#else
constexpr bool enablePtrTagDebugAssert = true;
#endif

#define WTF_PTRTAG_ASSERT(action, ptr, expectedTag, assertion) \
    do { \
        if (action == PtrTagAction::ReleaseAssert \
            || (WTF::enablePtrTagDebugAssert && action == PtrTagAction::DebugAssert)) { \
            bool passed = (assertion); \
            if (UNLIKELY(!passed)) { \
                reportBadTag(reinterpret_cast<const void*>(ptr), expectedTag); \
            } \
            RELEASE_ASSERT(passed && #assertion); \
        } \
    } while (false)


template<typename T>
inline T* tagArrayPtr(std::nullptr_t ptr, size_t length)
{
    ASSERT(!length);
    return ptrauth_sign_unauthenticated(static_cast<T*>(ptr), ptrauth_key_process_dependent_data, length);
}


template<typename T>
inline T* tagArrayPtr(T* ptr, size_t length)
{
    return ptrauth_sign_unauthenticated(ptr, ptrauth_key_process_dependent_data, length);
}

template<typename T>
inline T* untagArrayPtr(T* ptr, size_t length)
{
    return ptrauth_auth_data(ptr, ptrauth_key_process_dependent_data, length);
}

template<typename T>
inline T* removeArrayPtrTag(T* ptr)
{
    return ptrauth_strip(ptr, ptrauth_key_process_dependent_data);
}

template<typename T>
inline T* retagArrayPtr(T* ptr, size_t oldLength, size_t newLength)
{
    return ptrauth_auth_and_resign(ptr, ptrauth_key_process_dependent_data, oldLength, ptrauth_key_process_dependent_data, newLength);
}

template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
inline constexpr T removeCodePtrTag(PtrType ptr)
{
    return bitwise_cast<T>(ptrauth_strip(ptr, ptrauth_key_process_dependent_code));
}

template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline constexpr PtrType removeCodePtrTag(PtrType ptr)
{
    return ptrauth_strip(ptr, ptrauth_key_process_dependent_code);
}

template<PtrTagAction tagAction, typename PtrType>
inline PtrType tagCodePtrImpl(PtrType ptr, PtrTag tag)
{
    if (!ptr)
        return nullptr;
    WTF_PTRTAG_ASSERT(tagAction, ptr, NoPtrTag, removeCodePtrTag(ptr) == ptr);
    if (tag == NoPtrTag)
        return ptr;
    if (tag == CFunctionPtrTag)
        return ptrauth_sign_unauthenticated(ptr, ptrauth_key_function_pointer, 0);
    return ptrauth_sign_unauthenticated(ptr, ptrauth_key_process_dependent_code, tag);
}

template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
inline T tagCodePtr(PtrType ptr, PtrTag tag)
{
    return bitwise_cast<T>(tagCodePtrImpl<PtrTagAction::DebugAssert>(ptr, tag));
}

template<typename T, PtrTag tag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline T tagCodePtr(PtrType ptr)
{
    return bitwise_cast<T>(tagCodePtrImpl<PtrTagAction::DebugAssert>(ptr, tag));
}

template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline PtrType tagCodePtr(PtrType ptr, PtrTag tag)
{
    return tagCodePtrImpl<PtrTagAction::DebugAssert>(ptr, tag);
}

template<PtrTag tag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline PtrType tagCodePtr(PtrType ptr) { return tagCodePtr(ptr, tag); }

template<typename PtrType>
inline PtrType untagCodePtrImplHelper(PtrType ptr, PtrTag tag)
{
    if (tag == NoPtrTag)
        return ptr;
    if (tag == CFunctionPtrTag)
        return __builtin_ptrauth_auth(ptr, ptrauth_key_function_pointer, 0);
    return __builtin_ptrauth_auth(ptr, ptrauth_key_process_dependent_code, tag);
}

template<PtrTagAction tagAction, typename PtrType>
inline PtrType untagCodePtrImpl(PtrType ptr, PtrTag tag)
{
    if (!ptr)
        return nullptr;
    PtrType result = untagCodePtrImplHelper(ptr, tag);
    WTF_PTRTAG_ASSERT(tagAction, ptr, tag, removeCodePtrTag(ptr) == result);
    return result;
}

template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
inline T untagCodePtr(PtrType ptr, PtrTag tag)
{
    return bitwise_cast<T>(untagCodePtrImpl<PtrTagAction::ReleaseAssert>(ptr, tag));
}

template<typename T, PtrTag tag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline T untagCodePtr(PtrType ptr)
{
    return bitwise_cast<T>(untagCodePtrImpl<PtrTagAction::ReleaseAssert>(ptr, tag));
}

template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline PtrType untagCodePtr(PtrType ptr, PtrTag tag)
{
    return untagCodePtrImpl<PtrTagAction::ReleaseAssert>(ptr, tag);
}

template<PtrTag tag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline PtrType untagCodePtr(PtrType ptr) { return untagCodePtr(ptr, tag); }

template<PtrTagAction tagAction, typename PtrType>
inline PtrType retagCodePtrImplHelper(PtrType ptr, PtrTag oldTag, PtrTag newTag)
{
    if (oldTag == newTag || (oldTag == NoPtrTag && newTag == NoPtrTag))
        return ptr;
    if (newTag == NoPtrTag)
        return untagCodePtrImpl<tagAction>(ptr, oldTag);
    if (oldTag == NoPtrTag)
        return tagCodePtrImpl<tagAction>(ptr, newTag);
    if (oldTag == CFunctionPtrTag)
        return ptrauth_auth_and_resign(ptr, ptrauth_key_function_pointer, 0, ptrauth_key_process_dependent_code, newTag);
    if (newTag == CFunctionPtrTag)
        return ptrauth_auth_and_resign(ptr, ptrauth_key_process_dependent_code, oldTag, ptrauth_key_function_pointer, 0);
    return ptrauth_auth_and_resign(ptr, ptrauth_key_process_dependent_code, oldTag, ptrauth_key_process_dependent_code, newTag);
}

template<PtrTagAction tagAction, typename PtrType>
inline PtrType retagCodePtrImpl(PtrType ptr, PtrTag oldTag, PtrTag newTag)
{
    if (!ptr)
        return nullptr;
    PtrTagAction untagAction = (tagAction == PtrTagAction::NoAssert) ? PtrTagAction::NoAssert : PtrTagAction::ReleaseAssert;
    WTF_PTRTAG_ASSERT(untagAction, ptr, oldTag, removeCodePtrTag(ptr) == untagCodePtrImpl<PtrTagAction::NoAssert>(ptr, oldTag));
    PtrType result = retagCodePtrImplHelper<tagAction>(ptr, oldTag, newTag);
    WTF_PTRTAG_ASSERT(tagAction, ptr, newTag, result == tagCodePtrImpl<PtrTagAction::NoAssert>(removeCodePtrTag(ptr), newTag));
    return result;
}

template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
inline T retagCodePtr(PtrType ptr, PtrTag oldTag, PtrTag newTag)
{
    return bitwise_cast<T>(retagCodePtrImpl<PtrTagAction::DebugAssert>(ptr, oldTag, newTag));
}

template<typename T, PtrTag oldTag, PtrTag newTag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline T retagCodePtr(PtrType ptr)
{
    return bitwise_cast<T>(retagCodePtrImpl<PtrTagAction::DebugAssert>(ptr, oldTag, newTag));
}

template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline PtrType retagCodePtr(PtrType ptr, PtrTag oldTag, PtrTag newTag)
{
    return retagCodePtrImpl<PtrTagAction::DebugAssert>(ptr, oldTag, newTag);
}

template<PtrTag oldTag, PtrTag newTag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline PtrType retagCodePtr(PtrType ptr) { return retagCodePtr(ptr, oldTag, newTag); }

template<PtrTagAction tagAction, typename PtrType>
inline PtrType tagCFunctionPtrImpl(PtrType ptr, PtrTag tag)
{
    if (!ptr)
        return nullptr;
    WTF_PTRTAG_ASSERT(tagAction, ptr, CFunctionPtrTag, removeCodePtrTag(ptr) == untagCodePtrImpl<PtrTagAction::NoAssert>(ptr, CFunctionPtrTag));
    return retagCodePtrImpl<tagAction>(ptr, CFunctionPtrTag, tag);
}

template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
inline T tagCFunctionPtr(PtrType ptr, PtrTag tag)
{
    return bitwise_cast<T>(tagCFunctionPtrImpl<PtrTagAction::DebugAssert>(ptr, tag));
}

template<typename T, PtrTag tag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline T tagCFunctionPtr(PtrType ptr)
{
    return bitwise_cast<T>(tagCFunctionPtrImpl<PtrTagAction::DebugAssert>(ptr, tag));
}

template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline PtrType tagCFunctionPtr(PtrType ptr, PtrTag tag)
{
    return tagCFunctionPtrImpl<PtrTagAction::DebugAssert>(ptr, tag);
}

template<PtrTag tag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline PtrType tagCFunctionPtr(PtrType ptr) { return tagCFunctionPtr(ptr, tag); }

template<PtrTagAction tagAction, typename PtrType>
inline PtrType untagCFunctionPtrImpl(PtrType ptr, PtrTag tag)
{
    if (!ptr)
        return nullptr;
    WTF_PTRTAG_ASSERT(tagAction, ptr, tag, removeCodePtrTag(ptr) == untagCodePtrImpl<PtrTagAction::NoAssert>(ptr, tag));
    return retagCodePtrImpl<tagAction>(ptr, tag, CFunctionPtrTag);
}

template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
inline T untagCFunctionPtr(PtrType ptr, PtrTag tag)
{
    return bitwise_cast<T>(untagCFunctionPtrImpl<PtrTagAction::DebugAssert>(ptr, tag));
}

template<typename T, PtrTag tag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline T untagCFunctionPtr(PtrType ptr)
{
    return bitwise_cast<T>(untagCFunctionPtrImpl<PtrTagAction::DebugAssert>(ptr, tag));
}

template<typename T, PtrTag tag, PtrTagAction tagAction, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline T untagCFunctionPtr(PtrType ptr)
{
    return bitwise_cast<T>(untagCFunctionPtrImpl<tagAction>(ptr, tag));
}

template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline PtrType untagCFunctionPtr(PtrType ptr, PtrTag tag)
{
    return untagCFunctionPtrImpl<PtrTagAction::DebugAssert>(ptr, tag);
}

template<PtrTag tag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline PtrType untagCFunctionPtr(PtrType ptr) { return untagCFunctionPtr(ptr, tag); }

template <typename IntType>
inline IntType tagInt(IntType ptrInt, PtrTag tag)
{
    static_assert(sizeof(IntType) == sizeof(uintptr_t), "");
    return bitwise_cast<IntType>(ptrauth_sign_unauthenticated(bitwise_cast<void*>(ptrInt), ptrauth_key_process_dependent_data, tag));
}

template<typename PtrType>
void assertIsCFunctionPtr(PtrType value)
{
    void* ptr = bitwise_cast<void*>(value);
    WTF_PTRTAG_ASSERT(PtrTagAction::ReleaseAssert, ptr, CFunctionPtrTag, untagCodePtrImpl<PtrTagAction::NoAssert>(ptr, CFunctionPtrTag) == removeCodePtrTag(ptr));
}

template<typename PtrType>
void assertIsNullOrCFunctionPtr(PtrType ptr)
{
    if (ptr)
        assertIsCFunctionPtr(ptr);
}

template<typename PtrType>
void assertIsNotTagged(PtrType value)
{
    void* ptr = bitwise_cast<void*>(value);
    WTF_PTRTAG_ASSERT(PtrTagAction::ReleaseAssert, ptr, NoPtrTag, ptr == removeCodePtrTag(ptr));
}

template<typename PtrType>
void assertIsTagged(PtrType value)
{
    void* ptr = bitwise_cast<void*>(value);
    WTF_PTRTAG_ASSERT(PtrTagAction::ReleaseAssert, ptr, AnyPtrTag, ptr != removeCodePtrTag(ptr));
}

template<typename PtrType>
void assertIsNullOrTagged(PtrType ptr)
{
    if (ptr)
        assertIsTagged(ptr);
}

template<typename PtrType>
bool isTaggedWith(PtrType value, PtrTag tag)
{
    void* ptr = bitwise_cast<void*>(value);
    if (tag == NoPtrTag)
        return ptr == removeCodePtrTag(ptr);
    return untagCodePtrImpl<PtrTagAction::NoAssert>(ptr, tag) == removeCodePtrTag(ptr);
}

template<typename PtrType>
void assertIsTaggedWith(PtrType value, PtrTag tag)
{
    WTF_PTRTAG_ASSERT(PtrTagAction::ReleaseAssert, value, tag, isTaggedWith(value, tag));
}

template<typename PtrType>
void assertIsNullOrTaggedWith(PtrType ptr, PtrTag tag)
{
    if (ptr)
        assertIsTaggedWith(ptr, tag);
}

inline bool usesPointerTagging() { return true; }

#else // not CPU(ARM64E)

inline void registerPtrTagLookup(PtrTagLookup*) { }
inline void reportBadTag(const void*, PtrTag) { }

template<typename T>
inline T* tagArrayPtr(std::nullptr_t, size_t size)
{
    ASSERT_UNUSED(size, !size);
    return nullptr;
}

template<typename T>
inline T* tagArrayPtr(T* ptr, size_t)
{
    return ptr;
}

template<typename T>
inline T* untagArrayPtr(T* ptr, size_t)
{
    return ptr;
}

template<typename T>
inline T* removeArrayPtrTag(T* ptr)
{
    return ptr;
}

template<typename T>
inline T* retagArrayPtr(T* ptr, size_t, size_t)
{
    return ptr;
}


template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
constexpr T tagCodePtr(PtrType ptr, PtrTag) { return bitwise_cast<T>(ptr); }

template<typename T, PtrTag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline T tagCodePtr(PtrType ptr) { return bitwise_cast<T>(ptr); }

template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
constexpr PtrType tagCodePtr(PtrType ptr, PtrTag) { return ptr; }

template<PtrTag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline PtrType tagCodePtr(PtrType ptr) { return ptr; }

template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
constexpr T untagCodePtr(PtrType ptr, PtrTag) { return bitwise_cast<T>(ptr); }

template<typename T, PtrTag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline T untagCodePtr(PtrType ptr)  { return bitwise_cast<T>(ptr); }

template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
constexpr PtrType untagCodePtr(PtrType ptr, PtrTag) { return ptr; }

template<PtrTag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline PtrType untagCodePtr(PtrType ptr) { return ptr; }

template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
constexpr T retagCodePtr(PtrType ptr, PtrTag, PtrTag) { return bitwise_cast<T>(ptr); }

template<typename T, PtrTag, PtrTag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline T retagCodePtr(PtrType ptr) { return bitwise_cast<T>(ptr); }

template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
constexpr PtrType retagCodePtr(PtrType ptr, PtrTag, PtrTag) { return ptr; }

template<PtrTag, PtrTag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline PtrType retagCodePtr(PtrType ptr) { return ptr; }

template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
constexpr T removeCodePtrTag(PtrType ptr) { return bitwise_cast<T>(ptr); }

template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
constexpr PtrType removeCodePtrTag(PtrType ptr) { return ptr; }

template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
inline T tagCFunctionPtr(PtrType ptr, PtrTag) { return bitwise_cast<T>(ptr); }

template<typename T, PtrTag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline T tagCFunctionPtr(PtrType ptr) { return bitwise_cast<T>(ptr); }

template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline PtrType tagCFunctionPtr(PtrType ptr, PtrTag) { return ptr; }

template<PtrTag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline PtrType tagCFunctionPtr(PtrType ptr) { return ptr; }

template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
inline T untagCFunctionPtr(PtrType ptr, PtrTag) { return bitwise_cast<T>(ptr); }

template<typename T, PtrTag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline T untagCFunctionPtr(PtrType ptr) { return bitwise_cast<T>(ptr); }

template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline PtrType untagCFunctionPtr(PtrType ptr, PtrTag) { return ptr; }

template<PtrTag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
inline PtrType untagCFunctionPtr(PtrType ptr) { return ptr; }

template <typename IntType>
inline IntType tagInt(IntType ptrInt, PtrTag)
{
    static_assert(sizeof(IntType) == sizeof(uintptr_t), "");
    return ptrInt;
}

template<typename PtrType> void assertIsCFunctionPtr(PtrType) { }
template<typename PtrType> void assertIsNullOrCFunctionPtr(PtrType) { }

template<typename PtrType> void assertIsNotTagged(PtrType) { }
template<typename PtrType> void assertIsTagged(PtrType) { }
template<typename PtrType> void assertIsNullOrTagged(PtrType) { }

template<typename PtrType> bool isTaggedWith(PtrType, PtrTag) { return false; }

template<typename PtrType> void assertIsTaggedWith(PtrType, PtrTag) { }
template<typename PtrType> void assertIsNullOrTaggedWith(PtrType, PtrTag) { }

inline bool usesPointerTagging() { return false; }

#endif // CPU(ARM64E)

} // namespace WTF

using WTF::CFunctionPtrTag;
using WTF::NoPtrTag;
using WTF::PlatformRegistersLRPtrTag;
using WTF::PlatformRegistersPCPtrTag;
using WTF::PtrTag;

using WTF::reportBadTag;

using WTF::tagArrayPtr;
using WTF::untagArrayPtr;
using WTF::retagArrayPtr;
using WTF::removeArrayPtrTag;

using WTF::tagCodePtr;
using WTF::untagCodePtr;
using WTF::retagCodePtr;
using WTF::removeCodePtrTag;
using WTF::tagCFunctionPtr;
using WTF::untagCFunctionPtr;
using WTF::tagInt;

using WTF::assertIsCFunctionPtr;
using WTF::assertIsNullOrCFunctionPtr;
using WTF::assertIsNotTagged;
using WTF::assertIsTagged;
using WTF::assertIsNullOrTagged;
using WTF::isTaggedWith;
using WTF::assertIsTaggedWith;
using WTF::assertIsNullOrTaggedWith;
using WTF::usesPointerTagging;
