clang 22.0.0git
BitcastBuffer.h
Go to the documentation of this file.
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
10
11#include "llvm/ADT/SmallVector.h"
12#include <cassert>
13#include <cstddef>
14#include <memory>
15
16namespace clang {
17namespace interp {
18
19enum class Endian { Little, Big };
20
21struct Bytes;
22
23/// A quantity in bits.
24struct Bits {
25 size_t N = 0;
26 Bits() = default;
27 static Bits zero() { return Bits(0); }
28 explicit Bits(size_t Quantity) : N(Quantity) {}
29 size_t getQuantity() const { return N; }
30 size_t roundToBytes() const { return N / 8; }
31 size_t getOffsetInByte() const { return N % 8; }
32 bool isFullByte() const { return N % 8 == 0; }
33 bool nonZero() const { return N != 0; }
34 bool isZero() const { return N == 0; }
35 Bytes toBytes() const;
36
37 Bits operator-(Bits Other) const { return Bits(N - Other.N); }
38 Bits operator+(Bits Other) const { return Bits(N + Other.N); }
39 Bits operator+=(size_t O) {
40 N += O;
41 return *this;
42 }
44 N += O.N;
45 return *this;
46 }
47
48 bool operator>=(Bits Other) const { return N >= Other.N; }
49 bool operator<=(Bits Other) const { return N <= Other.N; }
50 bool operator==(Bits Other) const { return N == Other.N; }
51 bool operator!=(Bits Other) const { return N != Other.N; }
52};
53
54/// A quantity in bytes.
55struct Bytes {
56 size_t N;
57 explicit Bytes(size_t Quantity) : N(Quantity) {}
58 size_t getQuantity() const { return N; }
59 Bits toBits() const { return Bits(N * 8); }
60};
61
62inline Bytes Bits::toBytes() const {
63 assert(isFullByte());
64 return Bytes(N / 8);
65}
66
67/// A bit range. Both Start and End are inclusive.
68struct BitRange {
71
73 Bits size() const { return End - Start + Bits(1); }
74 bool operator<(BitRange Other) const { return Start.N < Other.Start.N; }
75
76 bool contains(Bits B) { return Start <= B && End >= B; }
77};
78
79/// Track what bits have been initialized to known values and which ones
80/// have indeterminate value.
83 std::unique_ptr<std::byte[]> Data;
85
87 assert(FinalBitSize.isFullByte());
88 unsigned ByteSize = FinalBitSize.roundToBytes();
89 Data = std::make_unique<std::byte[]>(ByteSize);
90 }
91
92 /// Returns the byte at the given offset.
93 std::byte *atByte(unsigned Offset) {
94 assert(Offset < FinalBitSize.roundToBytes());
95 return Data.get() + Offset;
96 }
97
98 /// Returns the buffer size in bits.
99 Bits size() const { return FinalBitSize; }
100 Bytes byteSize() const { return FinalBitSize.toBytes(); }
101
102 /// Returns \c true if all bits in the buffer have been initialized.
103 bool allInitialized() const;
104 /// Marks the bits in the given range as initialized.
105 /// FIXME: Can we do this automatically in pushData()?
106 void markInitialized(Bits Start, Bits Length);
107 bool rangeInitialized(Bits Offset, Bits Length) const;
108
109 /// Push \p BitWidth bits at \p BitOffset from \p In into the buffer.
110 /// \p TargetEndianness is the endianness of the target we're compiling for.
111 /// \p In must hold at least \p BitWidth many bits.
112 void pushData(const std::byte *In, Bits BitOffset, Bits BitWidth,
113 Endian TargetEndianness);
114
115 /// Copy \p BitWidth bits at offset \p BitOffset from the buffer.
116 /// \p TargetEndianness is the endianness of the target we're compiling for.
117 ///
118 /// The returned output holds exactly (\p FullBitWidth / 8) bytes.
119 std::unique_ptr<std::byte[]> copyBits(Bits BitOffset, Bits BitWidth,
120 Bits FullBitWidth,
121 Endian TargetEndianness) const;
122
123 /// Dereferences the value at the given offset.
124 template <typename T> T deref(Bytes Offset) const {
125 assert(Offset.getQuantity() < FinalBitSize.roundToBytes());
126 assert((Offset.getQuantity() + sizeof(T)) <= FinalBitSize.roundToBytes());
127 return *reinterpret_cast<T *>(Data.get() + Offset.getQuantity());
128 }
129};
130
131} // namespace interp
132} // namespace clang
133#endif
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
@ Other
Other implicit parameter.
Definition Decl.h:1746
bool operator<(BitRange Other) const
BitRange(Bits Start, Bits End)
std::unique_ptr< std::byte[]> copyBits(Bits BitOffset, Bits BitWidth, Bits FullBitWidth, Endian TargetEndianness) const
Copy BitWidth bits at offset BitOffset from the buffer.
T deref(Bytes Offset) const
Dereferences the value at the given offset.
void markInitialized(Bits Start, Bits Length)
Marks the bits in the given range as initialized.
llvm::SmallVector< BitRange > InitializedBits
bool allInitialized() const
Returns true if all bits in the buffer have been initialized.
BitcastBuffer(Bits FinalBitSize)
bool rangeInitialized(Bits Offset, Bits Length) const
std::byte * atByte(unsigned Offset)
Returns the byte at the given offset.
Bits size() const
Returns the buffer size in bits.
void pushData(const std::byte *In, Bits BitOffset, Bits BitWidth, Endian TargetEndianness)
Push BitWidth bits at BitOffset from In into the buffer.
std::unique_ptr< std::byte[]> Data
A quantity in bits.
bool operator!=(Bits Other) const
bool nonZero() const
Bytes toBytes() const
bool operator==(Bits Other) const
bool isZero() const
size_t roundToBytes() const
Bits operator+=(size_t O)
bool operator<=(Bits Other) const
bool isFullByte() const
static Bits zero()
Bits(size_t Quantity)
Bits operator-(Bits Other) const
Bits operator+(Bits Other) const
size_t getOffsetInByte() const
Bits operator+=(Bits O)
bool operator>=(Bits Other) const
size_t getQuantity() const
A quantity in bytes.
size_t getQuantity() const
Bytes(size_t Quantity)