diff options
author | Tanya Lattner <tonic@nondot.org> | 2009-09-13 19:02:05 +0000 |
---|---|---|
committer | Tanya Lattner <tonic@nondot.org> | 2009-09-13 19:02:05 +0000 |
commit | bdf147f759c7adb15668e58b84b82ba96c9ee7dc (patch) | |
tree | 4ecf3f2ee255dd69d458d37bb7080778bb9cf0d7 | |
parent | Merge 81175 from mainline. (diff) | |
download | llvm-project-bdf147f759c7adb15668e58b84b82ba96c9ee7dc.tar.gz llvm-project-bdf147f759c7adb15668e58b84b82ba96c9ee7dc.tar.bz2 llvm-project-bdf147f759c7adb15668e58b84b82ba96c9ee7dc.zip |
Merge 81316 from mainline.
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.
llvm-svn: 81694
-rw-r--r-- | llvm/include/llvm/Support/TypeBuilder.h | 109 | ||||
-rw-r--r-- | llvm/unittests/Support/TypeBuilderTest.cpp | 12 |
2 files changed, 24 insertions, 97 deletions
diff --git a/llvm/include/llvm/Support/TypeBuilder.h b/llvm/include/llvm/Support/TypeBuilder.h index 64af647cdb8c..fb22e3f5241d 100644 --- a/llvm/include/llvm/Support/TypeBuilder.h +++ b/llvm/include/llvm/Support/TypeBuilder.h @@ -50,15 +50,14 @@ namespace llvm { /// namespace llvm { /// template<bool xcompile> class TypeBuilder<MyType, xcompile> { /// 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<types::i<32>, xcompile>::get(), -/// TypeBuilder<types::i<32>*, xcompile>::get(), -/// TypeBuilder<types::i<8>*[], 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<types::i<32>, xcompile>::get(Context), +/// TypeBuilder<types::i<32>*, xcompile>::get(Context), +/// TypeBuilder<types::i<8>*[], 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<typename T, bool cross> class TypeBuilder<const volatile T, cross> template<typename T, bool cross> class TypeBuilder<T*, cross> { public: static const PointerType *get(LLVMContext &Context) { - static const PointerType *const result = - PointerType::getUnqual(TypeBuilder<T,cross>::get(Context)); - return result; + return PointerType::getUnqual(TypeBuilder<T,cross>::get(Context)); } }; @@ -119,18 +113,14 @@ template<typename T, bool cross> class TypeBuilder<T&, cross> {}; template<typename T, size_t N, bool cross> class TypeBuilder<T[N], cross> { public: static const ArrayType *get(LLVMContext &Context) { - static const ArrayType *const result = - ArrayType::get(TypeBuilder<T, cross>::get(Context), N); - return result; + 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 const ArrayType *get(LLVMContext &Context) { - static const ArrayType *const result = - ArrayType::get(TypeBuilder<T, cross>::get(Context), 0); - return result; + return ArrayType::get(TypeBuilder<T, cross>::get(Context), 0); } }; @@ -160,9 +150,7 @@ public: template<> class TypeBuilder<T, false> { \ 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<T, true> { \ @@ -191,8 +179,7 @@ template<uint32_t num_bits, bool cross> class TypeBuilder<types::i<num_bits>, 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<void*, false> template<typename R, bool cross> class TypeBuilder<R(), cross> { 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<R, cross>::get(Context), false); } }; template<typename R, typename A1, bool cross> class TypeBuilder<R(A1), cross> { 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<const Type*> params; params.reserve(1); params.push_back(TypeBuilder<A1, cross>::get(Context)); @@ -277,12 +252,6 @@ template<typename R, typename A1, typename A2, bool cross> class TypeBuilder<R(A1, A2), cross> { 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<const Type*> params; params.reserve(2); params.push_back(TypeBuilder<A1, cross>::get(Context)); @@ -295,12 +264,6 @@ template<typename R, typename A1, typename A2, typename A3, bool cross> class TypeBuilder<R(A1, A2, A3), cross> { 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<const Type*> params; params.reserve(3); params.push_back(TypeBuilder<A1, cross>::get(Context)); @@ -316,12 +279,6 @@ template<typename R, typename A1, typename A2, typename A3, typename A4, class TypeBuilder<R(A1, A2, A3, A4), cross> { 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<const Type*> params; params.reserve(4); params.push_back(TypeBuilder<A1, cross>::get(Context)); @@ -338,12 +295,6 @@ template<typename R, typename A1, typename A2, typename A3, typename A4, class TypeBuilder<R(A1, A2, A3, A4, A5), cross> { 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<const Type*> params; params.reserve(5); params.push_back(TypeBuilder<A1, cross>::get(Context)); @@ -359,12 +310,6 @@ private: template<typename R, bool cross> class TypeBuilder<R(...), cross> { 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<R, cross>::get(Context), true); } }; @@ -372,12 +317,6 @@ template<typename R, typename A1, bool cross> class TypeBuilder<R(A1, ...), cross> { 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<const Type*> params; params.reserve(1); params.push_back(TypeBuilder<A1, cross>::get(Context)); @@ -388,12 +327,6 @@ template<typename R, typename A1, typename A2, bool cross> class TypeBuilder<R(A1, A2, ...), cross> { 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<const Type*> params; params.reserve(2); params.push_back(TypeBuilder<A1, cross>::get(Context)); @@ -406,12 +339,6 @@ template<typename R, typename A1, typename A2, typename A3, bool cross> class TypeBuilder<R(A1, A2, A3, ...), cross> { 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<const Type*> params; params.reserve(3); params.push_back(TypeBuilder<A1, cross>::get(Context)); @@ -427,12 +354,6 @@ template<typename R, typename A1, typename A2, typename A3, typename A4, class TypeBuilder<R(A1, A2, A3, A4, ...), cross> { 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<const Type*> params; params.reserve(4); params.push_back(TypeBuilder<A1, cross>::get(Context)); @@ -449,12 +370,6 @@ template<typename R, typename A1, typename A2, typename A3, typename A4, class TypeBuilder<R(A1, A2, A3, A4, A5, ...), cross> { 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<const Type*> params; params.reserve(5); params.push_back(TypeBuilder<A1, cross>::get(Context)); diff --git a/llvm/unittests/Support/TypeBuilderTest.cpp b/llvm/unittests/Support/TypeBuilderTest.cpp index bd9f5d64a2c7..fae8907cda6e 100644 --- a/llvm/unittests/Support/TypeBuilderTest.cpp +++ b/llvm/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<types::i<1>, true>::get(context1))->getContext()); + LLVMContext context2; + EXPECT_EQ(&context2, + &(TypeBuilder<types::i<1>, true>::get(context2))->getContext()); +} + class MyType { int a; int *b; |