Index: include/llvm/IR/BasicBlock.h =================================================================== --- include/llvm/IR/BasicBlock.h +++ include/llvm/IR/BasicBlock.h @@ -29,31 +29,6 @@ class LLVMContext; class BlockAddress; -template<> struct ilist_traits - : public SymbolTableListTraits { - - /// \brief Return a node that marks the end of a list. - /// - /// The sentinel is relative to this instance, so we use a non-static - /// method. - Instruction *createSentinel() const { - // Since i(p)lists always publicly derive from their corresponding traits, - // placing a data member in this class will augment the i(p)list. But since - // the NodeTy is expected to be publicly derive from ilist_node, - // there is a legal viable downcast from it to NodeTy. We use this trick to - // superimpose an i(p)list with a "ghostly" NodeTy, which becomes the - // sentinel. Dereferencing the sentinel is forbidden (save the - // ilist_node), so no one will ever notice the superposition. - return static_cast(&Sentinel); - } - static void destroySentinel(Instruction*) {} - - Instruction *provideInitialHead() const { return createSentinel(); } - Instruction *ensureHead(Instruction*) const { return createSentinel(); } - static void noteHead(Instruction*, Instruction*) {} -private: - mutable ilist_half_node Sentinel; -}; /// \brief LLVM Basic Block Representation /// Index: include/llvm/IR/Instruction.h =================================================================== --- include/llvm/IR/Instruction.h +++ include/llvm/IR/Instruction.h @@ -18,6 +18,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/ilist_node.h" #include "llvm/IR/DebugLoc.h" +#include "llvm/IR/SymbolTableListTraits.h" #include "llvm/IR/User.h" namespace llvm { @@ -25,10 +26,27 @@ class FastMathFlags; class LLVMContext; class MDNode; +class BasicBlock; struct AAMDNodes; -template - class SymbolTableListTraits; +template <> +struct ilist_traits + : public SymbolTableListTraits { + + /// \brief Return a node that marks the end of a list. + /// + /// The sentinel is relative to this instance, so we use a non-static + /// method. + Instruction *createSentinel() const; + static void destroySentinel(Instruction *) {} + + Instruction *provideInitialHead() const { return createSentinel(); } + Instruction *ensureHead(Instruction *) const { return createSentinel(); } + static void noteHead(Instruction *, Instruction *) {} + +private: + mutable ilist_half_node Sentinel; +}; class Instruction : public User, public ilist_node { void operator=(const Instruction &) = delete; @@ -69,7 +87,8 @@ /// eraseFromParent - This method unlinks 'this' from the containing basic /// block and deletes it. /// - void eraseFromParent(); + /// \returns an iterator pointing to the element after the erased one + iplist::iterator eraseFromParent(); /// insertBefore - Insert an unlinked instructions into a basic block /// immediately before the specified instruction. @@ -493,6 +512,17 @@ }; +inline Instruction *ilist_traits::createSentinel() const { + // Since i(p)lists always publicly derive from their corresponding traits, + // placing a data member in this class will augment the i(p)list. But since + // the NodeTy is expected to be publicly derive from ilist_node, + // there is a legal viable downcast from it to NodeTy. We use this trick to + // superimpose an i(p)list with a "ghostly" NodeTy, which becomes the + // sentinel. Dereferencing the sentinel is forbidden (save the + // ilist_node), so no one will ever notice the superposition. + return static_cast(&Sentinel); +} + // Instruction* is only 4-byte aligned. template<> class PointerLikeTypeTraits { Index: lib/IR/Instruction.cpp =================================================================== --- lib/IR/Instruction.cpp +++ lib/IR/Instruction.cpp @@ -62,8 +62,8 @@ getParent()->getInstList().remove(this); } -void Instruction::eraseFromParent() { - getParent()->getInstList().erase(this); +iplist::iterator Instruction::eraseFromParent() { + return getParent()->getInstList().erase(this); } /// insertBefore - Insert an unlinked instructions into a basic block