LCOV - code coverage report
Current view: top level - /usr/lib/llvm-19/include/llvm/Support - PointerLikeTypeTraits.h (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 100.0 % 6 6
Test Date: 2026-02-27 05:14:50 Functions: 92.3 % 13 12
Legend: Lines:     hit not hit

            Line data    Source code
       1              : //===- llvm/Support/PointerLikeTypeTraits.h - Pointer Traits ----*- C++ -*-===//
       2              : //
       3              : // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
       4              : // See https://llvm.org/LICENSE.txt for license information.
       5              : // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
       6              : //
       7              : //===----------------------------------------------------------------------===//
       8              : //
       9              : // This file defines the PointerLikeTypeTraits class.  This allows data
      10              : // structures to reason about pointers and other things that are pointer sized.
      11              : //
      12              : //===----------------------------------------------------------------------===//
      13              : 
      14              : #ifndef LLVM_SUPPORT_POINTERLIKETYPETRAITS_H
      15              : #define LLVM_SUPPORT_POINTERLIKETYPETRAITS_H
      16              : 
      17              : #include "llvm/Support/DataTypes.h"
      18              : #include <cassert>
      19              : #include <type_traits>
      20              : 
      21              : namespace llvm {
      22              : 
      23              : /// A traits type that is used to handle pointer types and things that are just
      24              : /// wrappers for pointers as a uniform entity.
      25              : template <typename T> struct PointerLikeTypeTraits;
      26              : 
      27              : namespace detail {
      28              : /// A tiny meta function to compute the log2 of a compile time constant.
      29              : template <size_t N>
      30              : struct ConstantLog2
      31              :     : std::integral_constant<size_t, ConstantLog2<N / 2>::value + 1> {};
      32              : template <> struct ConstantLog2<1> : std::integral_constant<size_t, 0> {};
      33              : 
      34              : // Provide a trait to check if T is pointer-like.
      35              : template <typename T, typename U = void> struct HasPointerLikeTypeTraits {
      36              :   static const bool value = false;
      37              : };
      38              : 
      39              : // sizeof(T) is valid only for a complete T.
      40              : template <typename T>
      41              : struct HasPointerLikeTypeTraits<
      42              :     T, decltype((sizeof(PointerLikeTypeTraits<T>) + sizeof(T)), void())> {
      43              :   static const bool value = true;
      44              : };
      45              : 
      46              : template <typename T> struct IsPointerLike {
      47              :   static const bool value = HasPointerLikeTypeTraits<T>::value;
      48              : };
      49              : 
      50              : template <typename T> struct IsPointerLike<T *> {
      51              :   static const bool value = true;
      52              : };
      53              : } // namespace detail
      54              : 
      55              : // Provide PointerLikeTypeTraits for non-cvr pointers.
      56              : template <typename T> struct PointerLikeTypeTraits<T *> {
      57       803357 :   static inline void *getAsVoidPointer(T *P) { return P; }
      58        47930 :   static inline T *getFromVoidPointer(void *P) { return static_cast<T *>(P); }
      59              : 
      60              :   static constexpr int NumLowBitsAvailable =
      61              :       detail::ConstantLog2<alignof(T)>::value;
      62              : };
      63              : 
      64              : template <> struct PointerLikeTypeTraits<void *> {
      65              :   static inline void *getAsVoidPointer(void *P) { return P; }
      66              :   static inline void *getFromVoidPointer(void *P) { return P; }
      67              : 
      68              :   /// Note, we assume here that void* is related to raw malloc'ed memory and
      69              :   /// that malloc returns objects at least 4-byte aligned. However, this may be
      70              :   /// wrong, or pointers may be from something other than malloc. In this case,
      71              :   /// you should specify a real typed pointer or avoid this template.
      72              :   ///
      73              :   /// All clients should use assertions to do a run-time check to ensure that
      74              :   /// this is actually true.
      75              :   static constexpr int NumLowBitsAvailable = 2;
      76              : };
      77              : 
      78              : // Provide PointerLikeTypeTraits for const things.
      79              : template <typename T> struct PointerLikeTypeTraits<const T> {
      80              :   typedef PointerLikeTypeTraits<T> NonConst;
      81              : 
      82              :   static inline const void *getAsVoidPointer(const T P) {
      83              :     return NonConst::getAsVoidPointer(P);
      84              :   }
      85              :   static inline const T getFromVoidPointer(const void *P) {
      86              :     return NonConst::getFromVoidPointer(const_cast<void *>(P));
      87              :   }
      88              :   static constexpr int NumLowBitsAvailable = NonConst::NumLowBitsAvailable;
      89              : };
      90              : 
      91              : // Provide PointerLikeTypeTraits for const pointers.
      92              : template <typename T> struct PointerLikeTypeTraits<const T *> {
      93              :   typedef PointerLikeTypeTraits<T *> NonConst;
      94              : 
      95       729832 :   static inline const void *getAsVoidPointer(const T *P) {
      96       729832 :     return NonConst::getAsVoidPointer(const_cast<T *>(P));
      97              :   }
      98         9002 :   static inline const T *getFromVoidPointer(const void *P) {
      99         9002 :     return NonConst::getFromVoidPointer(const_cast<void *>(P));
     100              :   }
     101              :   static constexpr int NumLowBitsAvailable = NonConst::NumLowBitsAvailable;
     102              : };
     103              : 
     104              : // Provide PointerLikeTypeTraits for uintptr_t.
     105              : template <> struct PointerLikeTypeTraits<uintptr_t> {
     106              :   static inline void *getAsVoidPointer(uintptr_t P) {
     107              :     return reinterpret_cast<void *>(P);
     108              :   }
     109              :   static inline uintptr_t getFromVoidPointer(void *P) {
     110              :     return reinterpret_cast<uintptr_t>(P);
     111              :   }
     112              :   // No bits are available!
     113              :   static constexpr int NumLowBitsAvailable = 0;
     114              : };
     115              : 
     116              : /// Provide suitable custom traits struct for function pointers.
     117              : ///
     118              : /// Function pointers can't be directly given these traits as functions can't
     119              : /// have their alignment computed with `alignof` and we need different casting.
     120              : ///
     121              : /// To rely on higher alignment for a specialized use, you can provide a
     122              : /// customized form of this template explicitly with higher alignment, and
     123              : /// potentially use alignment attributes on functions to satisfy that.
     124              : template <int Alignment, typename FunctionPointerT>
     125              : struct FunctionPointerLikeTypeTraits {
     126              :   static constexpr int NumLowBitsAvailable =
     127              :       detail::ConstantLog2<Alignment>::value;
     128              :   static inline void *getAsVoidPointer(FunctionPointerT P) {
     129              :     assert((reinterpret_cast<uintptr_t>(P) &
     130              :             ~((uintptr_t)-1 << NumLowBitsAvailable)) == 0 &&
     131              :            "Alignment not satisfied for an actual function pointer!");
     132              :     return reinterpret_cast<void *>(P);
     133              :   }
     134              :   static inline FunctionPointerT getFromVoidPointer(void *P) {
     135              :     return reinterpret_cast<FunctionPointerT>(P);
     136              :   }
     137              : };
     138              : 
     139              : /// Provide a default specialization for function pointers that assumes 4-byte
     140              : /// alignment.
     141              : ///
     142              : /// We assume here that functions used with this are always at least 4-byte
     143              : /// aligned. This means that, for example, thumb functions won't work or systems
     144              : /// with weird unaligned function pointers won't work. But all practical systems
     145              : /// we support satisfy this requirement.
     146              : template <typename ReturnT, typename... ParamTs>
     147              : struct PointerLikeTypeTraits<ReturnT (*)(ParamTs...)>
     148              :     : FunctionPointerLikeTypeTraits<4, ReturnT (*)(ParamTs...)> {};
     149              : 
     150              : } // end namespace llvm
     151              : 
     152              : #endif
        

Generated by: LCOV version 2.0-1