chromium/v8/include/cppgc/internal/name-trait.h

// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_
#define INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_

#include <cstddef>
#include <cstdint>
#include <type_traits>

#include "cppgc/name-provider.h"
#include "v8config.h"  // NOLINT(build/include_directory)

namespace cppgc {
namespace internal {

#if CPPGC_SUPPORTS_OBJECT_NAMES && defined(__clang__)
#define CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME

// Provides constexpr c-string storage for a name of fixed |Size| characters.
// Automatically appends terminating 0 byte.
template <size_t Size>
struct NameBuffer {
  char name[Size + 1]{};

  static constexpr NameBuffer FromCString(const char* str) {
    NameBuffer result;
    for (size_t i = 0; i < Size; ++i) result.name[i] = str[i];
    result.name[Size] = 0;
    return result;
  }
};

template <typename T>
const char* GetTypename() {
  static constexpr char kSelfPrefix[] =
      "const char *cppgc::internal::GetTypename() [T =";
  static_assert(__builtin_strncmp(__PRETTY_FUNCTION__, kSelfPrefix,
                                  sizeof(kSelfPrefix) - 1) == 0,
                "The prefix must match");
  static constexpr const char* kTypenameStart =
      __PRETTY_FUNCTION__ + sizeof(kSelfPrefix);
  static constexpr size_t kTypenameSize =
      __builtin_strlen(__PRETTY_FUNCTION__) - sizeof(kSelfPrefix) - 1;
  // NameBuffer is an indirection that is needed to make sure that only a
  // substring of __PRETTY_FUNCTION__ gets materialized in the binary.
  static constexpr auto buffer =
      NameBuffer<kTypenameSize>::FromCString(kTypenameStart);
  return buffer.name;
}

#else
#define CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME
#endif

struct HeapObjectName {};

enum class HeapObjectNameForUnnamedObject : uint8_t {};

class V8_EXPORT NameTraitBase {};

// Trait that specifies how the garbage collector retrieves the name for a
// given object.
template <typename T>
class NameTrait final : public NameTraitBase {};

NameCallback;

}  // namespace internal
}  // namespace cppgc

#undef CPPGC_SUPPORTS_COMPILE_TIME_TYPENAME

#endif  // INCLUDE_CPPGC_INTERNAL_NAME_TRAIT_H_