[clang][bytecode] Handle bitcasts involving bitfields (#116843)
[llvm-project.git] / clang / lib / AST / ByteCode / BitcastBuffer.h
blob8442df5c60cf5657ae34fee121aeb8062600f582
1 //===--------------------- BitcastBuffer.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 #ifndef LLVM_CLANG_AST_INTERP_BITCAST_BUFFER_H
9 #define LLVM_CLANG_AST_INTERP_BITCAST_BUFFER_H
11 #include <cassert>
12 #include <cstddef>
13 #include <memory>
15 namespace clang {
16 namespace interp {
18 enum class Endian { Little, Big };
20 /// A quantity in bits.
21 struct Bits {
22 size_t N = 0;
23 Bits() = default;
24 static Bits zero() { return Bits(0); }
25 explicit Bits(size_t Quantity) : N(Quantity) {}
26 size_t getQuantity() const { return N; }
27 size_t roundToBytes() const { return N / 8; }
28 size_t getOffsetInByte() const { return N % 8; }
29 bool isFullByte() const { return N % 8 == 0; }
30 bool nonZero() const { return N != 0; }
32 Bits operator-(Bits Other) { return Bits(N - Other.N); }
33 Bits operator+(Bits Other) { return Bits(N + Other.N); }
34 Bits operator+=(size_t O) {
35 N += O;
36 return *this;
39 bool operator>=(Bits Other) { return N >= Other.N; }
42 /// A quantity in bytes.
43 struct Bytes {
44 size_t N;
45 explicit Bytes(size_t Quantity) : N(Quantity) {}
46 size_t getQuantity() const { return N; }
47 Bits toBits() const { return Bits(N * 8); }
50 /// Track what bits have been initialized to known values and which ones
51 /// have indeterminate value.
52 struct BitcastBuffer {
53 Bits FinalBitSize;
54 std::unique_ptr<std::byte[]> Data;
56 BitcastBuffer(Bits FinalBitSize) : FinalBitSize(FinalBitSize) {
57 assert(FinalBitSize.isFullByte());
58 unsigned ByteSize = FinalBitSize.roundToBytes();
59 Data = std::make_unique<std::byte[]>(ByteSize);
62 /// Returns the buffer size in bits.
63 Bits size() const { return FinalBitSize; }
65 /// Returns \c true if all bits in the buffer have been initialized.
66 bool allInitialized() const {
67 // FIXME: Implement.
68 return true;
71 /// Push \p BitWidth bits at \p BitOffset from \p In into the buffer.
72 /// \p TargetEndianness is the endianness of the target we're compiling for.
73 /// \p In must hold at least \p BitWidth many bits.
74 void pushData(const std::byte *In, Bits BitOffset, Bits BitWidth,
75 Endian TargetEndianness);
77 /// Copy \p BitWidth bits at offset \p BitOffset from the buffer.
78 /// \p TargetEndianness is the endianness of the target we're compiling for.
79 ///
80 /// The returned output holds exactly (\p FullBitWidth / 8) bytes.
81 std::unique_ptr<std::byte[]> copyBits(Bits BitOffset, Bits BitWidth,
82 Bits FullBitWidth,
83 Endian TargetEndianness) const;
86 } // namespace interp
87 } // namespace clang
88 #endif