clang 23.0.0git
Char.h
Go to the documentation of this file.
1//===------- Char.h - Wrapper for numeric types for the VM ------*- 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#ifndef LLVM_CLANG_AST_INTERP_CHAR_H
10#define LLVM_CLANG_AST_INTERP_CHAR_H
11
12#include "Integral.h"
13#include <limits>
14
15namespace clang {
16namespace interp {
17
18template <unsigned N, bool Signed> class Integral;
19
20template <bool Signed> struct CharRepr;
21template <> struct CharRepr<false> {
22 using Type = uint8_t;
23};
24template <> struct CharRepr<true> {
25 using Type = int8_t;
26};
27
28template <bool Signed> class Char final {
29private:
30 template <bool OtherSigned> friend class Char;
31 using ReprT = typename CharRepr<Signed>::Type;
32 ReprT V = 0;
33 static_assert(std::is_trivially_copyable_v<ReprT>);
34
35public:
37
38 constexpr Char() = default;
39 constexpr Char(ReprT V) : V(V) {}
40 // constexpr Char(const Char &C) : V(C.V) {}
41 explicit Char(const APSInt &V)
42 : V(V.isSigned() ? V.getSExtValue() : V.getZExtValue()) {}
43
44 template <typename T> static Char from(T t) {
45 return Char(static_cast<ReprT>(t));
46 }
47 template <typename T> static Char from(T t, unsigned BitWidth) {
48 return Char(static_cast<ReprT>(t));
49 }
50
51 static bool isSigned() { return Signed; }
52 static unsigned bitWidth() { return 8; }
53 static bool isNumber() { return true; }
54 static Char zero(unsigned BitWidth = 8) { return Char(0); }
55
56 constexpr bool isMin() const {
57 return V == std::numeric_limits<ReprT>::min();
58 }
59 constexpr bool isNegative() const { return Signed && V < 0; }
60 constexpr bool isPositive() const { return !isNegative(); }
61 constexpr bool isZero() const { return V == 0; }
62 constexpr bool isMinusOne() const { return Signed && V == -1; }
63
64 template <typename Ty, typename = std::enable_if_t<std::is_integral_v<Ty>>>
65 explicit operator Ty() const {
66 return V;
67 }
68
69 bool operator<(Char RHS) const { return V < RHS.V; }
70 bool operator>(Char RHS) const { return V > RHS.V; }
71 bool operator<=(Char RHS) const { return V <= RHS.V; }
72 bool operator>=(Char RHS) const { return V >= RHS.V; }
73 bool operator==(Char RHS) const { return V == RHS.V; }
74 bool operator!=(Char RHS) const { return V != RHS.V; }
75 bool operator>=(unsigned RHS) const {
76 return static_cast<unsigned>(V) >= RHS;
77 }
78
79 bool operator>(unsigned RHS) const {
80 return V >= 0 && static_cast<unsigned>(V) > RHS;
81 }
82
83 Char operator-() const { return Char(-V); }
84 Char operator-(Char Other) const { return Char(V - Other.V); }
85
86 ComparisonCategoryResult compare(Char RHS) const { return Compare(V, RHS.V); }
87
88 void bitcastToMemory(std::byte *Dest) const {
89 std::memcpy(Dest, &V, sizeof(V));
90 }
91
92 static Char bitcastFromMemory(const std::byte *Src, unsigned BitWidth) {
93 assert(BitWidth == 8);
94 ReprT V;
95
96 std::memcpy(&V, Src, sizeof(ReprT));
97 return Char(V);
98 }
99
100 APSInt toAPSInt() const {
101 return APSInt(APInt(8, static_cast<uint64_t>(V), Signed), !Signed);
102 }
103 APSInt toAPSInt(unsigned BitWidth) const {
104 return APSInt(toAPInt(BitWidth), !Signed);
105 }
106 APInt toAPInt(unsigned BitWidth) const {
107 if constexpr (Signed)
108 return APInt(8, static_cast<uint64_t>(V), Signed).sextOrTrunc(BitWidth);
109 else
110 return APInt(8, static_cast<uint64_t>(V), Signed).zextOrTrunc(BitWidth);
111 }
112 APValue toAPValue(const ASTContext &) const { return APValue(toAPSInt()); }
113 std::string toDiagnosticString(const ASTContext &Ctx) const {
114 std::string NameStr;
115 llvm::raw_string_ostream OS(NameStr);
116 OS << V;
117 return NameStr;
118 }
119 Char<false> toUnsigned() const { return Char<false>(V); }
120
121 Char truncate(unsigned TruncBits) const {
122 assert(TruncBits >= 1);
123 if (TruncBits >= 8)
124 return *this;
125 const ReprT BitMask = (ReprT(1) << ReprT(TruncBits)) - 1;
126 const ReprT SignBit = ReprT(1) << (TruncBits - 1);
127 const ReprT ExtMask = ~BitMask;
128 return Char((V & BitMask) | (Signed && (V & SignBit) ? ExtMask : 0));
129 }
130
131 unsigned countLeadingZeros() const {
132 if constexpr (!Signed)
133 return llvm::countl_zero<ReprT>(V);
134 if (isPositive())
135 return llvm::countl_zero<typename AsUnsigned::ReprT>(
136 static_cast<typename AsUnsigned::ReprT>(V));
137 llvm_unreachable("Don't call countLeadingZeros() on negative values.");
138 }
139
140 static bool increment(Char A, Char *R) {
141 return add(A, Char(ReprT(1)), A.bitWidth(), R);
142 }
143
144 static bool decrement(Char A, Char *R) {
145 return sub(A, Char(ReprT(1)), A.bitWidth(), R);
146 }
147
148 static bool add(Char A, Char B, unsigned OpBits, Char *R) {
149 return CheckAddUB(A.V, B.V, R->V);
150 }
151
152 static bool sub(Char A, Char B, unsigned OpBits, Char *R) {
153 return CheckSubUB(A.V, B.V, R->V);
154 }
155
156 static bool mul(Char A, Char B, unsigned OpBits, Char *R) {
157 return CheckMulUB(A.V, B.V, R->V);
158 }
159
160 static bool rem(Char A, Char B, unsigned OpBits, Char *R) {
161 *R = Char(A.V % B.V);
162 return false;
163 }
164
165 static bool div(Char A, Char B, unsigned OpBits, Char *R) {
166 *R = Char(A.V / B.V);
167 return false;
168 }
169
170 static bool bitAnd(Char A, Char B, unsigned OpBits, Char *R) {
171 *R = Char(A.V & B.V);
172 return false;
173 }
174
175 static bool bitOr(Char A, Char B, unsigned OpBits, Char *R) {
176 *R = Char(A.V | B.V);
177 return false;
178 }
179
180 static bool bitXor(Char A, Char B, unsigned OpBits, Char *R) {
181 *R = Char(A.V ^ B.V);
182 return false;
183 }
184
185 static bool neg(Char A, Char *R) {
186 if (Signed && A.isMin())
187 return true;
188
189 *R = Char(-A.V);
190 return false;
191 }
192
193 static bool comp(Char A, Char *R) {
194 *R = Char(~A.V);
195 return false;
196 }
197
198 template <bool RHSSign>
199 static void shiftLeft(const Char A, const Char<RHSSign> B, unsigned OpBits,
200 Char *R) {
201 *R = Char(A.V << B.V);
202 }
203
204 template <bool RHSSign>
205 static void shiftRight(const Char A, const Char<RHSSign> B, unsigned OpBits,
206 Char *R) {
207 *R = Char(A.V >> B.V);
208 }
209
210 void print(llvm::raw_ostream &OS) const { OS << V; }
211};
212
213static_assert(sizeof(Char<true>) == 1);
214static_assert(sizeof(Char<false>) == 1);
215
216template <bool Signed>
217llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Char<Signed> I) {
218 I.print(OS);
219 return OS;
220}
221
222} // namespace interp
223} // namespace clang
224
225#endif
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition APValue.h:122
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:226
static bool bitAnd(Char A, Char B, unsigned OpBits, Char *R)
Definition Char.h:170
static bool neg(Char A, Char *R)
Definition Char.h:185
constexpr bool isZero() const
Definition Char.h:61
Char truncate(unsigned TruncBits) const
Definition Char.h:121
void bitcastToMemory(std::byte *Dest) const
Definition Char.h:88
constexpr Char()=default
constexpr bool isPositive() const
Definition Char.h:60
ComparisonCategoryResult compare(Char RHS) const
Definition Char.h:86
bool operator>=(unsigned RHS) const
Definition Char.h:75
static bool decrement(Char A, Char *R)
Definition Char.h:144
static bool rem(Char A, Char B, unsigned OpBits, Char *R)
Definition Char.h:160
APSInt toAPSInt() const
Definition Char.h:100
static bool sub(Char A, Char B, unsigned OpBits, Char *R)
Definition Char.h:152
APValue toAPValue(const ASTContext &) const
Definition Char.h:112
static Char zero(unsigned BitWidth=8)
Definition Char.h:54
static bool bitOr(Char A, Char B, unsigned OpBits, Char *R)
Definition Char.h:175
bool operator<(Char RHS) const
Definition Char.h:69
static bool isSigned()
Definition Char.h:51
static unsigned bitWidth()
Definition Char.h:52
bool operator>=(Char RHS) const
Definition Char.h:72
static bool bitXor(Char A, Char B, unsigned OpBits, Char *R)
Definition Char.h:180
static bool mul(Char A, Char B, unsigned OpBits, Char *R)
Definition Char.h:156
static Char from(T t)
Definition Char.h:44
bool operator!=(Char RHS) const
Definition Char.h:74
Char(const APSInt &V)
Definition Char.h:41
std::string toDiagnosticString(const ASTContext &Ctx) const
Definition Char.h:113
static void shiftRight(const Char A, const Char< RHSSign > B, unsigned OpBits, Char *R)
Definition Char.h:205
unsigned countLeadingZeros() const
Definition Char.h:131
static bool div(Char A, Char B, unsigned OpBits, Char *R)
Definition Char.h:165
static bool isNumber()
Definition Char.h:53
static bool add(Char A, Char B, unsigned OpBits, Char *R)
Definition Char.h:148
Char< false > AsUnsigned
Definition Char.h:36
Char operator-(Char Other) const
Definition Char.h:84
static Char bitcastFromMemory(const std::byte *Src, unsigned BitWidth)
Definition Char.h:92
static void shiftLeft(const Char A, const Char< RHSSign > B, unsigned OpBits, Char *R)
Definition Char.h:199
constexpr bool isNegative() const
Definition Char.h:59
bool operator>(Char RHS) const
Definition Char.h:70
bool operator>(unsigned RHS) const
Definition Char.h:79
Char< false > toUnsigned() const
Definition Char.h:119
APSInt toAPSInt(unsigned BitWidth) const
Definition Char.h:103
static Char from(T t, unsigned BitWidth)
Definition Char.h:47
constexpr bool isMin() const
Definition Char.h:56
bool operator<=(Char RHS) const
Definition Char.h:71
bool operator==(Char RHS) const
Definition Char.h:73
static bool increment(Char A, Char *R)
Definition Char.h:140
friend class Char
Definition Char.h:30
Char operator-() const
Definition Char.h:83
constexpr Char(ReprT V)
Definition Char.h:39
void print(llvm::raw_ostream &OS) const
Definition Char.h:210
APInt toAPInt(unsigned BitWidth) const
Definition Char.h:106
constexpr bool isMinusOne() const
Definition Char.h:62
static bool comp(Char A, Char *R)
Definition Char.h:193
Wrapper around numeric types.
Definition Integral.h:69
bool CheckMulUB(T A, T B, T &R)
Definition Primitives.h:64
llvm::APInt APInt
Definition FixedPoint.h:19
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const Boolean &B)
Definition Boolean.h:153
ComparisonCategoryResult Compare(const T &X, const T &Y)
Helper to compare two comparable types.
Definition Primitives.h:38
bool CheckSubUB(T A, T B, T &R)
Definition Primitives.h:55
bool CheckAddUB(T A, T B, T &R)
Definition Primitives.h:46
llvm::APSInt APSInt
Definition FixedPoint.h:20
The JSON file list parser is used to communicate input to InstallAPI.
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
@ Other
Other implicit parameter.
Definition Decl.h:1761
#define false
Definition stdbool.h:26
#define true
Definition stdbool.h:25