/3rd_party/llvm/include/llvm/Support/TypeBuilder.h

https://code.google.com/p/softart/ · C++ Header · 399 lines · 274 code · 25 blank · 100 comment · 0 complexity · 385ca3bb30dd9948bd717c07dc1148d0 MD5 · raw file

  1. //===---- llvm/Support/TypeBuilder.h - Builder for LLVM types ---*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file defines the TypeBuilder class, which is used as a convenient way to
  11. // create LLVM types with a consistent and simplified interface.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #ifndef LLVM_SUPPORT_TYPEBUILDER_H
  15. #define LLVM_SUPPORT_TYPEBUILDER_H
  16. #include "llvm/DerivedTypes.h"
  17. #include "llvm/LLVMContext.h"
  18. #include <limits.h>
  19. namespace llvm {
  20. /// TypeBuilder - This provides a uniform API for looking up types
  21. /// known at compile time. To support cross-compilation, we define a
  22. /// series of tag types in the llvm::types namespace, like i<N>,
  23. /// ieee_float, ppc_fp128, etc. TypeBuilder<T, false> allows T to be
  24. /// any of these, a native C type (whose size may depend on the host
  25. /// compiler), or a pointer, function, or struct type built out of
  26. /// these. TypeBuilder<T, true> removes native C types from this set
  27. /// to guarantee that its result is suitable for cross-compilation.
  28. /// We define the primitive types, pointer types, and functions up to
  29. /// 5 arguments here, but to use this class with your own types,
  30. /// you'll need to specialize it. For example, say you want to call a
  31. /// function defined externally as:
  32. ///
  33. /// struct MyType {
  34. /// int32 a;
  35. /// int32 *b;
  36. /// void *array[1]; // Intended as a flexible array.
  37. /// };
  38. /// int8 AFunction(struct MyType *value);
  39. ///
  40. /// You'll want to use
  41. /// Function::Create(TypeBuilder<types::i<8>(MyType*), true>::get(), ...)
  42. /// to declare the function, but when you first try this, your compiler will
  43. /// complain that TypeBuilder<MyType, true>::get() doesn't exist. To fix this,
  44. /// write:
  45. ///
  46. /// namespace llvm {
  47. /// template<bool xcompile> class TypeBuilder<MyType, xcompile> {
  48. /// public:
  49. /// static StructType *get(LLVMContext &Context) {
  50. /// // If you cache this result, be sure to cache it separately
  51. /// // for each LLVMContext.
  52. /// return StructType::get(
  53. /// TypeBuilder<types::i<32>, xcompile>::get(Context),
  54. /// TypeBuilder<types::i<32>*, xcompile>::get(Context),
  55. /// TypeBuilder<types::i<8>*[], xcompile>::get(Context),
  56. /// NULL);
  57. /// }
  58. ///
  59. /// // You may find this a convenient place to put some constants
  60. /// // to help with getelementptr. They don't have any effect on
  61. /// // the operation of TypeBuilder.
  62. /// enum Fields {
  63. /// FIELD_A,
  64. /// FIELD_B,
  65. /// FIELD_ARRAY
  66. /// };
  67. /// }
  68. /// } // namespace llvm
  69. ///
  70. /// TypeBuilder cannot handle recursive types or types you only know at runtime.
  71. /// If you try to give it a recursive type, it will deadlock, infinitely
  72. /// recurse, or do something similarly undesirable.
  73. template<typename T, bool cross_compilable> class TypeBuilder {};
  74. // Types for use with cross-compilable TypeBuilders. These correspond
  75. // exactly with an LLVM-native type.
  76. namespace types {
  77. /// i<N> corresponds to the LLVM IntegerType with N bits.
  78. template<uint32_t num_bits> class i {};
  79. // The following classes represent the LLVM floating types.
  80. class ieee_float {};
  81. class ieee_double {};
  82. class x86_fp80 {};
  83. class fp128 {};
  84. class ppc_fp128 {};
  85. // X86 MMX.
  86. class x86_mmx {};
  87. } // namespace types
  88. // LLVM doesn't have const or volatile types.
  89. template<typename T, bool cross> class TypeBuilder<const T, cross>
  90. : public TypeBuilder<T, cross> {};
  91. template<typename T, bool cross> class TypeBuilder<volatile T, cross>
  92. : public TypeBuilder<T, cross> {};
  93. template<typename T, bool cross> class TypeBuilder<const volatile T, cross>
  94. : public TypeBuilder<T, cross> {};
  95. // Pointers
  96. template<typename T, bool cross> class TypeBuilder<T*, cross> {
  97. public:
  98. static PointerType *get(LLVMContext &Context) {
  99. return PointerType::getUnqual(TypeBuilder<T,cross>::get(Context));
  100. }
  101. };
  102. /// There is no support for references
  103. template<typename T, bool cross> class TypeBuilder<T&, cross> {};
  104. // Arrays
  105. template<typename T, size_t N, bool cross> class TypeBuilder<T[N], cross> {
  106. public:
  107. static ArrayType *get(LLVMContext &Context) {
  108. return ArrayType::get(TypeBuilder<T, cross>::get(Context), N);
  109. }
  110. };
  111. /// LLVM uses an array of length 0 to represent an unknown-length array.
  112. template<typename T, bool cross> class TypeBuilder<T[], cross> {
  113. public:
  114. static ArrayType *get(LLVMContext &Context) {
  115. return ArrayType::get(TypeBuilder<T, cross>::get(Context), 0);
  116. }
  117. };
  118. // Define the C integral types only for TypeBuilder<T, false>.
  119. //
  120. // C integral types do not have a defined size. It would be nice to use the
  121. // stdint.h-defined typedefs that do have defined sizes, but we'd run into the
  122. // following problem:
  123. //
  124. // On an ILP32 machine, stdint.h might define:
  125. //
  126. // typedef int int32_t;
  127. // typedef long long int64_t;
  128. // typedef long size_t;
  129. //
  130. // If we defined TypeBuilder<int32_t> and TypeBuilder<int64_t>, then any use of
  131. // TypeBuilder<size_t> would fail. We couldn't define TypeBuilder<size_t> in
  132. // addition to the defined-size types because we'd get duplicate definitions on
  133. // platforms where stdint.h instead defines:
  134. //
  135. // typedef int int32_t;
  136. // typedef long long int64_t;
  137. // typedef int size_t;
  138. //
  139. // So we define all the primitive C types and nothing else.
  140. #define DEFINE_INTEGRAL_TYPEBUILDER(T) \
  141. template<> class TypeBuilder<T, false> { \
  142. public: \
  143. static IntegerType *get(LLVMContext &Context) { \
  144. return IntegerType::get(Context, sizeof(T) * CHAR_BIT); \
  145. } \
  146. }; \
  147. template<> class TypeBuilder<T, true> { \
  148. /* We provide a definition here so users don't accidentally */ \
  149. /* define these types to work. */ \
  150. }
  151. DEFINE_INTEGRAL_TYPEBUILDER(char);
  152. DEFINE_INTEGRAL_TYPEBUILDER(signed char);
  153. DEFINE_INTEGRAL_TYPEBUILDER(unsigned char);
  154. DEFINE_INTEGRAL_TYPEBUILDER(short);
  155. DEFINE_INTEGRAL_TYPEBUILDER(unsigned short);
  156. DEFINE_INTEGRAL_TYPEBUILDER(int);
  157. DEFINE_INTEGRAL_TYPEBUILDER(unsigned int);
  158. DEFINE_INTEGRAL_TYPEBUILDER(long);
  159. DEFINE_INTEGRAL_TYPEBUILDER(unsigned long);
  160. #ifdef _MSC_VER
  161. DEFINE_INTEGRAL_TYPEBUILDER(__int64);
  162. DEFINE_INTEGRAL_TYPEBUILDER(unsigned __int64);
  163. #else /* _MSC_VER */
  164. DEFINE_INTEGRAL_TYPEBUILDER(long long);
  165. DEFINE_INTEGRAL_TYPEBUILDER(unsigned long long);
  166. #endif /* _MSC_VER */
  167. #undef DEFINE_INTEGRAL_TYPEBUILDER
  168. template<uint32_t num_bits, bool cross>
  169. class TypeBuilder<types::i<num_bits>, cross> {
  170. public:
  171. static IntegerType *get(LLVMContext &C) {
  172. return IntegerType::get(C, num_bits);
  173. }
  174. };
  175. template<> class TypeBuilder<float, false> {
  176. public:
  177. static Type *get(LLVMContext& C) {
  178. return Type::getFloatTy(C);
  179. }
  180. };
  181. template<> class TypeBuilder<float, true> {};
  182. template<> class TypeBuilder<double, false> {
  183. public:
  184. static Type *get(LLVMContext& C) {
  185. return Type::getDoubleTy(C);
  186. }
  187. };
  188. template<> class TypeBuilder<double, true> {};
  189. template<bool cross> class TypeBuilder<types::ieee_float, cross> {
  190. public:
  191. static Type *get(LLVMContext& C) { return Type::getFloatTy(C); }
  192. };
  193. template<bool cross> class TypeBuilder<types::ieee_double, cross> {
  194. public:
  195. static Type *get(LLVMContext& C) { return Type::getDoubleTy(C); }
  196. };
  197. template<bool cross> class TypeBuilder<types::x86_fp80, cross> {
  198. public:
  199. static Type *get(LLVMContext& C) { return Type::getX86_FP80Ty(C); }
  200. };
  201. template<bool cross> class TypeBuilder<types::fp128, cross> {
  202. public:
  203. static Type *get(LLVMContext& C) { return Type::getFP128Ty(C); }
  204. };
  205. template<bool cross> class TypeBuilder<types::ppc_fp128, cross> {
  206. public:
  207. static Type *get(LLVMContext& C) { return Type::getPPC_FP128Ty(C); }
  208. };
  209. template<bool cross> class TypeBuilder<types::x86_mmx, cross> {
  210. public:
  211. static Type *get(LLVMContext& C) { return Type::getX86_MMXTy(C); }
  212. };
  213. template<bool cross> class TypeBuilder<void, cross> {
  214. public:
  215. static Type *get(LLVMContext &C) {
  216. return Type::getVoidTy(C);
  217. }
  218. };
  219. /// void* is disallowed in LLVM types, but it occurs often enough in C code that
  220. /// we special case it.
  221. template<> class TypeBuilder<void*, false>
  222. : public TypeBuilder<types::i<8>*, false> {};
  223. template<> class TypeBuilder<const void*, false>
  224. : public TypeBuilder<types::i<8>*, false> {};
  225. template<> class TypeBuilder<volatile void*, false>
  226. : public TypeBuilder<types::i<8>*, false> {};
  227. template<> class TypeBuilder<const volatile void*, false>
  228. : public TypeBuilder<types::i<8>*, false> {};
  229. template<typename R, bool cross> class TypeBuilder<R(), cross> {
  230. public:
  231. static FunctionType *get(LLVMContext &Context) {
  232. return FunctionType::get(TypeBuilder<R, cross>::get(Context), false);
  233. }
  234. };
  235. template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> {
  236. public:
  237. static FunctionType *get(LLVMContext &Context) {
  238. Type *params[] = {
  239. TypeBuilder<A1, cross>::get(Context),
  240. };
  241. return FunctionType::get(TypeBuilder<R, cross>::get(Context),
  242. params, false);
  243. }
  244. };
  245. template<typename R, typename A1, typename A2, bool cross>
  246. class TypeBuilder<R(A1, A2), cross> {
  247. public:
  248. static FunctionType *get(LLVMContext &Context) {
  249. Type *params[] = {
  250. TypeBuilder<A1, cross>::get(Context),
  251. TypeBuilder<A2, cross>::get(Context),
  252. };
  253. return FunctionType::get(TypeBuilder<R, cross>::get(Context),
  254. params, false);
  255. }
  256. };
  257. template<typename R, typename A1, typename A2, typename A3, bool cross>
  258. class TypeBuilder<R(A1, A2, A3), cross> {
  259. public:
  260. static FunctionType *get(LLVMContext &Context) {
  261. Type *params[] = {
  262. TypeBuilder<A1, cross>::get(Context),
  263. TypeBuilder<A2, cross>::get(Context),
  264. TypeBuilder<A3, cross>::get(Context),
  265. };
  266. return FunctionType::get(TypeBuilder<R, cross>::get(Context),
  267. params, false);
  268. }
  269. };
  270. template<typename R, typename A1, typename A2, typename A3, typename A4,
  271. bool cross>
  272. class TypeBuilder<R(A1, A2, A3, A4), cross> {
  273. public:
  274. static FunctionType *get(LLVMContext &Context) {
  275. Type *params[] = {
  276. TypeBuilder<A1, cross>::get(Context),
  277. TypeBuilder<A2, cross>::get(Context),
  278. TypeBuilder<A3, cross>::get(Context),
  279. TypeBuilder<A4, cross>::get(Context),
  280. };
  281. return FunctionType::get(TypeBuilder<R, cross>::get(Context),
  282. params, false);
  283. }
  284. };
  285. template<typename R, typename A1, typename A2, typename A3, typename A4,
  286. typename A5, bool cross>
  287. class TypeBuilder<R(A1, A2, A3, A4, A5), cross> {
  288. public:
  289. static FunctionType *get(LLVMContext &Context) {
  290. Type *params[] = {
  291. TypeBuilder<A1, cross>::get(Context),
  292. TypeBuilder<A2, cross>::get(Context),
  293. TypeBuilder<A3, cross>::get(Context),
  294. TypeBuilder<A4, cross>::get(Context),
  295. TypeBuilder<A5, cross>::get(Context),
  296. };
  297. return FunctionType::get(TypeBuilder<R, cross>::get(Context),
  298. params, false);
  299. }
  300. };
  301. template<typename R, bool cross> class TypeBuilder<R(...), cross> {
  302. public:
  303. static FunctionType *get(LLVMContext &Context) {
  304. return FunctionType::get(TypeBuilder<R, cross>::get(Context), true);
  305. }
  306. };
  307. template<typename R, typename A1, bool cross>
  308. class TypeBuilder<R(A1, ...), cross> {
  309. public:
  310. static FunctionType *get(LLVMContext &Context) {
  311. Type *params[] = {
  312. TypeBuilder<A1, cross>::get(Context),
  313. };
  314. return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, true);
  315. }
  316. };
  317. template<typename R, typename A1, typename A2, bool cross>
  318. class TypeBuilder<R(A1, A2, ...), cross> {
  319. public:
  320. static FunctionType *get(LLVMContext &Context) {
  321. Type *params[] = {
  322. TypeBuilder<A1, cross>::get(Context),
  323. TypeBuilder<A2, cross>::get(Context),
  324. };
  325. return FunctionType::get(TypeBuilder<R, cross>::get(Context),
  326. params, true);
  327. }
  328. };
  329. template<typename R, typename A1, typename A2, typename A3, bool cross>
  330. class TypeBuilder<R(A1, A2, A3, ...), cross> {
  331. public:
  332. static FunctionType *get(LLVMContext &Context) {
  333. Type *params[] = {
  334. TypeBuilder<A1, cross>::get(Context),
  335. TypeBuilder<A2, cross>::get(Context),
  336. TypeBuilder<A3, cross>::get(Context),
  337. };
  338. return FunctionType::get(TypeBuilder<R, cross>::get(Context),
  339. params, true);
  340. }
  341. };
  342. template<typename R, typename A1, typename A2, typename A3, typename A4,
  343. bool cross>
  344. class TypeBuilder<R(A1, A2, A3, A4, ...), cross> {
  345. public:
  346. static FunctionType *get(LLVMContext &Context) {
  347. Type *params[] = {
  348. TypeBuilder<A1, cross>::get(Context),
  349. TypeBuilder<A2, cross>::get(Context),
  350. TypeBuilder<A3, cross>::get(Context),
  351. TypeBuilder<A4, cross>::get(Context),
  352. };
  353. return FunctionType::get(TypeBuilder<R, cross>::get(Context),
  354. params, true);
  355. }
  356. };
  357. template<typename R, typename A1, typename A2, typename A3, typename A4,
  358. typename A5, bool cross>
  359. class TypeBuilder<R(A1, A2, A3, A4, A5, ...), cross> {
  360. public:
  361. static FunctionType *get(LLVMContext &Context) {
  362. Type *params[] = {
  363. TypeBuilder<A1, cross>::get(Context),
  364. TypeBuilder<A2, cross>::get(Context),
  365. TypeBuilder<A3, cross>::get(Context),
  366. TypeBuilder<A4, cross>::get(Context),
  367. TypeBuilder<A5, cross>::get(Context),
  368. };
  369. return FunctionType::get(TypeBuilder<R, cross>::get(Context),
  370. params, true);
  371. }
  372. };
  373. } // namespace llvm
  374. #endif