clang 22.0.0git
PrimType.h
Go to the documentation of this file.
1//===--- PrimType.h - Types for the constexpr 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// Defines the VM types and helpers operating on types.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_AST_INTERP_TYPE_H
14#define LLVM_CLANG_AST_INTERP_TYPE_H
15
16#include "llvm/Support/raw_ostream.h"
17#include <climits>
18#include <cstddef>
19#include <cstdint>
20
21namespace clang {
22namespace interp {
23
24class Pointer;
25class Boolean;
26class Floating;
27class FunctionPointer;
28class MemberPointer;
29class FixedPoint;
30template <bool Signed> class IntegralAP;
31template <unsigned Bits, bool Signed> class Integral;
32
33/// Enumeration of the primitive types of the VM.
34enum PrimType : uint8_t {
45 PT_Bool = 10,
48 PT_Ptr = 13,
50};
51
52// Like std::optional<PrimType>, but only sizeof(PrimType).
53class OptPrimType final {
54 static constexpr uint8_t None = 0xFF;
55 uint8_t V = None;
56
57public:
58 OptPrimType() = default;
59 OptPrimType(std::nullopt_t) {}
60 OptPrimType(PrimType T) : V(static_cast<unsigned>(T)) {}
61
62 explicit constexpr operator bool() const { return V != None; }
64 assert(operator bool());
65 return static_cast<PrimType>(V);
66 }
67
69 if (operator bool())
70 return static_cast<PrimType>(V);
71 return PT;
72 }
73
74 bool operator==(PrimType PT) const {
75 if (!operator bool())
76 return false;
77 return V == static_cast<unsigned>(PT);
78 }
79 bool operator==(OptPrimType OPT) const { return V == OPT.V; }
80 bool operator!=(PrimType PT) const { return !(*this == PT); }
81 bool operator!=(OptPrimType OPT) const { return V != OPT.V; }
82};
83static_assert(sizeof(OptPrimType) == sizeof(PrimType));
84
85inline constexpr bool isPtrType(PrimType T) {
86 return T == PT_Ptr || T == PT_MemberPtr;
87}
88
89inline constexpr bool isSignedType(PrimType T) {
90 switch (T) {
91 case PT_Sint8:
92 case PT_Sint16:
93 case PT_Sint32:
94 case PT_Sint64:
95 return true;
96 default:
97 return false;
98 }
99 return false;
100}
101
102enum class CastKind : uint8_t {
104 Volatile,
105 Dynamic,
106};
107
108inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
109 interp::CastKind CK) {
110 switch (CK) {
112 OS << "reinterpret_cast";
113 break;
115 OS << "volatile";
116 break;
118 OS << "dynamic";
119 break;
120 }
121 return OS;
122}
123
124constexpr bool isIntegralType(PrimType T) { return T <= PT_FixedPoint; }
125template <typename T> constexpr bool needsAlloc() {
126 return std::is_same_v<T, IntegralAP<false>> ||
127 std::is_same_v<T, IntegralAP<true>> || std::is_same_v<T, Floating>;
128}
129constexpr bool needsAlloc(PrimType T) {
130 return T == PT_IntAP || T == PT_IntAPS || T == PT_Float;
131}
132
133/// Mapping from primitive types to their representation.
134template <PrimType T> struct PrimConv;
135template <> struct PrimConv<PT_Sint8> {
137};
138template <> struct PrimConv<PT_Uint8> {
140};
141template <> struct PrimConv<PT_Sint16> {
143};
144template <> struct PrimConv<PT_Uint16> {
146};
147template <> struct PrimConv<PT_Sint32> {
149};
150template <> struct PrimConv<PT_Uint32> {
152};
153template <> struct PrimConv<PT_Sint64> {
155};
156template <> struct PrimConv<PT_Uint64> {
158};
159template <> struct PrimConv<PT_IntAP> {
161};
162template <> struct PrimConv<PT_IntAPS> {
164};
165template <> struct PrimConv<PT_Float> {
166 using T = Floating;
167};
168template <> struct PrimConv<PT_Bool> {
169 using T = Boolean;
170};
171template <> struct PrimConv<PT_Ptr> {
172 using T = Pointer;
173};
174template <> struct PrimConv<PT_MemberPtr> {
176};
177template <> struct PrimConv<PT_FixedPoint> {
178 using T = FixedPoint;
179};
180
181/// Returns the size of a primitive type in bytes.
182size_t primSize(PrimType Type);
183
184/// Aligns a size to the pointer alignment.
185constexpr size_t align(size_t Size) {
186 return ((Size + alignof(void *) - 1) / alignof(void *)) * alignof(void *);
187}
188
189constexpr bool aligned(uintptr_t Value) { return Value == align(Value); }
190static_assert(aligned(sizeof(void *)));
191
192static inline bool aligned(const void *P) {
193 return aligned(reinterpret_cast<uintptr_t>(P));
194}
195
196} // namespace interp
197} // namespace clang
198
199/// Helper macro to simplify type switches.
200/// The macro implicitly exposes a type T in the scope of the inner block.
201#define TYPE_SWITCH_CASE(Name, B) \
202 case Name: { \
203 using T = PrimConv<Name>::T; \
204 B; \
205 break; \
206 }
207#define TYPE_SWITCH(Expr, B) \
208 do { \
209 switch (Expr) { \
210 TYPE_SWITCH_CASE(PT_Sint8, B) \
211 TYPE_SWITCH_CASE(PT_Uint8, B) \
212 TYPE_SWITCH_CASE(PT_Sint16, B) \
213 TYPE_SWITCH_CASE(PT_Uint16, B) \
214 TYPE_SWITCH_CASE(PT_Sint32, B) \
215 TYPE_SWITCH_CASE(PT_Uint32, B) \
216 TYPE_SWITCH_CASE(PT_Sint64, B) \
217 TYPE_SWITCH_CASE(PT_Uint64, B) \
218 TYPE_SWITCH_CASE(PT_IntAP, B) \
219 TYPE_SWITCH_CASE(PT_IntAPS, B) \
220 TYPE_SWITCH_CASE(PT_Float, B) \
221 TYPE_SWITCH_CASE(PT_Bool, B) \
222 TYPE_SWITCH_CASE(PT_Ptr, B) \
223 TYPE_SWITCH_CASE(PT_MemberPtr, B) \
224 TYPE_SWITCH_CASE(PT_FixedPoint, B) \
225 } \
226 } while (0)
227
228#define INT_TYPE_SWITCH(Expr, B) \
229 do { \
230 switch (Expr) { \
231 TYPE_SWITCH_CASE(PT_Sint8, B) \
232 TYPE_SWITCH_CASE(PT_Uint8, B) \
233 TYPE_SWITCH_CASE(PT_Sint16, B) \
234 TYPE_SWITCH_CASE(PT_Uint16, B) \
235 TYPE_SWITCH_CASE(PT_Sint32, B) \
236 TYPE_SWITCH_CASE(PT_Uint32, B) \
237 TYPE_SWITCH_CASE(PT_Sint64, B) \
238 TYPE_SWITCH_CASE(PT_Uint64, B) \
239 TYPE_SWITCH_CASE(PT_IntAP, B) \
240 TYPE_SWITCH_CASE(PT_IntAPS, B) \
241 TYPE_SWITCH_CASE(PT_Bool, B) \
242 default: \
243 llvm_unreachable("Not an integer value"); \
244 } \
245 } while (0)
246
247#define INT_TYPE_SWITCH_NO_BOOL(Expr, B) \
248 do { \
249 switch (Expr) { \
250 TYPE_SWITCH_CASE(PT_Sint8, B) \
251 TYPE_SWITCH_CASE(PT_Uint8, B) \
252 TYPE_SWITCH_CASE(PT_Sint16, B) \
253 TYPE_SWITCH_CASE(PT_Uint16, B) \
254 TYPE_SWITCH_CASE(PT_Sint32, B) \
255 TYPE_SWITCH_CASE(PT_Uint32, B) \
256 TYPE_SWITCH_CASE(PT_Sint64, B) \
257 TYPE_SWITCH_CASE(PT_Uint64, B) \
258 TYPE_SWITCH_CASE(PT_IntAP, B) \
259 TYPE_SWITCH_CASE(PT_IntAPS, B) \
260 default: \
261 llvm_unreachable("Not an integer value"); \
262 } \
263 } while (0)
264
265#define TYPE_SWITCH_ALLOC(Expr, B) \
266 do { \
267 switch (Expr) { \
268 TYPE_SWITCH_CASE(PT_Float, B) \
269 TYPE_SWITCH_CASE(PT_IntAP, B) \
270 TYPE_SWITCH_CASE(PT_IntAPS, B) \
271 default:; \
272 } \
273 } while (0)
274
275#endif
#define V(N, I)
Definition: ASTContext.h:3597
StringRef P
The base class of the type hierarchy.
Definition: TypeBase.h:1833
Wrapper around boolean types.
Definition: Boolean.h:25
Wrapper around fixed point types.
Definition: FixedPoint.h:23
If a Floating is constructed from Memory, it DOES NOT OWN THAT MEMORY.
Definition: Floating.h:35
If an IntegralAP is constructed from Memory, it DOES NOT OWN THAT MEMORY.
Definition: IntegralAP.h:36
Wrapper around numeric types.
Definition: Integral.h:66
OptPrimType(std::nullopt_t)
Definition: PrimType.h:59
bool operator!=(PrimType PT) const
Definition: PrimType.h:80
PrimType operator*() const
Definition: PrimType.h:63
bool operator==(OptPrimType OPT) const
Definition: PrimType.h:79
bool operator!=(OptPrimType OPT) const
Definition: PrimType.h:81
PrimType value_or(PrimType PT) const
Definition: PrimType.h:68
OptPrimType(PrimType T)
Definition: PrimType.h:60
bool operator==(PrimType PT) const
Definition: PrimType.h:74
A pointer to a memory block, live or dead.
Definition: Pointer.h:90
#define bool
Definition: gpuintrin.h:32
constexpr bool isSignedType(PrimType T)
Definition: PrimType.h:89
constexpr bool aligned(uintptr_t Value)
Definition: PrimType.h:189
constexpr bool isPtrType(PrimType T)
Definition: PrimType.h:85
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
Definition: PrimType.h:185
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const Boolean &B)
Definition: Boolean.h:154
PrimType
Enumeration of the primitive types of the VM.
Definition: PrimType.h:34
constexpr bool needsAlloc()
Definition: PrimType.h:125
size_t primSize(PrimType Type)
Returns the size of a primitive type in bytes.
Definition: PrimType.cpp:23
constexpr bool isIntegralType(PrimType T)
Definition: PrimType.h:124
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
Mapping from primitive types to their representation.
Definition: PrimType.h:134