GCC Code Coverage Report


Directory: ./
File: openvdb_ax/openvdb_ax/codegen/Types.h
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 27 28 96.4%
Functions: 55 55 100.0%
Branches: 144 319 45.1%

Line Branch Exec Source
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
4 /// @file codegen/Types.h
5 ///
6 /// @authors Nick Avramoussis
7 ///
8 /// @brief Consolidated llvm types for most supported types
9 ///
10
11 #ifndef OPENVDB_AX_CODEGEN_TYPES_HAS_BEEN_INCLUDED
12 #define OPENVDB_AX_CODEGEN_TYPES_HAS_BEEN_INCLUDED
13
14 #include "openvdb_ax/ast/Tokens.h"
15 #include "openvdb_ax/Exceptions.h"
16 #include "String.h"
17
18 #include <openvdb/version.h>
19 #include <openvdb/Types.h>
20 #include <openvdb/math/Mat3.h>
21 #include <openvdb/math/Mat4.h>
22 #include <openvdb/math/Vec3.h>
23
24 #include <llvm/IR/Constants.h>
25 #include <llvm/IR/IRBuilder.h>
26 #include <llvm/IR/LLVMContext.h>
27
28 #include <type_traits>
29
30 namespace openvdb {
31 OPENVDB_USE_VERSION_NAMESPACE
32 namespace OPENVDB_VERSION_NAME {
33
34 namespace ax {
35 namespace codegen {
36
37 template <size_t Bits> struct int_t;
38 template <> struct int_t<8> { using type = int8_t; };
39 template <> struct int_t<16> { using type = int16_t; };
40 template <> struct int_t<32> { using type = int32_t; };
41 template <> struct int_t<64> { using type = int64_t; };
42
43 /// @brief LLVM type mapping from pod types
44 /// @note LLVM Types do not store information about the value sign, only meta
45 /// information about the primitive type (i.e. float, int, pointer) and
46 /// the precision width. LLVMType<uint64_t>::get(C) will provide the same
47 /// type as LLVMType<int64_t>::get(C), however sign is taken into account
48 /// during construction of LLVM constants.
49 /// @note LLVMType classes are importantly used to provided automatic external
50 /// function mapping. Note that references are not supported, pointers
51 /// should be used instead.
52 /// @note Provide your own custom class mapping by specializing the below.
53 template <typename T>
54 struct LLVMType
55 {
56 static_assert(!std::is_reference<T>::value,
57 "Reference types/arguments are not supported for automatic "
58 "LLVM Type conversion. Use pointers instead.");
59 static_assert(!std::is_class<T>::value,
60 "Object types/arguments are not supported for automatic "
61 "LLVM Type conversion.");
62
63 /// @brief Return an LLVM type which represents T
64 /// @param C The LLVMContext to request the Type from.
65 static inline llvm::Type*
66 get(llvm::LLVMContext& C)
67 {
68 // @note bools always treated as i1 values as the constants
69 // true and false from the IRBuilder are i1
70 if (std::is_same<T, bool>::value) {
71
4/8
✓ Branch 1 taken 209 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 16 times.
✗ Branch 11 not taken.
126733 return llvm::Type::getInt1Ty(C);
72 }
73
74 #if LLVM_VERSION_MAJOR > 6
75 return llvm::Type::getScalarTy<T>(C);
76 #else
77 int bits = sizeof(T) * CHAR_BIT;
78 if (std::is_integral<T>::value) {
79 return llvm::Type::getIntNTy(C, bits);
80 }
81 else if (std::is_floating_point<T>::value) {
82 switch (bits) {
83 case 16: return llvm::Type::getHalfTy(C);
84 case 32: return llvm::Type::getFloatTy(C);
85 case 64: return llvm::Type::getDoubleTy(C);
86 }
87 }
88 OPENVDB_THROW(AXCodeGenError, "LLVMType called with an unsupported type \"" +
89 std::string(typeNameAsString<T>()) + "\".");
90 #endif
91 }
92
93 /// @brief Return an LLVM constant Value which represents T value
94 /// @param C The LLVMContext
95 /// @param V The value to convert to an LLVM constant
96 /// @return If successful, returns a pointer to an LLVM constant which
97 /// holds the value T.
98 static inline llvm::Constant*
99 105849 get(llvm::LLVMContext& C, const T V)
100 {
101 llvm::Type* type = LLVMType<T>::get(C);
102 llvm::Constant* constant = nullptr;
103
104 if (std::is_floating_point<T>::value) {
105
2/4
✓ Branch 2 taken 29281 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 29281 times.
58562 assert(llvm::ConstantFP::isValueValidForType(type,
106 llvm::APFloat(static_cast<typename std::conditional
107 <std::is_floating_point<T>::value, T, double>::type>(V))));
108 58562 constant = llvm::ConstantFP::get(type, static_cast<double>(V));
109 }
110 else if (std::is_integral<T>::value) {
111 const constexpr bool isSigned = std::is_signed<T>::value;
112
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 30604 times.
47287 assert((isSigned && llvm::ConstantInt::isValueValidForType(type, static_cast<int64_t>(V))) ||
113 (!isSigned && llvm::ConstantInt::isValueValidForType(type, static_cast<uint64_t>(V))));
114 47287 constant = llvm::ConstantInt::get(type, static_cast<uint64_t>(V), isSigned);
115 }
116
117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59885 times.
105849 assert(constant);
118 105849 return constant;
119 }
120
121 /// @brief Return an LLVM constant which holds an uintptr_t, representing
122 /// the current address of the given value.
123 /// @param C The LLVMContext
124 /// @param V The address of a given type to convert to an LLVM constant
125 static inline llvm::Constant*
126 get(llvm::LLVMContext& C, const T* const V)
127 {
128 21 return LLVMType<uintptr_t>::get(C,
129 reinterpret_cast<uintptr_t>(V));
130 }
131 };
132
133 template <typename T, size_t S>
134 struct LLVMType<T[S]>
135 {
136 static_assert(S != 0,
137 "Zero size array types are not supported for automatic LLVM "
138 "Type conversion");
139
140 static inline llvm::Type*
141 1227527 get(llvm::LLVMContext& C) {
142
75/171
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✓ Branch 11 taken 2 times.
✓ Branch 12 taken 85 times.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 84 times.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 12 times.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 12 times.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 20 times.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 20 times.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 20 times.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 20 times.
✓ Branch 34 taken 1 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 148 times.
✓ Branch 37 taken 1 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 8 times.
✗ Branch 40 not taken.
✓ Branch 42 taken 4 times.
✗ Branch 43 not taken.
✓ Branch 45 taken 8 times.
✗ Branch 46 not taken.
✓ Branch 48 taken 8 times.
✗ Branch 49 not taken.
✓ Branch 51 taken 16 times.
✗ Branch 52 not taken.
✓ Branch 54 taken 4 times.
✗ Branch 55 not taken.
✓ Branch 57 taken 8 times.
✗ Branch 58 not taken.
✓ Branch 60 taken 4 times.
✗ Branch 61 not taken.
✓ Branch 63 taken 4 times.
✗ Branch 64 not taken.
✓ Branch 66 taken 4 times.
✗ Branch 67 not taken.
✓ Branch 69 taken 8 times.
✗ Branch 70 not taken.
✓ Branch 72 taken 4 times.
✗ Branch 73 not taken.
✓ Branch 75 taken 8 times.
✗ Branch 76 not taken.
✓ Branch 78 taken 4 times.
✗ Branch 79 not taken.
✓ Branch 81 taken 8 times.
✗ Branch 82 not taken.
✓ Branch 84 taken 4 times.
✗ Branch 85 not taken.
✓ Branch 87 taken 8 times.
✗ Branch 88 not taken.
✓ Branch 90 taken 4 times.
✗ Branch 91 not taken.
✓ Branch 93 taken 8 times.
✗ Branch 94 not taken.
✓ Branch 96 taken 4 times.
✗ Branch 97 not taken.
✓ Branch 99 taken 8 times.
✗ Branch 100 not taken.
✓ Branch 102 taken 4 times.
✗ Branch 103 not taken.
✓ Branch 105 taken 8 times.
✗ Branch 106 not taken.
✓ Branch 108 taken 4 times.
✗ Branch 109 not taken.
✓ Branch 111 taken 8 times.
✗ Branch 112 not taken.
✓ Branch 114 taken 4 times.
✗ Branch 115 not taken.
✓ Branch 117 taken 8 times.
✗ Branch 118 not taken.
✓ Branch 120 taken 12 times.
✗ Branch 121 not taken.
✗ Branch 123 not taken.
✗ Branch 124 not taken.
✓ Branch 126 taken 12 times.
✗ Branch 127 not taken.
✗ Branch 129 not taken.
✗ Branch 130 not taken.
✓ Branch 132 taken 12 times.
✗ Branch 133 not taken.
✗ Branch 135 not taken.
✗ Branch 136 not taken.
✓ Branch 138 taken 12 times.
✗ Branch 139 not taken.
✗ Branch 141 not taken.
✗ Branch 142 not taken.
✓ Branch 144 taken 8 times.
✗ Branch 145 not taken.
✓ Branch 147 taken 16 times.
✗ Branch 148 not taken.
✗ Branch 150 not taken.
✗ Branch 151 not taken.
✗ Branch 153 not taken.
✗ Branch 154 not taken.
✓ Branch 156 taken 16 times.
✗ Branch 157 not taken.
✓ Branch 159 taken 32 times.
✗ Branch 160 not taken.
✗ Branch 162 not taken.
✗ Branch 163 not taken.
✗ Branch 165 not taken.
✗ Branch 166 not taken.
✓ Branch 168 taken 8 times.
✗ Branch 169 not taken.
✓ Branch 171 taken 16 times.
✗ Branch 172 not taken.
✗ Branch 174 not taken.
✗ Branch 175 not taken.
✗ Branch 177 not taken.
✗ Branch 178 not taken.
✓ Branch 180 taken 8 times.
✗ Branch 181 not taken.
✓ Branch 183 taken 16 times.
✗ Branch 184 not taken.
✗ Branch 186 not taken.
✗ Branch 187 not taken.
✗ Branch 189 not taken.
✗ Branch 190 not taken.
✓ Branch 192 taken 16 times.
✗ Branch 193 not taken.
✓ Branch 195 taken 32 times.
✗ Branch 196 not taken.
✗ Branch 198 not taken.
✗ Branch 199 not taken.
✗ Branch 201 not taken.
✗ Branch 202 not taken.
✓ Branch 204 taken 8 times.
✗ Branch 205 not taken.
✓ Branch 207 taken 16 times.
✗ Branch 208 not taken.
✗ Branch 210 not taken.
✗ Branch 211 not taken.
✗ Branch 213 not taken.
✗ Branch 214 not taken.
✓ Branch 216 taken 24 times.
✗ Branch 217 not taken.
✓ Branch 219 taken 40 times.
✗ Branch 220 not taken.
✓ Branch 222 taken 24 times.
✗ Branch 223 not taken.
✓ Branch 225 taken 40 times.
✗ Branch 226 not taken.
✓ Branch 228 taken 4 times.
✗ Branch 229 not taken.
✓ Branch 231 taken 8 times.
✗ Branch 232 not taken.
✓ Branch 234 taken 4 times.
✗ Branch 235 not taken.
✓ Branch 237 taken 8 times.
✗ Branch 238 not taken.
✓ Branch 240 taken 14 times.
✗ Branch 241 not taken.
1392603 return llvm::ArrayType::get(LLVMType<T>::get(C), S);
143 }
144 static inline llvm::Constant*
145 get(llvm::LLVMContext& C, const T(&array)[S]) {
146 return llvm::ConstantDataArray::get(C, array);
147 }
148 static inline llvm::Constant*
149 get(llvm::LLVMContext& C, const T(*array)[S])
150 {
151 52 return LLVMType<uintptr_t>::get(C,
152 reinterpret_cast<uintptr_t>(array));
153 }
154 };
155
156 template <typename T>
157 struct LLVMType<T*>
158 {
159 static inline llvm::PointerType*
160 2265428 get(llvm::LLVMContext& C) {
161
27/49
✓ Branch 15 taken 484 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 484 times.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 256 times.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 24 taken 256 times.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 349 times.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
✓ Branch 30 taken 349 times.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 328 times.
✓ Branch 34 taken 1 times.
✗ Branch 35 not taken.
✓ Branch 36 taken 316 times.
✓ Branch 37 taken 1 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 204 times.
✓ Branch 40 taken 1 times.
✗ Branch 41 not taken.
✓ Branch 42 taken 144 times.
✓ Branch 43 taken 1 times.
✗ Branch 44 not taken.
✓ Branch 45 taken 24 times.
✓ Branch 46 taken 1 times.
✗ Branch 47 not taken.
✓ Branch 48 taken 24 times.
✓ Branch 49 taken 1 times.
✗ Branch 50 not taken.
✗ Branch 51 not taken.
✓ Branch 52 taken 1 times.
✗ Branch 53 not taken.
✗ Branch 54 not taken.
✓ Branch 55 taken 1 times.
✗ Branch 56 not taken.
✓ Branch 134 taken 12 times.
✗ Branch 135 not taken.
✗ Branch 137 not taken.
✗ Branch 138 not taken.
✓ Branch 140 taken 14 times.
✗ Branch 141 not taken.
✗ Branch 143 not taken.
✗ Branch 144 not taken.
2693702 return LLVMType<T>::get(C)->getPointerTo(0);
162 }
163 };
164
165 template <>
166 struct LLVMType<char> : public LLVMType<uint8_t>
167 {
168 static_assert(std::is_same<uint8_t, unsigned char>::value,
169 "This library requires std::uint8_t to be implemented as unsigned char.");
170 };
171
172 template <>
173 struct LLVMType<codegen::String>
174 {
175 static inline llvm::StructType*
176 354140 get(llvm::LLVMContext& C) {
177 const std::vector<llvm::Type*> types {
178 354140 LLVMType<char*>::get(C), // ptr
179 354140 LLVMType<char[codegen::String::SSO_LENGTH]>::get(C), // SSO
180 LLVMType<int64_t>::get(C) // size
181
1/2
✓ Branch 4 taken 354140 times.
✗ Branch 5 not taken.
354140 };
182
2/6
✓ Branch 1 taken 354140 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 354140 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
708280 return llvm::StructType::get(C, types);
183 }
184 static inline llvm::Constant*
185 get(llvm::LLVMContext& C, const codegen::String* const string)
186 {
187 4 return LLVMType<uintptr_t>::get(C,
188 reinterpret_cast<uintptr_t>(string));
189 }
190 };
191
192 template <>
193 struct LLVMType<void>
194 {
195 static inline llvm::Type*
196 get(llvm::LLVMContext& C) {
197
5/11
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
355872 return llvm::Type::getVoidTy(C);
198 }
199 };
200
201 /// @note void* implemented as signed int_t* to match clang IR generation
202 template <> struct LLVMType<void*> : public LLVMType<int_t<sizeof(void*)>::type*> {};
203 template <> struct LLVMType<openvdb::math::half>
204 {
205 // @note LLVM has a special representation of half types. Don't alias to
206 // uint16_t as we want type->isFloatingPointTy() to still return true.
207
208
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
14828 static inline llvm::Type* get(llvm::LLVMContext& C) { return llvm::Type::getHalfTy(C); }
209 static inline llvm::Constant* get(llvm::LLVMContext& C, const openvdb::math::half V)
210 {
211 llvm::Type* type = LLVMType<openvdb::math::half>::get(C);
212 assert(llvm::ConstantFP::isValueValidForType(type, llvm::APFloat(V)));
213 llvm::Constant* constant = llvm::ConstantFP::get(type, static_cast<double>(V));
214 assert(constant);
215 return constant;
216 }
217 static inline llvm::Constant* get(llvm::LLVMContext& C, const openvdb::math::half* const V)
218 {
219 return LLVMType<uintptr_t>::get(C, reinterpret_cast<uintptr_t>(V));
220 }
221 };
222
223 template <typename T> struct LLVMType<const T> : public LLVMType<T> {};
224 template <typename T> struct LLVMType<const T*> : public LLVMType<T*> {};
225
226 /// @brief Alias mapping between two types, a frontend type T1 and a backend
227 /// type T2. This class is the intended interface for binding objects
228 /// which implement supported backend AX/IR types to this given backend
229 /// type. More specifically, it's current and expected usage is limited
230 /// to objects which hold a single member of a supported backend type
231 /// and implements a StandardLayoutType as defined by the standard.
232 /// Fundamentally, T1->T2 mapping should be supported by
233 /// reinterpret_cast<> as defined by the type aliasing rules.
234 /// @note The static asserts provide preliminary checks but are by no means
235 /// a guarantee that a provided mapping is correct. Ensure the above
236 /// requirements are met when instantiating an alias.
237 template <typename T1, typename T2>
238 struct AliasTypeMap
239 {
240 using LLVMTypeT = LLVMType<T2>;
241
242 static_assert(sizeof(T1) == sizeof(T2),
243 "T1 differs in size to T2 during alias mapping. Types should have "
244 "the same memory layout.");
245 static_assert(std::is_standard_layout<T1>::value,
246 "T1 in instantiation of an AliasTypeMap does not have a standard layout. "
247 "This will most likely cause undefined behaviour when attempting to map "
248 "T1->T2.");
249
250 static inline llvm::Type*
251 get(llvm::LLVMContext& C) {
252
20/56
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 20 taken 72 times.
✗ Branch 21 not taken.
✓ Branch 23 taken 12 times.
✗ Branch 24 not taken.
✓ Branch 26 taken 60 times.
✗ Branch 27 not taken.
✓ Branch 29 taken 12 times.
✗ Branch 30 not taken.
✓ Branch 32 taken 96 times.
✗ Branch 33 not taken.
✓ Branch 35 taken 24 times.
✗ Branch 36 not taken.
✓ Branch 38 taken 36 times.
✗ Branch 39 not taken.
✓ Branch 41 taken 12 times.
✗ Branch 42 not taken.
✓ Branch 44 taken 24 times.
✗ Branch 45 not taken.
✓ Branch 47 taken 12 times.
✗ Branch 48 not taken.
✓ Branch 50 taken 24 times.
✗ Branch 51 not taken.
✓ Branch 53 taken 24 times.
✗ Branch 54 not taken.
✗ Branch 56 not taken.
✗ Branch 57 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
✗ Branch 62 not taken.
✗ Branch 63 not taken.
✗ Branch 65 not taken.
✗ Branch 66 not taken.
✓ Branch 98 taken 12 times.
✗ Branch 99 not taken.
✓ Branch 101 taken 12 times.
✗ Branch 102 not taken.
✗ Branch 104 not taken.
✗ Branch 105 not taken.
✗ Branch 107 not taken.
✗ Branch 108 not taken.
✓ Branch 110 taken 14 times.
✗ Branch 111 not taken.
✓ Branch 113 taken 14 times.
✗ Branch 114 not taken.
✗ Branch 116 not taken.
✗ Branch 117 not taken.
✗ Branch 119 not taken.
✗ Branch 120 not taken.
252529 return LLVMTypeT::get(C);
253 }
254 static inline llvm::Constant*
255 get(llvm::LLVMContext& C, const T1& value) {
256 return LLVMTypeT::get(C, reinterpret_cast<const T2&>(value));
257 }
258 static inline llvm::Constant*
259 get(llvm::LLVMContext& C, const T1* const value) {
260 return LLVMTypeT::get(C, reinterpret_cast<const T2* const>(value));
261 }
262 };
263
264 /// @brief Supported aliasing for VDB math types, allowing use in external
265 /// function signatures.
266 template <typename T> struct LLVMType<openvdb::math::Vec2<T>> : public AliasTypeMap<openvdb::math::Vec2<T>, T[2]> {};
267 template <typename T> struct LLVMType<openvdb::math::Vec3<T>> : public AliasTypeMap<openvdb::math::Vec3<T>, T[3]> {};
268 template <typename T> struct LLVMType<openvdb::math::Vec4<T>> : public AliasTypeMap<openvdb::math::Vec4<T>, T[4]> {};
269 template <typename T> struct LLVMType<openvdb::math::Mat3<T>> : public AliasTypeMap<openvdb::math::Mat3<T>, T[9]> {};
270 template <typename T> struct LLVMType<openvdb::math::Mat4<T>> : public AliasTypeMap<openvdb::math::Mat4<T>, T[16]> {};
271
272 ///////////////////////////////////////////////////////////////////////////
273 ///////////////////////////////////////////////////////////////////////////
274
275 /// @brief Templated function traits which provides compile-time index access to
276 /// the types of the function signature
277 ///
278 template<typename SignatureT>
279 struct FunctionTraits;
280
281 template<typename R, typename... Args>
282 struct FunctionTraits<R(&)(Args...)> : public FunctionTraits<R(Args...)> {};
283
284 template<typename R, typename... Args>
285 struct FunctionTraits<R(*)(Args...)> : public FunctionTraits<R(Args...)> {};
286
287 // Only enable noexcept signatures from C++17 onwards when it is actually
288 // respected. Otherwise the compiler ignores it and we get duplicating
289 // definitions for FunctionTraits specializations.
290 #if __cplusplus >= 201703L
291 template<typename R, typename... Args>
292 struct FunctionTraits<R(Args...) noexcept> : public FunctionTraits<R(Args...)> {};
293
294 template<typename R, typename... Args>
295 struct FunctionTraits<R(*)(Args...) noexcept> : public FunctionTraits<R(Args...)> {};
296 #endif
297
298 template<typename ReturnT, typename ...Args>
299 struct FunctionTraits<ReturnT(Args...)>
300 {
301 using ReturnType = ReturnT;
302 using SignatureType = ReturnType(Args...);
303 static const size_t N_ARGS = sizeof...(Args);
304
305 template <size_t I>
306 struct Arg
307 {
308 public:
309 static_assert(I < N_ARGS,
310 "Invalid index specified for function argument access");
311 using Type = typename std::tuple_element<I, std::tuple<Args...>>::type;
312 static_assert(!std::is_reference<Type>::value,
313 "Reference types/arguments are not supported for automatic "
314 "LLVM Type conversion. Use pointers instead.");
315 };
316 };
317
318 ///////////////////////////////////////////////////////////////////////////
319 ///////////////////////////////////////////////////////////////////////////
320
321 /// @brief Returns an llvm Constant holding a scalar value
322 /// @param t The scalar constant
323 /// @param type The LLVM type. Can differ from the type of t, in which
324 /// case the value will be cast to the llvm type
325 ///
326 template <typename T>
327 inline llvm::Constant*
328
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 208 times.
274 llvmConstant(const T t, llvm::Type* type)
329 {
330 static_assert(std::is_floating_point<T>::value || std::is_integral<T>::value,
331 "T type for llvmConstant must be a floating point or integral type.");
332
333
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 208 times.
274 if (type->isIntegerTy()) {
334 66 return llvm::ConstantInt::get(type, static_cast<uint64_t>(t), /*signed*/true);
335 }
336 else {
337 assert(type->isFloatingPointTy());
338 208 return llvm::ConstantFP::get(type, static_cast<double>(t));
339 }
340 }
341
342 /// @brief Returns an llvm IntegerType given a requested size and context
343 /// @param size The number of bits of the integer type
344 /// @param C The LLVMContext to request the Type from.
345 ///
346 OPENVDB_AX_API llvm::IntegerType* llvmIntType(const uint32_t size, llvm::LLVMContext& C);
347
348 /// @brief Returns an llvm floating point Type given a requested size and context
349 /// @param size The size of the float to request, i.e. float - 32, double - 64 etc.
350 /// @param C The LLVMContext to request the Type from.
351 ///
352 OPENVDB_AX_API llvm::Type* llvmFloatType(const uint32_t size, llvm::LLVMContext& C);
353
354 /// @brief Returns an llvm type representing a type defined by a string.
355 /// @note For string types, this function returns the element type, not the
356 /// object type! The llvm type representing a char block of memory
357 /// is LLVMType<char*>::get(C);
358 /// @param type The AX token type
359 /// @param C The LLVMContext to request the Type from.
360 ///
361 OPENVDB_AX_API llvm::Type* llvmTypeFromToken(const ast::tokens::CoreType& type, llvm::LLVMContext& C);
362
363 /// @brief Return a corresponding AX token which represents the given LLVM Type.
364 /// @note If the type does not exist in AX, ast::tokens::UNKNOWN is returned.
365 /// Must not be a nullptr.
366 /// @param type a valid LLVM Type
367 ///
368 OPENVDB_AX_API ast::tokens::CoreType tokenFromLLVMType(const llvm::Type* type);
369
370 } // namespace codegen
371 } // namespace ax
372 } // namespace OPENVDB_VERSION_NAME
373 } // namespace openvdb
374
375 #endif // OPENVDB_AX_CODEGEN_TYPES_HAS_BEEN_INCLUDED
376
377