diff options
Diffstat (limited to 'unittests/VMCore')
-rw-r--r-- | unittests/VMCore/CMakeLists.txt | 35 | ||||
-rw-r--r-- | unittests/VMCore/IRBuilderTest.cpp | 99 | ||||
-rw-r--r-- | unittests/VMCore/InstructionsTest.cpp | 6 | ||||
-rw-r--r-- | unittests/VMCore/MDBuilderTest.cpp | 107 | ||||
-rw-r--r-- | unittests/VMCore/Makefile | 2 | ||||
-rw-r--r-- | unittests/VMCore/PassManagerTest.cpp | 2 | ||||
-rw-r--r-- | unittests/VMCore/TypeBuilderTest.cpp | 254 | ||||
-rw-r--r-- | unittests/VMCore/TypesTest.cpp | 30 |
8 files changed, 530 insertions, 5 deletions
diff --git a/unittests/VMCore/CMakeLists.txt b/unittests/VMCore/CMakeLists.txt new file mode 100644 index 0000000..4025c7a --- /dev/null +++ b/unittests/VMCore/CMakeLists.txt @@ -0,0 +1,35 @@ +set(LLVM_LINK_COMPONENTS + asmparser + core + ipa + ) + +set(VMCoreSources + ConstantsTest.cpp + DominatorTreeTest.cpp + IRBuilderTest.cpp + InstructionsTest.cpp + MDBuilderTest.cpp + MetadataTest.cpp + PassManagerTest.cpp + TypeBuilderTest.cpp + TypesTest.cpp + ValueMapTest.cpp + VerifierTest.cpp + ) + +# MSVC9 and 8 cannot compile ValueMapTest.cpp due to their bug. +# See issue#331418 in Visual Studio. +if(MSVC AND MSVC_VERSION LESS 1600) + list(REMOVE_ITEM VMCoreSources ValueMapTest.cpp) +endif() + +# HACK: Declare a couple of source files as optionally compiled to satisfy the +# missing-file-checker in LLVM's weird CMake build. +set(LLVM_OPTIONAL_SOURCES + ValueMapTest.cpp + ) + +add_llvm_unittest(VMCoreTests + ${VMCoreSources} + ) diff --git a/unittests/VMCore/IRBuilderTest.cpp b/unittests/VMCore/IRBuilderTest.cpp new file mode 100644 index 0000000..b6a3795 --- /dev/null +++ b/unittests/VMCore/IRBuilderTest.cpp @@ -0,0 +1,99 @@ +//===- llvm/unittest/VMCore/IRBuilderTest.cpp - IRBuilder tests -----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/BasicBlock.h" +#include "llvm/Function.h" +#include "llvm/IRBuilder.h" +#include "llvm/IntrinsicInst.h" +#include "llvm/LLVMContext.h" +#include "llvm/MDBuilder.h" +#include "llvm/Module.h" +#include "llvm/ADT/OwningPtr.h" + +#include "gtest/gtest.h" + +using namespace llvm; + +namespace { + +class IRBuilderTest : public testing::Test { +protected: + virtual void SetUp() { + M.reset(new Module("MyModule", getGlobalContext())); + FunctionType *FTy = FunctionType::get(Type::getVoidTy(getGlobalContext()), + /*isVarArg=*/false); + F = Function::Create(FTy, Function::ExternalLinkage, "", M.get()); + BB = BasicBlock::Create(getGlobalContext(), "", F); + } + + virtual void TearDown() { + BB = 0; + M.reset(); + } + + OwningPtr<Module> M; + Function *F; + BasicBlock *BB; +}; + +TEST_F(IRBuilderTest, Lifetime) { + IRBuilder<> Builder(BB); + AllocaInst *Var1 = Builder.CreateAlloca(Builder.getInt8Ty()); + AllocaInst *Var2 = Builder.CreateAlloca(Builder.getInt32Ty()); + AllocaInst *Var3 = Builder.CreateAlloca(Builder.getInt8Ty(), + Builder.getInt32(123)); + + CallInst *Start1 = Builder.CreateLifetimeStart(Var1); + CallInst *Start2 = Builder.CreateLifetimeStart(Var2); + CallInst *Start3 = Builder.CreateLifetimeStart(Var3, Builder.getInt64(100)); + + EXPECT_EQ(Start1->getArgOperand(0), Builder.getInt64(-1)); + EXPECT_EQ(Start2->getArgOperand(0), Builder.getInt64(-1)); + EXPECT_EQ(Start3->getArgOperand(0), Builder.getInt64(100)); + + EXPECT_EQ(Start1->getArgOperand(1), Var1); + EXPECT_NE(Start2->getArgOperand(1), Var2); + EXPECT_EQ(Start3->getArgOperand(1), Var3); + + Value *End1 = Builder.CreateLifetimeEnd(Var1); + Builder.CreateLifetimeEnd(Var2); + Builder.CreateLifetimeEnd(Var3); + + IntrinsicInst *II_Start1 = dyn_cast<IntrinsicInst>(Start1); + IntrinsicInst *II_End1 = dyn_cast<IntrinsicInst>(End1); + ASSERT_TRUE(II_Start1 != NULL); + EXPECT_EQ(II_Start1->getIntrinsicID(), Intrinsic::lifetime_start); + ASSERT_TRUE(II_End1 != NULL); + EXPECT_EQ(II_End1->getIntrinsicID(), Intrinsic::lifetime_end); +} + +TEST_F(IRBuilderTest, CreateCondBr) { + IRBuilder<> Builder(BB); + BasicBlock *TBB = BasicBlock::Create(getGlobalContext(), "", F); + BasicBlock *FBB = BasicBlock::Create(getGlobalContext(), "", F); + + BranchInst *BI = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB); + TerminatorInst *TI = BB->getTerminator(); + EXPECT_EQ(BI, TI); + EXPECT_EQ(2u, TI->getNumSuccessors()); + EXPECT_EQ(TBB, TI->getSuccessor(0)); + EXPECT_EQ(FBB, TI->getSuccessor(1)); + + BI->eraseFromParent(); + MDNode *Weights = MDBuilder(getGlobalContext()).createBranchWeights(42, 13); + BI = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB, Weights); + TI = BB->getTerminator(); + EXPECT_EQ(BI, TI); + EXPECT_EQ(2u, TI->getNumSuccessors()); + EXPECT_EQ(TBB, TI->getSuccessor(0)); + EXPECT_EQ(FBB, TI->getSuccessor(1)); + EXPECT_EQ(Weights, TI->getMetadata(LLVMContext::MD_prof)); +} + +} diff --git a/unittests/VMCore/InstructionsTest.cpp b/unittests/VMCore/InstructionsTest.cpp index d002101..72cdc8b 100644 --- a/unittests/VMCore/InstructionsTest.cpp +++ b/unittests/VMCore/InstructionsTest.cpp @@ -7,16 +7,16 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Instructions.h" #include "llvm/BasicBlock.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" +#include "llvm/IRBuilder.h" +#include "llvm/Instructions.h" #include "llvm/LLVMContext.h" +#include "llvm/MDBuilder.h" #include "llvm/Operator.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Analysis/ValueTracking.h" -#include "llvm/Support/MDBuilder.h" -#include "llvm/Support/IRBuilder.h" #include "llvm/Target/TargetData.h" #include "gtest/gtest.h" diff --git a/unittests/VMCore/MDBuilderTest.cpp b/unittests/VMCore/MDBuilderTest.cpp new file mode 100644 index 0000000..847039b --- /dev/null +++ b/unittests/VMCore/MDBuilderTest.cpp @@ -0,0 +1,107 @@ +//===- llvm/unittests/MDBuilderTest.cpp - MDBuilder unit tests ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IRBuilder.h" +#include "llvm/MDBuilder.h" +#include "llvm/Operator.h" + +#include "gtest/gtest.h" + +using namespace llvm; + +namespace { + +class MDBuilderTest : public testing::Test { +protected: + LLVMContext Context; +}; + +TEST_F(MDBuilderTest, createString) { + MDBuilder MDHelper(Context); + MDString *Str0 = MDHelper.createString(""); + MDString *Str1 = MDHelper.createString("string"); + EXPECT_EQ(Str0->getString(), StringRef("")); + EXPECT_EQ(Str1->getString(), StringRef("string")); +} +TEST_F(MDBuilderTest, createFPMath) { + MDBuilder MDHelper(Context); + MDNode *MD0 = MDHelper.createFPMath(0.0); + MDNode *MD1 = MDHelper.createFPMath(1.0); + EXPECT_EQ(MD0, (MDNode *)0); + EXPECT_NE(MD1, (MDNode *)0); + EXPECT_EQ(MD1->getNumOperands(), 1U); + Value *Op = MD1->getOperand(0); + EXPECT_TRUE(isa<ConstantFP>(Op)); + EXPECT_TRUE(Op->getType()->isFloatingPointTy()); + ConstantFP *Val = cast<ConstantFP>(Op); + EXPECT_TRUE(Val->isExactlyValue(1.0)); +} +TEST_F(MDBuilderTest, createRangeMetadata) { + MDBuilder MDHelper(Context); + APInt A(8, 1), B(8, 2); + MDNode *R0 = MDHelper.createRange(A, A); + MDNode *R1 = MDHelper.createRange(A, B); + EXPECT_EQ(R0, (MDNode *)0); + EXPECT_NE(R1, (MDNode *)0); + EXPECT_EQ(R1->getNumOperands(), 2U); + EXPECT_TRUE(isa<ConstantInt>(R1->getOperand(0))); + EXPECT_TRUE(isa<ConstantInt>(R1->getOperand(1))); + ConstantInt *C0 = cast<ConstantInt>(R1->getOperand(0)); + ConstantInt *C1 = cast<ConstantInt>(R1->getOperand(1)); + EXPECT_EQ(C0->getValue(), A); + EXPECT_EQ(C1->getValue(), B); +} +TEST_F(MDBuilderTest, createAnonymousTBAARoot) { + MDBuilder MDHelper(Context); + MDNode *R0 = MDHelper.createAnonymousTBAARoot(); + MDNode *R1 = MDHelper.createAnonymousTBAARoot(); + EXPECT_NE(R0, R1); + EXPECT_GE(R0->getNumOperands(), 1U); + EXPECT_GE(R1->getNumOperands(), 1U); + EXPECT_EQ(R0->getOperand(0), R0); + EXPECT_EQ(R1->getOperand(0), R1); + EXPECT_TRUE(R0->getNumOperands() == 1 || R0->getOperand(1) == 0); + EXPECT_TRUE(R1->getNumOperands() == 1 || R1->getOperand(1) == 0); +} +TEST_F(MDBuilderTest, createTBAARoot) { + MDBuilder MDHelper(Context); + MDNode *R0 = MDHelper.createTBAARoot("Root"); + MDNode *R1 = MDHelper.createTBAARoot("Root"); + EXPECT_EQ(R0, R1); + EXPECT_GE(R0->getNumOperands(), 1U); + EXPECT_TRUE(isa<MDString>(R0->getOperand(0))); + EXPECT_EQ(cast<MDString>(R0->getOperand(0))->getString(), "Root"); + EXPECT_TRUE(R0->getNumOperands() == 1 || R0->getOperand(1) == 0); +} +TEST_F(MDBuilderTest, createTBAANode) { + MDBuilder MDHelper(Context); + MDNode *R = MDHelper.createTBAARoot("Root"); + MDNode *N0 = MDHelper.createTBAANode("Node", R); + MDNode *N1 = MDHelper.createTBAANode("edoN", R); + MDNode *N2 = MDHelper.createTBAANode("Node", R, true); + MDNode *N3 = MDHelper.createTBAANode("Node", R); + EXPECT_EQ(N0, N3); + EXPECT_NE(N0, N1); + EXPECT_NE(N0, N2); + EXPECT_GE(N0->getNumOperands(), 2U); + EXPECT_GE(N1->getNumOperands(), 2U); + EXPECT_GE(N2->getNumOperands(), 3U); + EXPECT_TRUE(isa<MDString>(N0->getOperand(0))); + EXPECT_TRUE(isa<MDString>(N1->getOperand(0))); + EXPECT_TRUE(isa<MDString>(N2->getOperand(0))); + EXPECT_EQ(cast<MDString>(N0->getOperand(0))->getString(), "Node"); + EXPECT_EQ(cast<MDString>(N1->getOperand(0))->getString(), "edoN"); + EXPECT_EQ(cast<MDString>(N2->getOperand(0))->getString(), "Node"); + EXPECT_EQ(N0->getOperand(1), R); + EXPECT_EQ(N1->getOperand(1), R); + EXPECT_EQ(N2->getOperand(1), R); + EXPECT_TRUE(isa<ConstantInt>(N2->getOperand(2))); + EXPECT_EQ(cast<ConstantInt>(N2->getOperand(2))->getZExtValue(), 1U); +} +} diff --git a/unittests/VMCore/Makefile b/unittests/VMCore/Makefile index df55065..d743dc5 100644 --- a/unittests/VMCore/Makefile +++ b/unittests/VMCore/Makefile @@ -9,7 +9,7 @@ LEVEL = ../.. TESTNAME = VMCore -LINK_COMPONENTS := core support target ipa asmparser +LINK_COMPONENTS := core ipa asmparser include $(LEVEL)/Makefile.config include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest diff --git a/unittests/VMCore/PassManagerTest.cpp b/unittests/VMCore/PassManagerTest.cpp index af845b0..60d33c1 100644 --- a/unittests/VMCore/PassManagerTest.cpp +++ b/unittests/VMCore/PassManagerTest.cpp @@ -324,7 +324,7 @@ namespace llvm { Passes.run(M); // Some passes must be rerun because a pass that modified the - // module/function was run inbetween + // module/function was run in between EXPECT_EQ(2, mNDM->run); EXPECT_EQ(1, mNDNM->run); EXPECT_EQ(1, mNDM2->run); diff --git a/unittests/VMCore/TypeBuilderTest.cpp b/unittests/VMCore/TypeBuilderTest.cpp new file mode 100644 index 0000000..a746b1f --- /dev/null +++ b/unittests/VMCore/TypeBuilderTest.cpp @@ -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 diff --git a/unittests/VMCore/TypesTest.cpp b/unittests/VMCore/TypesTest.cpp new file mode 100644 index 0000000..0416643 --- /dev/null +++ b/unittests/VMCore/TypesTest.cpp @@ -0,0 +1,30 @@ +//===- llvm/unittest/VMCore/TypesTest.cpp - Type unit tests ---------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DerivedTypes.h" +#include "llvm/LLVMContext.h" +#include "gtest/gtest.h" +using namespace llvm; + +namespace { + +TEST(TypesTest, StructType) { + LLVMContext C; + + // PR13522 + StructType *Struct = StructType::create(C, "FooBar"); + EXPECT_EQ("FooBar", Struct->getName()); + Struct->setName(Struct->getName().substr(0, 3)); + EXPECT_EQ("Foo", Struct->getName()); + Struct->setName(""); + EXPECT_TRUE(Struct->getName().empty()); + EXPECT_FALSE(Struct->hasName()); +} + +} // end anonymous namespace |