Index: include/llvm/ADT/DepthFirstIterator.h =================================================================== --- include/llvm/ADT/DepthFirstIterator.h +++ include/llvm/ADT/DepthFirstIterator.h @@ -66,17 +66,28 @@ // one more method, completed, which is invoked when all children of a // node have been processed. It is intended to distinguish of back and // cross edges in the spanning tree but is not used in the common case. -template -struct df_iterator_default_set : public SmallPtrSet { - using BaseSet = SmallPtrSet; - using iterator = typename BaseSet::iterator; - - std::pair insert(NodeRef N) { return BaseSet::insert(N); } - template - void insert(IterT Begin, IterT End) { BaseSet::insert(Begin,End); } +// If completed exists in the set type, it is called. +template +using df_iterator_default_set = SmallPtrSet; + +// This lets us detect if the set we've been handed has a completed method we +// should be calling. The int vs bool argument is to make it prefer one +// overload over another in the case of ambiguity. bool requires a conversion, +// the int does not. +template +auto call_completed_method_imp(T &t, NodeRef V, int) + -> decltype(t.completed(V), void()) { + return t.completed(V); +} +template +void call_completed_method_imp(T &t, NodeRef V, bool) { + return; +} - void completed(NodeRef) {} -}; +template +void call_completed_method(T &t, NodeRef V){ + call_completed_method_imp(t, V, 0); +} // Generic Depth First Iterator template Visited.completed(Node); + call_completed_method(this->Visited, Node); // Oops, ran out of successors... go up a level on the stack. VisitStack.pop_back();