xref: /openbsd-src/gnu/llvm/clang/lib/AST/Interp/PrimType.h (revision 12c855180aad702bbcca06e0398d774beeafb155)
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 "Integral.h"
17 #include <climits>
18 #include <cstddef>
19 #include <cstdint>
20 
21 namespace clang {
22 namespace interp {
23 
24 class Pointer;
25 class Boolean;
26 
27 /// Enumeration of the primitive types of the VM.
28 enum PrimType : unsigned {
29   PT_Sint8,
30   PT_Uint8,
31   PT_Sint16,
32   PT_Uint16,
33   PT_Sint32,
34   PT_Uint32,
35   PT_Sint64,
36   PT_Uint64,
37   PT_Bool,
38   PT_Ptr,
39 };
40 
41 /// Mapping from primitive types to their representation.
42 template <PrimType T> struct PrimConv;
43 template <> struct PrimConv<PT_Sint8> { using T = Integral<8, true>; };
44 template <> struct PrimConv<PT_Uint8> { using T = Integral<8, false>; };
45 template <> struct PrimConv<PT_Sint16> { using T = Integral<16, true>; };
46 template <> struct PrimConv<PT_Uint16> { using T = Integral<16, false>; };
47 template <> struct PrimConv<PT_Sint32> { using T = Integral<32, true>; };
48 template <> struct PrimConv<PT_Uint32> { using T = Integral<32, false>; };
49 template <> struct PrimConv<PT_Sint64> { using T = Integral<64, true>; };
50 template <> struct PrimConv<PT_Uint64> { using T = Integral<64, false>; };
51 template <> struct PrimConv<PT_Bool> { using T = Boolean; };
52 template <> struct PrimConv<PT_Ptr> { using T = Pointer; };
53 
54 /// Returns the size of a primitive type in bytes.
55 size_t primSize(PrimType Type);
56 
57 /// Aligns a size to the pointer alignment.
58 constexpr size_t align(size_t Size) {
59   return ((Size + alignof(void *) - 1) / alignof(void *)) * alignof(void *);
60 }
61 
62 constexpr bool aligned(uintptr_t Value) { return Value == align(Value); }
63 static_assert(aligned(sizeof(void *)));
64 
65 static inline bool aligned(const void *P) {
66   return aligned(reinterpret_cast<uintptr_t>(P));
67 }
68 
69 inline bool isPrimitiveIntegral(PrimType Type) {
70   switch (Type) {
71   case PT_Bool:
72   case PT_Sint8:
73   case PT_Uint8:
74   case PT_Sint16:
75   case PT_Uint16:
76   case PT_Sint32:
77   case PT_Uint32:
78   case PT_Sint64:
79   case PT_Uint64:
80     return true;
81   default:
82     return false;
83   }
84 }
85 
86 } // namespace interp
87 } // namespace clang
88 
89 /// Helper macro to simplify type switches.
90 /// The macro implicitly exposes a type T in the scope of the inner block.
91 #define TYPE_SWITCH_CASE(Name, B) \
92   case Name: { using T = PrimConv<Name>::T; B; break; }
93 #define TYPE_SWITCH(Expr, B)                                                   \
94   do {                                                                         \
95     switch (Expr) {                                                            \
96       TYPE_SWITCH_CASE(PT_Sint8, B)                                            \
97       TYPE_SWITCH_CASE(PT_Uint8, B)                                            \
98       TYPE_SWITCH_CASE(PT_Sint16, B)                                           \
99       TYPE_SWITCH_CASE(PT_Uint16, B)                                           \
100       TYPE_SWITCH_CASE(PT_Sint32, B)                                           \
101       TYPE_SWITCH_CASE(PT_Uint32, B)                                           \
102       TYPE_SWITCH_CASE(PT_Sint64, B)                                           \
103       TYPE_SWITCH_CASE(PT_Uint64, B)                                           \
104       TYPE_SWITCH_CASE(PT_Bool, B)                                             \
105       TYPE_SWITCH_CASE(PT_Ptr, B)                                              \
106     }                                                                          \
107   } while (0)
108 #define COMPOSITE_TYPE_SWITCH(Expr, B, D)                                      \
109   do {                                                                         \
110     switch (Expr) {                                                            \
111       TYPE_SWITCH_CASE(PT_Ptr, B)                                              \
112       default: { D; break; }                                                   \
113     }                                                                          \
114   } while (0)
115 #endif
116