TypeBuilderTest.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. //===- llvm/unittest/TypeBuilderTest.cpp - TypeBuilder tests --------------===//
  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. #include "llvm/IR/TypeBuilder.h"
  10. #include "llvm/IR/LLVMContext.h"
  11. #include "gtest/gtest.h"
  12. using namespace llvm;
  13. namespace {
  14. TEST(TypeBuilderTest, Void) {
  15. LLVMContext Context;
  16. EXPECT_EQ(Type::getVoidTy(Context), (TypeBuilder<void, true>::get(Context)));
  17. EXPECT_EQ(Type::getVoidTy(Context), (TypeBuilder<void, false>::get(Context)));
  18. // Special cases for C compatibility:
  19. EXPECT_EQ(Type::getInt8PtrTy(Context),
  20. (TypeBuilder<void *, false>::get(Context)));
  21. EXPECT_EQ(Type::getInt8PtrTy(Context),
  22. (TypeBuilder<const void *, false>::get(Context)));
  23. EXPECT_EQ(Type::getInt8PtrTy(Context),
  24. (TypeBuilder<volatile void *, false>::get(Context)));
  25. EXPECT_EQ(Type::getInt8PtrTy(Context),
  26. (TypeBuilder<const volatile void *, false>::get(Context)));
  27. }
  28. TEST(TypeBuilderTest, HostIntegers) {
  29. LLVMContext Context;
  30. EXPECT_EQ(Type::getInt8Ty(Context),
  31. (TypeBuilder<int8_t, false>::get(Context)));
  32. EXPECT_EQ(Type::getInt8Ty(Context),
  33. (TypeBuilder<uint8_t, false>::get(Context)));
  34. EXPECT_EQ(Type::getInt16Ty(Context),
  35. (TypeBuilder<int16_t, false>::get(Context)));
  36. EXPECT_EQ(Type::getInt16Ty(Context),
  37. (TypeBuilder<uint16_t, false>::get(Context)));
  38. EXPECT_EQ(Type::getInt32Ty(Context),
  39. (TypeBuilder<int32_t, false>::get(Context)));
  40. EXPECT_EQ(Type::getInt32Ty(Context),
  41. (TypeBuilder<uint32_t, false>::get(Context)));
  42. EXPECT_EQ(Type::getInt64Ty(Context),
  43. (TypeBuilder<int64_t, false>::get(Context)));
  44. EXPECT_EQ(Type::getInt64Ty(Context),
  45. (TypeBuilder<uint64_t, false>::get(Context)));
  46. EXPECT_EQ(IntegerType::get(Context, sizeof(size_t) * CHAR_BIT),
  47. (TypeBuilder<size_t, false>::get(Context)));
  48. EXPECT_EQ(IntegerType::get(Context, sizeof(ptrdiff_t) * CHAR_BIT),
  49. (TypeBuilder<ptrdiff_t, false>::get(Context)));
  50. }
  51. TEST(TypeBuilderTest, CrossCompilableIntegers) {
  52. LLVMContext Context;
  53. EXPECT_EQ(IntegerType::get(Context, 1),
  54. (TypeBuilder<types::i<1>, true>::get(Context)));
  55. EXPECT_EQ(IntegerType::get(Context, 1),
  56. (TypeBuilder<types::i<1>, false>::get(Context)));
  57. EXPECT_EQ(IntegerType::get(Context, 72),
  58. (TypeBuilder<types::i<72>, true>::get(Context)));
  59. EXPECT_EQ(IntegerType::get(Context, 72),
  60. (TypeBuilder<types::i<72>, false>::get(Context)));
  61. }
  62. TEST(TypeBuilderTest, Float) {
  63. LLVMContext Context;
  64. EXPECT_EQ(Type::getFloatTy(Context),
  65. (TypeBuilder<float, false>::get(Context)));
  66. EXPECT_EQ(Type::getDoubleTy(Context),
  67. (TypeBuilder<double, false>::get(Context)));
  68. // long double isn't supported yet.
  69. EXPECT_EQ(Type::getFloatTy(Context),
  70. (TypeBuilder<types::ieee_float, true>::get(Context)));
  71. EXPECT_EQ(Type::getFloatTy(Context),
  72. (TypeBuilder<types::ieee_float, false>::get(Context)));
  73. EXPECT_EQ(Type::getDoubleTy(Context),
  74. (TypeBuilder<types::ieee_double, true>::get(Context)));
  75. EXPECT_EQ(Type::getDoubleTy(Context),
  76. (TypeBuilder<types::ieee_double, false>::get(Context)));
  77. EXPECT_EQ(Type::getX86_FP80Ty(Context),
  78. (TypeBuilder<types::x86_fp80, true>::get(Context)));
  79. EXPECT_EQ(Type::getX86_FP80Ty(Context),
  80. (TypeBuilder<types::x86_fp80, false>::get(Context)));
  81. EXPECT_EQ(Type::getFP128Ty(Context),
  82. (TypeBuilder<types::fp128, true>::get(Context)));
  83. EXPECT_EQ(Type::getFP128Ty(Context),
  84. (TypeBuilder<types::fp128, false>::get(Context)));
  85. EXPECT_EQ(Type::getPPC_FP128Ty(Context),
  86. (TypeBuilder<types::ppc_fp128, true>::get(Context)));
  87. EXPECT_EQ(Type::getPPC_FP128Ty(Context),
  88. (TypeBuilder<types::ppc_fp128, false>::get(Context)));
  89. }
  90. TEST(TypeBuilderTest, Derived) {
  91. LLVMContext Context;
  92. EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(Context)),
  93. (TypeBuilder<int8_t **, false>::get(Context)));
  94. EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 7),
  95. (TypeBuilder<int8_t[7], false>::get(Context)));
  96. EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 0),
  97. (TypeBuilder<int8_t[], false>::get(Context)));
  98. EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(Context)),
  99. (TypeBuilder<types::i<8> **, false>::get(Context)));
  100. EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 7),
  101. (TypeBuilder<types::i<8>[7], false>::get(Context)));
  102. EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 0),
  103. (TypeBuilder<types::i<8>[], false>::get(Context)));
  104. EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(Context)),
  105. (TypeBuilder<types::i<8> **, true>::get(Context)));
  106. EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 7),
  107. (TypeBuilder<types::i<8>[7], true>::get(Context)));
  108. EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 0),
  109. (TypeBuilder<types::i<8>[], true>::get(Context)));
  110. EXPECT_EQ(Type::getInt8Ty(Context),
  111. (TypeBuilder<const int8_t, false>::get(Context)));
  112. EXPECT_EQ(Type::getInt8Ty(Context),
  113. (TypeBuilder<volatile int8_t, false>::get(Context)));
  114. EXPECT_EQ(Type::getInt8Ty(Context),
  115. (TypeBuilder<const volatile int8_t, false>::get(Context)));
  116. EXPECT_EQ(Type::getInt8Ty(Context),
  117. (TypeBuilder<const types::i<8>, false>::get(Context)));
  118. EXPECT_EQ(Type::getInt8Ty(Context),
  119. (TypeBuilder<volatile types::i<8>, false>::get(Context)));
  120. EXPECT_EQ(Type::getInt8Ty(Context),
  121. (TypeBuilder<const volatile types::i<8>, false>::get(Context)));
  122. EXPECT_EQ(Type::getInt8Ty(Context),
  123. (TypeBuilder<const types::i<8>, true>::get(Context)));
  124. EXPECT_EQ(Type::getInt8Ty(Context),
  125. (TypeBuilder<volatile types::i<8>, true>::get(Context)));
  126. EXPECT_EQ(Type::getInt8Ty(Context),
  127. (TypeBuilder<const volatile types::i<8>, true>::get(Context)));
  128. EXPECT_EQ(Type::getInt8PtrTy(Context),
  129. (TypeBuilder<const volatile int8_t *const volatile, false>::get(
  130. Context)));
  131. }
  132. TEST(TypeBuilderTest, Functions) {
  133. LLVMContext Context;
  134. std::vector<Type*> params;
  135. EXPECT_EQ(FunctionType::get(Type::getVoidTy(Context), params, false),
  136. (TypeBuilder<void(), true>::get(Context)));
  137. EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, true),
  138. (TypeBuilder<int8_t(...), false>::get(Context)));
  139. params.push_back(TypeBuilder<int32_t *, false>::get(Context));
  140. EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, false),
  141. (TypeBuilder<int8_t(const int32_t *), false>::get(Context)));
  142. EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, true),
  143. (TypeBuilder<int8_t(const int32_t *, ...), false>::get(Context)));
  144. params.push_back(TypeBuilder<char *, false>::get(Context));
  145. EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, false),
  146. (TypeBuilder<int8_t(int32_t *, void *), false>::get(Context)));
  147. EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, true),
  148. (TypeBuilder<int8_t(int32_t *, char *, ...), false>::get(Context)));
  149. params.push_back(TypeBuilder<char, false>::get(Context));
  150. EXPECT_EQ(
  151. FunctionType::get(Type::getInt8Ty(Context), params, false),
  152. (TypeBuilder<int8_t(int32_t *, void *, char), false>::get(Context)));
  153. EXPECT_EQ(
  154. FunctionType::get(Type::getInt8Ty(Context), params, true),
  155. (TypeBuilder<int8_t(int32_t *, char *, char, ...), false>::get(Context)));
  156. params.push_back(TypeBuilder<char, false>::get(Context));
  157. EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, false),
  158. (TypeBuilder<int8_t(int32_t *, void *, char, char), false>::get(
  159. Context)));
  160. EXPECT_EQ(
  161. FunctionType::get(Type::getInt8Ty(Context), params, true),
  162. (TypeBuilder<int8_t(int32_t *, char *, char, char, ...), false>::get(
  163. Context)));
  164. params.push_back(TypeBuilder<char, false>::get(Context));
  165. EXPECT_EQ(
  166. FunctionType::get(Type::getInt8Ty(Context), params, false),
  167. (TypeBuilder<int8_t(int32_t *, void *, char, char, char), false>::get(
  168. Context)));
  169. EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, true),
  170. (TypeBuilder<int8_t(int32_t *, char *, char, char, char, ...),
  171. false>::get(Context)));
  172. }
  173. TEST(TypeBuilderTest, Context) {
  174. // We used to cache TypeBuilder results in static local variables. This
  175. // produced the same type for different contexts, which of course broke
  176. // things.
  177. LLVMContext context1;
  178. EXPECT_EQ(&context1,
  179. &(TypeBuilder<types::i<1>, true>::get(context1))->getContext());
  180. LLVMContext context2;
  181. EXPECT_EQ(&context2,
  182. &(TypeBuilder<types::i<1>, true>::get(context2))->getContext());
  183. }
  184. struct MyType {
  185. int a;
  186. int *b;
  187. void *array[1];
  188. };
  189. struct MyPortableType {
  190. int32_t a;
  191. int32_t *b;
  192. void *array[1];
  193. };
  194. } // anonymous namespace
  195. namespace llvm {
  196. template<bool cross> class TypeBuilder<MyType, cross> {
  197. public:
  198. static StructType *get(LLVMContext &Context) {
  199. // Using the static result variable ensures that the type is
  200. // only looked up once.
  201. std::vector<Type*> st;
  202. st.push_back(TypeBuilder<int, cross>::get(Context));
  203. st.push_back(TypeBuilder<int*, cross>::get(Context));
  204. st.push_back(TypeBuilder<void*[], cross>::get(Context));
  205. static StructType *const result = StructType::get(Context, st);
  206. return result;
  207. }
  208. // You may find this a convenient place to put some constants
  209. // to help with getelementptr. They don't have any effect on
  210. // the operation of TypeBuilder.
  211. enum Fields {
  212. FIELD_A,
  213. FIELD_B,
  214. FIELD_ARRAY
  215. };
  216. };
  217. template<bool cross> class TypeBuilder<MyPortableType, cross> {
  218. public:
  219. static StructType *get(LLVMContext &Context) {
  220. // Using the static result variable ensures that the type is
  221. // only looked up once.
  222. std::vector<Type*> st;
  223. st.push_back(TypeBuilder<types::i<32>, cross>::get(Context));
  224. st.push_back(TypeBuilder<types::i<32>*, cross>::get(Context));
  225. st.push_back(TypeBuilder<types::i<8>*[], cross>::get(Context));
  226. static StructType *const result = StructType::get(Context, st);
  227. return result;
  228. }
  229. // You may find this a convenient place to put some constants
  230. // to help with getelementptr. They don't have any effect on
  231. // the operation of TypeBuilder.
  232. enum Fields {
  233. FIELD_A,
  234. FIELD_B,
  235. FIELD_ARRAY
  236. };
  237. };
  238. } // namespace llvm
  239. namespace {
  240. TEST(TypeBuilderTest, Extensions) {
  241. LLVMContext Context;
  242. EXPECT_EQ(PointerType::getUnqual(
  243. StructType::get(TypeBuilder<int, false>::get(Context),
  244. TypeBuilder<int *, false>::get(Context),
  245. TypeBuilder<void *[], false>::get(Context))),
  246. (TypeBuilder<MyType *, false>::get(Context)));
  247. EXPECT_EQ(PointerType::getUnqual(StructType::get(
  248. TypeBuilder<types::i<32>, false>::get(Context),
  249. TypeBuilder<types::i<32> *, false>::get(Context),
  250. TypeBuilder<types::i<8> *[], false>::get(Context))),
  251. (TypeBuilder<MyPortableType *, false>::get(Context)));
  252. EXPECT_EQ(PointerType::getUnqual(StructType::get(
  253. TypeBuilder<types::i<32>, false>::get(Context),
  254. TypeBuilder<types::i<32> *, false>::get(Context),
  255. TypeBuilder<types::i<8> *[], false>::get(Context))),
  256. (TypeBuilder<MyPortableType *, true>::get(Context)));
  257. }
  258. } // anonymous namespace