Skip to content

Commit

Permalink
Merge 81316 from mainline.
Browse files Browse the repository at this point in the history
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/branches/release_26@81694 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
tlattner committed Sep 13, 2009
1 parent ac591b8 commit bb16ea9
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 97 deletions.
109 changes: 12 additions & 97 deletions include/llvm/Support/TypeBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand Down Expand Up @@ -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));
}
};

Expand All @@ -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);
}
};

Expand Down Expand Up @@ -160,9 +150,7 @@ template<typename T, bool cross> class TypeBuilder<T[], cross> {
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> { \
Expand Down Expand Up @@ -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);
}
};

Expand Down Expand Up @@ -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));
Expand All @@ -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));
Expand All @@ -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));
Expand All @@ -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));
Expand All @@ -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));
Expand All @@ -359,25 +310,13 @@ class TypeBuilder<R(A1, A2, A3, A4, A5), cross> {
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);
}
};
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));
Expand All @@ -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));
Expand All @@ -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));
Expand All @@ -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));
Expand All @@ -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));
Expand Down
12 changes: 12 additions & 0 deletions unittests/Support/TypeBuilderTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit bb16ea9

Please sign in to comment.