+//===----------------------------------------------------------------------===//
+/// FoldingSetNodeWrapper - This template class is used to "wrap" arbitrary
+/// types in an enclosing object so that they can be inserted into FoldingSets.
+template <typename T>
+class FoldingSetNodeWrapper : public FoldingSetNode {
+ T data;
+public:
+ explicit FoldingSetNodeWrapper(const T& x) : data(x) {}
+ virtual ~FoldingSetNodeWrapper() {}
+
+ template<typename A1>
+ explicit FoldingSetNodeWrapper(const A1& a1)
+ : data(a1) {}
+
+ template <typename A1, typename A2>
+ explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2)
+ : data(a1,a2) {}
+
+ template <typename A1, typename A2, typename A3>
+ explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3)
+ : data(a1,a2,a3) {}
+
+ template <typename A1, typename A2, typename A3, typename A4>
+ explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3,
+ const A4& a4)
+ : data(a1,a2,a3,a4) {}
+
+ template <typename A1, typename A2, typename A3, typename A4, typename A5>
+ explicit FoldingSetNodeWrapper(const A1& a1, const A2& a2, const A3& a3,
+ const A4& a4, const A5& a5)
+ : data(a1,a2,a3,a4,a5) {}
+
+
+ void Profile(FoldingSetNodeID& ID) { FoldingSetTrait<T>::Profile(data, ID); }
+
+ T& getValue() { return data; }
+ const T& getValue() const { return data; }
+
+ operator T&() { return data; }
+ operator const T&() const { return data; }
+};
+
+//===----------------------------------------------------------------------===//
+// Partial specializations of FoldingSetTrait.
+
+template<typename T> struct FoldingSetTrait<T*> {
+ static inline void Profile(const T* X, FoldingSetNodeID& ID) {
+ ID.AddPointer(X);
+ }
+ static inline void Profile(T* X, FoldingSetNodeID& ID) {
+ ID.AddPointer(X);
+ }
+};
+
+template<typename T> struct FoldingSetTrait<const T*> {
+ static inline void Profile(const T* X, FoldingSetNodeID& ID) {
+ ID.AddPointer(X);
+ }
+};
+
+} // End of namespace llvm.
+
+#endif