Skip to content

Commit

Permalink
[libc++][format] Improve ABI stability.
Browse files Browse the repository at this point in the history
During the review of D115991 @vitaut pointed out the enum shouldn't
depend on whether or not _LIBCPP_HAS_NO_INT128 is defined. The current
implementation lets the enum's ABI depend on this configuration option
without a good cause.

Reviewed By: ldionne, #libc

Differential Revision: https://reviews.llvm.org/D116120
  • Loading branch information
mordante committed Dec 23, 2021
1 parent b7b260e commit dfb20d4
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 7 deletions.
17 changes: 10 additions & 7 deletions libcxx/include/__format/format_arg.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)

namespace __format {
/** The type stored in @ref basic_format_arg. */
/// The type stored in @ref basic_format_arg.
///
/// @note The 128-bit types are unconditionally in the list to avoid the values
/// of the enums to depend on the availability of 128-bit integers.
enum class _LIBCPP_ENUM_VIS __arg_t : uint8_t {
__none,
__boolean,
__char_type,
__int,
__long_long,
#ifndef _LIBCPP_HAS_NO_INT128
__i128,
#endif
__unsigned,
__unsigned_long_long,
#ifndef _LIBCPP_HAS_NO_INT128
__u128,
#endif
__float,
__double,
__long_double,
Expand All @@ -75,18 +74,22 @@ visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__int);
case __format::__arg_t::__long_long:
return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__long_long);
#ifndef _LIBCPP_HAS_NO_INT128
case __format::__arg_t::__i128:
#ifndef _LIBCPP_HAS_NO_INT128
return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__i128);
#else
_LIBCPP_UNREACHABLE();
#endif
case __format::__arg_t::__unsigned:
return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__unsigned);
case __format::__arg_t::__unsigned_long_long:
return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis),
__arg.__unsigned_long_long);
#ifndef _LIBCPP_HAS_NO_INT128
case __format::__arg_t::__u128:
#ifndef _LIBCPP_HAS_NO_INT128
return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__u128);
#else
_LIBCPP_UNREACHABLE();
#endif
case __format::__arg_t::__float:
return _VSTD::invoke(_VSTD::forward<_Visitor>(__vis), __arg.__float);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//===----------------------------------------------------------------------===//
// 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
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17
// UNSUPPORTED: libcpp-no-concepts
// UNSUPPORTED: libcpp-has-no-incomplete-format

// <format>

// namespace __format { enum class __arg_t : uint8_t{...}; }

#include <format>

#include <type_traits>

#include "test_macros.h"

static_assert(std::is_same_v<std::underlying_type_t<std::__format::__arg_t>, uint8_t>);

static_assert(uint8_t(std::__format::__arg_t::__none) == 0);
static_assert(uint8_t(std::__format::__arg_t::__boolean) == 1);
static_assert(uint8_t(std::__format::__arg_t::__char_type) == 2);
static_assert(uint8_t(std::__format::__arg_t::__int) == 3);
static_assert(uint8_t(std::__format::__arg_t::__long_long) == 4);
static_assert(uint8_t(std::__format::__arg_t::__i128) == 5);
static_assert(uint8_t(std::__format::__arg_t::__unsigned) == 6);
static_assert(uint8_t(std::__format::__arg_t::__unsigned_long_long) == 7);
static_assert(uint8_t(std::__format::__arg_t::__u128) == 8);
static_assert(uint8_t(std::__format::__arg_t::__float) == 9);
static_assert(uint8_t(std::__format::__arg_t::__double) == 10);
static_assert(uint8_t(std::__format::__arg_t::__long_double) == 11);
static_assert(uint8_t(std::__format::__arg_t::__const_char_type_ptr) == 12);
static_assert(uint8_t(std::__format::__arg_t::__string_view) == 13);
static_assert(uint8_t(std::__format::__arg_t::__ptr) == 14);

0 comments on commit dfb20d4

Please sign in to comment.