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