From 4a38930a4595d94b1f379d6955c531c48e5c2aa0 Mon Sep 17 00:00:00 2001 From: Jeffrey Yasskin Date: Wed, 9 Sep 2009 05:04:01 +0000 Subject: [PATCH] Make TypeBuilder's result depend on the LLVMContext it's passed. TypeBuilder was using a local static variable to cache its result. This made it ignore changes in its LLVMContext argument and always return a type constructed from the argument to the first call. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81316 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/TypeBuilder.h | 109 +++----------------------- unittests/Support/TypeBuilderTest.cpp | 12 +++ 2 files changed, 24 insertions(+), 97 deletions(-) diff --git a/include/llvm/Support/TypeBuilder.h b/include/llvm/Support/TypeBuilder.h index 64af647cdb8..fb22e3f5241 100644 --- a/include/llvm/Support/TypeBuilder.h +++ b/include/llvm/Support/TypeBuilder.h @@ -50,15 +50,14 @@ namespace llvm { /// namespace llvm { /// template class TypeBuilder { /// public: -/// static const StructType *get() { -/// // Using the static result variable ensures that the type is -/// // only looked up once. -/// static const StructType *const result = StructType::get( -/// TypeBuilder, xcompile>::get(), -/// TypeBuilder*, xcompile>::get(), -/// TypeBuilder*[], xcompile>::get(), +/// static const StructType *get(LLVMContext &Context) { +/// // If you cache this result, be sure to cache it separately +/// // for each LLVMContext. +/// return StructType::get( +/// TypeBuilder, xcompile>::get(Context), +/// TypeBuilder*, xcompile>::get(Context), +/// TypeBuilder*[], xcompile>::get(Context), /// NULL); -/// return result; /// } /// /// // You may find this a convenient place to put some constants @@ -72,9 +71,6 @@ namespace llvm { /// } /// } // namespace llvm /// -/// Using the static result variable ensures that the type is only looked up -/// once. -/// /// 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 throw a recursive_init exception. @@ -106,9 +102,7 @@ template class TypeBuilder template class TypeBuilder { public: static const PointerType *get(LLVMContext &Context) { - static const PointerType *const result = - PointerType::getUnqual(TypeBuilder::get(Context)); - return result; + return PointerType::getUnqual(TypeBuilder::get(Context)); } }; @@ -119,18 +113,14 @@ template class TypeBuilder {}; template class TypeBuilder { public: static const ArrayType *get(LLVMContext &Context) { - static const ArrayType *const result = - ArrayType::get(TypeBuilder::get(Context), N); - return result; + return ArrayType::get(TypeBuilder::get(Context), N); } }; /// LLVM uses an array of length 0 to represent an unknown-length array. template class TypeBuilder { public: static const ArrayType *get(LLVMContext &Context) { - static const ArrayType *const result = - ArrayType::get(TypeBuilder::get(Context), 0); - return result; + return ArrayType::get(TypeBuilder::get(Context), 0); } }; @@ -160,9 +150,7 @@ public: template<> class TypeBuilder { \ public: \ static const IntegerType *get(LLVMContext &Context) { \ - static const IntegerType *const result = \ - IntegerType::get(Context, sizeof(T) * CHAR_BIT); \ - return result; \ + return IntegerType::get(Context, sizeof(T) * CHAR_BIT); \ } \ }; \ template<> class TypeBuilder { \ @@ -191,8 +179,7 @@ template class TypeBuilder, cross> { public: static const IntegerType *get(LLVMContext &C) { - static const IntegerType *const result = IntegerType::get(C, num_bits); - return result; + return IntegerType::get(C, num_bits); } }; @@ -248,24 +235,12 @@ template<> class TypeBuilder template class TypeBuilder { public: static const FunctionType *get(LLVMContext &Context) { - static const FunctionType *const result = create(Context); - return result; - } - -private: - static const FunctionType *create(LLVMContext &Context) { return FunctionType::get(TypeBuilder::get(Context), false); } }; template class TypeBuilder { public: static const FunctionType *get(LLVMContext &Context) { - static const FunctionType *const result = create(Context); - return result; - } - -private: - static const FunctionType *create(LLVMContext &Context) { std::vector params; params.reserve(1); params.push_back(TypeBuilder::get(Context)); @@ -277,12 +252,6 @@ template class TypeBuilder { public: static const FunctionType *get(LLVMContext &Context) { - static const FunctionType *const result = create(Context); - return result; - } - -private: - static const FunctionType *create(LLVMContext &Context) { std::vector params; params.reserve(2); params.push_back(TypeBuilder::get(Context)); @@ -295,12 +264,6 @@ template class TypeBuilder { public: static const FunctionType *get(LLVMContext &Context) { - static const FunctionType *const result = create(Context); - return result; - } - -private: - static const FunctionType *create(LLVMContext &Context) { std::vector params; params.reserve(3); params.push_back(TypeBuilder::get(Context)); @@ -316,12 +279,6 @@ template { public: static const FunctionType *get(LLVMContext &Context) { - static const FunctionType *const result = create(Context); - return result; - } - -private: - static const FunctionType *create(LLVMContext &Context) { std::vector params; params.reserve(4); params.push_back(TypeBuilder::get(Context)); @@ -338,12 +295,6 @@ template { public: static const FunctionType *get(LLVMContext &Context) { - static const FunctionType *const result = create(Context); - return result; - } - -private: - static const FunctionType *create(LLVMContext &Context) { std::vector params; params.reserve(5); params.push_back(TypeBuilder::get(Context)); @@ -359,12 +310,6 @@ private: template class TypeBuilder { public: static const FunctionType *get(LLVMContext &Context) { - static const FunctionType *const result = create(Context); - return result; - } - -private: - static const FunctionType *create(LLVMContext &Context) { return FunctionType::get(TypeBuilder::get(Context), true); } }; @@ -372,12 +317,6 @@ template class TypeBuilder { public: static const FunctionType *get(LLVMContext &Context) { - static const FunctionType *const result = create(Context); - return result; - } - -private: - static const FunctionType *create(LLVMContext &Context) { std::vector params; params.reserve(1); params.push_back(TypeBuilder::get(Context)); @@ -388,12 +327,6 @@ template class TypeBuilder { public: static const FunctionType *get(LLVMContext &Context) { - static const FunctionType *const result = create(Context); - return result; - } - -private: - static const FunctionType *create(LLVMContext &Context) { std::vector params; params.reserve(2); params.push_back(TypeBuilder::get(Context)); @@ -406,12 +339,6 @@ template class TypeBuilder { public: static const FunctionType *get(LLVMContext &Context) { - static const FunctionType *const result = create(Context); - return result; - } - -private: - static const FunctionType *create(LLVMContext &Context) { std::vector params; params.reserve(3); params.push_back(TypeBuilder::get(Context)); @@ -427,12 +354,6 @@ template { public: static const FunctionType *get(LLVMContext &Context) { - static const FunctionType *const result = create(Context); - return result; - } - -private: - static const FunctionType *create(LLVMContext &Context) { std::vector params; params.reserve(4); params.push_back(TypeBuilder::get(Context)); @@ -449,12 +370,6 @@ template { public: static const FunctionType *get(LLVMContext &Context) { - static const FunctionType *const result = create(Context); - return result; - } - -private: - static const FunctionType *create(LLVMContext &Context) { std::vector params; params.reserve(5); params.push_back(TypeBuilder::get(Context)); diff --git a/unittests/Support/TypeBuilderTest.cpp b/unittests/Support/TypeBuilderTest.cpp index bd9f5d64a2c..fae8907cda6 100644 --- a/unittests/Support/TypeBuilderTest.cpp +++ b/unittests/Support/TypeBuilderTest.cpp @@ -147,6 +147,18 @@ TEST(TypeBuilderTest, Functions) { 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, true>::get(context1))->getContext()); + LLVMContext context2; + EXPECT_EQ(&context2, + &(TypeBuilder, true>::get(context2))->getContext()); +} + class MyType { int a; int *b;