Move llvm/Support/TypeBuilder.h -> llvm/TypeBuilder.h. This completes
authorChandler Carruth <chandlerc@gmail.com>
Sun, 15 Jul 2012 23:45:24 +0000 (23:45 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Sun, 15 Jul 2012 23:45:24 +0000 (23:45 +0000)
the move of *Builder classes into the Core library.

No uses of this builder in Clang or DragonEgg I could find.

If there is a desire to have an IR-building-support library that
contains all of these builders, that can be easily added, but currently
it seems likely that these add no real overhead to VMCore.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160243 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Support/TypeBuilder.h [deleted file]
include/llvm/TypeBuilder.h [new file with mode: 0644]
lib/Analysis/PathNumbering.cpp
lib/Transforms/Instrumentation/PathProfiling.cpp
unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
unittests/ExecutionEngine/JIT/JITEventListenerTestCommon.h
unittests/ExecutionEngine/JIT/JITTest.cpp
unittests/Support/CMakeLists.txt
unittests/Support/TypeBuilderTest.cpp [deleted file]
unittests/VMCore/CMakeLists.txt
unittests/VMCore/TypeBuilderTest.cpp [new file with mode: 0644]

diff --git a/include/llvm/Support/TypeBuilder.h b/include/llvm/Support/TypeBuilder.h
deleted file mode 100644 (file)
index c756069..0000000
+++ /dev/null
@@ -1,399 +0,0 @@
-//===---- llvm/Support/TypeBuilder.h - Builder for LLVM types ---*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the TypeBuilder class, which is used as a convenient way to
-// create LLVM types with a consistent and simplified interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_TYPEBUILDER_H
-#define LLVM_SUPPORT_TYPEBUILDER_H
-
-#include "llvm/DerivedTypes.h"
-#include "llvm/LLVMContext.h"
-#include <limits.h>
-
-namespace llvm {
-
-/// TypeBuilder - This provides a uniform API for looking up types
-/// known at compile time.  To support cross-compilation, we define a
-/// series of tag types in the llvm::types namespace, like i<N>,
-/// ieee_float, ppc_fp128, etc.  TypeBuilder<T, false> allows T to be
-/// any of these, a native C type (whose size may depend on the host
-/// compiler), or a pointer, function, or struct type built out of
-/// these.  TypeBuilder<T, true> removes native C types from this set
-/// to guarantee that its result is suitable for cross-compilation.
-/// We define the primitive types, pointer types, and functions up to
-/// 5 arguments here, but to use this class with your own types,
-/// you'll need to specialize it.  For example, say you want to call a
-/// function defined externally as:
-///
-///   struct MyType {
-///     int32 a;
-///     int32 *b;
-///     void *array[1];  // Intended as a flexible array.
-///   };
-///   int8 AFunction(struct MyType *value);
-///
-/// You'll want to use
-///   Function::Create(TypeBuilder<types::i<8>(MyType*), true>::get(), ...)
-/// to declare the function, but when you first try this, your compiler will
-/// complain that TypeBuilder<MyType, true>::get() doesn't exist. To fix this,
-/// write:
-///
-///   namespace llvm {
-///   template<bool xcompile> class TypeBuilder<MyType, xcompile> {
-///   public:
-///     static StructType *get(LLVMContext &Context) {
-///       // If you cache this result, be sure to cache it separately
-///       // for each LLVMContext.
-///       return StructType::get(
-///         TypeBuilder<types::i<32>, xcompile>::get(Context),
-///         TypeBuilder<types::i<32>*, xcompile>::get(Context),
-///         TypeBuilder<types::i<8>*[], xcompile>::get(Context),
-///         NULL);
-///     }
-///
-///     // You may find this a convenient place to put some constants
-///     // to help with getelementptr.  They don't have any effect on
-///     // the operation of TypeBuilder.
-///     enum Fields {
-///       FIELD_A,
-///       FIELD_B,
-///       FIELD_ARRAY
-///     };
-///   }
-///   }  // namespace llvm
-///
-/// TypeBuilder cannot handle recursive types or types you only know at runtime.
-/// If you try to give it a recursive type, it will deadlock, infinitely
-/// recurse, or do something similarly undesirable.
-template<typename T, bool cross_compilable> class TypeBuilder {};
-
-// Types for use with cross-compilable TypeBuilders.  These correspond
-// exactly with an LLVM-native type.
-namespace types {
-/// i<N> corresponds to the LLVM IntegerType with N bits.
-template<uint32_t num_bits> class i {};
-
-// The following classes represent the LLVM floating types.
-class ieee_float {};
-class ieee_double {};
-class x86_fp80 {};
-class fp128 {};
-class ppc_fp128 {};
-// X86 MMX.
-class x86_mmx {};
-}  // namespace types
-
-// LLVM doesn't have const or volatile types.
-template<typename T, bool cross> class TypeBuilder<const T, cross>
-  : public TypeBuilder<T, cross> {};
-template<typename T, bool cross> class TypeBuilder<volatile T, cross>
-  : public TypeBuilder<T, cross> {};
-template<typename T, bool cross> class TypeBuilder<const volatile T, cross>
-  : public TypeBuilder<T, cross> {};
-
-// Pointers
-template<typename T, bool cross> class TypeBuilder<T*, cross> {
-public:
-  static PointerType *get(LLVMContext &Context) {
-    return PointerType::getUnqual(TypeBuilder<T,cross>::get(Context));
-  }
-};
-
-/// There is no support for references
-template<typename T, bool cross> class TypeBuilder<T&, cross> {};
-
-// Arrays
-template<typename T, size_t N, bool cross> class TypeBuilder<T[N], cross> {
-public:
-  static ArrayType *get(LLVMContext &Context) {
-    return ArrayType::get(TypeBuilder<T, cross>::get(Context), N);
-  }
-};
-/// LLVM uses an array of length 0 to represent an unknown-length array.
-template<typename T, bool cross> class TypeBuilder<T[], cross> {
-public:
-  static ArrayType *get(LLVMContext &Context) {
-    return ArrayType::get(TypeBuilder<T, cross>::get(Context), 0);
-  }
-};
-
-// Define the C integral types only for TypeBuilder<T, false>.
-//
-// C integral types do not have a defined size. It would be nice to use the
-// stdint.h-defined typedefs that do have defined sizes, but we'd run into the
-// following problem:
-//
-// On an ILP32 machine, stdint.h might define:
-//
-//   typedef int int32_t;
-//   typedef long long int64_t;
-//   typedef long size_t;
-//
-// If we defined TypeBuilder<int32_t> and TypeBuilder<int64_t>, then any use of
-// TypeBuilder<size_t> would fail.  We couldn't define TypeBuilder<size_t> in
-// addition to the defined-size types because we'd get duplicate definitions on
-// platforms where stdint.h instead defines:
-//
-//   typedef int int32_t;
-//   typedef long long int64_t;
-//   typedef int size_t;
-//
-// So we define all the primitive C types and nothing else.
-#define DEFINE_INTEGRAL_TYPEBUILDER(T) \
-template<> class TypeBuilder<T, false> { \
-public: \
-  static IntegerType *get(LLVMContext &Context) { \
-    return IntegerType::get(Context, sizeof(T) * CHAR_BIT); \
-  } \
-}; \
-template<> class TypeBuilder<T, true> { \
-  /* We provide a definition here so users don't accidentally */ \
-  /* define these types to work. */ \
-}
-DEFINE_INTEGRAL_TYPEBUILDER(char);
-DEFINE_INTEGRAL_TYPEBUILDER(signed char);
-DEFINE_INTEGRAL_TYPEBUILDER(unsigned char);
-DEFINE_INTEGRAL_TYPEBUILDER(short);
-DEFINE_INTEGRAL_TYPEBUILDER(unsigned short);
-DEFINE_INTEGRAL_TYPEBUILDER(int);
-DEFINE_INTEGRAL_TYPEBUILDER(unsigned int);
-DEFINE_INTEGRAL_TYPEBUILDER(long);
-DEFINE_INTEGRAL_TYPEBUILDER(unsigned long);
-#ifdef _MSC_VER
-DEFINE_INTEGRAL_TYPEBUILDER(__int64);
-DEFINE_INTEGRAL_TYPEBUILDER(unsigned __int64);
-#else /* _MSC_VER */
-DEFINE_INTEGRAL_TYPEBUILDER(long long);
-DEFINE_INTEGRAL_TYPEBUILDER(unsigned long long);
-#endif /* _MSC_VER */
-#undef DEFINE_INTEGRAL_TYPEBUILDER
-
-template<uint32_t num_bits, bool cross>
-class TypeBuilder<types::i<num_bits>, cross> {
-public:
-  static IntegerType *get(LLVMContext &C) {
-    return IntegerType::get(C, num_bits);
-  }
-};
-
-template<> class TypeBuilder<float, false> {
-public:
-  static Type *get(LLVMContext& C) {
-    return Type::getFloatTy(C);
-  }
-};
-template<> class TypeBuilder<float, true> {};
-
-template<> class TypeBuilder<double, false> {
-public:
-  static Type *get(LLVMContext& C) {
-    return Type::getDoubleTy(C);
-  }
-};
-template<> class TypeBuilder<double, true> {};
-
-template<bool cross> class TypeBuilder<types::ieee_float, cross> {
-public:
-  static Type *get(LLVMContext& C) { return Type::getFloatTy(C); }
-};
-template<bool cross> class TypeBuilder<types::ieee_double, cross> {
-public:
-  static Type *get(LLVMContext& C) { return Type::getDoubleTy(C); }
-};
-template<bool cross> class TypeBuilder<types::x86_fp80, cross> {
-public:
-  static Type *get(LLVMContext& C) { return Type::getX86_FP80Ty(C); }
-};
-template<bool cross> class TypeBuilder<types::fp128, cross> {
-public:
-  static Type *get(LLVMContext& C) { return Type::getFP128Ty(C); }
-};
-template<bool cross> class TypeBuilder<types::ppc_fp128, cross> {
-public:
-  static Type *get(LLVMContext& C) { return Type::getPPC_FP128Ty(C); }
-};
-template<bool cross> class TypeBuilder<types::x86_mmx, cross> {
-public:
-  static Type *get(LLVMContext& C) { return Type::getX86_MMXTy(C); }
-};
-
-template<bool cross> class TypeBuilder<void, cross> {
-public:
-  static Type *get(LLVMContext &C) {
-    return Type::getVoidTy(C);
-  }
-};
-
-/// void* is disallowed in LLVM types, but it occurs often enough in C code that
-/// we special case it.
-template<> class TypeBuilder<void*, false>
-  : public TypeBuilder<types::i<8>*, false> {};
-template<> class TypeBuilder<const void*, false>
-  : public TypeBuilder<types::i<8>*, false> {};
-template<> class TypeBuilder<volatile void*, false>
-  : public TypeBuilder<types::i<8>*, false> {};
-template<> class TypeBuilder<const volatile void*, false>
-  : public TypeBuilder<types::i<8>*, false> {};
-
-template<typename R, bool cross> class TypeBuilder<R(), cross> {
-public:
-  static FunctionType *get(LLVMContext &Context) {
-    return FunctionType::get(TypeBuilder<R, cross>::get(Context), false);
-  }
-};
-template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> {
-public:
-  static FunctionType *get(LLVMContext &Context) {
-    Type *params[] = {
-      TypeBuilder<A1, cross>::get(Context),
-    };
-    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
-                             params, false);
-  }
-};
-template<typename R, typename A1, typename A2, bool cross>
-class TypeBuilder<R(A1, A2), cross> {
-public:
-  static FunctionType *get(LLVMContext &Context) {
-    Type *params[] = {
-      TypeBuilder<A1, cross>::get(Context),
-      TypeBuilder<A2, cross>::get(Context),
-    };
-    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
-                             params, false);
-  }
-};
-template<typename R, typename A1, typename A2, typename A3, bool cross>
-class TypeBuilder<R(A1, A2, A3), cross> {
-public:
-  static FunctionType *get(LLVMContext &Context) {
-    Type *params[] = {
-      TypeBuilder<A1, cross>::get(Context),
-      TypeBuilder<A2, cross>::get(Context),
-      TypeBuilder<A3, cross>::get(Context),
-    };
-    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
-                             params, false);
-  }
-};
-
-template<typename R, typename A1, typename A2, typename A3, typename A4,
-         bool cross>
-class TypeBuilder<R(A1, A2, A3, A4), cross> {
-public:
-  static FunctionType *get(LLVMContext &Context) {
-    Type *params[] = {
-      TypeBuilder<A1, cross>::get(Context),
-      TypeBuilder<A2, cross>::get(Context),
-      TypeBuilder<A3, cross>::get(Context),
-      TypeBuilder<A4, cross>::get(Context),
-    };
-    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
-                             params, false);
-  }
-};
-
-template<typename R, typename A1, typename A2, typename A3, typename A4,
-         typename A5, bool cross>
-class TypeBuilder<R(A1, A2, A3, A4, A5), cross> {
-public:
-  static FunctionType *get(LLVMContext &Context) {
-    Type *params[] = {
-      TypeBuilder<A1, cross>::get(Context),
-      TypeBuilder<A2, cross>::get(Context),
-      TypeBuilder<A3, cross>::get(Context),
-      TypeBuilder<A4, cross>::get(Context),
-      TypeBuilder<A5, cross>::get(Context),
-    };
-    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
-                             params, false);
-  }
-};
-
-template<typename R, bool cross> class TypeBuilder<R(...), cross> {
-public:
-  static FunctionType *get(LLVMContext &Context) {
-    return FunctionType::get(TypeBuilder<R, cross>::get(Context), true);
-  }
-};
-template<typename R, typename A1, bool cross>
-class TypeBuilder<R(A1, ...), cross> {
-public:
-  static FunctionType *get(LLVMContext &Context) {
-    Type *params[] = {
-      TypeBuilder<A1, cross>::get(Context),
-    };
-    return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, true);
-  }
-};
-template<typename R, typename A1, typename A2, bool cross>
-class TypeBuilder<R(A1, A2, ...), cross> {
-public:
-  static FunctionType *get(LLVMContext &Context) {
-    Type *params[] = {
-      TypeBuilder<A1, cross>::get(Context),
-      TypeBuilder<A2, cross>::get(Context),
-    };
-    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
-                                   params, true);
-  }
-};
-template<typename R, typename A1, typename A2, typename A3, bool cross>
-class TypeBuilder<R(A1, A2, A3, ...), cross> {
-public:
-  static FunctionType *get(LLVMContext &Context) {
-    Type *params[] = {
-      TypeBuilder<A1, cross>::get(Context),
-      TypeBuilder<A2, cross>::get(Context),
-      TypeBuilder<A3, cross>::get(Context),
-    };
-    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
-                                   params, true);
-  }
-};
-
-template<typename R, typename A1, typename A2, typename A3, typename A4,
-         bool cross>
-class TypeBuilder<R(A1, A2, A3, A4, ...), cross> {
-public:
-  static FunctionType *get(LLVMContext &Context) {
-    Type *params[] = {
-      TypeBuilder<A1, cross>::get(Context),
-      TypeBuilder<A2, cross>::get(Context),
-      TypeBuilder<A3, cross>::get(Context),
-      TypeBuilder<A4, cross>::get(Context),
-    };
-    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
-                             params, true);
-  }
-};
-
-template<typename R, typename A1, typename A2, typename A3, typename A4,
-         typename A5, bool cross>
-class TypeBuilder<R(A1, A2, A3, A4, A5, ...), cross> {
-public:
-  static FunctionType *get(LLVMContext &Context) {
-    Type *params[] = {
-      TypeBuilder<A1, cross>::get(Context),
-      TypeBuilder<A2, cross>::get(Context),
-      TypeBuilder<A3, cross>::get(Context),
-      TypeBuilder<A4, cross>::get(Context),
-      TypeBuilder<A5, cross>::get(Context),
-    };
-    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
-                                   params, true);
-  }
-};
-
-}  // namespace llvm
-
-#endif
diff --git a/include/llvm/TypeBuilder.h b/include/llvm/TypeBuilder.h
new file mode 100644 (file)
index 0000000..0b56479
--- /dev/null
@@ -0,0 +1,399 @@
+//===---- llvm/TypeBuilder.h - Builder for LLVM types -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TypeBuilder class, which is used as a convenient way to
+// create LLVM types with a consistent and simplified interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TYPEBUILDER_H
+#define LLVM_TYPEBUILDER_H
+
+#include "llvm/DerivedTypes.h"
+#include "llvm/LLVMContext.h"
+#include <limits.h>
+
+namespace llvm {
+
+/// TypeBuilder - This provides a uniform API for looking up types
+/// known at compile time.  To support cross-compilation, we define a
+/// series of tag types in the llvm::types namespace, like i<N>,
+/// ieee_float, ppc_fp128, etc.  TypeBuilder<T, false> allows T to be
+/// any of these, a native C type (whose size may depend on the host
+/// compiler), or a pointer, function, or struct type built out of
+/// these.  TypeBuilder<T, true> removes native C types from this set
+/// to guarantee that its result is suitable for cross-compilation.
+/// We define the primitive types, pointer types, and functions up to
+/// 5 arguments here, but to use this class with your own types,
+/// you'll need to specialize it.  For example, say you want to call a
+/// function defined externally as:
+///
+///   struct MyType {
+///     int32 a;
+///     int32 *b;
+///     void *array[1];  // Intended as a flexible array.
+///   };
+///   int8 AFunction(struct MyType *value);
+///
+/// You'll want to use
+///   Function::Create(TypeBuilder<types::i<8>(MyType*), true>::get(), ...)
+/// to declare the function, but when you first try this, your compiler will
+/// complain that TypeBuilder<MyType, true>::get() doesn't exist. To fix this,
+/// write:
+///
+///   namespace llvm {
+///   template<bool xcompile> class TypeBuilder<MyType, xcompile> {
+///   public:
+///     static StructType *get(LLVMContext &Context) {
+///       // If you cache this result, be sure to cache it separately
+///       // for each LLVMContext.
+///       return StructType::get(
+///         TypeBuilder<types::i<32>, xcompile>::get(Context),
+///         TypeBuilder<types::i<32>*, xcompile>::get(Context),
+///         TypeBuilder<types::i<8>*[], xcompile>::get(Context),
+///         NULL);
+///     }
+///
+///     // You may find this a convenient place to put some constants
+///     // to help with getelementptr.  They don't have any effect on
+///     // the operation of TypeBuilder.
+///     enum Fields {
+///       FIELD_A,
+///       FIELD_B,
+///       FIELD_ARRAY
+///     };
+///   }
+///   }  // namespace llvm
+///
+/// TypeBuilder cannot handle recursive types or types you only know at runtime.
+/// If you try to give it a recursive type, it will deadlock, infinitely
+/// recurse, or do something similarly undesirable.
+template<typename T, bool cross_compilable> class TypeBuilder {};
+
+// Types for use with cross-compilable TypeBuilders.  These correspond
+// exactly with an LLVM-native type.
+namespace types {
+/// i<N> corresponds to the LLVM IntegerType with N bits.
+template<uint32_t num_bits> class i {};
+
+// The following classes represent the LLVM floating types.
+class ieee_float {};
+class ieee_double {};
+class x86_fp80 {};
+class fp128 {};
+class ppc_fp128 {};
+// X86 MMX.
+class x86_mmx {};
+}  // namespace types
+
+// LLVM doesn't have const or volatile types.
+template<typename T, bool cross> class TypeBuilder<const T, cross>
+  : public TypeBuilder<T, cross> {};
+template<typename T, bool cross> class TypeBuilder<volatile T, cross>
+  : public TypeBuilder<T, cross> {};
+template<typename T, bool cross> class TypeBuilder<const volatile T, cross>
+  : public TypeBuilder<T, cross> {};
+
+// Pointers
+template<typename T, bool cross> class TypeBuilder<T*, cross> {
+public:
+  static PointerType *get(LLVMContext &Context) {
+    return PointerType::getUnqual(TypeBuilder<T,cross>::get(Context));
+  }
+};
+
+/// There is no support for references
+template<typename T, bool cross> class TypeBuilder<T&, cross> {};
+
+// Arrays
+template<typename T, size_t N, bool cross> class TypeBuilder<T[N], cross> {
+public:
+  static ArrayType *get(LLVMContext &Context) {
+    return ArrayType::get(TypeBuilder<T, cross>::get(Context), N);
+  }
+};
+/// LLVM uses an array of length 0 to represent an unknown-length array.
+template<typename T, bool cross> class TypeBuilder<T[], cross> {
+public:
+  static ArrayType *get(LLVMContext &Context) {
+    return ArrayType::get(TypeBuilder<T, cross>::get(Context), 0);
+  }
+};
+
+// Define the C integral types only for TypeBuilder<T, false>.
+//
+// C integral types do not have a defined size. It would be nice to use the
+// stdint.h-defined typedefs that do have defined sizes, but we'd run into the
+// following problem:
+//
+// On an ILP32 machine, stdint.h might define:
+//
+//   typedef int int32_t;
+//   typedef long long int64_t;
+//   typedef long size_t;
+//
+// If we defined TypeBuilder<int32_t> and TypeBuilder<int64_t>, then any use of
+// TypeBuilder<size_t> would fail.  We couldn't define TypeBuilder<size_t> in
+// addition to the defined-size types because we'd get duplicate definitions on
+// platforms where stdint.h instead defines:
+//
+//   typedef int int32_t;
+//   typedef long long int64_t;
+//   typedef int size_t;
+//
+// So we define all the primitive C types and nothing else.
+#define DEFINE_INTEGRAL_TYPEBUILDER(T) \
+template<> class TypeBuilder<T, false> { \
+public: \
+  static IntegerType *get(LLVMContext &Context) { \
+    return IntegerType::get(Context, sizeof(T) * CHAR_BIT); \
+  } \
+}; \
+template<> class TypeBuilder<T, true> { \
+  /* We provide a definition here so users don't accidentally */ \
+  /* define these types to work. */ \
+}
+DEFINE_INTEGRAL_TYPEBUILDER(char);
+DEFINE_INTEGRAL_TYPEBUILDER(signed char);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned char);
+DEFINE_INTEGRAL_TYPEBUILDER(short);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned short);
+DEFINE_INTEGRAL_TYPEBUILDER(int);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned int);
+DEFINE_INTEGRAL_TYPEBUILDER(long);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned long);
+#ifdef _MSC_VER
+DEFINE_INTEGRAL_TYPEBUILDER(__int64);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned __int64);
+#else /* _MSC_VER */
+DEFINE_INTEGRAL_TYPEBUILDER(long long);
+DEFINE_INTEGRAL_TYPEBUILDER(unsigned long long);
+#endif /* _MSC_VER */
+#undef DEFINE_INTEGRAL_TYPEBUILDER
+
+template<uint32_t num_bits, bool cross>
+class TypeBuilder<types::i<num_bits>, cross> {
+public:
+  static IntegerType *get(LLVMContext &C) {
+    return IntegerType::get(C, num_bits);
+  }
+};
+
+template<> class TypeBuilder<float, false> {
+public:
+  static Type *get(LLVMContext& C) {
+    return Type::getFloatTy(C);
+  }
+};
+template<> class TypeBuilder<float, true> {};
+
+template<> class TypeBuilder<double, false> {
+public:
+  static Type *get(LLVMContext& C) {
+    return Type::getDoubleTy(C);
+  }
+};
+template<> class TypeBuilder<double, true> {};
+
+template<bool cross> class TypeBuilder<types::ieee_float, cross> {
+public:
+  static Type *get(LLVMContext& C) { return Type::getFloatTy(C); }
+};
+template<bool cross> class TypeBuilder<types::ieee_double, cross> {
+public:
+  static Type *get(LLVMContext& C) { return Type::getDoubleTy(C); }
+};
+template<bool cross> class TypeBuilder<types::x86_fp80, cross> {
+public:
+  static Type *get(LLVMContext& C) { return Type::getX86_FP80Ty(C); }
+};
+template<bool cross> class TypeBuilder<types::fp128, cross> {
+public:
+  static Type *get(LLVMContext& C) { return Type::getFP128Ty(C); }
+};
+template<bool cross> class TypeBuilder<types::ppc_fp128, cross> {
+public:
+  static Type *get(LLVMContext& C) { return Type::getPPC_FP128Ty(C); }
+};
+template<bool cross> class TypeBuilder<types::x86_mmx, cross> {
+public:
+  static Type *get(LLVMContext& C) { return Type::getX86_MMXTy(C); }
+};
+
+template<bool cross> class TypeBuilder<void, cross> {
+public:
+  static Type *get(LLVMContext &C) {
+    return Type::getVoidTy(C);
+  }
+};
+
+/// void* is disallowed in LLVM types, but it occurs often enough in C code that
+/// we special case it.
+template<> class TypeBuilder<void*, false>
+  : public TypeBuilder<types::i<8>*, false> {};
+template<> class TypeBuilder<const void*, false>
+  : public TypeBuilder<types::i<8>*, false> {};
+template<> class TypeBuilder<volatile void*, false>
+  : public TypeBuilder<types::i<8>*, false> {};
+template<> class TypeBuilder<const volatile void*, false>
+  : public TypeBuilder<types::i<8>*, false> {};
+
+template<typename R, bool cross> class TypeBuilder<R(), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context), false);
+  }
+};
+template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    Type *params[] = {
+      TypeBuilder<A1, cross>::get(Context),
+    };
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+                             params, false);
+  }
+};
+template<typename R, typename A1, typename A2, bool cross>
+class TypeBuilder<R(A1, A2), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    Type *params[] = {
+      TypeBuilder<A1, cross>::get(Context),
+      TypeBuilder<A2, cross>::get(Context),
+    };
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+                             params, false);
+  }
+};
+template<typename R, typename A1, typename A2, typename A3, bool cross>
+class TypeBuilder<R(A1, A2, A3), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    Type *params[] = {
+      TypeBuilder<A1, cross>::get(Context),
+      TypeBuilder<A2, cross>::get(Context),
+      TypeBuilder<A3, cross>::get(Context),
+    };
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+                             params, false);
+  }
+};
+
+template<typename R, typename A1, typename A2, typename A3, typename A4,
+         bool cross>
+class TypeBuilder<R(A1, A2, A3, A4), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    Type *params[] = {
+      TypeBuilder<A1, cross>::get(Context),
+      TypeBuilder<A2, cross>::get(Context),
+      TypeBuilder<A3, cross>::get(Context),
+      TypeBuilder<A4, cross>::get(Context),
+    };
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+                             params, false);
+  }
+};
+
+template<typename R, typename A1, typename A2, typename A3, typename A4,
+         typename A5, bool cross>
+class TypeBuilder<R(A1, A2, A3, A4, A5), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    Type *params[] = {
+      TypeBuilder<A1, cross>::get(Context),
+      TypeBuilder<A2, cross>::get(Context),
+      TypeBuilder<A3, cross>::get(Context),
+      TypeBuilder<A4, cross>::get(Context),
+      TypeBuilder<A5, cross>::get(Context),
+    };
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+                             params, false);
+  }
+};
+
+template<typename R, bool cross> class TypeBuilder<R(...), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context), true);
+  }
+};
+template<typename R, typename A1, bool cross>
+class TypeBuilder<R(A1, ...), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    Type *params[] = {
+      TypeBuilder<A1, cross>::get(Context),
+    };
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context), params, true);
+  }
+};
+template<typename R, typename A1, typename A2, bool cross>
+class TypeBuilder<R(A1, A2, ...), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    Type *params[] = {
+      TypeBuilder<A1, cross>::get(Context),
+      TypeBuilder<A2, cross>::get(Context),
+    };
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+                                   params, true);
+  }
+};
+template<typename R, typename A1, typename A2, typename A3, bool cross>
+class TypeBuilder<R(A1, A2, A3, ...), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    Type *params[] = {
+      TypeBuilder<A1, cross>::get(Context),
+      TypeBuilder<A2, cross>::get(Context),
+      TypeBuilder<A3, cross>::get(Context),
+    };
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+                                   params, true);
+  }
+};
+
+template<typename R, typename A1, typename A2, typename A3, typename A4,
+         bool cross>
+class TypeBuilder<R(A1, A2, A3, A4, ...), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    Type *params[] = {
+      TypeBuilder<A1, cross>::get(Context),
+      TypeBuilder<A2, cross>::get(Context),
+      TypeBuilder<A3, cross>::get(Context),
+      TypeBuilder<A4, cross>::get(Context),
+    };
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+                             params, true);
+  }
+};
+
+template<typename R, typename A1, typename A2, typename A3, typename A4,
+         typename A5, bool cross>
+class TypeBuilder<R(A1, A2, A3, A4, A5, ...), cross> {
+public:
+  static FunctionType *get(LLVMContext &Context) {
+    Type *params[] = {
+      TypeBuilder<A1, cross>::get(Context),
+      TypeBuilder<A2, cross>::get(Context),
+      TypeBuilder<A3, cross>::get(Context),
+      TypeBuilder<A4, cross>::get(Context),
+      TypeBuilder<A5, cross>::get(Context),
+    };
+    return FunctionType::get(TypeBuilder<R, cross>::get(Context),
+                                   params, true);
+  }
+};
+
+}  // namespace llvm
+
+#endif
index 80c5222a27a59c33c0faf3787bed8e7fcd3f970d..d4ad72648166147783ae39c8f171fdab9bd49436 100644 (file)
 #include "llvm/Instructions.h"
 #include "llvm/Module.h"
 #include "llvm/Pass.h"
+#include "llvm/TypeBuilder.h"
 #include "llvm/Support/CFG.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Support/TypeBuilder.h"
 #include "llvm/Support/raw_ostream.h"
 
 #include <queue>
index b2147968dfac93c768072e3d9a92c47c32cd31cb..cc27146ebcf009642fa2e788d4f4e3892ae9c637 100644 (file)
 #include "llvm/LLVMContext.h"
 #include "llvm/Module.h"
 #include "llvm/Pass.h"
+#include "llvm/TypeBuilder.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/CFG.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Support/TypeBuilder.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Transforms/Instrumentation.h"
index f8d88301ba1ee1bfb0d44318b0aa0a1d1bb447fd..333888a5655da9e7abbd3c0592307559378cf152 100644 (file)
 #include "llvm/LLVMContext.h"
 #include "llvm/Instructions.h"
 #include "llvm/Module.h"
+#include "llvm/TypeBuilder.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/CodeGen/MachineCodeInfo.h"
 #include "llvm/ExecutionEngine/JIT.h"
-#include "llvm/Support/TypeBuilder.h"
 #include "llvm/Support/TargetSelect.h"
 #include "gtest/gtest.h"
 #include <vector>
index d669ecc03dbfed9e47988cceb96460588043bc26..5f02b38847b8655769ce2cc99118e39f3bed79de 100644 (file)
 #include "llvm/IRBuilder.h"
 #include "llvm/Instructions.h"
 #include "llvm/Module.h"
+#include "llvm/TypeBuilder.h"
 #include "llvm/CodeGen/MachineCodeInfo.h"
 #include "llvm/ExecutionEngine/JIT.h"
 #include "llvm/ExecutionEngine/JITEventListener.h"
 #include "llvm/Support/Dwarf.h"
 #include "llvm/Support/TargetSelect.h"
-#include "llvm/Support/TypeBuilder.h"
 #include "llvm/Config/config.h"
 
 #include "gtest/gtest.h"
index 8780aa556c43443193b6253dd109de577cb07b2b..0fde6fc66b99fe641a011cecfb4337804b0fba3d 100644 (file)
@@ -18,6 +18,7 @@
 #include "llvm/LLVMContext.h"
 #include "llvm/Module.h"
 #include "llvm/Type.h"
+#include "llvm/TypeBuilder.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Assembly/Parser.h"
@@ -27,7 +28,6 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/TargetSelect.h"
-#include "llvm/Support/TypeBuilder.h"
 
 #include "gtest/gtest.h"
 #include <vector>
index 674da35dce87d62c63a92978c021e8ab6e382e05..ad16e627cfa46e7b8d25f986111888fb2562ab74 100644 (file)
@@ -22,7 +22,6 @@ add_llvm_unittest(SupportTests
   RegexTest.cpp
   SwapByteOrderTest.cpp
   TimeValue.cpp
-  TypeBuilderTest.cpp
   ValueHandleTest.cpp
   YAMLParserTest.cpp
   )
diff --git a/unittests/Support/TypeBuilderTest.cpp b/unittests/Support/TypeBuilderTest.cpp
deleted file mode 100644 (file)
index 1d32257..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-//===- llvm/unittest/Support/TypeBuilderTest.cpp - TypeBuilder tests -----===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/TypeBuilder.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/ADT/ArrayRef.h"
-
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-namespace {
-
-TEST(TypeBuilderTest, Void) {
-  EXPECT_EQ(Type::getVoidTy(getGlobalContext()), (TypeBuilder<void, true>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getVoidTy(getGlobalContext()), (TypeBuilder<void, false>::get(getGlobalContext())));
-  // Special cases for C compatibility:
-  EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
-            (TypeBuilder<void*, false>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
-            (TypeBuilder<const void*, false>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
-            (TypeBuilder<volatile void*, false>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
-            (TypeBuilder<const volatile void*, false>::get(
-              getGlobalContext())));
-}
-
-TEST(TypeBuilderTest, HostIntegers) {
-  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), (TypeBuilder<int8_t, false>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), (TypeBuilder<uint8_t, false>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getInt16Ty(getGlobalContext()), (TypeBuilder<int16_t, false>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getInt16Ty(getGlobalContext()), (TypeBuilder<uint16_t, false>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (TypeBuilder<int32_t, false>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (TypeBuilder<uint32_t, false>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getInt64Ty(getGlobalContext()), (TypeBuilder<int64_t, false>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getInt64Ty(getGlobalContext()), (TypeBuilder<uint64_t, false>::get(getGlobalContext())));
-
-  EXPECT_EQ(IntegerType::get(getGlobalContext(), sizeof(size_t) * CHAR_BIT),
-            (TypeBuilder<size_t, false>::get(getGlobalContext())));
-  EXPECT_EQ(IntegerType::get(getGlobalContext(), sizeof(ptrdiff_t) * CHAR_BIT),
-            (TypeBuilder<ptrdiff_t, false>::get(getGlobalContext())));
-}
-
-TEST(TypeBuilderTest, CrossCompilableIntegers) {
-  EXPECT_EQ(IntegerType::get(getGlobalContext(), 1), (TypeBuilder<types::i<1>, true>::get(getGlobalContext())));
-  EXPECT_EQ(IntegerType::get(getGlobalContext(), 1), (TypeBuilder<types::i<1>, false>::get(getGlobalContext())));
-  EXPECT_EQ(IntegerType::get(getGlobalContext(), 72), (TypeBuilder<types::i<72>, true>::get(getGlobalContext())));
-  EXPECT_EQ(IntegerType::get(getGlobalContext(), 72), (TypeBuilder<types::i<72>, false>::get(getGlobalContext())));
-}
-
-TEST(TypeBuilderTest, Float) {
-  EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<float, false>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<double, false>::get(getGlobalContext())));
-  // long double isn't supported yet.
-  EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<types::ieee_float, true>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<types::ieee_float, false>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<types::ieee_double, true>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<types::ieee_double, false>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getX86_FP80Ty(getGlobalContext()), (TypeBuilder<types::x86_fp80, true>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getX86_FP80Ty(getGlobalContext()), (TypeBuilder<types::x86_fp80, false>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getFP128Ty(getGlobalContext()), (TypeBuilder<types::fp128, true>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getFP128Ty(getGlobalContext()), (TypeBuilder<types::fp128, false>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getPPC_FP128Ty(getGlobalContext()), (TypeBuilder<types::ppc_fp128, true>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getPPC_FP128Ty(getGlobalContext()), (TypeBuilder<types::ppc_fp128, false>::get(getGlobalContext())));
-}
-
-TEST(TypeBuilderTest, Derived) {
-  EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())),
-            (TypeBuilder<int8_t**, false>::get(getGlobalContext())));
-  EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7),
-            (TypeBuilder<int8_t[7], false>::get(getGlobalContext())));
-  EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0),
-            (TypeBuilder<int8_t[], false>::get(getGlobalContext())));
-
-  EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())),
-            (TypeBuilder<types::i<8>**, false>::get(getGlobalContext())));
-  EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7),
-            (TypeBuilder<types::i<8>[7], false>::get(getGlobalContext())));
-  EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0),
-            (TypeBuilder<types::i<8>[], false>::get(getGlobalContext())));
-
-  EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())),
-            (TypeBuilder<types::i<8>**, true>::get(getGlobalContext())));
-  EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7),
-            (TypeBuilder<types::i<8>[7], true>::get(getGlobalContext())));
-  EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0),
-            (TypeBuilder<types::i<8>[], true>::get(getGlobalContext())));
-
-
-  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
-            (TypeBuilder<const int8_t, false>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
-            (TypeBuilder<volatile int8_t, false>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
-            (TypeBuilder<const volatile int8_t, false>::get(getGlobalContext())));
-
-  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
-            (TypeBuilder<const types::i<8>, false>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
-            (TypeBuilder<volatile types::i<8>, false>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
-            (TypeBuilder<const volatile types::i<8>, false>::get(getGlobalContext())));
-
-  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
-            (TypeBuilder<const types::i<8>, true>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
-            (TypeBuilder<volatile types::i<8>, true>::get(getGlobalContext())));
-  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
-            (TypeBuilder<const volatile types::i<8>, true>::get(getGlobalContext())));
-
-  EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
-            (TypeBuilder<const volatile int8_t*const volatile, false>::get(getGlobalContext())));
-}
-
-TEST(TypeBuilderTest, Functions) {
-  std::vector<Type*> params;
-  EXPECT_EQ(FunctionType::get(Type::getVoidTy(getGlobalContext()), params, false),
-            (TypeBuilder<void(), true>::get(getGlobalContext())));
-  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
-            (TypeBuilder<int8_t(...), false>::get(getGlobalContext())));
-  params.push_back(TypeBuilder<int32_t*, false>::get(getGlobalContext()));
-  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
-            (TypeBuilder<int8_t(const int32_t*), false>::get(getGlobalContext())));
-  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
-            (TypeBuilder<int8_t(const int32_t*, ...), false>::get(getGlobalContext())));
-  params.push_back(TypeBuilder<char*, false>::get(getGlobalContext()));
-  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
-            (TypeBuilder<int8_t(int32_t*, void*), false>::get(getGlobalContext())));
-  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
-            (TypeBuilder<int8_t(int32_t*, char*, ...), false>::get(getGlobalContext())));
-  params.push_back(TypeBuilder<char, false>::get(getGlobalContext()));
-  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
-            (TypeBuilder<int8_t(int32_t*, void*, char), false>::get(getGlobalContext())));
-  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
-            (TypeBuilder<int8_t(int32_t*, char*, char, ...), false>::get(getGlobalContext())));
-  params.push_back(TypeBuilder<char, false>::get(getGlobalContext()));
-  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
-            (TypeBuilder<int8_t(int32_t*, void*, char, char), false>::get(getGlobalContext())));
-  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
-            (TypeBuilder<int8_t(int32_t*, char*, char, char, ...),
-                         false>::get(getGlobalContext())));
-  params.push_back(TypeBuilder<char, false>::get(getGlobalContext()));
-  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
-            (TypeBuilder<int8_t(int32_t*, void*, char, char, char),
-                         false>::get(getGlobalContext())));
-  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
-            (TypeBuilder<int8_t(int32_t*, char*, char, char, char, ...),
-                         false>::get(getGlobalContext())));
-}
-
-TEST(TypeBuilderTest, Context) {
-  // We used to cache TypeBuilder results in static local variables.  This
-  // produced the same type for different contexts, which of course broke
-  // things.
-  LLVMContext context1;
-  EXPECT_EQ(&context1,
-            &(TypeBuilder<types::i<1>, true>::get(context1))->getContext());
-  LLVMContext context2;
-  EXPECT_EQ(&context2,
-            &(TypeBuilder<types::i<1>, true>::get(context2))->getContext());
-}
-
-struct MyType {
-  int a;
-  int *b;
-  void *array[1];
-};
-
-struct MyPortableType {
-  int32_t a;
-  int32_t *b;
-  void *array[1];
-};
-
-}  // anonymous namespace
-
-namespace llvm {
-template<bool cross> class TypeBuilder<MyType, cross> {
-public:
-  static StructType *get(LLVMContext &Context) {
-    // Using the static result variable ensures that the type is
-    // only looked up once.
-    std::vector<Type*> st;
-    st.push_back(TypeBuilder<int, cross>::get(Context));
-    st.push_back(TypeBuilder<int*, cross>::get(Context));
-    st.push_back(TypeBuilder<void*[], cross>::get(Context));
-    static StructType *const result = StructType::get(Context, st);
-    return result;
-  }
-
-  // You may find this a convenient place to put some constants
-  // to help with getelementptr.  They don't have any effect on
-  // the operation of TypeBuilder.
-  enum Fields {
-    FIELD_A,
-    FIELD_B,
-    FIELD_ARRAY
-  };
-};
-
-template<bool cross> class TypeBuilder<MyPortableType, cross> {
-public:
-  static StructType *get(LLVMContext &Context) {
-    // Using the static result variable ensures that the type is
-    // only looked up once.
-    std::vector<Type*> st;
-    st.push_back(TypeBuilder<types::i<32>, cross>::get(Context));
-    st.push_back(TypeBuilder<types::i<32>*, cross>::get(Context));
-    st.push_back(TypeBuilder<types::i<8>*[], cross>::get(Context));
-    static StructType *const result = StructType::get(Context, st);
-    return result;
-  }
-
-  // You may find this a convenient place to put some constants
-  // to help with getelementptr.  They don't have any effect on
-  // the operation of TypeBuilder.
-  enum Fields {
-    FIELD_A,
-    FIELD_B,
-    FIELD_ARRAY
-  };
-};
-}  // namespace llvm
-namespace {
-
-TEST(TypeBuilderTest, Extensions) {
-  EXPECT_EQ(PointerType::getUnqual(StructType::get(
-                                     TypeBuilder<int, false>::get(getGlobalContext()),
-                                     TypeBuilder<int*, false>::get(getGlobalContext()),
-                                     TypeBuilder<void*[], false>::get(getGlobalContext()),
-                                     (void*)0)),
-            (TypeBuilder<MyType*, false>::get(getGlobalContext())));
-  EXPECT_EQ(PointerType::getUnqual(StructType::get(
-                                     TypeBuilder<types::i<32>, false>::get(getGlobalContext()),
-                                     TypeBuilder<types::i<32>*, false>::get(getGlobalContext()),
-                                     TypeBuilder<types::i<8>*[], false>::get(getGlobalContext()),
-                                     (void*)0)),
-            (TypeBuilder<MyPortableType*, false>::get(getGlobalContext())));
-  EXPECT_EQ(PointerType::getUnqual(StructType::get(
-                                     TypeBuilder<types::i<32>, false>::get(getGlobalContext()),
-                                     TypeBuilder<types::i<32>*, false>::get(getGlobalContext()),
-                                     TypeBuilder<types::i<8>*[], false>::get(getGlobalContext()),
-                                     (void*)0)),
-            (TypeBuilder<MyPortableType*, true>::get(getGlobalContext())));
-}
-
-}  // anonymous namespace
index 79ee22c186d986454fd81aa070418b41f38ba045..b9029309273601b49dcfe45a9126cdf69fdb026b 100644 (file)
@@ -11,6 +11,7 @@ set(VMCoreSources
   MDBuilderTest.cpp
   MetadataTest.cpp
   PassManagerTest.cpp
+  TypeBuilderTest.cpp
   ValueMapTest.cpp
   VerifierTest.cpp
   )
diff --git a/unittests/VMCore/TypeBuilderTest.cpp b/unittests/VMCore/TypeBuilderTest.cpp
new file mode 100644 (file)
index 0000000..a746b1f
--- /dev/null
@@ -0,0 +1,254 @@
+//===- llvm/unittest/TypeBuilderTest.cpp - TypeBuilder tests --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/TypeBuilder.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/ADT/ArrayRef.h"
+
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(TypeBuilderTest, Void) {
+  EXPECT_EQ(Type::getVoidTy(getGlobalContext()), (TypeBuilder<void, true>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getVoidTy(getGlobalContext()), (TypeBuilder<void, false>::get(getGlobalContext())));
+  // Special cases for C compatibility:
+  EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
+            (TypeBuilder<void*, false>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
+            (TypeBuilder<const void*, false>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
+            (TypeBuilder<volatile void*, false>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
+            (TypeBuilder<const volatile void*, false>::get(
+              getGlobalContext())));
+}
+
+TEST(TypeBuilderTest, HostIntegers) {
+  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), (TypeBuilder<int8_t, false>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), (TypeBuilder<uint8_t, false>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getInt16Ty(getGlobalContext()), (TypeBuilder<int16_t, false>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getInt16Ty(getGlobalContext()), (TypeBuilder<uint16_t, false>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (TypeBuilder<int32_t, false>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (TypeBuilder<uint32_t, false>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getInt64Ty(getGlobalContext()), (TypeBuilder<int64_t, false>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getInt64Ty(getGlobalContext()), (TypeBuilder<uint64_t, false>::get(getGlobalContext())));
+
+  EXPECT_EQ(IntegerType::get(getGlobalContext(), sizeof(size_t) * CHAR_BIT),
+            (TypeBuilder<size_t, false>::get(getGlobalContext())));
+  EXPECT_EQ(IntegerType::get(getGlobalContext(), sizeof(ptrdiff_t) * CHAR_BIT),
+            (TypeBuilder<ptrdiff_t, false>::get(getGlobalContext())));
+}
+
+TEST(TypeBuilderTest, CrossCompilableIntegers) {
+  EXPECT_EQ(IntegerType::get(getGlobalContext(), 1), (TypeBuilder<types::i<1>, true>::get(getGlobalContext())));
+  EXPECT_EQ(IntegerType::get(getGlobalContext(), 1), (TypeBuilder<types::i<1>, false>::get(getGlobalContext())));
+  EXPECT_EQ(IntegerType::get(getGlobalContext(), 72), (TypeBuilder<types::i<72>, true>::get(getGlobalContext())));
+  EXPECT_EQ(IntegerType::get(getGlobalContext(), 72), (TypeBuilder<types::i<72>, false>::get(getGlobalContext())));
+}
+
+TEST(TypeBuilderTest, Float) {
+  EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<float, false>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<double, false>::get(getGlobalContext())));
+  // long double isn't supported yet.
+  EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<types::ieee_float, true>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<types::ieee_float, false>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<types::ieee_double, true>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<types::ieee_double, false>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getX86_FP80Ty(getGlobalContext()), (TypeBuilder<types::x86_fp80, true>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getX86_FP80Ty(getGlobalContext()), (TypeBuilder<types::x86_fp80, false>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getFP128Ty(getGlobalContext()), (TypeBuilder<types::fp128, true>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getFP128Ty(getGlobalContext()), (TypeBuilder<types::fp128, false>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getPPC_FP128Ty(getGlobalContext()), (TypeBuilder<types::ppc_fp128, true>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getPPC_FP128Ty(getGlobalContext()), (TypeBuilder<types::ppc_fp128, false>::get(getGlobalContext())));
+}
+
+TEST(TypeBuilderTest, Derived) {
+  EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())),
+            (TypeBuilder<int8_t**, false>::get(getGlobalContext())));
+  EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7),
+            (TypeBuilder<int8_t[7], false>::get(getGlobalContext())));
+  EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0),
+            (TypeBuilder<int8_t[], false>::get(getGlobalContext())));
+
+  EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())),
+            (TypeBuilder<types::i<8>**, false>::get(getGlobalContext())));
+  EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7),
+            (TypeBuilder<types::i<8>[7], false>::get(getGlobalContext())));
+  EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0),
+            (TypeBuilder<types::i<8>[], false>::get(getGlobalContext())));
+
+  EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())),
+            (TypeBuilder<types::i<8>**, true>::get(getGlobalContext())));
+  EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7),
+            (TypeBuilder<types::i<8>[7], true>::get(getGlobalContext())));
+  EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0),
+            (TypeBuilder<types::i<8>[], true>::get(getGlobalContext())));
+
+
+  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+            (TypeBuilder<const int8_t, false>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+            (TypeBuilder<volatile int8_t, false>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+            (TypeBuilder<const volatile int8_t, false>::get(getGlobalContext())));
+
+  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+            (TypeBuilder<const types::i<8>, false>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+            (TypeBuilder<volatile types::i<8>, false>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+            (TypeBuilder<const volatile types::i<8>, false>::get(getGlobalContext())));
+
+  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+            (TypeBuilder<const types::i<8>, true>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+            (TypeBuilder<volatile types::i<8>, true>::get(getGlobalContext())));
+  EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+            (TypeBuilder<const volatile types::i<8>, true>::get(getGlobalContext())));
+
+  EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
+            (TypeBuilder<const volatile int8_t*const volatile, false>::get(getGlobalContext())));
+}
+
+TEST(TypeBuilderTest, Functions) {
+  std::vector<Type*> params;
+  EXPECT_EQ(FunctionType::get(Type::getVoidTy(getGlobalContext()), params, false),
+            (TypeBuilder<void(), true>::get(getGlobalContext())));
+  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
+            (TypeBuilder<int8_t(...), false>::get(getGlobalContext())));
+  params.push_back(TypeBuilder<int32_t*, false>::get(getGlobalContext()));
+  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
+            (TypeBuilder<int8_t(const int32_t*), false>::get(getGlobalContext())));
+  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
+            (TypeBuilder<int8_t(const int32_t*, ...), false>::get(getGlobalContext())));
+  params.push_back(TypeBuilder<char*, false>::get(getGlobalContext()));
+  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
+            (TypeBuilder<int8_t(int32_t*, void*), false>::get(getGlobalContext())));
+  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
+            (TypeBuilder<int8_t(int32_t*, char*, ...), false>::get(getGlobalContext())));
+  params.push_back(TypeBuilder<char, false>::get(getGlobalContext()));
+  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
+            (TypeBuilder<int8_t(int32_t*, void*, char), false>::get(getGlobalContext())));
+  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
+            (TypeBuilder<int8_t(int32_t*, char*, char, ...), false>::get(getGlobalContext())));
+  params.push_back(TypeBuilder<char, false>::get(getGlobalContext()));
+  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
+            (TypeBuilder<int8_t(int32_t*, void*, char, char), false>::get(getGlobalContext())));
+  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
+            (TypeBuilder<int8_t(int32_t*, char*, char, char, ...),
+                         false>::get(getGlobalContext())));
+  params.push_back(TypeBuilder<char, false>::get(getGlobalContext()));
+  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
+            (TypeBuilder<int8_t(int32_t*, void*, char, char, char),
+                         false>::get(getGlobalContext())));
+  EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
+            (TypeBuilder<int8_t(int32_t*, char*, char, char, char, ...),
+                         false>::get(getGlobalContext())));
+}
+
+TEST(TypeBuilderTest, Context) {
+  // We used to cache TypeBuilder results in static local variables.  This
+  // produced the same type for different contexts, which of course broke
+  // things.
+  LLVMContext context1;
+  EXPECT_EQ(&context1,
+            &(TypeBuilder<types::i<1>, true>::get(context1))->getContext());
+  LLVMContext context2;
+  EXPECT_EQ(&context2,
+            &(TypeBuilder<types::i<1>, true>::get(context2))->getContext());
+}
+
+struct MyType {
+  int a;
+  int *b;
+  void *array[1];
+};
+
+struct MyPortableType {
+  int32_t a;
+  int32_t *b;
+  void *array[1];
+};
+
+}  // anonymous namespace
+
+namespace llvm {
+template<bool cross> class TypeBuilder<MyType, cross> {
+public:
+  static StructType *get(LLVMContext &Context) {
+    // Using the static result variable ensures that the type is
+    // only looked up once.
+    std::vector<Type*> st;
+    st.push_back(TypeBuilder<int, cross>::get(Context));
+    st.push_back(TypeBuilder<int*, cross>::get(Context));
+    st.push_back(TypeBuilder<void*[], cross>::get(Context));
+    static StructType *const result = StructType::get(Context, st);
+    return result;
+  }
+
+  // You may find this a convenient place to put some constants
+  // to help with getelementptr.  They don't have any effect on
+  // the operation of TypeBuilder.
+  enum Fields {
+    FIELD_A,
+    FIELD_B,
+    FIELD_ARRAY
+  };
+};
+
+template<bool cross> class TypeBuilder<MyPortableType, cross> {
+public:
+  static StructType *get(LLVMContext &Context) {
+    // Using the static result variable ensures that the type is
+    // only looked up once.
+    std::vector<Type*> st;
+    st.push_back(TypeBuilder<types::i<32>, cross>::get(Context));
+    st.push_back(TypeBuilder<types::i<32>*, cross>::get(Context));
+    st.push_back(TypeBuilder<types::i<8>*[], cross>::get(Context));
+    static StructType *const result = StructType::get(Context, st);
+    return result;
+  }
+
+  // You may find this a convenient place to put some constants
+  // to help with getelementptr.  They don't have any effect on
+  // the operation of TypeBuilder.
+  enum Fields {
+    FIELD_A,
+    FIELD_B,
+    FIELD_ARRAY
+  };
+};
+}  // namespace llvm
+namespace {
+
+TEST(TypeBuilderTest, Extensions) {
+  EXPECT_EQ(PointerType::getUnqual(StructType::get(
+                                     TypeBuilder<int, false>::get(getGlobalContext()),
+                                     TypeBuilder<int*, false>::get(getGlobalContext()),
+                                     TypeBuilder<void*[], false>::get(getGlobalContext()),
+                                     (void*)0)),
+            (TypeBuilder<MyType*, false>::get(getGlobalContext())));
+  EXPECT_EQ(PointerType::getUnqual(StructType::get(
+                                     TypeBuilder<types::i<32>, false>::get(getGlobalContext()),
+                                     TypeBuilder<types::i<32>*, false>::get(getGlobalContext()),
+                                     TypeBuilder<types::i<8>*[], false>::get(getGlobalContext()),
+                                     (void*)0)),
+            (TypeBuilder<MyPortableType*, false>::get(getGlobalContext())));
+  EXPECT_EQ(PointerType::getUnqual(StructType::get(
+                                     TypeBuilder<types::i<32>, false>::get(getGlobalContext()),
+                                     TypeBuilder<types::i<32>*, false>::get(getGlobalContext()),
+                                     TypeBuilder<types::i<8>*[], false>::get(getGlobalContext()),
+                                     (void*)0)),
+            (TypeBuilder<MyPortableType*, true>::get(getGlobalContext())));
+}
+
+}  // anonymous namespace