summaryrefslogtreecommitdiff
path: root/include/llvm/ADT/alist_node.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/ADT/alist_node.h')
-rw-r--r--include/llvm/ADT/alist_node.h126
1 files changed, 126 insertions, 0 deletions
diff --git a/include/llvm/ADT/alist_node.h b/include/llvm/ADT/alist_node.h
new file mode 100644
index 0000000000..a1f18c0bcb
--- /dev/null
+++ b/include/llvm/ADT/alist_node.h
@@ -0,0 +1,126 @@
+//==- llvm/ADT/alist_node.h - Next/Prev helper class for alist ---*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the alist_node class template, which is used by the alist
+// class template to provide next/prev pointers for arbitrary objects.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ALIST_NODE_H
+#define LLVM_ADT_ALIST_NODE_H
+
+#include <cassert>
+#include "llvm/ADT/ilist.h"
+#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+/// alist_node - This is a utility class used by alist. It holds prev and next
+/// pointers for use with ilists, as well as storage for objects as large as
+/// LargestT, that are in T's inheritance tree.
+///
+template<class T, class LargestT = T>
+class alist_node {
+ alist_node *Prev, *Next;
+
+public:
+ alist_node() : Prev(0), Next(0) {}
+
+ alist_node *getPrev() const { return Prev; }
+ alist_node *getNext() const { return Next; }
+ void setPrev(alist_node *N) { Prev = N; }
+ void setNext(alist_node *N) { Next = N; }
+
+ union {
+ char Bytes[sizeof(LargestT)];
+ long long L;
+ void *P;
+ } Storage;
+
+ template<class SubClass>
+ SubClass *getElement(SubClass *) {
+ assert(sizeof(SubClass) <= sizeof(LargestT));
+ assert(unsigned(AlignOf<SubClass>::Alignment) <=
+ unsigned(AlignOf<LargestT>::Alignment));
+ return reinterpret_cast<SubClass*>(&Storage.Bytes);
+ }
+
+ template<class SubClass>
+ const SubClass *getElement(SubClass *) const {
+ assert(sizeof(SubClass) <= sizeof(LargestT));
+ assert(unsigned(AlignOf<SubClass>::Alignment) <=
+ unsigned(AlignOf<LargestT>::Alignment));
+ return reinterpret_cast<const SubClass*>(&Storage.Bytes);
+ }
+
+ // This code essentially does offsetof, but actual offsetof hits an ICE in
+ // GCC 4.0 relating to offsetof being used inside a template.
+ static alist_node* getNode(T *D) {
+ return reinterpret_cast<alist_node*>(reinterpret_cast<char*>(D) -
+ (uintptr_t)&getNull()->Storage);
+ }
+ static const alist_node* getNode(const T *D) {
+ return reinterpret_cast<alist_node*>(reinterpret_cast<char*>(D) -
+ (uintptr_t)&getNull()->Storage);
+ }
+private:
+ static alist_node* getNull() { return 0; }
+};
+
+// A specialization of ilist_traits for alist_nodes.
+template<class T, class LargestT>
+class ilist_traits<alist_node<T, LargestT> > {
+ typedef alist_node<T, LargestT> NodeTy;
+
+protected:
+ // Allocate a sentinel inside the traits class. This works
+ // because iplist carries an instance of the traits class.
+ NodeTy Sentinel;
+
+public:
+ static NodeTy *getPrev(NodeTy *N) { return N->getPrev(); }
+ static NodeTy *getNext(NodeTy *N) { return N->getNext(); }
+ static const NodeTy *getPrev(const NodeTy *N) { return N->getPrev(); }
+ static const NodeTy *getNext(const NodeTy *N) { return N->getNext(); }
+
+ static void setPrev(NodeTy *N, NodeTy *Prev) { N->setPrev(Prev); }
+ static void setNext(NodeTy *N, NodeTy *Next) { N->setNext(Next); }
+
+ NodeTy *createSentinel() const {
+ assert(Sentinel.getPrev() == 0);
+ assert(Sentinel.getNext() == 0);
+ return const_cast<NodeTy*>(&Sentinel);
+ }
+
+ void destroySentinel(NodeTy *N) {
+ assert(N == &Sentinel);
+ Sentinel.setPrev(0);
+ Sentinel.setNext(0);
+ }
+
+ void addNodeToList(NodeTy *N) {}
+ void removeNodeFromList(NodeTy *N) {}
+ void transferNodesFromList(iplist<NodeTy, ilist_traits> &L2,
+ ilist_iterator<NodeTy> first,
+ ilist_iterator<NodeTy> last) {}
+
+ // Ideally we wouldn't implement this, but ilist's clear calls it,
+ // which is called from ilist's destructor. We won't ever call
+ // either of those with a non-empty list, but statically this
+ // method needs to exist.
+ void deleteNode(NodeTy *N) { assert(0); }
+
+private:
+ static NodeTy *createNode(const NodeTy &V); // do not implement
+};
+
+}
+
+#endif