// file : CCF/IDL2/Traversal/Elements.hpp // author : Boris Kolpackov // cvs-id : $Id$ #ifndef CCF_IDL2_TRAVERSAL_ELEMENTS_HPP #define CCF_IDL2_TRAVERSAL_ELEMENTS_HPP #include #include #include "CCF/CompilerElements/Introspection.hpp" #include "CCF/IDL2/SemanticGraph/Elements.hpp" /* #include using std::cerr; using std::endl; */ namespace CCF { namespace IDL2 { namespace Traversal { // // // template class Traverser { protected: virtual ~Traverser (); virtual void trampoline (T& n) = 0; template friend class Dispatcher; }; // // // template class Dispatcher { public: virtual ~Dispatcher (); virtual void traverse (T& n); void map (Introspection::TypeId id, Traverser& t) { Traversers& traversers (traversal_map_[id]); traversers.push_back (&t); } public: typedef std::vector*> Traversers; typedef std::map TraversalMap; typedef typename TraversalMap::const_iterator Iterator; Iterator begin () const { return traversal_map_.begin (); } Iterator end () const { return traversal_map_.end (); } private: struct TypeInfoComparator { bool operator () (Introspection::TypeInfo const& x, Introspection::TypeInfo const& y) const { return x.type_id () < y.type_id (); } }; typedef std::map LevelMap; typedef std::set TypeInfoSet; static unsigned long compute_levels (Introspection::TypeInfo const& ti, unsigned long cur, LevelMap& map); static void flatten_tree (Introspection::TypeInfo const& ti, TypeInfoSet& set); private: TraversalMap traversal_map_; }; // // // typedef Dispatcher NodeDispatcherBase; typedef Dispatcher EdgeDispatcherBase; // // // class NodeDispatcher : public virtual NodeDispatcherBase { public: void edge_traverser (EdgeDispatcherBase& d) { //@@ this should be done in Dispatcher in merge() function? // for (EdgeDispatcherBase::Iterator i (d.begin ()), end (d.end ()); i != end; ++i) { for (EdgeDispatcherBase::Traversers::const_iterator t (i->second.begin ()), end (i->second.end ()); t != end; ++t) { dispatcher_.map (i->first, **t); } } } protected: template void iterate_and_traverse (I begin, I end, EdgeDispatcherBase& d) { for (; begin != end; ++begin) { d.traverse (**begin); } } template void iterate_and_traverse (I begin, I end, EdgeDispatcherBase& d, X& x, void (X::*f)(A&), A& a) { for (I i (begin); i != end;) { d.traverse (**i); if (++i != end) (x.*f) (a); } } EdgeDispatcherBase& edge_traverser () { return dispatcher_; } protected: EdgeDispatcherBase dispatcher_; }; class EdgeDispatcher : public virtual EdgeDispatcherBase { public: //@@ this should be done in Dispatcher in merge() function? // void node_traverser (NodeDispatcherBase& d) { for (NodeDispatcherBase::Iterator i (d.begin ()), end (d.end ()); i != end; ++i) { for (NodeDispatcherBase::Traversers::const_iterator t (i->second.begin ()), end (i->second.end ()); t != end; ++t) { dispatcher_.map (i->first, **t); } } } protected: NodeDispatcherBase& node_traverser () { return dispatcher_; } protected: NodeDispatcherBase dispatcher_; }; // // // template struct Node : Traverser, virtual NodeDispatcher { typedef T Type; Node () { map (typeid (Type), *this); } virtual void trampoline (SemanticGraph::Node& n) { //cerr << "trampoline for " << &n << " to type " // << typeid (Type).name () << endl; traverse (dynamic_cast (n)); } virtual void traverse (Type&) = 0; }; template struct Edge : Traverser , virtual EdgeDispatcher { typedef T Type; Edge () { map (typeid (Type), *this); } virtual void trampoline (SemanticGraph::Edge& e) { traverse (dynamic_cast (e)); } virtual void traverse (Type& e) = 0; }; // Edges // // struct Names : Edge { virtual void traverse (Type& e) { node_traverser ().traverse (e.named ()); } }; struct Defines : Edge { virtual void traverse (Type& e) { node_traverser ().traverse (e.named ()); } }; struct Mentions : Edge { virtual void traverse (Type& e) { node_traverser ().traverse (e.named ()); } }; struct Aliases : Edge { virtual void traverse (Type& a) { pre (a); type (a); name (a); post (a); } virtual void pre (Type&) { } virtual void type (Type& e) { node_traverser ().traverse (e.named ()); } virtual void name (Type&) { } virtual void post (Type&) { } }; struct Belongs : Edge { virtual void traverse (Type& e) { node_traverser ().traverse (e.type ()); } }; struct Arguments : Edge { virtual void traverse (Type& a) { node_traverser ().traverse (a.argument ()); } }; struct ArgumentsWithType : Edge { virtual void traverse (Type& a) { node_traverser ().traverse (a.type ()); } }; struct ArgumentsWithValue : Edge { virtual void traverse (Type& a) { node_traverser ().traverse (a.value ()); } }; struct Inherits : Edge { virtual void traverse (Type& e) { node_traverser ().traverse (e.inheritee ()); } }; struct Contains : Edge { }; // Nodes // // struct Nameable : Node { }; template struct ScopeTemplate : Node { public: /* GCC#13590/DR#39 using Node::edge_traverser; */ virtual void traverse (T& s) { names (s); } virtual void names (T& s) { names_pre (s); names (s, this->edge_traverser ()); names_post (s); } virtual void names (T& s, EdgeDispatcherBase& d) { iterate_and_traverse (s.names_begin (), s.names_end (), d); } virtual void names_pre (T&) { } virtual void names_post (T&) { } }; // // // typedef ScopeTemplate Scope; // // // struct Type : Node { virtual void traverse (SemanticGraph::Type&) = 0; }; } } } #include "CCF/IDL2/Traversal/Elements.tpp" #endif // CCF_IDL2_TRAVERSAL_ELEMENTS_HPP