add enum ``LLVMTypeKind`` and modify
``LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty)`` for the new type
-#. ``llvm/include/llvm/IR/TypeBuilder.h``:
-
- add new class to represent new type in the hierarchy
-
#. ``llvm/lib/AsmParser/LLLexer.cpp``:
add ability to parse in the type from text assembly
add enum ``LLVMTypeKind`` and modify
`LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty)` for the new type
-#. ``llvm/include/llvm/IR/TypeBuilder.h``:
-
- add new class to represent new class in the hierarchy
-
#. ``llvm/lib/AsmParser/LLLexer.cpp``:
modify ``lltok::Kind LLLexer::LexIdentifier()`` to add ability to
GV->eraseFromParent();
-.. _create_types:
-
-How to Create Types
--------------------
-
-In generating IR, you may need some complex types. If you know these types
-statically, you can use ``TypeBuilder<...>::get()``, defined in
-``llvm/Support/TypeBuilder.h``, to retrieve them. ``TypeBuilder`` has two forms
-depending on whether you're building types for cross-compilation or native
-library use. ``TypeBuilder<T, true>`` requires that ``T`` be independent of the
-host environment, meaning that it's built out of types from the ``llvm::types``
-(`doxygen <http://llvm.org/doxygen/namespacellvm_1_1types.html>`__) namespace
-and pointers, functions, arrays, etc. built of those. ``TypeBuilder<T, false>``
-additionally allows native C types whose size may depend on the host compiler.
-For example,
-
-.. code-block:: c++
-
- FunctionType *ft = TypeBuilder<types::i<8>(types::i<32>*), true>::get();
-
-is easier to read and write than the equivalent
-
-.. code-block:: c++
-
- std::vector<const Type*> params;
- params.push_back(PointerType::getUnqual(Type::Int32Ty));
- FunctionType *ft = FunctionType::get(Type::Int8Ty, params, false);
-
-See the `class comment
-<http://llvm.org/doxygen/TypeBuilder_8h_source.html#l00001>`_ for more details.
-
.. _threading:
Threads and LLVM
+++ /dev/null
-//===---- 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_IR_TYPEBUILDER_H
-#define LLVM_IR_TYPEBUILDER_H
-
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/LLVMContext.h"
-#include <climits>
-
-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:
-///
-/// \code{.cpp}
-///
-/// struct MyType {
-/// int32 a;
-/// int32 *b;
-/// void *array[1]; // Intended as a flexible array.
-/// };
-/// int8 AFunction(struct MyType *value);
-///
-/// \endcode
-///
-/// 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:
-///
-/// \code{.cpp}
-///
-/// 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),
-/// nullptr);
-/// }
-///
-/// // 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
-///
-/// \endcode
-///
-/// 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
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
-#include "llvm/IR/TypeBuilder.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Object/Archive.h"
M->setTargetTriple(TargetTripleStr);
// Create an empty function named "__main".
- Function *Result;
- if (TargetTriple.isArch64Bit()) {
- Result = Function::Create(
- TypeBuilder<int64_t(void), false>::get(Context),
- GlobalValue::ExternalLinkage, "__main", M.get());
- } else {
- Result = Function::Create(
- TypeBuilder<int32_t(void), false>::get(Context),
- GlobalValue::ExternalLinkage, "__main", M.get());
- }
- BasicBlock *BB = BasicBlock::Create(Context, "__main", Result);
- Builder.SetInsertPoint(BB);
- Value *ReturnVal;
+ Type *ReturnTy;
if (TargetTriple.isArch64Bit())
- ReturnVal = ConstantInt::get(Context, APInt(64, 0));
+ ReturnTy = Type::getInt64Ty(Context);
else
- ReturnVal = ConstantInt::get(Context, APInt(32, 0));
+ ReturnTy = Type::getInt32Ty(Context);
+ Function *Result =
+ Function::Create(FunctionType::get(ReturnTy, {}, false),
+ GlobalValue::ExternalLinkage, "__main", M.get());
+
+ BasicBlock *BB = BasicBlock::Create(Context, "__main", Result);
+ Builder.SetInsertPoint(BB);
+ Value *ReturnVal = ConstantInt::get(ReturnTy, 0);
Builder.CreateRet(ReturnVal);
// Add this new module to the ExecutionEngine.
std::unique_ptr<Module> A, B;
Function *FA1, *FA2, *FB;
createTwoModuleExternCase(A, FA1, B, FB);
- FA2 = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(A.get(), FA1);
+ FA2 = insertSimpleCallFunction(A.get(), FA1);
createJIT(std::move(A));
TheJIT->addModule(std::move(B));
std::unique_ptr<Module> A, B;
Function *FA, *FB;
GlobalVariable *GVA, *GVB, *GVC;
+
A.reset(createEmptyModule("A"));
B.reset(createEmptyModule("B"));
int32_t initialNum = 7;
GVA = insertGlobalInt32(A.get(), "GVA", initialNum);
GVB = insertGlobalInt32(B.get(), "GVB", initialNum);
- FA = startFunction<int32_t(void)>(A.get(), "FA");
+ FA = startFunction(A.get(),
+ FunctionType::get(Builder.getInt32Ty(), {}, false), "FA");
endFunctionWithRet(FA, Builder.CreateLoad(GVA));
- FB = startFunction<int32_t(void)>(B.get(), "FB");
+ FB = startFunction(B.get(),
+ FunctionType::get(Builder.getInt32Ty(), {}, false), "FB");
endFunctionWithRet(FB, Builder.CreateLoad(GVB));
GVC = insertGlobalInt32(B.get(), "GVC", initialNum);
int32_t initialNum = 7;
GlobalVariable *GV = insertGlobalInt32(M.get(), "myglob", initialNum);
- Function *ReturnGlobal = startFunction<int32_t(void)>(M.get(),
- "ReturnGlobal");
+ Function *ReturnGlobal =
+ startFunction(M.get(), FunctionType::get(Builder.getInt32Ty(), {}, false),
+ "ReturnGlobal");
Value *ReadGlobal = Builder.CreateLoad(GV);
endFunctionWithRet(ReturnGlobal, ReadGlobal);
SKIP_UNSUPPORTED_PLATFORM;
int32_t initialNum = 5;
- Function *IncrementGlobal = startFunction<int32_t(void)>(M.get(), "IncrementGlobal");
+ Function *IncrementGlobal = startFunction(
+ M.get(),
+ FunctionType::get(Builder.getInt32Ty(), {}, false),
+ "IncrementGlobal");
GlobalVariable *GV = insertGlobalInt32(M.get(), "my_global", initialNum);
Value *DerefGV = Builder.CreateLoad(GV);
Value *AddResult = Builder.CreateAdd(DerefGV,
unsigned int numLevels = 23;
int32_t innerRetVal= 5;
- Function *Inner = startFunction<int32_t(void)>(M.get(), "Inner");
+ Function *Inner = startFunction(
+ M.get(), FunctionType::get(Builder.getInt32Ty(), {}, false), "Inner");
endFunctionWithRet(Inner, ConstantInt::get(Context, APInt(32, innerRetVal)));
Function *Outer;
for (unsigned int i = 0; i < numLevels; ++i) {
std::stringstream funcName;
funcName << "level_" << i;
- Outer = startFunction<int32_t(void)>(M.get(), funcName.str());
+ Outer = startFunction(M.get(),
+ FunctionType::get(Builder.getInt32Ty(), {}, false),
+ funcName.str());
Value *innerResult = Builder.CreateCall(Inner, {});
endFunctionWithRet(Outer, innerResult);
TEST_F(MCJITTest, multiple_decl_lookups) {
SKIP_UNSUPPORTED_PLATFORM;
- Function *Foo = insertExternalReferenceToFunction<void(void)>(M.get(), "_exit");
+ Function *Foo = insertExternalReferenceToFunction(
+ M.get(), FunctionType::get(Builder.getVoidTy(), {}, false), "_exit");
createJIT(std::move(M));
void *A = TheJIT->getPointerToFunction(Foo);
void *B = TheJIT->getPointerToFunction(Foo);
TEST_F(MCJITTest, lazy_function_creator_pointer) {
SKIP_UNSUPPORTED_PLATFORM;
-
- Function *Foo = insertExternalReferenceToFunction<int32_t(void)>(M.get(),
- "\1Foo");
- startFunction<int32_t(void)>(M.get(), "Parent");
+
+ Function *Foo = insertExternalReferenceToFunction(
+ M.get(), FunctionType::get(Builder.getInt32Ty(), {}, false),
+ "\1Foo");
+ startFunction(M.get(), FunctionType::get(Builder.getInt32Ty(), {}, false),
+ "Parent");
CallInst *Call = Builder.CreateCall(Foo, {});
Builder.CreateRet(Call);
TEST_F(MCJITTest, lazy_function_creator_lambda) {
SKIP_UNSUPPORTED_PLATFORM;
-
- Function *Foo1 = insertExternalReferenceToFunction<int32_t(void)>(M.get(),
- "\1Foo1");
- Function *Foo2 = insertExternalReferenceToFunction<int32_t(void)>(M.get(),
- "\1Foo2");
- startFunction<int32_t(void)>(M.get(), "Parent");
+
+ FunctionType *Int32VoidFnTy =
+ FunctionType::get(Builder.getInt32Ty(), {}, false);
+ Function *Foo1 =
+ insertExternalReferenceToFunction(M.get(), Int32VoidFnTy, "\1Foo1");
+ Function *Foo2 =
+ insertExternalReferenceToFunction(M.get(), Int32VoidFnTy, "\1Foo2");
+ startFunction(M.get(), Int32VoidFnTy, "Parent");
CallInst *Call1 = Builder.CreateCall(Foo1, {});
CallInst *Call2 = Builder.CreateCall(Foo2, {});
Value *Result = Builder.CreateAdd(Call1, Call2);
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/TypeBuilder.h"
+#include "llvm/IR/Type.h"
#include "llvm/Support/CodeGen.h"
namespace llvm {
return M;
}
- template<typename FuncType>
- Function *startFunction(Module *M, StringRef Name) {
- Function *Result = Function::Create(
- TypeBuilder<FuncType, false>::get(Context),
- GlobalValue::ExternalLinkage, Name, M);
+ Function *startFunction(Module *M, FunctionType *FT, StringRef Name) {
+ Function *Result =
+ Function::Create(FT, GlobalValue::ExternalLinkage, Name, M);
BasicBlock *BB = BasicBlock::Create(Context, Name, Result);
Builder.SetInsertPoint(BB);
// Inserts a simple function that invokes Callee and takes the same arguments:
// int Caller(...) { return Callee(...); }
- template<typename Signature>
Function *insertSimpleCallFunction(Module *M, Function *Callee) {
- Function *Result = startFunction<Signature>(M, "caller");
+ Function *Result = startFunction(M, Callee->getFunctionType(), "caller");
SmallVector<Value*, 1> CallArgs;
// int32_t main() { return X; }
// where X is given by returnCode
Function *insertMainFunction(Module *M, uint32_t returnCode) {
- Function *Result = startFunction<int32_t(void)>(M, "main");
+ Function *Result = startFunction(
+ M, FunctionType::get(Type::getInt32Ty(Context), {}, false), "main");
Value *ReturnVal = ConstantInt::get(Context, APInt(32, returnCode));
endFunctionWithRet(Result, ReturnVal);
// int32_t add(int32_t a, int32_t b) { return a + b; }
// in the current module and returns a pointer to it.
Function *insertAddFunction(Module *M, StringRef Name = "add") {
- Function *Result = startFunction<int32_t(int32_t, int32_t)>(M, Name);
+ Function *Result = startFunction(
+ M,
+ FunctionType::get(
+ Type::getInt32Ty(Context),
+ {Type::getInt32Ty(Context), Type::getInt32Ty(Context)}, false),
+ Name);
Function::arg_iterator args = Result->arg_begin();
Value *Arg1 = &*args;
}
// Inserts a declaration to a function defined elsewhere
- template <typename FuncType>
- Function *insertExternalReferenceToFunction(Module *M, StringRef Name) {
- Function *Result = Function::Create(
- TypeBuilder<FuncType, false>::get(Context),
- GlobalValue::ExternalLinkage, Name, M);
- return Result;
- }
-
- // Inserts an declaration to a function defined elsewhere
- Function *insertExternalReferenceToFunction(Module *M, StringRef Name,
- FunctionType *FuncTy) {
- Function *Result = Function::Create(FuncTy,
- GlobalValue::ExternalLinkage,
- Name, M);
+ Function *insertExternalReferenceToFunction(Module *M, FunctionType *FTy,
+ StringRef Name) {
+ Function *Result =
+ Function::Create(FTy, GlobalValue::ExternalLinkage, Name, M);
return Result;
}
GlobalVariable *insertGlobalInt32(Module *M,
StringRef name,
int32_t InitialValue) {
- Type *GlobalTy = TypeBuilder<types::i<32>, true>::get(Context);
+ Type *GlobalTy = Type::getInt32Ty(Context);
Constant *IV = ConstantInt::get(Context, APInt(32, InitialValue));
GlobalVariable *Global = new GlobalVariable(*M,
GlobalTy,
Function *insertAccumulateFunction(Module *M,
Function *Helper = nullptr,
StringRef Name = "accumulate") {
- Function *Result = startFunction<int32_t(int32_t)>(M, Name);
+ Function *Result =
+ startFunction(M,
+ FunctionType::get(Type::getInt32Ty(Context),
+ {Type::getInt32Ty(Context)}, false),
+ Name);
if (!Helper)
Helper = Result;
B.reset(createEmptyModule("B"));
Function *FAExtern_in_B = insertExternalReferenceToFunction(B.get(), FA);
- FB = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(B.get(), FAExtern_in_B);
+ FB = insertSimpleCallFunction(B.get(), FAExtern_in_B);
C.reset(createEmptyModule("C"));
Function *FBExtern_in_C = insertExternalReferenceToFunction(C.get(), FB);
- FC = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(C.get(), FBExtern_in_C);
+ FC = insertSimpleCallFunction(C.get(), FBExtern_in_C);
}
// Module A { Function FA },
B.reset(createEmptyModule("B"));
Function *FAExtern_in_B = insertExternalReferenceToFunction(B.get(), FA);
- FB = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(B.get(),
- FAExtern_in_B);
+ FB = insertSimpleCallFunction(B.get(), FAExtern_in_B);
}
// Module A { Function FA },
B.reset(createEmptyModule("B"));
Function *FAExtern_in_B = insertExternalReferenceToFunction(B.get(), FA);
- FB = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(B.get(), FAExtern_in_B);
+ FB = insertSimpleCallFunction(B.get(), FAExtern_in_B);
C.reset(createEmptyModule("C"));
Function *FAExtern_in_C = insertExternalReferenceToFunction(C.get(), FA);
- FC = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(C.get(), FAExtern_in_C);
+ FC = insertSimpleCallFunction(C.get(), FAExtern_in_C);
}
};
TEST(IndirectionUtilsTest, MakeStub) {
LLVMContext Context;
ModuleBuilder MB(Context, "x86_64-apple-macosx10.10", "");
- Function *F = MB.createFunctionDecl<void(DummyStruct, DummyStruct)>("");
+ FunctionType *FTy = FunctionType::get(
+ Type::getVoidTy(Context),
+ {getDummyStructTy(Context), getDummyStructTy(Context)}, false);
+ Function *F = MB.createFunctionDecl(FTy, "");
AttributeSet FnAttrs = AttributeSet::get(
Context, AttrBuilder().addAttribute(Attribute::NoUnwind));
AttributeSet RetAttrs; // None
if (!SupportsJIT)
return;
+ Type *Int32Ty = IntegerType::get(Context, 32);
+
ExecutionSession ES;
auto MM = std::make_shared<SectionMemoryManagerWrapper>();
ModuleBuilder MB1(Context, "", "dummy");
{
MB1.getModule()->setDataLayout(TM->createDataLayout());
- Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("bar");
+ Function *BarImpl =
+ MB1.createFunctionDecl(FunctionType::get(Int32Ty, {}, false), "bar");
BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl);
IRBuilder<> Builder(BarEntry);
IntegerType *Int32Ty = IntegerType::get(Context, 32);
ModuleBuilder MB2(Context, "", "dummy");
{
MB2.getModule()->setDataLayout(TM->createDataLayout());
- Function *BarDecl = MB2.createFunctionDecl<int32_t(void)>("bar");
- Function *FooImpl = MB2.createFunctionDecl<int32_t(void)>("foo");
+ Function *BarDecl =
+ MB2.createFunctionDecl(FunctionType::get(Int32Ty, {}, false), "bar");
+ Function *FooImpl =
+ MB2.createFunctionDecl(FunctionType::get(Int32Ty, {}, false), "foo");
BasicBlock *FooEntry = BasicBlock::Create(Context, "entry", FooImpl);
IRBuilder<> Builder(FooEntry);
Builder.CreateRet(Builder.CreateCall(BarDecl));
if (!SupportsJIT)
return;
+ Type *Int32Ty = IntegerType::get(Context, 32);
+
ExecutionSession ES;
auto MM = std::make_shared<SectionMemoryManagerWrapper>();
ModuleBuilder MB1(Context, "", "dummy");
{
MB1.getModule()->setDataLayout(TM->createDataLayout());
- Function *BarImpl = MB1.createFunctionDecl<int32_t(void)>("foo");
+ Function *BarImpl =
+ MB1.createFunctionDecl(FunctionType::get(Int32Ty, {}, false), "foo");
BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl);
IRBuilder<> Builder(BarEntry);
IntegerType *Int32Ty = IntegerType::get(Context, 32);
ModuleBuilder MB2(Context, "", "dummy");
{
MB2.getModule()->setDataLayout(TM->createDataLayout());
- Function *BarImpl = MB2.createFunctionDecl<int32_t(void)>("bar");
+ Function *BarImpl =
+ MB2.createFunctionDecl(FunctionType::get(Int32Ty, {}, false), "bar");
BasicBlock *BarEntry = BasicBlock::Create(Context, "entry", BarImpl);
IRBuilder<> Builder(BarEntry);
IntegerType *Int32Ty = IntegerType::get(Context, 32);
protected:
std::unique_ptr<Module> createTestModule(const Triple &TT) {
ModuleBuilder MB(Context, TT.str(), "");
- Function *TestFunc = MB.createFunctionDecl<int()>("testFunc");
- Function *Main = MB.createFunctionDecl<int(int, char*[])>("main");
+ Type *IntTy = Type::getScalarTy<int>(Context);
+ Function *TestFunc =
+ MB.createFunctionDecl(FunctionType::get(IntTy, {}, false), "testFunc");
+ Function *Main = MB.createFunctionDecl(
+ FunctionType::get(
+ IntTy,
+ {IntTy, Type::getInt8PtrTy(Context)->getPointerTo()},
+ false),
+ "main");
Main->getBasicBlockList().push_back(BasicBlock::Create(Context));
IRBuilder<> B(&Main->back());
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/TypeBuilder.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
ModuleBuilder(LLVMContext &Context, StringRef Triple,
StringRef Name);
- template <typename FuncType>
- Function* createFunctionDecl(StringRef Name) {
- return Function::Create(
- TypeBuilder<FuncType, false>::get(M->getContext()),
- GlobalValue::ExternalLinkage, Name, M.get());
+ Function *createFunctionDecl(FunctionType *FTy, StringRef Name) {
+ return Function::Create(FTy, GlobalValue::ExternalLinkage, Name, M.get());
}
Module* getModule() { return M.get(); }
int X[256];
};
-// TypeBuilder specialization for DummyStruct.
-template <bool XCompile>
-class TypeBuilder<DummyStruct, XCompile> {
-public:
- static StructType *get(LLVMContext &Context) {
- return StructType::get(
- TypeBuilder<types::i<32>[256], XCompile>::get(Context));
- }
-};
+inline StructType *getDummyStructTy(LLVMContext &Context) {
+ return StructType::get(ArrayType::get(Type::getInt32Ty(Context), 256));
+}
template <typename HandleT, typename ModuleT>
class MockBaseLayer {
ModuleBuilder MB(*TSCtx.getContext(), TM->getTargetTriple().str(), "dummy");
MB.getModule()->setDataLayout(TM->createDataLayout());
- Function *FooImpl = MB.createFunctionDecl<void()>("foo");
+ Function *FooImpl = MB.createFunctionDecl(
+ FunctionType::get(Type::getVoidTy(*TSCtx.getContext()), {}, false),
+ "foo");
BasicBlock *FooEntry =
BasicBlock::Create(*TSCtx.getContext(), "entry", FooImpl);
IRBuilder<> B1(FooEntry);
B1.CreateRetVoid();
- Function *BarImpl = MB.createFunctionDecl<void()>("bar");
+ Function *BarImpl = MB.createFunctionDecl(
+ FunctionType::get(Type::getVoidTy(*TSCtx.getContext()), {}, false),
+ "bar");
BasicBlock *BarEntry =
BasicBlock::Create(*TSCtx.getContext(), "entry", BarImpl);
IRBuilder<> B2(BarEntry);
FunkySimpleCompiler(TargetMachine &TM) : SimpleCompiler(TM) {}
CompileResult operator()(Module &M) {
- Function *BarImpl =
- Function::Create(TypeBuilder<void(), false>::get(M.getContext()),
- GlobalValue::ExternalLinkage, "bar", &M);
+ Function *BarImpl = Function::Create(
+ FunctionType::get(Type::getVoidTy(M.getContext()), {}, false),
+ GlobalValue::ExternalLinkage, "bar", &M);
BasicBlock *BarEntry =
BasicBlock::Create(M.getContext(), "entry", BarImpl);
IRBuilder<> B(BarEntry);
ModuleBuilder MB(*TSCtx.getContext(), TM->getTargetTriple().str(), "dummy");
MB.getModule()->setDataLayout(TM->createDataLayout());
- Function *FooImpl = MB.createFunctionDecl<void()>("foo");
+ Function *FooImpl = MB.createFunctionDecl(
+ FunctionType::get(Type::getVoidTy(*TSCtx.getContext()), {}, false),
+ "foo");
BasicBlock *FooEntry =
BasicBlock::Create(*TSCtx.getContext(), "entry", FooImpl);
IRBuilder<> B(FooEntry);
LLVMContext Ctx;
ModuleBuilder MB(Ctx, TM->getTargetTriple().str(), "TestModule");
MB.getModule()->setDataLayout(TM->createDataLayout());
- auto *Main = MB.createFunctionDecl<void(int, char**)>("main");
+ auto *Main = MB.createFunctionDecl(
+ FunctionType::get(Type::getInt32Ty(Ctx),
+ {Type::getInt32Ty(Ctx),
+ Type::getInt8PtrTy(Ctx)->getPointerTo()},
+ false),
+ "main");
Main->getBasicBlockList().push_back(BasicBlock::Create(Ctx));
IRBuilder<> B(&Main->back());
B.CreateRet(ConstantInt::getSigned(Type::getInt32Ty(Ctx), 42));
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/TypeBuilder.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"
CFGHolder::CFGHolder(StringRef ModuleName, StringRef FunctionName)
: Context(llvm::make_unique<LLVMContext>()),
M(llvm::make_unique<Module>(ModuleName, *Context)) {
- FunctionType *FTy = TypeBuilder<void(), false>::get(*Context);
+ FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Context), {}, false);
F = cast<Function>(M->getOrInsertFunction(FunctionName, FTy));
}
CFGHolder::~CFGHolder() = default;
ModuleTest.cpp
PassManagerTest.cpp
PatternMatch.cpp
- TypeBuilderTest.cpp
TypesTest.cpp
UseTest.cpp
UserTest.cpp
+++ /dev/null
-//===- 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/IR/TypeBuilder.h"
-#include "llvm/IR/LLVMContext.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-namespace {
-
-TEST(TypeBuilderTest, Void) {
- LLVMContext Context;
- EXPECT_EQ(Type::getVoidTy(Context), (TypeBuilder<void, true>::get(Context)));
- EXPECT_EQ(Type::getVoidTy(Context), (TypeBuilder<void, false>::get(Context)));
- // Special cases for C compatibility:
- EXPECT_EQ(Type::getInt8PtrTy(Context),
- (TypeBuilder<void *, false>::get(Context)));
- EXPECT_EQ(Type::getInt8PtrTy(Context),
- (TypeBuilder<const void *, false>::get(Context)));
- EXPECT_EQ(Type::getInt8PtrTy(Context),
- (TypeBuilder<volatile void *, false>::get(Context)));
- EXPECT_EQ(Type::getInt8PtrTy(Context),
- (TypeBuilder<const volatile void *, false>::get(Context)));
-}
-
-TEST(TypeBuilderTest, HostIntegers) {
- LLVMContext Context;
- EXPECT_EQ(Type::getInt8Ty(Context),
- (TypeBuilder<int8_t, false>::get(Context)));
- EXPECT_EQ(Type::getInt8Ty(Context),
- (TypeBuilder<uint8_t, false>::get(Context)));
- EXPECT_EQ(Type::getInt16Ty(Context),
- (TypeBuilder<int16_t, false>::get(Context)));
- EXPECT_EQ(Type::getInt16Ty(Context),
- (TypeBuilder<uint16_t, false>::get(Context)));
- EXPECT_EQ(Type::getInt32Ty(Context),
- (TypeBuilder<int32_t, false>::get(Context)));
- EXPECT_EQ(Type::getInt32Ty(Context),
- (TypeBuilder<uint32_t, false>::get(Context)));
- EXPECT_EQ(Type::getInt64Ty(Context),
- (TypeBuilder<int64_t, false>::get(Context)));
- EXPECT_EQ(Type::getInt64Ty(Context),
- (TypeBuilder<uint64_t, false>::get(Context)));
-
- EXPECT_EQ(IntegerType::get(Context, sizeof(size_t) * CHAR_BIT),
- (TypeBuilder<size_t, false>::get(Context)));
- EXPECT_EQ(IntegerType::get(Context, sizeof(ptrdiff_t) * CHAR_BIT),
- (TypeBuilder<ptrdiff_t, false>::get(Context)));
-}
-
-TEST(TypeBuilderTest, CrossCompilableIntegers) {
- LLVMContext Context;
- EXPECT_EQ(IntegerType::get(Context, 1),
- (TypeBuilder<types::i<1>, true>::get(Context)));
- EXPECT_EQ(IntegerType::get(Context, 1),
- (TypeBuilder<types::i<1>, false>::get(Context)));
- EXPECT_EQ(IntegerType::get(Context, 72),
- (TypeBuilder<types::i<72>, true>::get(Context)));
- EXPECT_EQ(IntegerType::get(Context, 72),
- (TypeBuilder<types::i<72>, false>::get(Context)));
-}
-
-TEST(TypeBuilderTest, Float) {
- LLVMContext Context;
- EXPECT_EQ(Type::getFloatTy(Context),
- (TypeBuilder<float, false>::get(Context)));
- EXPECT_EQ(Type::getDoubleTy(Context),
- (TypeBuilder<double, false>::get(Context)));
- // long double isn't supported yet.
- EXPECT_EQ(Type::getFloatTy(Context),
- (TypeBuilder<types::ieee_float, true>::get(Context)));
- EXPECT_EQ(Type::getFloatTy(Context),
- (TypeBuilder<types::ieee_float, false>::get(Context)));
- EXPECT_EQ(Type::getDoubleTy(Context),
- (TypeBuilder<types::ieee_double, true>::get(Context)));
- EXPECT_EQ(Type::getDoubleTy(Context),
- (TypeBuilder<types::ieee_double, false>::get(Context)));
- EXPECT_EQ(Type::getX86_FP80Ty(Context),
- (TypeBuilder<types::x86_fp80, true>::get(Context)));
- EXPECT_EQ(Type::getX86_FP80Ty(Context),
- (TypeBuilder<types::x86_fp80, false>::get(Context)));
- EXPECT_EQ(Type::getFP128Ty(Context),
- (TypeBuilder<types::fp128, true>::get(Context)));
- EXPECT_EQ(Type::getFP128Ty(Context),
- (TypeBuilder<types::fp128, false>::get(Context)));
- EXPECT_EQ(Type::getPPC_FP128Ty(Context),
- (TypeBuilder<types::ppc_fp128, true>::get(Context)));
- EXPECT_EQ(Type::getPPC_FP128Ty(Context),
- (TypeBuilder<types::ppc_fp128, false>::get(Context)));
-}
-
-TEST(TypeBuilderTest, Derived) {
- LLVMContext Context;
- EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(Context)),
- (TypeBuilder<int8_t **, false>::get(Context)));
- EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 7),
- (TypeBuilder<int8_t[7], false>::get(Context)));
- EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 0),
- (TypeBuilder<int8_t[], false>::get(Context)));
-
- EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(Context)),
- (TypeBuilder<types::i<8> **, false>::get(Context)));
- EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 7),
- (TypeBuilder<types::i<8>[7], false>::get(Context)));
- EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 0),
- (TypeBuilder<types::i<8>[], false>::get(Context)));
-
- EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(Context)),
- (TypeBuilder<types::i<8> **, true>::get(Context)));
- EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 7),
- (TypeBuilder<types::i<8>[7], true>::get(Context)));
- EXPECT_EQ(ArrayType::get(Type::getInt8Ty(Context), 0),
- (TypeBuilder<types::i<8>[], true>::get(Context)));
-
- EXPECT_EQ(Type::getInt8Ty(Context),
- (TypeBuilder<const int8_t, false>::get(Context)));
- EXPECT_EQ(Type::getInt8Ty(Context),
- (TypeBuilder<volatile int8_t, false>::get(Context)));
- EXPECT_EQ(Type::getInt8Ty(Context),
- (TypeBuilder<const volatile int8_t, false>::get(Context)));
-
- EXPECT_EQ(Type::getInt8Ty(Context),
- (TypeBuilder<const types::i<8>, false>::get(Context)));
- EXPECT_EQ(Type::getInt8Ty(Context),
- (TypeBuilder<volatile types::i<8>, false>::get(Context)));
- EXPECT_EQ(Type::getInt8Ty(Context),
- (TypeBuilder<const volatile types::i<8>, false>::get(Context)));
-
- EXPECT_EQ(Type::getInt8Ty(Context),
- (TypeBuilder<const types::i<8>, true>::get(Context)));
- EXPECT_EQ(Type::getInt8Ty(Context),
- (TypeBuilder<volatile types::i<8>, true>::get(Context)));
- EXPECT_EQ(Type::getInt8Ty(Context),
- (TypeBuilder<const volatile types::i<8>, true>::get(Context)));
-
- EXPECT_EQ(Type::getInt8PtrTy(Context),
- (TypeBuilder<const volatile int8_t *const volatile, false>::get(
- Context)));
-}
-
-TEST(TypeBuilderTest, Functions) {
- LLVMContext Context;
- std::vector<Type*> params;
- EXPECT_EQ(FunctionType::get(Type::getVoidTy(Context), params, false),
- (TypeBuilder<void(), true>::get(Context)));
- EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, true),
- (TypeBuilder<int8_t(...), false>::get(Context)));
- params.push_back(TypeBuilder<int32_t *, false>::get(Context));
- EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, false),
- (TypeBuilder<int8_t(const int32_t *), false>::get(Context)));
- EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, true),
- (TypeBuilder<int8_t(const int32_t *, ...), false>::get(Context)));
- params.push_back(TypeBuilder<char *, false>::get(Context));
- EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, false),
- (TypeBuilder<int8_t(int32_t *, void *), false>::get(Context)));
- EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, true),
- (TypeBuilder<int8_t(int32_t *, char *, ...), false>::get(Context)));
- params.push_back(TypeBuilder<char, false>::get(Context));
- EXPECT_EQ(
- FunctionType::get(Type::getInt8Ty(Context), params, false),
- (TypeBuilder<int8_t(int32_t *, void *, char), false>::get(Context)));
- EXPECT_EQ(
- FunctionType::get(Type::getInt8Ty(Context), params, true),
- (TypeBuilder<int8_t(int32_t *, char *, char, ...), false>::get(Context)));
- params.push_back(TypeBuilder<char, false>::get(Context));
- EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, false),
- (TypeBuilder<int8_t(int32_t *, void *, char, char), false>::get(
- Context)));
- EXPECT_EQ(
- FunctionType::get(Type::getInt8Ty(Context), params, true),
- (TypeBuilder<int8_t(int32_t *, char *, char, char, ...), false>::get(
- Context)));
- params.push_back(TypeBuilder<char, false>::get(Context));
- EXPECT_EQ(
- FunctionType::get(Type::getInt8Ty(Context), params, false),
- (TypeBuilder<int8_t(int32_t *, void *, char, char, char), false>::get(
- Context)));
- EXPECT_EQ(FunctionType::get(Type::getInt8Ty(Context), params, true),
- (TypeBuilder<int8_t(int32_t *, char *, char, char, char, ...),
- false>::get(Context)));
-}
-
-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) {
- LLVMContext Context;
- EXPECT_EQ(PointerType::getUnqual(
- StructType::get(TypeBuilder<int, false>::get(Context),
- TypeBuilder<int *, false>::get(Context),
- TypeBuilder<void *[], false>::get(Context))),
- (TypeBuilder<MyType *, false>::get(Context)));
- EXPECT_EQ(PointerType::getUnqual(StructType::get(
- TypeBuilder<types::i<32>, false>::get(Context),
- TypeBuilder<types::i<32> *, false>::get(Context),
- TypeBuilder<types::i<8> *[], false>::get(Context))),
- (TypeBuilder<MyPortableType *, false>::get(Context)));
- EXPECT_EQ(PointerType::getUnqual(StructType::get(
- TypeBuilder<types::i<32>, false>::get(Context),
- TypeBuilder<types::i<32> *, false>::get(Context),
- TypeBuilder<types::i<8> *[], false>::get(Context))),
- (TypeBuilder<MyPortableType *, true>::get(Context)));
-}
-
-} // anonymous namespace
"PassBuilderCallbacksTest.cpp",
"PassManagerTest.cpp",
"PatternMatch.cpp",
- "TypeBuilderTest.cpp",
"TypesTest.cpp",
"UseTest.cpp",
"UserTest.cpp",