Path: blob/main/contrib/llvm-project/clang/lib/AST/ByteCode/BitcastBuffer.h
213799 views
//===--------------------- BitcastBuffer.h ----------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7#ifndef LLVM_CLANG_AST_INTERP_BITCAST_BUFFER_H8#define LLVM_CLANG_AST_INTERP_BITCAST_BUFFER_H910#include "llvm/ADT/SmallVector.h"11#include <cassert>12#include <cstddef>13#include <memory>1415namespace clang {16namespace interp {1718enum class Endian { Little, Big };1920struct Bytes;2122/// A quantity in bits.23struct Bits {24size_t N = 0;25Bits() = default;26static Bits zero() { return Bits(0); }27explicit Bits(size_t Quantity) : N(Quantity) {}28size_t getQuantity() const { return N; }29size_t roundToBytes() const { return N / 8; }30size_t getOffsetInByte() const { return N % 8; }31bool isFullByte() const { return N % 8 == 0; }32bool nonZero() const { return N != 0; }33bool isZero() const { return N == 0; }34Bytes toBytes() const;3536Bits operator-(Bits Other) const { return Bits(N - Other.N); }37Bits operator+(Bits Other) const { return Bits(N + Other.N); }38Bits operator+=(size_t O) {39N += O;40return *this;41}42Bits operator+=(Bits O) {43N += O.N;44return *this;45}4647bool operator>=(Bits Other) const { return N >= Other.N; }48bool operator<=(Bits Other) const { return N <= Other.N; }49bool operator==(Bits Other) const { return N == Other.N; }50bool operator!=(Bits Other) const { return N != Other.N; }51};5253/// A quantity in bytes.54struct Bytes {55size_t N;56explicit Bytes(size_t Quantity) : N(Quantity) {}57size_t getQuantity() const { return N; }58Bits toBits() const { return Bits(N * 8); }59};6061inline Bytes Bits::toBytes() const {62assert(isFullByte());63return Bytes(N / 8);64}6566/// A bit range. Both Start and End are inclusive.67struct BitRange {68Bits Start;69Bits End;7071BitRange(Bits Start, Bits End) : Start(Start), End(End) {}72Bits size() const { return End - Start + Bits(1); }73bool operator<(BitRange Other) const { return Start.N < Other.Start.N; }7475bool contains(Bits B) { return Start <= B && End >= B; }76};7778/// Track what bits have been initialized to known values and which ones79/// have indeterminate value.80struct BitcastBuffer {81Bits FinalBitSize;82std::unique_ptr<std::byte[]> Data;83llvm::SmallVector<BitRange> InitializedBits;8485BitcastBuffer(Bits FinalBitSize) : FinalBitSize(FinalBitSize) {86assert(FinalBitSize.isFullByte());87unsigned ByteSize = FinalBitSize.roundToBytes();88Data = std::make_unique<std::byte[]>(ByteSize);89}9091/// Returns the buffer size in bits.92Bits size() const { return FinalBitSize; }93Bytes byteSize() const { return FinalBitSize.toBytes(); }9495/// Returns \c true if all bits in the buffer have been initialized.96bool allInitialized() const;97/// Marks the bits in the given range as initialized.98/// FIXME: Can we do this automatically in pushData()?99void markInitialized(Bits Start, Bits Length);100bool rangeInitialized(Bits Offset, Bits Length) const;101102/// Push \p BitWidth bits at \p BitOffset from \p In into the buffer.103/// \p TargetEndianness is the endianness of the target we're compiling for.104/// \p In must hold at least \p BitWidth many bits.105void pushData(const std::byte *In, Bits BitOffset, Bits BitWidth,106Endian TargetEndianness);107108/// Copy \p BitWidth bits at offset \p BitOffset from the buffer.109/// \p TargetEndianness is the endianness of the target we're compiling for.110///111/// The returned output holds exactly (\p FullBitWidth / 8) bytes.112std::unique_ptr<std::byte[]> copyBits(Bits BitOffset, Bits BitWidth,113Bits FullBitWidth,114Endian TargetEndianness) const;115};116117} // namespace interp118} // namespace clang119#endif120121122