FLANG
object-sizes.h
1//===-- include/flang/Evaluate/object-sizes.h -------------------*- 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// Object size/alignment for the opaque facades IntegerValue, RealValue,
10// CharacterValue and their variant-backed implementations IntegerValueImpl,
11// RealValueImpl, CharacterValueImpl.
12//
13// When not cross-compiling, flang-evaluate-object-size-probe measures these
14// with the very toolchain (and per build configuration) used for the build and
15// emits object-sizes-generated.h into the build tree's include
16// directory. Those values directly measured are preferred whenever that header
17// is available on the include path, regardless of -I ordering. The constants
18// below are the fallback used otherwise -- in particular when cross-compiling,
19// where the probe cannot run on the build host. They are verified against the
20// implementation classes by static_asserts in integer-value.cpp, real-value.cpp
21// and character-value.cpp.
22//
23// The probe itself (object-size-probe.cpp) compiles with
24// FLANG_OBJECT_SIZE_PROBE defined: it generates the header, so it
25// must not depend on it. The dedicated #if branch below omits __has_include so
26// dependency scanners do not record the generated header (probe -> generated
27// header -> probe cycle).
28//
29//===----------------------------------------------------------------------===//
30
31#ifndef FORTRAN_EVALUATE_OBJECT_SIZES_H_
32#define FORTRAN_EVALUATE_OBJECT_SIZES_H_
33
34#include <cstddef>
35
36#ifdef FLANG_OBJECT_SIZE_PROBE
37#error This header must not be included into the object-size-probe executable itself (in particular, integer-value-impl.h, real-value-impl.h, character-value-impl.h); it would cause a dependency cycle in incremental builds.
38#endif
39
40#if __has_include(<flang/Evaluate/object-sizes-generated.h>)
41// Measured object sizes
42#include <flang/Evaluate/object-sizes-generated.h>
43#else
44// Fallback known object sizes
45//
46// These fallbacks assume a 64-bit (LP64/LLP64) host, which covers the targets
47// flang is built for (x86_64, AArch64, PowerPC64).
48namespace Fortran::evaluate::value::detail {
49
50inline constexpr std::size_t kIntegerObjectSize{20};
51inline constexpr std::size_t kIntegerObjectAlign{4};
52
53inline constexpr std::size_t kRealObjectSize{32};
54inline constexpr std::size_t kRealObjectAlign{16};
55
56// CharacterValueImpl is a
57// std::variant<std::string, std::u16string, std::u32string>.
58//
59// * MSVC STL: 48 bytes with _ITERATOR_DEBUG_LEVEL==2
60// 40 bytes otherwise
61// * libc++: 32 bytes
62// invariant to _LIBCPP_HARDENING_MODE
63// * libstdc++: 40 bytes
64// invariant to _GLIBCXX_ASSERTIONS or _GLIBCXX_DEBUG
65#if defined(_MSC_VER)
66#if ((defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL >= 2) || \
67 (!defined(_ITERATOR_DEBUG_LEVEL) && defined(_DEBUG)))
68inline constexpr std::size_t kCharacterObjectSize{48};
69#else
70inline constexpr std::size_t kCharacterObjectSize{40};
71#endif
72#elif defined(_LIBCPP_VERSION)
73inline constexpr std::size_t kCharacterObjectSize{32};
74#elif defined(__GLIBCXX__) || defined(__GLIBCPP__)
75inline constexpr std::size_t kCharacterObjectSize{40};
76#else
77#error Unknown STL implementation
78#endif
79inline constexpr std::size_t kCharacterObjectAlign{8};
80
81} // namespace Fortran::evaluate::value::detail
82#endif
83
84#endif // FORTRAN_EVALUATE_OBJECT_SIZES_H_